This note is about calling Matlab from Python and moving data between the two. I've previously written about the reverse (i.e. calling Python from Matlab). There some different ways to approach this, the most obvious being to use the Matlab engine for Python.

We need a library to time the code and numpy, as well as the engine.

In [3]:

```
from time import perf_counter
import numpy as np
import matlab.engine
```

This starts the engine (so to speak):

In [4]:

```
eng=matlab.engine.start_matlab()
```

Firstly, we'll make a Matlab array (note: I'm using smaller arrays than in the previous example.)

In [5]:

```
tic=perf_counter()
mla=eng.rand(1e3,'double')
print("Elapsed time is",'%.6f' % (perf_counter()-tic),"seconds.")
```

In [6]:

```
type(mla)
```

Out[6]:

Now to make a numpy array:

In [7]:

```
tic=perf_counter()
npa=np.random.rand(int(1e3),int(1e3))
print("Elapsed time is",'%.6f' % (perf_counter()-tic),"seconds.")
```

Use the Matlab engine to transpose the array a couple of times:

In [8]:

```
tic=perf_counter()
mla_t=eng.transpose(mla)
mla_t=eng.transpose(mla_t)
print("Elapsed time is",'%.6f' % (perf_counter()-tic)," seconds.")
```

In [9]:

```
mla==mla_t
```

Out[9]:

Convert the Matlab array to a numpy array:

In [10]:

```
tic=perf_counter()
mla_npa=np.array(mla)
print("Elapsed time is",'%.6f' % (perf_counter()-tic)," seconds.")
```

In [11]:

```
type(mla_npa)
```

Out[11]:

Do the same tanspose operations in numpy (note: these may not be doing the same thing in both languages - I think Matlab actaully transposes the array, wheras numpy creates a 'view' that swaps rows and columns which is likely why it's faster).

In [12]:

```
tic=perf_counter()
mla_npa=np.transpose(mla_npa)
mla_npa=np.transpose(mla_npa)
print("Elapsed time is",'%.6f' % (perf_counter()-tic)," seconds.")
```

This won't run. While one can change a numpy array into a Matlab array from Matlab, it can't be done by the Matlab engine in Python. Only these data types are allowed.

In [13]:

```
#tic=perf_counter()
#mla_npa_mla=eng.double(mla_npa)
#print("Elapsed time is",'%.6f' % (perf_counter()-tic)," seconds.")
```

The inability to pass numpy arrays to Matlab could make working with the matlab engine very inconvenient. However, we can do this using octave (oct2py). Oct2py uses .mat files to pass data between the octave and python environments, which may become a slow process. However, it is probably less encumbered by licensing issues.

In [14]:

```
from oct2py import octave
```

In [15]:

```
tic=perf_counter()
octa=octave.rand(1e3,'double')
print("Elapsed time is",'%.6f' % (perf_counter()-tic),"seconds.")
```

In [16]:

```
type(octa) # we see this as a numpy array, not an octave native data type
```

Out[16]:

In [17]:

```
tic=perf_counter()
octa_t=octave.transpose(octa)
octa_t=octave.transpose(octa_t)
print("Elapsed time is",'%.6f' % (perf_counter()-tic)," seconds.")
```

In [18]:

```
np.array_equal(octa,octa_t)
```

Out[18]:

The strategy, here, is to save a numpy array as a file that matlab can read, then read it using the matlab engine. *hdf5* is the format we'll use. The benefit of this is we can use the actual matlab engine on the result, rather than octave.

In [19]:

```
import h5py #sometimes there are problems recognising this library
```

This converts a numpy array to a matlab array, but may need to be changed for higher dimensional arrays. There isn't any other obvious way of turning a numpy array into a matalb array - octave sees everything as a numpy array, it seems.

In [20]:

```
tic=perf_counter()
with h5py.File('temp.hdf5', 'w') as f:
dset = f.create_dataset("default", data=np.transpose(npa)) #transpose required as python is row-major and matlab is column-major
mla_hdf = eng.h5read("temp.hdf5","/default")
print("Elapsed time is",'%.6f' % (perf_counter()-tic),"seconds.")
type(mla_hdf)
```

Out[20]:

We can turn the matlab array back into a numpy array:

In [21]:

```
tic=perf_counter()
mla_hdf_npa=np.array(mla_hdf)
print("Elapsed time is",'%.6f' % (perf_counter()-tic)," seconds.")
```

And check it's the same as what we started with:

In [22]:

```
np.array_equal(npa,mla_hdf_npa)
```

Out[22]: