26

I am looking for a way to access a matlab module from python. My current situation is this:

  • I have a python code that does numerical computations by calling Lapack routines while the memory is allocated as ctypes and passed as pointers to the Lapack routines.
  • I also have a matlab module, which is compatible with octave, that does some mathematical tricks I want to use.

My question now is this:
What is an efficient way to keep all the main work in python while at the same time exploit the possibilities that matlab/octave modules offer. Also it would be kind of nice, if my ctype arrays do not have to be converted into some other object in order to run octave. However, I can see that that last point is hard to accomplish.

My current research shows me two possible options:

  1. Pytave: However it seems that this packages is kind of pre alpha?!
  2. Go this humpy road: ctypes -> *.mat file (via numpy) -> octave -> *.mat file -> ctypes (via numpy)
ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
Woltan
  • 13,723
  • 15
  • 78
  • 104
  • possible duplicate of [Calling MATLAB functions from python](http://stackoverflow.com/questions/2883189/calling-matlab-functions-from-python) – gnovice May 26 '11 at 18:09
  • @gnovice Partially I agree, however this question is not about accessing matlab (since it is not available for me) but a matlab module running with octave! Also it is about Lapack and ctypes in python. Thx for the link though^^. – Woltan May 27 '11 at 06:11
  • I put a bounty up on this because I'd quite like to know this myself, but don't have time to do the research. – detly May 30 '11 at 02:13
  • See my answer for another option. I added it here instead of in the duplicated question @gnovice pointed out because it is based on Octave, which is not mentioned there. – astrojuanlu May 05 '13 at 11:13
  • @Juanlu001 I get a notification anyhow if a new answer to a question of mine is posted^^. – Woltan May 06 '13 at 06:21

3 Answers3

22

You can use oct2py, which IIUC was started by its author because pytave didn't work on win32. It is successfully used in IPython through its octavemagic extension and I can tell it is easy to use on its own, the code is maintained (I reported a little Unicode bug and the author fixed it in a day) and works well. Most of the times is as simple as:

>>> from oct2py import octave
>>> octave.run("cos(pi / 3)")
'ans =  0.50000'
>>> octave.call("foo", a, b)  # Function in foo.m

For further examples you can check this blog article.

astrojuanlu
  • 6,744
  • 8
  • 45
  • 105
  • Thank you for this late answer! It seems to be a really great alternative to Pytave! Luckily I am not that dependent on octave anymore, since I ported most of my stuff to numpy. I'll give it a try though... – Woltan May 06 '13 at 06:23
8

Have you considered using OMPC, http://ompc.juricap.com/ ? I have used it with great success when not wishing to re-write some numerical linear algebra routines. I can imagine that the more esoteric the Matlab commands, the harder it would be to translate... but it might be worth a try. In the end, you're going to want to convert your Matlab code to Python because it will be a bottleneck on speed and performance. The only reason to leave the Matlab code in Matlab format is if it would be an enormous up-front cost to translate it all, which OMPC should mitigate somewhat. Otherwise, it's almost always worth that up-front cost to completely rid yourself of Matlab/Octave dependence.

ely
  • 74,674
  • 34
  • 147
  • 228
3

I had some trouble getting OMPC to work because (I) the md5 module is deprecated, (II) Python 2.6 and later no longer accept arguments for Object.__new__() or Object.__init__(), and (III) the byteplay.py script needed to be updated.

To solve issue (I), I changed line 74 of yacc.py found in the ompc/ directory. This line imports md5 among other things. I deleted the md5 module and added the line below:

from hashlib import md5

Later in the yacc.py script, at line 1160, I changed,

Signature = md5.new()

to the following,

Signature = md5()

To run the code generated by ompcply.py, add 'from ompc import *' to the beginning of the file and then run it with an earlier version of Python, as:

$ python2.5 ompcply.py script.m > newscript.pym
$ python2.5 newscript.pym

Using a version of Python later than 2.5 will give you the following error:

/home/connor/downloads/OMPC/ompclib/ompclib_numpy.py:66: DeprecationWarning: object.__new__() takes no parameters
  a = super(mvar, cls).__new__(cls, *args, **kwargs)

To solve issue (III) I googled byteplay, and replaced the existing script with the newer version.

cjohnson318
  • 3,154
  • 30
  • 33