Octave, a Free Math Language Very Similar To MATLAB
Do you need a matrix language quick, and one that won't cost you an
arm and a leg? One that's highly compatible with Matlab?
How about a language that offers all of that, is loaded with supplemental
math routines, and can cost you  nothing?
If that sounds enticing, then read on to learn about the popular
matrix scripting language Octave.
If you like what you see and want more complete information, check out the GNU Octave Beginner's Guide.
The image below was made with the Octave mesh command. It
shows what's called a sin(x)/x curve. It also happens to be the intensity graph
of a star image as seen through a telescope. It always makes an impressive
example for surface plot utilities. The primary graphics utilities of
Octave are implemented by the Gnuplot program, detailed in the
available manual:
Gnuplot 5.0 Reference Manual. Even though Octave doesn't have defined calls for every option
available in the powerful Gnuplot program, it does provide a primitive
interface for calling Gnuplot that will let the user impliment any
additional features of Gnuplot.
Octave Mesh Plot
Unlike the GUI interface of MATLAB, Octave historically has had a simple
command line interface (no GUI). But it does have a nice history mechanism
allowing one to scroll back to, and if desired modify, previous commands.
In fact, the history is maintained even when exiting Octave and reentering
it later. I do notice that in my lastest install of Octave in a Silax Linux
distro, Octave does optionally have a GUI interface similar to that of
Scilab.
In Windows, Octave isn't spectacular. It runs in kind of a pseudoLinux
environment, and this makes file access withing Windows an awkward and bit
arcane procedure.
The version of Octave reviewed in this article was included in my
Debian Etch Linux distribution, and thus was easily installed.
Octave Syntax
Octave is sort of the GNU answer to the commercial language MATLAB. That is,
it is a scripting matrix language, and has a syntax that is about 95%
compatible with MATLAB. It's a language designed by engineers, and thus is
heavily loaded with routines commonly used by engineers. It has many of the
same time series analysis routines, statistics routines, file commands, and
plotting commands of the MATLAB language.
Octave even uses the "m" file method of creating functions. That is, user
created functions are stored in files with an m extension, and can be called in
Octave programs or interactively without explicitly loading them. To a very
large degree, Octave can run MATLAB m files, and vice versa.
An example mfile routine definition for Octave is shown below. This
particular mfile routine emulates the handy rvals function in the
perl PDL math language.
## x = rvals(n1<,n2)  return pdl rvals type array or matrix
function b=rvals(varargin)
n1 = varargin{1};
n2 = 0;
if (length(varargin)>1)
n2 = varargin{2};
endif
if (n2 == 0)
a = 0:(n11);
a = (a  floor(n1/2)).**2;
b = a;
else
a = ((0:n21)floor(n2/2)).**2;
b = ((0:n11)floor(n1/2)).**2;
y1 = ones(n1,1)*a;
y2 = b'*ones(1,n2);
b = y1+y2;
endif
b = sqrt(b);
endfunction
The rvals mfile function mimics the handy rvals utility in the
perl PDL matrix
language. Rvals takes one or two arguments which are respectively the
dimesion(s) of a vector or matrix. It returns a vector or matrix of that
size, with the cell values being the cell radius from the central vector
or matrix position.
For example, rvals(5) returns a vector of [2 1 0 1 2]. Rvals(5,5)
returns a matrix as follows:
2.82843 2.23607 2.00000 2.23607 2.82843
2.23607 1.41421 1.00000 1.41421 2.23607
2.00000 1.00000 0.00000 1.00000 2.00000
2.23607 1.41421 1.00000 1.41421 2.23607
2.82843 2.23607 2.00000 2.23607 2.82843
Notice that the center element is always 0, being a zero distance from
then center cell (it IS the center cell). As the cell position gets further
from the center cell, it's value increases by it's positional radius from
center. So whats so need about it? Below is a graph of an rvals(50,50) call.
Rvals output
It turns out that this simple function makes it vary handy for making
image masks and functions like the sinx/x curve. The bottom graph is a one
line command of: mesh(sin(.5*x)./(.5*x)). The ./ operator is a scalar
divide operator.
sinx/x using rvals
Note that this quickly built sinx/x graph has an anomoly right at the
peak of the curve. For a true sinx/x, that point needs to be normalized,
because the simple equation plotted had a devide by zero at the center element.
However, hopefully the simple way of getting to sin/x using rvals as a
starting point shows the value of the routine, and the usefulness of
user defined mfiles.
Another handy use for rvals might be to constuct a mask for a graphic,
as an example. With x=rvals(50,50) and y=(x<20)*1.0, we use rvals to
contruct a circular function and turn it into a circular mask of radius
20. The 1.0 multiplier is used to convert the boolean y matrix into a
floating point matrix for the mesh plot.
Circular Mask From Rvals
As many mfile routines can be created as you wish, and if placed in a
directory in the octave search path (defined in .octaverc), octave will
automatically find them when referenced.
Octave's math routines only work on scalars, and 1 or 2 dimensional
matrices. One can make data structures of more than 2 dimensions, such as a
structure that is a collection of 2 dimensional matrices in a 3 dimensional
stack, but math routines can only be applied to the two dimensional elements of
the data structure.
As is true with MATLAB, Octave math operators default to matrix operations.
For example, the following expression does a full matrix multiply of
matrices x and y:
z = x * y;
If one wishes to force an operation to be scalar, such as merely
multiplying corresponding cells of matrices x and y, the dot modifier must
be applied to the multiply operator as follows:
z = x .* y;
Octave functions are declared in the same way as MATLAB functions. It is
also possible to have functions that receive a variable number of arguments.
Octave uses the varargin array method of passing variable number of
arguments to functions. For the user, this means that functions must have a bit
of logic to default arguments, then check if values for them were passed in the
varargin array.
One small difference between MATLAB and Octave is that comment lines
in Octave can start with either the % character or the #
character.
% This is a MATLAB or an Octave Comment
# This is also an Octave Comment
In Linux, Octave Makes A Great Batch Language
In Linux, Octave is also easy to use as a batch language. One simply uses
Octave like another shell. The following example would execute Octave as the
shell and perform whatever Octave commands are in the file. In this little
example, Octave prints out how many arguments (argv) are passed in. The
arguments could easily be parsed to be used in the program:
#!/usr/bin/octave qf
printf("You passed %d arguments\n",length(argv));
Using Octave in this way allows one to quickly script out solutions to
problems, yet run them as one would run any other data processing program.
Octave Uses Simple and CStyle I/O
Octave only has built high level I/O routines for a few file types. Octave
has simple commands for saving and loading matrices, and commands that import
and export some of the older MATLAB compatible files. Octave only reads in it's
own ASCII format image file format. It can output either its own format or
pnm format files (ppm for color, pgm for gray scale).
However, Octave does provide C style I/O primitives for reading and writing
all manner of user designed ASCII and binary files. So one could conceivably
read or write any kind of file with Octave, as long as the format of the file
is known. I was easily able to add a simple fits file reader to Octave for
handling fits images, and another for reading the pnm ppm and pgm files.
Octave Can Do Many Types Of Graphs
Octave, in Linux, uses a number of graphic programs in support. Most line
graphs are done with Gnuplot. Many
easy to use plot commands common to other languages, such as plot, contour,
and mesh are made available, and use gnuplot for the presentation. The
plot you see above is an example of a plain contour plot.
The plot you see above is a more elaborate version of the kind
made with the Octave mesh command. If you compare it with the plot in
the introduction section, you'll see that it has both the 3D mesh of the image,
and a contour graph on the xy plane. There are also contours, color coded with
those on the xy plane, drawn through the 3D mesh.
Octave doesn't directly provide a command for a plot with all the features
of the shown graphic. But Octave does provide additional primitive commands
for controlling gnuplot, so it is possible to add more graphic commands
(through m files) to get more performance from the very capable gnuplot
program, such as this augmented mesh plot.
Octave can also display images, such as digital photographs like the one of
the lunar crater Plato shown above. First, unfortunately, one has to convert
the image to the Octave image format, but Octave can then load the image and
display it. Rather than gnuplot, which is a line drawing graphic program,
Octave passes the image to the Imagemagick display program (in Linux).
Display then gives some additional control of the image, such as scaling,
rotation, and other commands. Newer versions of octave can use other
display utilities.
In working with Octave graphics commands, one thing I didn't find with the
gnuplot or display integrations was a way to interact with graphic windows.
That is, I was unable to find a way to receive mouse locations from within an
Octave plot.
This can be rectified in Linux by alternatively using the plplot
graphics package. Plplot has an Octave interface and can be used to replace the
gnuplot graphics. With plplot installed, one can issue the
toggle_plplot_use command and have access to another set of high level
plot commands. With the plplot interface, mouse locations can be returned to an
Octave program.
You can get help when in Octave by typing help i, or in some
newer renditions, doc. This will bring up a Linux info
information file with a hierarchal help system. You can also type help
routine, where routine is a documented function. Octave makes it easy
for the user to document his or her own functions, as the documentation for
each user generated function is in the function file.
Summary
Octave, with its high level of comparability with MATLAB, is a Linux
favorite. It's matrix routines are quite fast, and with the addition of the
Imagemagick and plplot supplemental graphics routines, provides a good platform
for a wide range of mathematical problems. It's used heavily for signal
processing and general statistical analysis. Because of the limitations of the
graphics system and image file formats recognized, Octave isn't probably the
first choice for image processing.
Nonetheless, if you do as I did and add fits file and pnm file readers,
you can work on images in octave. One note, if you decide to do this: octave
works only with 2 dimensional matrices. Languages more suited to image
processing typically hold color images in 3 dimensional matrices, with the
3 layers respectively holding each pixels red, green, and blue levels.
Octave uses a color map to supplement its 2 dimensional matrix format. With
color images, what works is to create a color map that has as many rows as
the number of pixels in an image, and 3 columns. The 3 columns are for the
red, green, and blue color components. The image matrix than becomes just
a matrix who's elements run from 1 to the number of cells in the image.
Thus each cell just points to the respective row in the color map which has
the 3 color levels for that image.
For example, assume a 4 x 4 pixel color image (I know that's lame, but it
illustrates the point. In Yorick, the read in image would be stored in a matrix
of 3 dimensions, like (3,4,4), for 3 layers of the 4 x 4 image: one for red,
green, and blue color levels. Assuming 256 levels of color, that might look
like:
Red Layer
209 193 179 157
178 116 189 187
66 86 133 133
69 57 51 59

Green Layer
198 178 161 137
157 85 147 148
57 64 95 90
51 39 34 40

Blue Layer
210 196 184 168
165 95 147 147
67 70 100 93
57 45 37 46

In octave, the image matrix and color map would look like this:
Image (Indexes Into Color map)
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16

Color map * 255 (rgb per pixel)
209 198 210
193 178 196
179 161 184
157 137 168
178 157 165
116 85 95
189 147 147
187 148 147
66 57 67
86 64 70
133 95 100
133 90 93
69 51 57
57 39 45
51 34 37
59 40 46

Notice that the first row of the color map is respectively the first
element of the red, green, and blue matrices. Then next row is the 2nd
element of the first row of red, green and blue. Then see that the each
element of the image matrix is simply the row number of the color map for
that pixel.
One final note, the color map listed is multiplied by 255 (for 255 colors).
In Octave, the actual color map values must be between 0 and 1. Dividing the
illustrated color map by 255 would provide a usable octave color map for our
little image example.
Below are listed my subjective pros and cons for the Octave Matrix language.
Pros:
Freely available for Linux and Windows. The Linux version is easier to use
IMHO.
Highly compatible (95%) with the commercial Matlab language, a terrific
boon to college students.
Loaded with engineering problem solution utilities, such as signal processing.
An easy to learn language style.
Makes many CStyle file I/O utilities available, making it easy
to write Octave routines to be compatible with files made with external
utilities.
Has a reasonable number of string handling utilities, such as compare,
search and replace, and split.
Very fast when solutions primarily use the intrinsic Matrix operators
Uses the handy m file system where each function file contains
a single function, and simply referencing functions causes them to be autoloaded.
Cons:
Works only with 1 and 2 dimensional matrices. As the above discussion of
Octave colormaps illustrates, handling things like 3 color images is awkward.
Slows down considerably if solutions contain looping logic.
Primarily uses GNUPLOT for plotting. GNUPLOT is very versatile, but
the combination doesn't provide the ability to have mouse actions in a plot
return values to Octave.
