10

I'd like to know how can I call Mathematica functions from Python.

I appreciate a example, for example, using the Mathematica function Prime.

I had search about MathLink but how to use it in Python is a little obscure to me.

I tried to use a Mathematica-Python library called pyml but I hadn't no sucess, maybe because this lib looks very old (in tutorial says Mathematica 2 or 3).

Tried compile a source in Wolfram/Mathematica/8.0/SystemFiles/Links/Python but ended with several errors when using python 2.6 (documentation says should work to python 2.3 only).

Pythonika is interesting, but, looks like is just to use in Mathematica notebooks and I would like write .py files who calls Mathematica functions.

So, someone knows a good way to write python programs who uses Mathematica functions and can give me an example?

GarouDan
  • 3,743
  • 9
  • 49
  • 75
  • 1
    Are there specific Mathematica *only* functions that you need to call? If not, it's quite likely that another library implements what you're after. `numpy` is an extensive math library for `Python`, for example. –  Apr 23 '12 at 11:19
  • Is an interesting point, but, I would like the power that I know is available in Mathematica and use it. So, numpy and scypy looks a litle behind in this power to me. – GarouDan Apr 23 '12 at 18:12
  • I had found a solution and I posted it as an answer. I'll embrace it soon. – GarouDan Apr 23 '12 at 19:55
  • This was cross-posted [here](http://mathematica.stackexchange.com/questions/4643/how-to-use-mathematica-functions-in-python-programs). – Szabolcs Apr 25 '12 at 13:26

2 Answers2

3

You can call Mathematica function in Python using the Python MathLink module (the source you found in .../SystemFiles/Links/Python), though you'll need to edit a couple of setup files to get it up and running (support@wolfram.com should be able to help you out there).

To use Prime from Python you would run something like:

kernel.ready()

0

kernel.putfunction("Prime",1)

kernel.putinteger(10)

kernel.flush()

kernel.ready()

1

kernel.nextpacket()

3

packetdescriptiondictionary[3]

'ReturnPacket'

kernel.getinteger()

29

nikko
  • 131
  • 1
  • Looks like I'm almost `nikko`^^. Almost everything runned but the final command breaks. Could you take a look in this [pastebin link](http://pastebin.com/BydJZF01) and tell to me what's going on? – GarouDan Apr 23 '12 at 17:50
  • Thx a lot about your help nikko. – GarouDan Apr 23 '12 at 19:54
  • It looks like the packet is coming back differently than on mine. Try using kernel.getstring() instead to see what the return string is (sorry about the late response btw) You'll probably get something back like: >>> kernel.getstring() 'Out[1]= ' after which you can run kernel.nextpacket() again and should be able to snag the integer – nikko May 02 '12 at 19:58
3

I had found a solution.

Steps:

1-Create a script named runMath with the content:

#!/usr/local/bin/MathematicaScript -script

value=ToExpression[$ScriptCommandLine[[2]]];

(*The next lime prints the script name.*)
(*Print[$ScriptCommandLine[[1]]];*)

Print[value];

2-I gave execution privilege to the file.

sudo chmod +x runMath

3-Moved the file to the execution path

sudo mv runMath /usr/bin/

4-Created a new script called run with the content:

#!/usr/bin/python
from subprocess import *
from sys import *

command='/usr/bin/runMath'
parameter=argv[1]

call([command,parameter])

5-Moved to the execution path

sudo mv run /usr/bin

6-Finally, tested it:

$run Prime[100]
541

$run 'Sum[2x-1,{x,1,k}]'
k^2

$run Integrate[Log[x],x]
-x + x*Log[x]

$run 'Zeta[2]'
Pi^2/6

You can use with or without '. The ' are needed for commands with spaces.

$run 'f[n_] := f[n] = f[n - 1] + f[n - 2]; f[1] = f[2] = 1; Table[f[n],{n,5}]'
{1, 1, 2, 3, 5}

Happy!

GarouDan
  • 3,743
  • 9
  • 49
  • 75
  • A variation on the theme to be able to pipe input via stdin: Print[ToExpression[Import["!cat", "string"]]] (Note: Input[] and InputString[] stop at new-lines and OpenRead["stdin"] fails) – alexei Dec 01 '13 at 11:37