Are there suggestions how to convert a rather long Mathematica expression to Julia?
With Matlab I use http://library.wolfram.com/infocenter/MathSource/577/
I also would appreciate suggestions for the same problem with Sage Math
2 Likes
The closest thing to it is this
1 Like
Use SymPy.jl . SymPy can parse Mathematica expressions , and SymPy.jl can convert SymPy expressions to Julia expressions. For example, if we define:
using SymPy
const sympy_parsing_mathematica = SymPy.PyCall.pyimport("sympy.parsing.mathematica")
mathematica2julia(s::AbstractString, substitutions::Pair{<:AbstractString,<:AbstractString}...) =
SymPy.lambdify_expr(sympy_parsing_mathematica["mathematica"](s, Dict(substitutions...))).args[2]
then we get:
julia> mathematica2julia("Log[Log[x]]")
:(log(log(x)))
julia> mathematica2julia("Exp[Log3[x]]", "Log3[x]"=>"log(x,3)")
:(x ^ (log(3) ^ -1))
17 Likes
Works charmingly well… thank you!
SymataSyntax
has not been upgraded for v1.0.
Ah, this stops working now for SymPy v1.0.10.
The updated code should be:
using SymPy
const sympy_parsing_mathematica = SymPy.PyCall.pyimport("sympy.parsing.mathematica")
mathematica2julia(s::AbstractString, substitutions::Pair{<:AbstractString,<:AbstractString}...) =
SymPy.walk_expression(sympy_parsing_mathematica."mathematica"(s, Dict(substitutions...)))
5 Likes
Mason
December 14, 2019, 9:38pm
8
How to replace the unknown function?Naively the following code does not work.
mathematica2julia("(Sqrt[Pi])/(2*Gamma[23/10])","Gamma"=>"gamma")
PyError ($(Expr(:escape, :(ccall(#= /Users/gangchen/.julia/packages/PyCall/ttONZ/src/pyfncall.jl:44 =# @pysym (:PyObject_Call), PyPtr, (PyPtr, PyPtr, PyPtr), o, pyargsptr, kw))))) <class ‘ValueError’>
ValueError(“‘Gamma’ function form is invalid.”)
File “/Users/gangchen/.julia/conda/3/lib/python3.7/site-packages/sympy/parsing/mathematica.py”, line 17, in mathematica
parser = MathematicaParser(additional_translations)
File “/Users/gangchen/.julia/conda/3/lib/python3.7/site-packages/sympy/parsing/mathematica.py”, line 154, in init
d = self._compile_dictionary(additional_translations)
File “/Users/gangchen/.julia/conda/3/lib/python3.7/site-packages/sympy/parsing/mathematica.py”, line 187, in _compile_dictionary
raise ValueError(err)
The dictionary has to map a Mathematica function-call expression to a Python/SymPy function call:
julia> mathematica2julia("(Sqrt[Pi])/(2*Gamma[23/10])","Gamma[x]"=>"gamma(x)")
:(__prod__(1 / 2, pi ^ (1 / 2), gamma(23//10) ^ -1))
See the documentation for the sympy.parsing.mathematica.mathematica
function that is being called here.
I got a Julia expression if I do this. How to turn expression that I get into a function?
you can use SyntaxTree.jl. The genfun is useful. You can also see the examples in my UseMathLink.jl
I eventually ended up using sage and copy paste to Julia since the syntax are quite similar. The only problem I found so far is that sage convert Exp(2)
from Mathematica to e^2
. But I often want it written as exp(2)
.
I am trying to run this now, but I got some errors. I tried to fix it and I got this function
using SymPy
const sympy_parsing_mathematica = SymPy.PyCall.pyimport("sympy.parsing.mathematica")
mathematica2julia(s::AbstractString, substitutions::Pair{<:AbstractString,<:AbstractString}...) =
SymPy.walk_expression(sympy_parsing_mathematica."parse_mathematica"(s))
When I now try, I get
mathematica2julia("(Sqrt[Pi])/(2*EllipticE[m])","EllipticE[x]"=>"elliptic_e(x)")
# :((1 / 2) * SymPy.__POW__(pi, 1 / 2) * SymPy.__POW__(EllipticE(m), -1))
My goal is to get
sqrt(pi) / (2*elliptic_e(m))
How can I get this?
You don’t really need the walk expression part, but you need to add the EllipticE function to help sympy out. This seems to work:
sympy_parsing_mathematica.mathematica(s, Dict("EllipticE[x]"=>"elliptic_e(x)"))
1 Like
Thanks, but I don’t understand the suggestion.
Following what you wrote I tried to run:
sympy_parsing_mathematica.mathematica("(Sqrt[Pi])/(2*EllipticE[m])", Dict("EllipticE[x]"=>"elliptic_e(x)"))
I get a latex expression. But I actually want to get an expression I then can copy into a julia function like
Do you know how to do that?
Okay, the “POW ” you are seeing was removed somewhat recently, and ^
should be used in the returned expression. You can update SymPy, or try passing in a dictionary holding the conversion, like SymPy.walk_expression(out, fns=Dict("Pow"=>:^))
.
1 Like
Thanks again!
But I think the substitutions do not work anyway. In this example
mathematica2julia("(Sqrt[Pi])/(2*EllipticE[m])", "EllipticE[x]"=>"elliptic_e(x)")
# :((1 / 2) * SymPy.__POW__(pi, 1 / 2) * SymPy.__POW__(EllipticE(m), -1))
I get that EllipticE[m]
is not substituted by elliptic_e(m)
.
Github Copilot is quite good for these kind of tasks. I use it to convert from latex to Julia.
1 Like