3
$\begingroup$

I have a Python file that has a variable defined using sympy. For instance, let us take the following (crazy) example that I could have eventually since I am automatizing a routine:

from sympy import *
e=symbols('e')
a=e*10**(-100)-sin(e**2-1)+cos(e*10**(-50)+1)
file=open('file.txt','w')
file.write(str(a))
file.close()

After this, the file is saved in the following way:

1.0e-100*e - sin(e**2 - 1) + cos(1.0e-50*e + 1)

I would like to open this file in Mathematica and save the output as a variable in Mathematica format.

The problem here is that to replace e by *^ is not an option since e is a parameter of the variable that is being saved so that would change even the variable e. An interesting fact about this is that when e is followed immediately by an integer, then the meaning of the e is *^. However, I don't know how to check that. Besides, I haven't been able to find a way to change the trigonometric functions into Mathematica input since the arguments of those functions could be anything.

Up until now, I have solved the problem with sqrt and general exponents but I don't know how to deal with the scientific notation and trigonometric functions.

EDIT: Up until now it seems that this solves the problem with e in Mathematica:

file=Import["file.txt"]
file = StringReplace[file, "**" -> "^"]
file = StringReplace[file, "e" -> "*^"]
file = StringReplace[file, "*^ " -> "e "]
file = StringReplace[file, "*^^" -> "e^"]
file = StringReplace[file, "*^*" -> "e*"]

Yet I am not sure if there is another method to solve it or if that would solve all the problems with the e.

$\endgroup$
5
  • $\begingroup$ I know little about python, but does there exist something amount to FullForm of Mathematica in sympy? If so, the conversion will be much easier. $\endgroup$
    – xzczd
    Commented Sep 20, 2021 at 3:19
  • $\begingroup$ I haven't read of a function like that for Python actually. I tried looking for something like that but the functions I found expand the expression but in Sympy's notation... $\endgroup$ Commented Sep 20, 2021 at 3:24
  • $\begingroup$ Aha, I found it, it's srepr. Now I believe you know what to do. $\endgroup$
    – xzczd
    Commented Sep 20, 2021 at 3:35
  • $\begingroup$ I found that function when I was looking for an analogous to FullForm in Python but, as I told you, the only thing that function does is to expand the operations done in a variable. For instance, if a=x**2, then srepr(a) will be equal to Pow(Symbol('x'),Integer(2)). That only expands the operations but not in a "usual" mathematical way. I don't know if that can be read by Mathematica then... $\endgroup$ Commented Sep 20, 2021 at 3:41
  • 2
    $\begingroup$ OK, so you don't know what to do, then please see my answer. $\endgroup$
    – xzczd
    Commented Sep 20, 2021 at 3:49

3 Answers 3

6
$\begingroup$

I would use Latex to convert sympy to Mathematica:

>python
>>> from sympy import *
>>> e=symbols('e')
>>> expr=e*10**(-100)-sin(e**2-1)+cos(e*10**(-50)+1)
>>> expr
1.0e-100*e - sin(e**2 - 1) + cos(1.0e-50*e + 1)
>>> latex(expr)
'1.0 \\cdot 10^{-100} e - \\sin{\\left(e^{2} - 1 \\right)} + \\cos{\\left(1.0 \\cdot 10^{-50} e + 1 \\right)}'
>>>

Copy the Latex above, either via text file or by copy/paste into Mathematica notebook. And then do, inside Mathematica

expr="1.0 \\cdot 10^{-100} e - \\sin{\\left(e^{2} - 1 \\right)} + \\cos{\\left(1.0 \\cdot 10^{-50} e + 1 \\right)}";
expr=StringReplace[expr,"\\cdot"->"*"]
exprInMathematica=ToExpression[expr,TeXForm]

Mathematica graphics

$\endgroup$
5
  • $\begingroup$ This seems quite useful. The only problem I am finding is that the expressions with sympy often omit the product sign *. For instance if in that expression you define two extra symbols and you multiply them, Mathematica reads those product as only one symbol $\endgroup$ Commented Sep 20, 2021 at 16:19
  • $\begingroup$ hello @edgardeitor. if the original math expression in sympy is valid, and assuming python generates valid Latex, and assuming Mathematica translate Latex correctly (which I know TeXForm is pretty good at this), then this method should work. But ofcourse this is not 100% robust method. Latex itself is fragile language and some argue it is not even a programing language, but Knuth says it is. You might want to accept xzczd answer instead if you find it works better for you and more robust. $\endgroup$
    – Nasser
    Commented Sep 20, 2021 at 20:04
  • $\begingroup$ Thanks for your reply. I know that maybe there is no method to deal with all the problems but I have worked with LaTeX and this seems a quite good way to solve the problem. I have only made one little change to deal with the spaces: expr=StringReplace[expr,"+ "->"+"] expr=StringReplace[expr," +"->"+"] expr=StringReplace[expr,"- "->"-"] expr=StringReplace[expr," -"->"-"] expr=StringReplace[expr," "->"*"] ` it seems to work fine up until now $\endgroup$ Commented Sep 20, 2021 at 20:37
  • 1
    $\begingroup$ @edgardeitor One troubesome case for latex I can think of at the moment: a=exp(e) $\endgroup$
    – xzczd
    Commented Sep 21, 2021 at 2:16
  • $\begingroup$ You are right. There are some problems when translating some numbers from LaTeX to Mathematica. I think there is no universal method to do this. I haven0t tried with your suggestion because it seems fine with this case but there are lots of functions that should be added apart from sin and cos in order to make the code available to run in "any" case. For instance, we have tan, arctan, sec, arcsec, exp, etc... $\endgroup$ Commented Sep 21, 2021 at 4:19
6
$\begingroup$

I believe the easiest and most robust solution is to make use of sexpr of python, which is amount to FullForm of Mathematica. First, use sexpr in place of str in the python code:

from sympy import *
e=symbols('e')
a=e*10**(-100)-sin(e**2-1)+cos(e*10**(-50)+1)
file=open('file.txt','w')
file.write(srepr(a))
file.close()

Then

string = Import@(* path to file.txt *)
(*
"Add(Mul(Float('1.0e-100', precision=53), Symbol('e')), Mul(Integer(-1), \
sin(Add(Pow(Symbol('e'), Integer(2)), Integer(-1)))), cos(Add(Mul(Float('1.0e-50', \
precision=53), Symbol('e')), Integer(1))))"
 *)

Block[{Add = Plus, Mul = Times, 
  Float = If[$VersionNumber >= 12.3, Internal`StringToMReal@# &, 
    Internal`StringToDouble@# &], cos = Cos, sin = Sin, Pow = Power}, 
 ToExpression@
  StringReplace[string, {"(" -> "[", ")" -> "]", "'" -> "\"", "Integer" -> "#&"}]]
(* 1.*10^-100 e + Cos[1 + 1.*10^-50 e] + Sin[1 - e^2] *)

To learn more about FullForm, you may want to read

What is the use of FullForm in Mathematica?

$\endgroup$
5
$\begingroup$

Sympy has a built-in function for this now

sympy.printing.mathematica.mathematica_code(expr, **settings)

Converts an expr to a string of the Wolfram Mathematica code

Examples

>>> from sympy import mathematica_code as mcode, symbols, sin
>>> x = symbols('x')
>>> mcode(sin(x).series(x).removeO())
'(1/120)*x^5 - 1/6*x^3 + x'

Source: https://docs.sympy.org/latest/modules/printing.html#sympy.printing.mathematica.mathematica_code

$\endgroup$
1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.