Interaction with MATLAB/Octave

Since both numerical computing environments are provide with a fourth-generation programming language, we discourage the straightforward inclusion of code from any of these two. There is no gain in terms of speed, resource usage, or coding power. In the extreme and rare cases, in which a specific routine is not available in SciPy, the preferred way to bring it to our session is by generating C code from the MATLAB/Octave code, and then wrap it with any of the methods suggested in the Interaction with C/C++ section of this chapter.

There is a different story when we receive data created from within MATLAB or Octave. SciPy has a dedicated module to deal with this situation—scipy.io.

Let's show you by example. We start with Octave, where we generate a Delaunay triangulation of a random set of 10 points in the plane.

We save the coordinates of these points, as well as the pointers to the triangles in the triangulation, to a MATLAB-style file (version 7) called data:

octave:1> x=rand(1,10);
octave:2> y=rand(size(x));
octave:3> T=delaunay(x,y);
octave:4> save -v7 data x y T

We are done here. We then go to our Python session, where we recover the file data:

>>> from scipy.io import loadmat
>>> datadict = loadmat("data")

The datadict variable holds a Python dictionary with the names of the variables as keys and the loaded matrices as their corresponding values:

>>> datadict.keys()

The output is shown as follows:

['__header__', '__globals__', 'T', 'y', 'x', '__version__']

Let's issue the datadict command:

>>> datadict['x']

The output is shown as follows:

array([[0.81222999,0.51836246,0.60425982,0.23660352,0.01305779,
        0.0875166,0.77873049,0.70505801,0.51406693,0.65760987]])

Let's take a look at following datadict command:

>>> datadict['__header__']

The output is shown as follows:

'MATLAB 5.0 MAT-file, written by Octave 3.2.4, 2012-11-27
 15:45:20 UTC'

It is possible to save data from our sessions to a format that MATLAB and Octave will understand. We do so with the savemat command, from the same module. The syntax is as follows:

savemat(file_name, mdict, appendmat=True, format='5', 
long_field_names=False, do_compression=False,
oned_as=None)

The file_name parameter contains the name of the MATLAB-type file where the data will be written. The Python dictionary mdict contains the names (as keys) of the variables, and their corresponding array values.

If we wish to append .mat at the end of the file, we may do so in the file_name variable, or by setting appendmat to True. In case we need to provide long names for the files (which not all versions of MATLAB accept), we need to indicate so by setting the long_field_names option to True.

We may indicate the version of MATLAB with the format option. We set it to the string '5' for versions 5 and later, or to the string '4' for version 4.

It is possible to compress the matrices we send, and we indicate so by setting the do_compression option to True.

The last option is very interesting. It allows us to indicate to MATLAB/Octave whether our arrays are to be read column by column, or row by row. Setting the oned_as parameter to the string 'column' will send our data into a collection of column vectors. If we set it to the string 'row', it will send the data as collections of row vectors. If set to None, the format in which the data was written is respected.