Skip to main content

The tool of converting Matlab/Octave code TO PYthon.

Project description

Motopy

Motopy is a tool used to translate Matlab/Octave code TO PYthon.

点此查看中文说明.

Introduce

Motopy is a powerful tool used to translate Matlab/Octave code to PYthon. In the process of translation, the python statement generated by mopy will be executed to ensure the translated correctness of subsequent code. For example, the following Matlab/Octave code:

a = ones(1, 3);
b = a';
c = a * b;

will be translated to python code:

import numpy as np
a = np.ones((1, 3))
b = a.T
c = a @ b

The type of the variables a and b are array. So the third statement c = a * b will be translate to: c = a @ b.

install

Please use pip install motopy:

pip install motopy

Quick Start

Motopy is very easy to use. First please prepare your Matlab/Octave files, put the script file and the function files with extetion ".m" in a folder, and ensure that your Matlab/Octave script can be run without exception. And meet Code Preprocessing.Here's a simple example:

  • Create a folder named "demo".

  • In the "demo" folder, create two ".m" files whose names are "fun.m" and "func_test.m". Input the folowing text:

     % file: func.m
     function s = func(a, b)
         s = sqrt(a.^2 + b.^2);
     end
    
     % file: func_test.m
     a = 3;
     b = 4;
     s = func(a, b);
     disp(s)
    
  • In the "demo" folder, create a python script file. Import motopy and use motopy.make() translate your mfile:

    import motopy
    motopy.make(entry_basename='func_test')
    

    The entryfile parameter specifies the mfile script to be translated(***!!Note that there is no extension!! ***).

    You can also execute the above code directly from the python command line. Ensure that the current directory is the "demo" folder.

Specify the input/output folder

The python script file may not be placed in the same folder as the mfile, and the input mfile and the output python file may be in a different folder. You can use the input_path parameter to specify the location of the input mfile and the output_path parameter to specify the output path of the generated python file.

import motopy

motopy.make(
    entry_basename='<the script filename without extension(*.m)>',
    input_path='<the input path of *.m files>', 
    output_path='<the output path of *.py files>' 
)

Specify replaced function

If you have already translated a function, you can specify an replaced function to that function using the replaced_functions argument in the motopy.make() function.

import motopy
motopy.make(
    entry_basename='func_test', # no extension
    input_path='The path that input ".m" files loaded', 
    output_path='The path that output ".py" files stored',
    replaced_functions={
        'func': ('func', 'func') # 
    }
)

The replaced_functions parameter is a dictionary, the key is the function name that appears in the mfile, and the value is a tuple (module_name, function_name). In the example above, the func function file will not be translated again.

When do you use replaced_functions:

  • The .py file generated by motopy has been modified manually, and do not want motopy to regenerate it.

  • The .m function that motpy does not support translated yet. You can implement it by yourself.

Code Annotation

The code line started with "%%>" in mfile is a python statment. And will be inserted to generated python file. And the next statment will be skiped. For example, the mfile:

%%> print('this is a code annotation.')
disp('this statment will be skiped.')

will be translated to:

print('this is a code annotation.')

Output Log

By default, motopy generate a log file named "motopy.log" under the output_path folder. You can use the 'logging_file' parameter to specify the output location and name of the log file. Using logging_level set log level: WARN|INFO|DEBUG

import motopy
motopy.make(.., logging_level=motopy.DEBUG, ..)

Indent

By default, the generated .py file uses 4 Spaces for indentation. You can use indent parameter specifies the number of Spaces required for indentation.

Code Preprocessing

The translation will failed if your Matlab/Octave code don't satisfy the folowing requirements:

  • Do not use blank spaces to separate elements in arrays and cells. The following code will make failed:

    a = [1 2 3; 4 5 6];
    c = {1 2 'abc'};
    
  • The first function name in a function file must be same as the filename.

  • Arrays and cells should be defined before used and allocated enough space. The following code will make failed:

    for k=1:5
        A(k) = 2*k; % The variable A is not defined before used.
    end
    
    A = []; % The variable A has not enough space.
    for k=1:5
        A(k) = 2*k; % the size of variable A will grow in iteration.
    end
    
  • Do not use "[]" to define empty array. The folowing mcode will translate failed:

    A = [];
    for k=1:5
        B= rand(2,2);
        A = [A;B];
    end
    disp(A)
    

    The expression [A;B] translate failed. because the empty array A with size of 0x0 cannot concatenate with array B with size of 2x2.

    An easy way to resolve this problem is to define the array A as an empty array with size of 0x2:

    A = zeros(0,2);
    for k=1:5
        B= rand(2,2);
        A = [A;B];
    end
    disp(A)
    

Implemented Translation

Creation of Array, Matrix and Cell

Matlab/Octave Python Note
a = [1,2,3,4] a = np.array([1, 2, 3, 4]) The array in matlab will be translated to np.array
a = [1,2;3,4] a = np.array([[1, 2], [3, 4]])
a = [1;2;3;4] a = np.array([[1], [2], [3], [4]])
C = {1,2,3;'4',[5,6],{7,8,9}} C = [[1, 2, 3], ['4', np.array([5, 6]), [7, 8, 9]]] The cell in matlab will be translated to list
r1 = 1:10; r1 = arange(1, 11) low_bound:high_bound in matlab will be translated to arange(low_bound, high_boud + 1)
N = 10;
r2 = 1:N;
N = 10
r2 = arange(1, N + 1)
zeros(3) np.zeros((3, 3))
zeros(2,3) np.zeros((2, 3))
ones(3) np.ones((3, 3))
ones((2, 3)) np.ones((2, 3))
C = cell(2,3) C = [[None for _c in range(3)] for _r in range(2)]

Slice of Array, Matrix and Cell

Matlab/Octave Python Note
a(1,1) a[0, 0] The value of index will decrease 1, if the index is a number.
a(1,:) a[0, :]
a(:,1) a[:, 0]
a(1, 1:2) a[0, 0:2]
a(1:2, 1) a[0:2, 0]
a(1,2:end) a[0, 1:]
m = 1;
n = 1;
a(m, n*2)
m = 1
n = 1
a[m - 1, n * 2 - 1]
The index will be replaced with index - 1, if index is a variable.

Functions

Matlab/Octave Python Note
abs np.abs
acos np.arccos
asin np.arcsin
atan np.arctan
[y,Fs] = audioread(filename) Fs, y = wavfile.read(filename)
ceil np.ceil
cos np.cos
diag np.diag
d = dir(name) d = [{'name':e.name, 'folder':e.path, 'isdir':e.is_dir()} for e in scandir(name)]
disp print
eye np.eye
exp np.exp
fft np.fft
fix np.fix
floor np.floor
fprintf
ifft np.ifft
inv linalg.inv
linspace np.linspace
S = load('data.mat') S = loadmat('data.mat') the Variable S is a dict
A = load('data.txt') A = np.loadtxt('data.txt') the file "data.txt" is a ASCII data.
load('data.mat') _mat = loadmat('data.mat');
a = _mat['a'];
b = _mat['b']
assume there are two variable a and b in "data.mat"
load('data.txt') data = np.loadtxt('data.txt') the file "data.txt" is a ASCII data.
log np.log
log10 np.log10
log2 np.log2
mod np.mod
ndims np.ndim
numel np.size
pinv linalg.pinv
rand random.rand
rank linalg.matrix_rank
round np.round
sin np.sin
sort np.sort
sprintf('%d%s',a, b) f'{a}{b}'
sqrt np.sqrt
s = strcat(s1,...,sN) s = ''.join([s1,...,sN])
unique np.unique

Change Log

See changelog.md for more information.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

motopy-2.1.0.tar.gz (31.8 kB view hashes)

Uploaded Source

Built Distribution

motopy-2.1.0-py3-none-any.whl (24.8 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page