5

I have to port a lot of files from Mathematica to Octave. I found a Lisp Mathematica parser from ~1991 but I am not really familiar with Lisp, so I was wondering if anyone has any experience with porting in this direction. After researching and sending an email to WolframAlpha and no real results I would have to use Lex and Yacc to produce a cross compiler. This seems a bit excessive to me.

Any hints or pointers would be greatly appreciated.

Clarification:

I am starting with a lot of Mathematica files and their functionality has to be ported to Octave. I just want to achieve this goal in as less time as possible, as this is a task my boss gave me to do over the holidays. Thanks for your help, I will look at FullForm and examine the Mathematica file for non-portable content. If it is just possible to convert a certain amount of the files, I would have to do the rest by hand, which would take some time. So this is basically a one time thing to move from one program to another.

As mentioned in Leonid's post, the task seems excessive but I am a student research assistant and this is exactly the task I have to complete in my department.

wikke
  • 51
  • 1
  • 4
  • 1
    Mathematica and Octave are different enough that I'm sure automatic conversion is impossible. Can you describe in more detail what you need? A Mathematica parser in C? A parser for [FullForm](http://reference.wolfram.com/mathematica/ref/FullForm.html) expressions is relatively easy to write, and you can use Mathematica to convert everything to FullForm. But I think you should make your question more clear first. – Szabolcs Dec 14 '11 at 16:04
  • 1
    Why does it seem excessive? If the files contain just simple expressions it should be simple, otherwise it may range up to effectively re-implementing mathematica in octave. – acl Dec 14 '11 at 17:06

3 Answers3

18

I work with both MATLAB (the $$$$ version of Octave) and Mathematica fairly regularly, and I'm pretty damn confident that it is impossible to implement an parser/porter that automatically converts from Mathematica to the other. For starters, MATLAB/Octave does not support pattern matching or term re-writing or functional programming, all of which are the most common and optimal coding styles in Mathematica.

For example, consider the pure function (Mathematica)

f = #^2&;

There really isn't an equivalent of this in MATLAB/Octave. Anonymous functions come close enough and you could write it as (MATLAB/Octave)

g=@(x)x.^2;

However, Mathematica will symbolically square anything you pass to the function, whereas MATLAB will only work on scalars/vectors/matrices. So even if you come across a pure function, you can't automatically rewrite it into an anonymous function without understanding what is being passed to the pure function.

Another concept that's missing in MATLAB/Octave is that of lazy evaluation/SetDelayed or := in mathematica. So if your pure function was

f := a #^2 &;

then, f uses the value of a at the time when f is called. However, writing it as an anonymous function:

g = @(x)a*x.^2;

will capture the value of a at the time of definition, forming a closure. I provide a better example in this answer of mine

If you have a code base that is written primarily in a procedural style in Mathematica, then it might be possible, in theory, to translate to octave. However, I have a hard time imagining a serious Mathematica project written entirely in a procedural manner. In short, it takes a human to translate the logic in a manner idiomatic to each language


Lastly, if you're trying to just convert expressions from Mathematica to MATLAB/Octave, then you might want to take a look at the ToMatlab package. I use this quite often, to convert expressions from computations in Mathematica for use in a different code base in MATLAB. A simple example would be:

expr = Sin[x + x^3] + ArcSin[y];
ToMatlab[expr]
Out[1]= sin(x + x.^3) + asin(y)
Community
  • 1
  • 1
abcd
  • 41,765
  • 7
  • 81
  • 98
11

You don't need Mathematica parser to port. You need to write your porting program in Mathematica and reuse the Mathematica's own parser. This is along the same direction as SymbolicC. If I were you, I would construct some Mathematica sub-language (call it SymbolicOctave), with completely inert heads, and then write a function called say ToOctaveCodeString. You can consult the implementation of SymbolicC to see how this was done for C - it is available within the Mathematica distribution.

The second, and most complicated part, would be to write a translator from the subset of Mathematica code to this inert SymbolicOctave representation. This part is really non-trivial, because (presumably) Mathematica language has a lot of features that Octave language does not natively support, and you will have to implement those in Octave. Here you will also need to use certain techniques to generate Mathematica code with Mathematica, one of which I described in this answer. This all assumes that you have access to Mathematica.

Having said all that, I'd give up on the general task and just use Mathematica, if there is such option. The task seems anywhere feasible only for a very narrow and speciic subset of Mathematica, and even then would be non-trivial. If there is an option to link Mathematica and use it from Octave instead of porting everything to Octave, I'd go that way (technically this should be easy to do). With the cost of even commercial license for full Mathematica being rather low these days (comparing to the competing products, particularly having in mind products similar to Octave), it may well be a better option also financially, given the development costs to create a converter which would be any good.

Community
  • 1
  • 1
Leonid Shifrin
  • 22,449
  • 4
  • 68
  • 100
2

An idiomatic way of generating a code for a less capable system from Mathematica is not to use a third party tool (which should be as powerful as Mathematica core), but to use Mathematica itself.

Some of the code generators of this kind are already available out of the box (for C and Fortran), take a look at how they're implemented and then retarget them for Octave/Matlab.

SK-logic
  • 9,605
  • 1
  • 23
  • 35
  • I agree in principle, but for someone who does not already know mma and has to do this over the holidays this seems over ambitious, and some things may simply not be translatable (consider NDSolve). But I could be wrong, I have never tried. – acl Dec 16 '11 at 10:13
  • I will choose an option and try to convert some code to see how much work it would be to convert everything. Then I can see if its even possible and can provide feedback to my boss. – wikke Dec 16 '11 at 10:19
  • @acl, with this approach Mathematica won't convert everything (it is absolutely and clearly impossible), but it can symbolically solve what is possible to solve and produce a numeric algorithm suitable for execution with a low level language (like C or Matlab). Of course you can't convert everything blindly, it should be a manually assisted process. – SK-logic Dec 16 '11 at 11:13
  • Yes, I appreciate that. But unless the code to be ported is either a) not code but just expressions, b) imperative code, I can't imagine how this can be done even semi-automatically. And if it's imperative code (such as can be automatically compiled to C by `Compile`, it looks nontrivial to set things up so that it is translated to matlab. I'm not being negative, just trying to give @wikke an idea of what's involved in this. But of course perhaps it is easier than it sounds in his case. – acl Dec 16 '11 at 15:10
  • @acl, I suspect it would not make much sense to try to "port" an entire notebook to Octave. It is likely that only a code for whatever is in `N[...]`, `NSolve[...]`, `NDSolve[...]` and alike must be generated, with the rest interpreted by Mathematica itself. – SK-logic Dec 16 '11 at 15:17
  • I'd agree. I've "ported" lots of code from mma to Python+numpy (roughly same style and level as matlab), and it's literally rewriting. But it depends on how it's written. – acl Dec 16 '11 at 15:20
  • @acl, try porting, say, `Integrate[...]`. If you're only doing numeric stuff in Mathematica, then yes, it is not a problem. It won't be easy to port even a single use of `//.` – SK-logic Dec 16 '11 at 15:43
  • @SK-logic I think that given Mathematica metaprogramming capabilities and the rather vague nature of the problem, implementing things like lex/yacc (or their bindings for Mathematica) would be a waste of time for this particular task. But, I am certain that one can implement custom (informal) code generators in Mathematica with relatively little effort, given its rule-based pattern-matching engine and the fact that one can write macros in Mathematica. – Leonid Shifrin Dec 16 '11 at 16:57
  • @LeonidShifrin, yep, that's exactly what I suggested – SK-logic Dec 16 '11 at 16:58
  • @SK-logic Oh, I see. Then, this seems similar in spirit to what I suggested in my answer. But all this of course would greatly depend on what subset of Mathematica functionality is involved - as you mentioned in the above comments. +1. – Leonid Shifrin Dec 16 '11 at 17:02
  • About trying to rewrite `Integrate`, I am not sure what you're trying to say. I'm not claiming rewriting is trivial, quite the opposite (actually my point is, "rewriting is what it is, not merely translating", but if I were to claim it's anything, it's not trivial I would call it!). You seem to have understood that I'm claiming it's easy because I've done some porting; I am just saying "I've done some porting, and it's a pain even when possible". – acl Dec 17 '11 at 17:24
  • @acl, of course I agree, just illustrated your point. Not even "rewriting" is always possible (unless you implement half of Mathematica in Python/Octave/Whatever). So what I propose is not to rewrite or "port" anything, but let them work together. Leave all the symbolic part to Mathematica, and generate refined numeric code for a computational backend (whatever it is - NumPy, OpenCL, Octave, ...). – SK-logic Dec 17 '11 at 17:27