MATLAB转换为Python

匿名 (未验证) 提交于 2019-12-02 22:51:30

SMOPSMOP将matlab翻译成python。SMOP生成人类可读的蟒蛇,这似乎也比八度快。速度有多快?表1显示了“移动家具”的计时结果。似乎对于该程序,转换为python导致加速大约两倍,并且SMOP运行时库编译runtime.py实现了额外的两倍加速这个伪基准测量标量性能,而我的解释是标量计算对八度组不太感兴趣。源代码

Working example

$ cd smop/smop $ python main.py solver.m $ python solver.py

solver.msolver.ma.py

01   function mv = solver(ai,af,w)  01 def solver_(ai,af,w,nargout=1): 02   nBlocks = max(ai(:));          02     nBlocks=max_(ai[:]) 03   [m,n] = size(ai);              03     m,n=size_(ai,nargout=2)
02Matlab uses round brackets both for array indexing and for function calls. To figure out which is which, SMOP computes local use-def information, and then applies the following rule: undefined names are functions, while defined are arrays.
03sizenargout.
04   I = [0  1  0 -1];              04     I=matlabarray([0,1,0,- 1]) 05   J = [1  0 -1  0];              05     J=matlabarray([1,0,- 1,0]) 06   a = ai;                        06     a=copy_(ai) 07   mv = [];                       07     mv=matlabarray([])
04matlabarrayndarraymatlabarrayIJ
06Matlab array assignment implies copying; python assignment implies data sharing. We use explicit copy here.
07matlabarrayndarraymatlabarray
08   while ~isequal(af,a)           08     while not isequal_(af,a): 09     bid = ceil(rand*nBlocks);    09         bid=ceil_(rand_() * nBlocks) 10     [i,j] = find(a==bid);        10         i,j=find_(a == bid,nargout=2) 11     r = ceil(rand*4);            11         r=ceil_(rand_() * 4) 12     ni = i + I(r);               12         ni=i + I[r] 13     nj = j + J(r);               13         nj=j + J[r]
09rand, can be used without parentheses. In python, parentheses are required. To detect such cases, used but undefined variables are assumed to be functions.
10findnargout.
12matlabarray, which among other features uses one based array indexing.
14     if (ni<1) || (ni>m) ||       14         if (ni < 1) or (ni > m) or                (nj<1) || (nj>n)                            (nj < 1) or (nj > n): 15         continue                 15             continue 16     end                          16 17     if a(ni,nj)>0                17         if a[ni,nj] > 0: 18         continue                 18           continue 19     end                          19 20     [ti,tj] = find(af==bid);     20         ti,tj=find_(af == bid,nargout=2) 21     d = (ti-i)^2 + (tj-j)^2;     21         d=(ti - i) ** 2 + (tj - j) ** 2 22     dn = (ti-ni)^2 + (tj-nj)^2;  22         dn=(ti - ni) ** 2 + (tj - nj) ** 2 23     if (d<dn) && (rand>0.05)     23         if (d < dn) and (rand_() > 0.05): 24         continue                 24             continue 25     end                          25 26     a(ni,nj) = bid;              26         a[ni,nj]=bid 27     a(i,j) = 0;                  27         a[i,j]=0 28     mv(end+1,[1 2]) = [bid r];   28         mv[mv.shape[0] + 1,[1,2]]=[bid,r] 29  end                             29 30                                  30     return mv

Implementation status

Random remarks

With less than five thousands lines of python code
SMOPSMOP
There is a price, too.
The generated sources are matlabic, rather than pythonic, which means that library maintainers must be fluent in both languages, and the old development environment must be kept around.
Should the generated program be pythonic or matlabic?

For example should array indexing start with zero (pythonic) or with one (matlabic)?

I beleive now that some matlabic accent is unavoidable in the generated python sources. Imagine matlab program is using regular expressions, matlab style. We are not going to translate them to python style, and that code will remain forever as a reminder of the program's matlab origin.

Another example. Matlab code opens a file; fopen returns -1 on error. Pythonic code would raise exception, but we are not going to do that. Instead, we will live with the accent, and smop takes this to the extreme --- the matlab program remains mostly unchanged.

It turns out that generating matlabic` allows for moving much of the project complexity out of the compiler (which is already complicated enough) and into the runtime library, where there is almost no interaction between the library parts.

Which one is faster --- python or octave? I don't know.
go.mgo.py
ai = zeros(10,10); af = ai;  ai(1,1)=2; ai(2,2)=3; ai(3,3)=4; ai(4,4)=5; ai(5,5)=1;  af(9,9)=1; af(8,8)=2; af(7,7)=3; af(6,6)=4; af(10,10)=5;  tic; mv = solver(ai,af,0); toc

Running the test suite:

$ cd smop $ make check $ make test 

Command-line options

lei@dilbert ~/smop-github/smop $ python main.py -h SMOP compiler version 0.25.1 Usage: smop [options] file-list     Options:     -V --version     -X --exclude=FILES      Ignore files listed in comma-separated list FILES     -d --dot=REGEX          For functions whose names match REGEX, save debugging                             information in "dot" format (see www.graphviz.org).                             You need an installation of graphviz to use --dot                             option.  Use "dot" utility to create a pdf file.                             For example:                                 $ python main.py fastsolver.m -d "solver|cbest"                                 $ dot -Tpdf -o resolve_solver.pdf resolve_solver.dot     -h --help     -o --output=FILENAME    By default create file named a.py     -o- --output=-          Use standard output     -s --strict             Stop on the first error     -v --verbose

文章来源: MATLAB转换为Python
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!