First Time Linux

Octave

Gnu Octave is a free alternative to the widely-used commercial software Matlab. It offers a powerful set of numerical manipulation and analysis tools, especially with regard to vector and matrix maths. It's also coupled with gnuplot to allow graphical display of the results. The command syntax is (mostly) compatible with Matlab syntax so you can take program files backwards and forwards between the two systems.

Installing and running

It doesn't get much easier. Just do a urpmi octave and it's beautifully downloaded and automatically installed. The only thing it might ask you is which package for "blas" to use - I just chose the most likely-sounding one for the "Basic Linear Algebra Subprograms library" and everything worked.

Now, to run it, just type octave from a command window. Octave itself runs in the command window, without a GUI, so you may want to increase the size of your command window to make some room.

$ octave
GNU Octave, version 3.0.1
Copyright (C) 2008 John W. Eaton and others.
This is free software; see the source code for copying conditions.
There is ABSOLUTELY NO WARRANTY; not even for MERCHANTIBILITY or
FITNESS FOR A PARTICULAR PURPOSE.  For details, type `warranty'.

Octave was configured for "i586-mandriva-linux-gnu".

Additional information about Octave is available at http://www.octave.org.

...

octave:1>

This last line is the command prompt, where you can enter your interactive commands.

Basic commands

We can use this interactive prompt to type in any commands we like, define variables and perform calculations. We don't have to declare variable types when we define our variables. So, for example:

octave:1> x = 4
x =  4
octave:2> y = 17 / x
y =  4.2500

That's simple scalar arithmetic. But we can do it equally easily on a vector:

octave:3> x = [1, 2, 3, 4, 5];
octave:4> y = sin(x * 0.2) + 3
y =
   3.1987   3.3894   3.5646   3.7174   3.8415

Note that the semicolon suppresses the output from the first line. We can also perform more complicated calculations using these vectors:

octave:5> y * (y-1)'
ans =  45.290
octave:6> y' * (y-1)
ans =
    7.0328    7.6430    8.2034    8.6919    9.0889
    7.4522    8.0987    8.6926    9.2103    9.6309
    7.8375    8.5174    9.1420    9.6864   10.1288
    8.1732    8.8823    9.5337   10.1014   10.5628
    8.4461    9.1789    9.8520   10.4386   10.9154

In this case the apostrophe ' calculates the transpose of the matrix or vector. The first example shows a row multiplied by a column, giving a single scalar result, and the second shows a column multiplied by a vector, giving a 5 by 5 matrix.

Just like in the bash shell, using the up cursor arrow will bring back a previously-typed command, which you can edit and resubmit. So you don't have to type in the whole thing again.

Saving functions

Using the interactive prompt is extremely convenient for trying things out, but awkward if you want to repeat a complicated set of calculations. So we need a way to save a set of commands in a file which we can then execute at any time. In Matlab we use the built-in GUI to create and save Matlab files (*.m) and add them to the execution path. In Octave we don't have the same kind of GUI so we use an external editor instead.

You can use any editor you like, whether it's a console-based one like vim or emacs, or a GUI one like Kate or gedit. Just use this external editor to create a new file, and inside it create a function:

function DoSomethingCool()
  % Start with a pair of vectors
  x = (0.0:0.2:5)';
  y = (0.0:0.2:5);
  % Calculate wavey grid
  z = 3 * sin(x) * cos(2*y);
  % Plot a surface
  surf(z)

Save this file as "DoSomethingCool.m" (the filename must match the function name with the ".m" suffix). Once you do this you should get nice syntax-colouring from your editor as long as it understands .m files. Now from the Octave console you should change directory to the directory where you saved the file (using the cd command just like in bash). Then you can call the function directly:

octave:5> DoSomethingCool()

Now grab the grid with your mouse and drag it around!

Printing plots

It's often the case that you want to include the output of an Octave program (or a gnuplot plot) into an OpenOffice document. There are a few ways you can do this.

Quickest and dirtiest is to just grab a screenshot using ksnapshot or gimp, crop the image and reduce the colour depth, and then save as png or gif format. It's obviously important to choose a lossless format for this, not a lossy one like jpeg. Then from OpenOffice you can Insert-Picture and select the picture file, and it's done. There are two main disadvantages with this method, firstly and most importantly you're just saving pixels, which is rough (may not print so nicely, may get jagged edges) and also inefficient (the file size is relatively big). Secondly the way gnuplot plots to the screen, you get a grey background which doesn't go nicely into a document, and apart from the arcane suggestions to modify your X resources it's a pain to reset (amazingly). So you probably have to edit the colour palette in gimp to change the background to white. For each plot.

A better way is to generate an encapsulated postscript file of the plot, which is a kind of vector format. So it's scaleable, sharp, crisp, and prints nicely no matter what the resolution. And as an added bonus it's probably smaller file size than the bitmap. To generate an eps file from the currently displayed plot, just use print -deps filename.eps which generates the specified file in the current directory. Then just use Insert-Picture as before in OpenOffice to insert the plot, still in vector format.

It might also be the case that you want to edit the plot, to provide annotation or change the styles. For this, inkscape is ideal but you have to jump through a few hoops first. Firstly, inkscape can't open the eps file, so you need to convert it first. One way is to use the ps2pdf command to convert it into a pdf file. Then you can open it in inkscape (File-Open), change the document properties to match the file, and then edit the colours, line widths, texts and so on. Alas you can't copy and paste it from here to OpenOffice, nor can you save as svg and import to OpenOffice, but instead you have to save again as eps format, (preferably with a new filename) and use the Insert-Picture function again. So then you get a nice vector format with all the options that inkscape can offer you.

Printing non-4:3 plots

It seems amazing, but unless I'm missing something, Octave can only produce eps files in 4:3 aspect ratio, and only in landscape format. Often that's exactly what you want, but sometimes it's not, especially if you want to stack a few subplots together. So how can you produce a portrait-format vector plot? It's extraordinarily awkward:

You can't specify the size when you do print -deps because the sizes upi specify only affect output to png and svg, not eps. You can't use the orient "portrait" command or the -portrait option to print, because they're both ignored. You can't resize the window because gnuplot and octave don't know and don't care what you've done to the window. You could export to png format with the correct size, but then you only get nasty raster images, not nice vectors. For some reason I can't export to pdf format (I get an error about an invalid terminal), but that would presumably be the same as eps if it worked, that is the desired size would be ignored. You could export to svg, and it would even be at the right size, but then how to convert the svg to an eps or pdf for inclusion in your document?

You could use imagemagick to convert from svg to eps, but then you get back to a nasty raster format again. You could use inkscape to convert the svg but then there's the new gotcha - inkscape doesn't like gnuplot's svg output (I'm still not sure whether this is a gnuplot bug or an inkscape bug, probably the latter) so when you load your svg (which looks fine in other viewers) into inkscape, some lines disappear and are lost when you export to eps. Aaaaarrrrrrggggghhh!

Gotcha

This isn't unique to Octave, it's a function of bash, but it can be surprising - if you accidentally hit Ctrl-Z during an Octave session, you get the strange message:

[1]+  Stopped                 octave
octave $

And then you're dropped unceremoniously back to the bash prompt. Time to panic at all that lost work? No, not in this case. What this terse message is telling you is that your octave job has been stopped and put into the background so you can do other stuff. But if you don't want to do other stuff, you can easily bring octave back to the foreground with the fg command - then you're back in octave with nothing lost.

Global variables

You may be tempted to define global variables at the top of your file so that they're accessible within all the functions of the file. Don't. Octave doesn't like it when the main function definition (with the same name as your .m file) isn't the very first thing it finds in the file.

If you try this, and define global variables before the first function definition, you'll get some extremely strange results. You don't get an error message, and the global variables are defined and are available in all the functions, but Octave will suddenly stop recompiling your code when you change it, it'll just keep running a previous version. So of course you can quit Octave and restart it, or do a "clear all", but then you'll get different error messages, apparently at random. Stuff like this:

octave:7> clear all
octave:8> amazeme()
warning: function 'amazeme' defined within script file `/home/user/octave/amazeme.m'

Well, of course it is. That's where I am, already. And Octave seems to be just confirming that the function name is the same as the filename, which it should be! So what's the problem, why didn't it run the code? Try again...

octave:9> amazeme()
Be amazed!

So the second time you run it, it works! Other times, it sometimes gives other error messages about not being able to find other functions in the file, even though it could find them fine just a few minutes ago. It seems the only workaround in this case is to quit Octave and restart, it seems there are big problems with the caching of function definitions, and the way Octave decides whether it needs to recompile(?) the file or not.

Bottom line: it saves a lot of pain to just avoid global variable definitions altogether. Unless anyone knows a way to define them without driving Octave up the wall?

More info

Octave's home is at gnu.org, which includes the comprehensive documentation and other goodies.

Also see Wikipedia's pages on Gnu Octave and MATLAB.