6 ways to convert MatLab code to Python

Links to skip below:

  • Skip to videos below

  • Manual conversion

  • Octave

  • LibreMat

  • Skip to MathWorks info

  • OMPC

  • SMOP

  • matlab2python
  • MatLab is used by many students for theses and other projects. MatLab is prominent because of the tools made available by MathWorks. However, MatLab is not free in the commercial setting. MatLab becomes very expensive with just a few tools (i.e., $15,000/license/yr). Here, we outline 6 ways to convert MatLab to Python. The first option is by manual conversion. If that is not appealing to you, skip to options 2-6.

    What is Difference Between Matlab and Python Code?

    Python is one of the easiest high-level programming languages ever created which is as easy as reading and writing English. It was first released in the 1990s by Guido van Rossum and now is been contributed by hundreds of developers worldwide. (pythonpool.com). Whereas, Matlab is closed source software managed by Mathworks. And most importantly, Python is free, unlike Matlab.

    There are thousands of modules within Python that can be helped to access any kind of API you need in your project. Moreover, you can edit the original source code of modules in Python.

    Whereas, in Matlab, this is nearly impossible. Also, the support for python by developers all around the world is increasing at an exponential rate.

    According to StatisticsTimes, python is the most searched language in the PYPL index. Also, considering the usage efficiency and support available, it’s already concluded that Python is far more flexible than Matlab.

    Option 1 – Manual Conversion

    There are a few options for converting code. The most reliable is probably by hand. To convert by hand requires a through understanding of both python and MatLab.

    Option 2 – Octave

     

    MatLab’s syntax can be interpreted via free software, Octave/Gnu. So, here we interface Matlab’s code with Octave, and Octave then interfaces with Python via the oct2py module in order for this to all work.

    First off, I’d like to start off by saying that Octave is essentially a free version of MatLab but you are stripping away all of the tools. For example, you won’t have cftool, simbio, mupad, etc. However, there are a wide range of fantastic libraries available to use within Octave. Octave is open source. A full list can be found here.

    Before you delve into this ensure you have downloaded and installed Octave (Gnu) onto your computer.

    Oct2Py allows you to “seamlessly call M-files and Octave functions from Python”. It manages the Octave session for you, sharing data behind the scenes using MAT files. 

    In order to connect python to Octave, we will then install and enact the oct2py module. I recommend using Jupyter for this which you can access via the GUI of Anaconda. You will want an Octave-kernel for Jupyter. You can do this directly from any python interface, however, as long as octave-cli.exe’s directory is added to your PATH (more information about this below). You can install the octave-kernel needed for Jupyter easily using:

    pip install octave-kernel

    or

    pipenv install octave-kernel

    You could also install this via conda:

    conda install octave_kernel

    This will enable you to  use matlab code in python directly. 

    To obtain the oct2py python library, in the python environment type in:

    pip install oct2py

    pipenv install oct2py

    or if you are using Anaconda, use:

    conda install -c conda-forge oct2py

    You can double check that Python and Octave can connect and see each other using the following command in the terminal:

    python -m octave_kernel.check

    If successful, the terminal should report the following (or something similar given versions may be different):

    Octave kernel v0.32.0
    Metakernel v0.24.4
    Python v3.7.3 (default, Apr 24 2019, 15:29:51) [MSC v.1915 64 bit (AMD64)]
    Python path: C:\Users\cbishop\AppData\Local\Continuum\anaconda3\python.exe

    Connecting to Octave…
    Octave connection established
    Octave Kernel v0.32.0 running GNU Octave v5.2.0
    Graphics toolkit: fltk
    Available toolkits: [1,1] = fltk
    [1,2] = gnuplot

    Documentation for the oct2py library can be found here.

    Of note, be sure to also add the directory where octave-cli.exe is to your system’s PATH variable. For more information on this, here is a great link.

    In [1]:
    %matplotlib inline
    from oct2py import octave
    from oct2py import Oct2Py
    import numpy as np
    
     

    Instantiate the Oct2Py object as oc

    In [3]:
    oc = Oct2Py()
    
     
     
     

    Matrix creation

     

    First, lets remind ourselves of matlab sytnax of matrix/array creation:

    In [4]:
    y = oc.eval("[1 2 3];")
    y
    
    Out[4]:
    array([[ 1.,  2.,  3.]])
     
     
    Another example of using this is the following:
     
    >>> oc = oct2py.Oct2Py()
    >>> x = oc.zeros(3,3)
    >>> print(x, x.dtype)
    [[ 0.  0.  0.]
     [ 0.  0.  0.]
     [ 0.  0.  0.]] float64
     
     

    Not bad. The difference in slicing arrays and matrices is a tough transition, but this makes it much easier than learning the fundamentals

    In [5]:
    y = oc.eval("[1 2 3;4 5 6];")
    y
    
    Out[5]:
    array([[ 1.,  2.,  3.],
           [ 4.,  5.,  6.]])
     

    We can see it creates a matlab matrix and converts it exactly how we would need it in numpy

    In [6]:
    type(y)
    
    Out[6]:
    numpy.ndarray
     

    Lets try something a bit more complex with analaogous syntax. Here is a matrix define natively in python

    In [7]:
    numpyarr = np.array([[1, 2,3,4], [5,6,7,8],[9,10,11,12],[13,14,15,16]], dtype=float)
    numpyarr
    
    Out[7]:
    array([[  1.,   2.,   3.,   4.],
           [  5.,   6.,   7.,   8.],
           [  9.,  10.,  11.,  12.],
           [ 13.,  14.,  15.,  16.]])
     

    and here is the same matrix defined in matlab/octave syntax

    In [8]:
    matlabarr = oc.eval("[1 2 3 4; 5 6 7 8; 9 10 11 12; 13 14 15 16];") 
    matlabarr
    
    Out[8]:
    array([[  1.,   2.,   3.,   4.],
           [  5.,   6.,   7.,   8.],
           [  9.,  10.,  11.,  12.],
           [ 13.,  14.,  15.,  16.]])
     

    clearly, they are the same!

    In [9]:
    matlabarr == numpyarr
    
    Out[9]:
    array([[ True,  True,  True,  True],
           [ True,  True,  True,  True],
           [ True,  True,  True,  True],
           [ True,  True,  True,  True]], dtype=bool)
     

    Plotting with oct2py

    Just using oct2py, we can plot using gnuplot, I haven’t been able to find a way to plot them inline, but they still look good in the gnuplot window:

    In [14]:
    x = np.arange(-2*np.pi, 2*np.pi, 0.1)
    y = np.sin(x)
    oc.plot(x,y,'-o', linewidth=2)
    
     

    We can see that is uses wxpython, which is another gui package. I am not 100% sure when that package was installed, but I am guess it was installed along with Octave

    More matlab execution

    Although this doesn’t convert the code to python, it executes it very well. Here is a MATLAB code snippet for LU Decomposition. We can create a python string with the contents of this and evaluate it as octave code

     
    % function [L,U] = LUCrout(A)
    % Decomposes matrix A into a Lower matrix L and Upper matrix U
    % A = LU
    A = [1,5,3,5;  2,5,6,7; 9,0,3,4; 9,4,7,6]
    A
    [R,C] = size(A);
    for i = 1:R
        L(i,1) = A(i,1);
        U(i,i) = 1;
    end
    for j = 2:R
        U(1,j) = A(1,j)/L(1,1);
    end
    for i = 2:R
        for j = 2:i
            L(i,j) = A(i,j) - L(i,1:j-1)*U(1:j-1,j);
        end
        for j = i+1:R
            U(i,j) = (A(i,j) - L(i,1:i-1)*U(1:i-1,j))/L(i,i);
        end
    end
    L
    U
    In [15]:
    x = '''
    % function [L,U] = LUCrout(A)
    % Decomposes matrix A into a Lower matrix L and Upper matrix U
    % A = LU
    A = [1,5,3,5;  2,5,6,7; 9,0,3,4; 9,4,7,6]
    A
    [R,C] = size(A);
    for i = 1:R
        L(i,1) = A(i,1);
        U(i,i) = 1;
    end
    for j = 2:R
        U(1,j) = A(1,j)/L(1,1);
    end
    for i = 2:R
        for j = 2:i
            L(i,j) = A(i,j) - L(i,1:j-1)*U(1:j-1,j);
        end
        for j = i+1:R
            U(i,j) = (A(i,j) - L(i,1:i-1)*U(1:i-1,j))/L(i,i);
        end
    end
    L
    U
    '''
    
    In [16]:
    oc.eval(x)
    
     
    A =
    
            1        5        3        5
            2        5        6        7
            9        0        3        4
            9        4        7        6
    
    A =
    
            1        5        3        5
            2        5        6        7
            9        0        3        4
            9        4        7        6
    
    L =
    
      1.0e+001 *
    
      0.10000  0.00000  0.00000  0.00000
      0.20000  -0.50000  0.00000  0.00000
      0.90000  -4.50000  -2.40000  0.00000
      0.90000  -4.10000  -2.00000  -0.27333
    
    U =
    
      1.00000  5.00000  3.00000  5.00000
      0.00000  1.00000  -0.00000  0.60000
      0.00000  0.00000  1.00000  0.58333
      0.00000  0.00000  0.00000  1.00000
    
     

    If you are using an ipython notebook, we can take advantage of the magic functions and execute Octave/MATLAB code directly in the cells. To activate this functionality, we need to install Octave first, then install oct2py.

    In [17]:
    %load_ext oct2py.ipython
    
     

    For single line octave code, we can use this syntax

    In [18]:
    x = %octave [1 2 3 4; 5 6 7 8; 9 10 11 12; 13 14 15 16];
    x
    
     
     
    Out[18]:
    array([[  1.,   2.,   3.,   4.],
           [  5.,   6.,   7.,   8.],
           [  9.,  10.,  11.,  12.],
           [ 13.,  14.,  15.,  16.]])
     

    This is very similar to the example earlier, except that is it running the code rather than evaluating a string. We can see that it creates a numpy array just like before

    In [19]:
    type(x)
    
    Out[19]:
    numpy.ndarray
     

    If we want multi-line MATLAB/Octave sytax, we can use this syntax

    In [20]:
    %%octave
    x = [1 2 3 4; 5 6 7 8; 9 10 11 12; 13 14 15 16];
    x
    typeinfo(x)
    
     
    x =
    
            1        2        3        4
            5        6        7        8
            9       10       11       12
           13       14       15       16
    
    ans = matrix
     

    in that cell, x is still a matlab matrix, but when we show ‘x’ in the next cell, it is now a numpy array

    In [21]:
    x
    
    Out[21]:
    array([[  1.,   2.,   3.,   4.],
           [  5.,   6.,   7.,   8.],
           [  9.,  10.,  11.,  12.],
           [ 13.,  14.,  15.,  16.]])
     

    Lets try our LU function by loading the file, and replacing adding the octave magic function. execute

    %load LU.m

    and then add

    %%octave

    to the very top and delete

    #%load LU.m
    In [22]:
    %%octave
    % function [L,U] = LUCrout(A)
    % Decomposes matrix A into a Lower matrix L and Upper matrix U
    % A = LU
    A = [1,5,3,5;  2,5,6,7; 9,0,3,4; 9,4,7,6]
    A
    [R,C] = size(A);
    for i = 1:R
        L(i,1) = A(i,1);
        U(i,i) = 1;
    end
    for j = 2:R
        U(1,j) = A(1,j)/L(1,1);
    end
    for i = 2:R
        for j = 2:i
            L(i,j) = A(i,j) - L(i,1:j-1)*U(1:j-1,j);
        end
        for j = i+1:R
            U(i,j) = (A(i,j) - L(i,1:i-1)*U(1:i-1,j))/L(i,i);
        end
    end
    L
    U
    
     
    A =
    
            1        5        3        5
            2        5        6        7
            9        0        3        4
            9        4        7        6
    
    A =
    
            1        5        3        5
            2        5        6        7
            9        0        3        4
            9        4        7        6
    
    L =
    
      1.0e+001 *
    
      0.10000  0.00000  0.00000  0.00000
      0.20000  -0.50000  0.00000  0.00000
      0.90000  -4.50000  -2.40000  0.00000
      0.90000  -4.10000  -2.00000  -0.27333
    
    U =
    
      1.00000  5.00000  3.00000  5.00000
      0.00000  1.00000  -0.00000  0.60000
      0.00000  0.00000  1.00000  0.58333
      0.00000  0.00000  0.00000  1.00000
     

    Excellent. This appraoch keeps the code more native than having the copy and paste the code and create a string to be evalauted. And just for fun we can plot inline also!!!

    In [23]:
    %%octave
    p = [12 -2.5 -8 -0.1 8];
    x = 0:0.01:1;
    
    polyout(p, 'x')
    plot(x, polyval(p, x));
    
     
    12*x^4 - 2.5*x^3 - 8*x^2 - 0.1*x^1 + 8
     
     
    In [24]:
    %%octave
    x = 1:10;
    y = exp(x);
    plot(x,y)
    xlabel('x')
    ylabel('y')
    title('testing MATLAB/OCTAVE in python!')
    
     

    Option 3 – SMOP

    SMOP (Small Matlab and Octave to Python Converter) or here

    The smop package seems impressive (SMOP development), and works well for an actual conversion of MATLAB code. Lets see how it works.

    git clone https://github.com/victorlei/smop
    cd smop
    python setup.py install --user
    easy_install smop --user
    smop file.m

    This last command will convert the file.m Matlab file and then save it to a.py file. If you want to change the output file, use the -o flag in the terminal. Also, it supports the -d flag which can be used to ignore functions by regex from the file.

    Another example:

    To convert a MATLAB file named LU.m, follow the sytanx here In [117]:

    !python smop-0.26.2/smop/main.py LU.m
    

    the resulting file is ‘a.py’, which is the python equivalent. Lets have a peek and see how we did. Load the file directly in ipython by

    %load a.py

    In [127]:

    # %load a.py
    # Autogenerated with SMOP version 
    # smop-0.26.2/smop/main.py LU.m
    
    from __future__ import division
    try:
        from runtime import *
    except ImportError:
        from smop.runtime import *
    
    A=[[1,5,3,5],[2,5,6,7],[9,0,3,4],[9,4,7,6]]
    R,C=size(A,nargout=2)
    for i in arange_(1,R).reshape(-1):
        L[i,1]=A(i,1)
        U[i,i]=1
    for j in arange_(2,R).reshape(-1):
        U[1,j]=A(1,j) / L(1,1)
    for i in arange_(2,R).reshape(-1):
        for j in arange_(2,i).reshape(-1):
            L[i,j]=A(i,j) - L(i,arange_(1,j - 1)) * U(arange_(1,j - 1),j)
        for j in arange_(i + 1,R).reshape(-1):
            U[i,j]=(A(i,j) - L(i,arange_(1,i - 1)) * U(arange_(1,i - 1),j)) / L(i,i)
    
    ---------------------------------------------------------------------------
    ImportError                               Traceback (most recent call last)
     in ()
          7     from runtime import *
          8 except ImportError:
    ----> 9     from smop.runtime import *
         10 
         11 A=[[1,5,3,5],[2,5,6,7],[9,0,3,4],[9,4,7,6]]
    
    ImportError: No module named smop.runtime

    The above code needs a bit of revamping…

    Option 4 – LibreMat

    LibreMate

    LiberMate: translate from Matlab to Python and SciPy (Requires Python 2, last update 4 years ago).  First, save the tar.gz file for pyclibs from here

    	
    tar -zxvf pyclips-1.0.7.348.tar.gz
    cd pyclibs
    sudo python setup.py build
    sudo python setup.py install
    
    
    
    git clone https://github.com/awesomebytes/libermate
    cd libermate
    python libermate.py file.m
    

    The above command will parse the file.m Matlab file and then create the file.ast with contains the abstract syntax tree of the file and save the translated file to file.py.

    Option 5 – OMPC

    • There’s OMPC, “Open-source Matlab-to-Python Compiler”, mentioned by @IoannisFilippidis in his answer for conversion. The website for information regarding downloading and installing OMPC is here.
    • An online OMPC platform is: http://ompclib.appspot.com/m2py but do note, as they indicated on their website, that they save all that is entered. They state: “The files you are uploading will be saved in our database. Please do not upload anything you wouldn’t like us to see.”

    The examples are descriptive and explain many user cases. So when you are ready to convert, check out the live web converter which is great for processing snippets. However, when I tried to convert the LU function above, I get this, which creates a wierd A array and an undeclared vector mslice. There may be an explanation of this in the documentation, but it isn’t obvious I didn’t look very much

    wget https://www.bitbucket.org/juricap/ompc/get/tip.bz2
    tar xvfj tip.bz2
    cd ompc-2f62b3a16cd5
    
    

    Then in the same directory open the python shell and you can import ompc directly.

    Here is a usage example:

    A = mcat([1, 5, 3, 5, OMPCSEMI, 2, 5, 6, 7, OMPCSEMI, 9, 0, 3, 4, OMPCSEMI, 9, 4, 7, 6])
    A()
    [R, C] = size(A)
    for i in mslice[1:R]:
        L(i, 1).lvalue = A(i, 1)
        U(i, i).lvalue = 1
        end
        for j in mslice[2:R]:
            U(1, j).lvalue = A(1, j) / L(1, 1)
            end
            for i in mslice[2:R]:
                for j in mslice[2:i]:
                    L(i, j).lvalue = A(i, j) - L(i, mslice[1:j - 1]) * U(mslice[1:j - 1], j)
                    end
                    for j in mslice[i + 1:R]:
                        U(i, j).lvalue = (A(i, j) - L(i, mslice[1:i - 1]) * U(mslice[1:i - 1], j)) / L(i, i)
                        end
                        end
                        U()
                        L()

    Because the code above resulted in something not fantastic, let’s just brush that aside and move on!

    Option 6 – matlab2python

    In order to install matlab2python, you can simply use the following:

    
    
    git clone https://github.com/ebranlard/matlab2python
    cd matlab2python
    pip install -r requirements.txt
    
    python matlab2python.py file.m -o file.py
    
    
    

    MathWorks

    There is a nice app in MatLab, that is owned by MathWorks, which can begin from the command line using “libraryCompiler”. You can then generate a python package and build the python application: LINK

    It is possible to also call matlab files directly from python using information found here.

    Summary

    I also prefer the oct2py package. I can run my native MATLAB code in a python environment, and surely there will be support for other languages in the ipython notebook (bash, R, Julia, etc.)

    Now that we have some options for running MATLAB/Octave code in python, the conversion process should be easier.

    <h2>Side Note – Converting MatLab to Fortran</h2>

    On a different note, though I’m not a fortran fan at all, For people who might find it useful there is:

    In addition, here is a link regarding using converting or using MatLab code in R.

    <h2>These are other fantastic links and information that you may find useful.</h2>

    • pymatlab: communicate from Python by sending data to the MATLAB workspace, operating on them with scripts and pulling back the resulting data.
    • Python-Matlab wormholes: both directions of interaction supported.
    • Python-Matlab bridge: use Matlab from within Python, offers matlab_magic for iPython, to execute normal matlab code from within ipython.
    • PyMat: Control Matlab session from Python.
    • pymat2: continuation of the seemingly abandoned PyMat.
    • mlabwrapmlabwrap-purepy: make Matlab look like Python library (based on PyMat).
    • oct2py: run GNU Octave commands from within Python. This can call *.m files within python (https://pypi.python.org/pypi/oct2py). It does require GNU Octave, however (https://www.gnu.org/software/octave/). Octave:  Octave has 99% MATLAB compatibility supposedly. It is possible to release the source code and test: www.gnu.org/software/octave 
    • pymex: Embeds the Python Interpreter in Matlab, also on File Exchange.
    • matpy: Access MATLAB in various ways: create variables, access .mat files, direct interface to MATLAB engine (requires MATLAB be installed).
    • MatPy: Python package for numerical linear algebra and plotting with a MatLab-like interface.
    • Many other comparisons exist for python and MatLab, like here on pyzo’s website. Pyzo is a free and open-source computing environment based on Python. If you’re used to e.g. Matlab, Pyzo can be considered a free alternative. Pyzo is a Python IDE that works with any Python interpreter installed on your system, including Conda environments. The IDE is aimed at interactivity and simplicity, and consists of an editor, a shell, and a set of tools to help the programmer in various ways. Get Pyzo going on your machine using the quickstart, or check the code on Github.

    By the way, it might be helpful to look here for other migration tips:

    Videos of potential interest

    Multiple Sources for this Content<

    Stack Overflow, Source Neal Gordon , pythonpool.com