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. Importmotopy
and usemotopy.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 bymotopy
has been modified manually, and do not wantmotopy
to regenerate it. -
The
.m
function thatmotpy
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 of0x0
cannot concatenate with array B with size of2x2
.An easy way to resolve this problem is to define the array
A
as an empty array with size of0x2
: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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.