forked from victorlei/smop
-
Notifications
You must be signed in to change notification settings - Fork 0
/
README
228 lines (199 loc) · 8.96 KB
/
README
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
Summary
-------
SMOP stands for Small Matlab/Octave to Python compiler. It is
supposed to help those who attempt migration from Matlab to Python.
Despite the similarities between the two languages, there are enough
differences to make manual translation too time consuming.
SMOP is not a polished product, nor a replacement to Octave and
Matlab. Taking into account its size (less than 3000 lines), this is
not surprizing. There are no toolboxes. Small everyday functions
(max, length, etc.) are recognized and supported, but that's all.
SMOP is written in Python, using PLY -- Python Lex/Yacc for lexical
analysis and parsing, and numpy for runtime environment. SMOP is
platform-independent, but is tested only on Linux. It is a
command-line utility.
Example
-------
It is possible to run an example without installing smop. Just unzip
it somewhere, and `cd` there. In your current directory you will find
a bunch of .py files and a file named fastsolver.m. It is taken from
the winning submission to Matlab programming competition in 2004
(Moving Furniture
http://www.mathworks.cn/matlabcentral/contest/contests/12/submissions/29989).
Now type `python main.py fastsolver.m -o fastsolver.py`. If you don't
specify the output file with -o option, it is written to `a.py`.
Each time a function is translated, its name is written.
.. code:: sh
lei@fuji:~/smop/smop$ python main.py fastsolver.m
fastsolver.m
solver
cbest
mainsolver
imoves
easysolver
localfiddler
findoverlaps
dijkstra
improve
TLL79
solverA
solver1
movefrompos
onemove
solver2
SearchPath
Faster10IntReps2
matrixsolver
outoftheway
ismember1
ismember2
setdiff
unique
sub2ind
randperm
perms
itTakesAThief
movefurniture
findshortestpath
dealWall1
lei@fuji:~/smop/smop$
The entire submission contains 2093 lines, and it is automatically
translated to Python by smop. These are the good news. The bad news
are that generating the code is not enough to run the program, so
there are no performance numbers yet.
#. While the submission itself --- the solver program --- does not use
graphics, the envelope code that is responsible to run the
submission, collect and display the results, does. So about 100
lines of the envelope must be rewritten by hand.
#. Many standard functions are not yet implemented --- rand, find,
and others. They are on the issues list.
#. Some matlab constructs, especially creating arrays by out of bound
assignment, are used in the submission, but not yet supported by
smop. Meanwhile, these lines should be rewritten in the Matlab
code.
.. code:: matlab
01 function moves=solver(A,B,w0)
02 [moves,optmove,optscore]=cbest(A,B,w0);
03 curscore=sum(w0(moves(:,1)));
04 lots=1;
05 if length(moves)-optmove<20||curscore/optscore<1.05
06 lots=2; return
07 else
08 lenw=length(w0);
09 [xx,nseq]=sort(rand(1,lenw));
10 A1=A;
11 B1=B;
12 w01=w0;
13 for i=1:lenw
14 A1(A==i)=nseq(i);
15 B1(B==i)=nseq(i);
16 w01(nseq(i))=w0(i);
17 end;
18 [moves2,optmove,optscore]=cbest(A1,B1,w01);
becomes
.. code:: python
01 def solver(A,B,w0):
02 moves,optmove,optscore = cbest(A,B,w0)
03 curscore=np.sum(w0[(moves[:,0]-1)])
04 lots=1
05 if max(moves.shape) - optmove < 20 or curscore / optscore < 1.05:
06 lots=2
07 return moves
08 else:
09 lenw=max(w0.shape)
10 xx,nseq=sort(rand(1,lenw))
11 A1=A
12 B1=B
13 w01=w0
14 for i in range(1,(lenw+1)):
15 A1[A == i]=nseq[(i-1)]
16 B1[B == i]=nseq[(i-1)]
17 w01[(nseq[(i-1)]-1)]=w0[(i-1)]
18 moves2,optmove,optscore = cbest(A1,B1,w01)
Now some random notes.
#. Line 03. Functions vs. arrays ambiguity is correctly resolved:
for example, `sum` is a function, but `w0` and `moves` are
arrays.
#. Line 09, Matlab function `length` is correctly inlined as
`max(w0.shape)` --- that is the maximum of the array dimensions.
#. For some functions, such as `abs`, `max`, and others, there are
both a builtin version and a different numpy version, and it is
important to use the right one. In line 03 `np.sum` is used, but
in line 09 builtin `max`. This is correct.
#. Line 10. Functions rand and sort are not yet implemented.
#. Lines 15-16. There is some support to boolean indexing.
#. Lines 15-17. Array subscripts are modified to start with zero
index. Note that if all subscripts were decremented, it would
break boolean indexing.
#. Line 13. Range specification in Matlab includes the upper bound.
In Python, it doesn't. So `for i=1:lenw` becomes `for i in
range(1,(lenw+1))`. Extra parentheses are known as issue #1.
-----------------------------------------------------------
The table below tries to summarize various features.
+------------------------+----------------------------------+
| Implemented features | |
+========================+==================================+
| Lexical and syntactical| Mostly complete, including |
| analysis | some weird Matlab features |
+------------------------+----------------------------------+
| Name resolution | For each occurrence of a |
| | variable, find a set of its |
| | possible definitions |
+------------------------+----------------------------------+
| Inlining of small | |
| functions | |
+------------------------+----------------------------------+
| Array subscripts | Also, end subscript implemented |
| translated from 1-based| |
| (Matlab and Fortran | |
| style) to 0-based (C | |
| and Python style) | |
+------------------------+----------------------------------+
| from:step:to | |
| translated to | |
| from:to:step | |
+------------------------+----------------------------------+
| Upper bound is n+1 | |
+------------------------+----------------------------------+
+------------------------+----------------------------------+
| Unimplemented features | |
| | |
+========================+==================================+
| Structs | |
| | To be implemented as soon as cc |
| | possible. |
+------------------------+----------------------------------+
| Arrays silently become | In some cases it may break the |
| C=style (rows first). | code. Not detected. |
+------------------------+----------------------------------+
| Function handles and | Handles break the heuristic that |
| lambda expressions | tells between function calls and |
| | array references. |
+------------------------+----------------------------------+
| Graphics, | Never |
+------------------------+----------------------------------+
| Auto-expanding arrays | Unlike other languages, matlab |
| | allows out-of-bounds assignment. |
| | As MathWorks tries to phase out |
| | this feature, there is a lot of |
| | legacy code depending on it. |
+------------------------+----------------------------------+
| Sparse matrices | Have good chances of being |
| | implemented, especially taking |
| | into account that scipy have |
| | several implementations to choose|
| | from. |
+------------------------+----------------------------------+
| Full support for | For example, x(x>0.5) = 1 |
| boolean indexing. | works, but y=x>0.5; x(y)=1 |
| Currently, some | does not work. |
| expressions don't work | |
| | |
+------------------------+----------------------------------+
| Command syntax | Too complex to support |
+------------------------+----------------------------------+
| Type, rank and shape | |
| inference | |
+------------------------+----------------------------------+
| Strings | |
+------------------------+----------------------------------+