Category Archives: Computing

Running xppaut in Windows

Running xppaut in Windows is sometimes tricky. My new book on nonlinear dynamics gives brief instructions on installing the Cygwin X server and xppaut in Windows, but I’ve often had trouble getting xppaut to play nice with Cygwin/X. After playing around with today, I think I’ve come up with a set of instructions that will work every time. And of course I expect to be proven wrong almost immediately… However, I’m still happy to share what I’ve learned.

What I’m trying to achieve here is a low-fuss installation that will let you run xppaut from the command line. Because I’m much more familiar with Unix shell programming than with DOS batch files, my solution involves the former. You’re going to be installing Cygwin anyway, so we might as well take advantage of its full power.

I will be leaving you to read the documentation for the details of how to accomplish some of the tasks below. None of them exceed the intelligence of an average person, and links to the documentation are given. Here are the steps:

  1. Install Cygwin. In the package installer, select the latest versions of xinit, xset and xhost for installation.
  2. Get the xppaut for Windows zip file. Unzip the package and put the xppall folder that it contains somewhere sensible. Bard Ermentrout recommends the top level of the boot (C:) drive, but I don’t think that’s necessary.
  3. Add the xppall folder’s location to your PATH environment variable. If you put this folder at the top level of your C: drive, you would add C:\xppall to your PATH variable.
  4. Create the following file using a file editor (Windows Notepad, or a Unix editor like vi or emacs; emacs must be installed first with the Cygwin installer if you want to use that) in the xppall folder that you just installed:
#!/bin/bash

# Script to run xppaut in Cygwin using the Cygwin/X server.
# You can call this script xpp, then invoke it on the command line as you would xppaut.

# Start X server if one isn't already running.
export DISPLAY=127.0.0.1:0.0
if ! xset q >&/dev/null; then
    startxwin -- -listen tcp >&/dev/null &
    # The following 5-second pause will slow down startup, but ensures that the
    # Xwindows server is up before trying to call xhost, which otherwise may hang.
    sleep 5
    xhost +127.0.0.1 >&/dev/null
fi


# Run xppaut, passing through any command-line parameters supplied to this script.
xppaut $1 $2 $3 $4 $5

I recommend that you save this file to into the xppall folder, using the file name xpp. Now open a Cygwin terminal and issue the following commands (assuming you put xppall at the top level of the C: drive):

cd /cygdrive/c/xppall
chmod u+x xpp

This will make this file executable. (It may already have been, but you might as well make sure.) If all went well, you should now be able to run xppaut by typing ‘xpp file.ode’ in a terminal window where, obviously, ‘file.ode’ would be replaced by the name of an ode file in the current working directory. There are a bunch of ode files in xppall/ode. I usually test a new installation of xppaut using lorenz.ode.

Note that this will work provided you do not start the XWin Server from the Start menu.

By all means let me know if you try this and run into problems. Within reason, I will try to help.

Passing arguments to a Matlab script

It’s sometimes useful to run the same program with different parameters many times, for example when we want to systematically vary a parameter in a model to see how it affects the behavior of the model. This is really easy in C and related languages, which have excellent command-line processing facilities. It turns out to be easy in Matlab as well. Since I had to hunt around to figure out how to make this trick work, I thought I would present it here.

Matlab has a -r command-line switch that allows you to execute a Matlab command right after Matlab starts up. For example, here is a Matlab command-line version of the classic “Hello, world!” program:

matlab -r "disp('Hello, world.')"

(As a parenthetical remark, the mysteries of bash command-line interpretation defeated my attempts to put an exclamation mark at the end of the sentence, as is traditional.) If you type this command at a shell prompt, Matlab will print “Hello, world.” just before the Matlab command-line prompt appears. You can of course imagine initializing one or more variables in similar manner:

matlab -r "x=1; y=2;"

OK, but what if you want to initialize some variables used by a Matlab program? There are a couple of options here. One is to include the program name in the quoted command string. If your program is called prog.m, for example, you could type

matlab -r "x=1; y=2; prog"

Alternatively, you could redirect standard input:

matlab -r "x=1; y=2;" < prog.m

The above will work provided the variables x and y are not defined inside prog.m. If you always want to define these variables from the command-line, then that’s fine. However, you might want to have variables that have default values that you can override from the command line. This is also fairly easy. Consider the following program, which we will assume has been saved into a file called prog2.m:

if ~exist('x')
    x = 0.1;
end
x

The command line matlab -r "x=1; prog2" displays an x value of 1, while the command line matlab -r prog2 sets x to 0.1, as you might have expected.

Matlab and integers

In computer programming, when a calculation involves variables of different types, we say that these calculations are performed in mixed-mode arithmetic. In most common typed programming languages, mixed-mode arithmetic involves promotion of variables in such a way as not to lose precision. The most common examples of mixed-mode arithmetic would be calculations involving integer and floating-point variables. As a rule, the integer variables are converted to floating-point values before the arithmetic operations are carried out. Consider for example the following C program:

int main()
{
    int two = 2;
    double x = 2.2;
    double y = two*x;
    printf("%f\n",y);
}

When computing y, the integer two is converted to a double-precision value in order not to degrade the precision of the mixed-mode multiplication with the double-precision value x. The multiplication is then carried out, and the computer prints out 4.4, as expected. Fortran functions in an essentially identical way. Note that the promotion rules are independent of the variable to which the result will be assigned. If necessary, the result of the computation is converted to another type before storage.

Of all the computer languages I have worked with, Matlab is the first one that goes the other way. Consider the following Matlab code:

two = int8(2);
x = 2.2;
y = two*x

Just assigning a value to x, whether or not it has a decimal point, implicitly makes x a double, as reported by class(x). (Most of us who started out with Fortran eventually came to the conclusion that implicit typing is a great evil. Too bad the Matlab folks don’t feel the same way.) If you run this code in Matlab, you will get the following result: y = 4. If you query Matlab about the class of y, it will return int8. Not what most of us would expect…

This unusual behavior means that you have to be very careful when using integers in Matlab. It is very easy to write a line of mixed-mode arithmetic that won’t trigger any warnings, but that will generate results different from those expected by the programmer.

So what is the rational response to Matlab’s unusual mixed-mode arithmetic rules? One might be tempted to simply avoid integers, but the fact is that there are good reasons to use integer variables from time to time. Here are a few guidelines that might help:

  1. Minimize the use of integers in Matlab programs. You probably don’t need an integer variable for a simple accumulator (e.g. a variable that counts up how many times something happened). (Note the use of the word “probably” in the previous sentence. I know that there are clever people who will cook up counterexamples. As with all things, you have to think a bit about what your data will look like. Since we’re talking about scientific programming here, we probably don’t need to worry about malicious users, although simple mistakes in the input are always a possibility and you do have to plan for those. But that’s a matter of testing the inputs to the program, and not what happens when reasonable inputs have passed through those filters.) You may not need an integer array to store data that, conceptually, ought to be integer in nature, provided you’re careful not to do things that are risky with floating-point numbers, such as comparing them for equality. (For a brief introduction to some of the issues you can run into with floating-point numbers, see http://floating-point-gui.de.) I have to say right up front that this is contrary to the advice I would give for any other computer language I know. We would normally think of appropriate typing of variables as a smart, safe practice that prevents, for example, variables representing whole numbers from accidentally being corrupted into non-integer values. Here though, the risk of numbers being unintentionally rounded to integers during a mixed-mode calculation is the greater risk.
  2. Make a habit of searching for instances of any integer variables in your Matlab programs. Be aware that code such as
    x = int16(1);
    y = x;
    

    implicitly makes y of class int16. (Again with the implicit typing!) In fact,

    x = int16(1);
    y(1) = x;
    y(2) = 4.8
    

    generates the output

    y =
    
          1      5
    

    since the entire array y is typed int16 by the assignment of the first element, and the floating-point value 4.8 is converted to an integer (by rounding) prior to storage.

    Comment any implicitly typed integer variables to make their types clear to anyone reading the code. Look for places where integer variables, whether implicit or explicit, are involved in mixed-mode arithmetic and explicitly convert the integers to double in the arithmetic expressions (unless you require some other behavior, of course).

  3. Watch for whole-number outputs to programs whose outputs are not expected to be whole numbers. This can be a sign that a mixed-mode calculation has resulted in an integer result.
  4. Do use integers for tags. Tags, in the sense I intend here, are numbers we associate with each of several possibilities, to be used perhaps in a case statement, or to symbolically represent positions in an array associated with particular objects. Here is a simple-minded example, which we might use in a program that handled employee data in a restaurant:
    Unclassified = int8(0);
    Cook = int8(1);
    ShiftSupervisor = int8(2);
    

    The idea is that we would have a field in the employee record that contained his or her job classification. Rather than store a word (where maintaining consistent spelling might be a long-term maintenance headache), we store a number that represents the job classification, and rather than using those numbers explicitly anywhere, we use the tags defined above, e.g.

    if (employee(i).jobclass == Cook)
    ...
    

    This makes the code easy to read and easy to maintain. Since we are going to compare tags from time to time for equality (as in the above code snippet), we need a type where these comparisons can be made exactly, i.e. an integer type.

I generally like Matlab because it provides a large set of functions to carry out just about every common numerical procedure you might run across, which is great from the point of view of not having to reinvent the wheel. It’s also a very easy programming environment for students to learn. Here though, we have run into two bad (in my opinion) language design decisions:

  1. Mixed-mode arithmetic rules that are likely to generate hard-to-find bugs because they violate most programmers’ expectations.
  2. Implicit typing, which was a common source of bugs in Fortran before the IMPLICIT NONE declaration was made standard.

Both of these design decisions are built into Matlab and it would be hard to fix them without breaking a lot of existing code. I guess we’ll all have to learn to be extremely careful with integers in Matlab.