Here is the pipeline that worked for me: Let us suppose you have an expression like the following:
-(1/Sqrt[Kallenλ[x, y, z]]) DiLog[(a^2 x + b^2)/(a^2 y - b^2 y), -x] Log[a c^2 x y]
where Log
is the (natural) logarithm function defined in Mathematica, but the functions Kallenλ
and DiLog
are "not functions inherent to Mathematica", in the sense that they are given by a Mathematica package. The aim is to turn such an expression into a Python-readable one:
As suggested by @Bill, the idea is to turn our expression into a string:
expression = -(1/Sqrt[Kallen\[Lambda][x, y, z]]) DiLog[(a^2 x + b^2)/(a^2 y - b^2 y), -x] Log[a c^2 x y];
tostring = ToString[InputForm[expression]];
Export["/your/path/mathematica_expression.txt", tostring]
If you open the .txt file, the expression will look like as follows:
-((DiLog[(b^2 + a^2*x)/(a^2*y - b^2*y), -x]*Log[a*c^2*x*y])/Sqrt[Kallenλ[x, y, z]])
Parentheses have been set to guarantee the correct order of evaluation of the operations; additionally, a *
symbol has been placed wherever a product applies. However, expressions like b^2
should be b**2
; we need to change []
by ()
, and some special characters, such as λ
, must be removed. Next, we continue working exclusively in Python:
The special characters can be removed as follows:
def search_and_replace(file_path, search_word, replace_word):
with open(file_path, 'r') as file:
file_contents = file.read()
updated_contents = file_contents.replace(search_word, replace_word)
with open(file_path, 'w') as file:
file.write(updated_contents)
and so
search_and_replace("/your/path/mathematica_expression.txt", "Kallenλ", "Kallen")
will replace the instances of Kallenλ
with Kallen
. You can use the same function to remove other special characters. Please note that you have overwritten the .txt file.
Now, we use sympy's method parse_mathematica
. The full documentation is here. By doing
from sympy.parsing.mathematica import parse_mathematica
with open("/your/path/mathematica_expression.txt", 'r') as file:
file_name = file.read()
parsed_expression = parse_mathematica(file_name)
you will replace []
with ()
, and lowercase some functions such as Sin
to sin
. Finally, probably you would like to use Python libraries such as cmath, numpy, etc. Then, for example, we would like to replace every instance of sin
with np.sin
. I did this with the RegEx Python module:
import re
import numpy as np
patterns = [
(r'Conjugate\((.*?)\)', r'np.conjugate(\1)'),
(r'sin\((.*?)\)', r'np.sin(\1)'),
(r'cos\((.*?)\)', r'np.cos(\1)'),
(r'log\((.*?)\)', r'cmath.log(\1)'),
(r'sqrt\((.*?)\)', r'cmath.sqrt(\1)'),
(r're\((.*?)\)', r'np.real(\1)'),
(r'im\((.*?)\)', r'np.imag(\1)'),
(r'pi', r'np.pi')
]
# Apply replacements using regular expression substitution
def replacepatterns(input_string):
for pattern, replacement in patterns:
input_string = re.sub(pattern, replacement, input_string)
return input_string
python_expression = replacepatterns(str(parsed_expression))
After this, your python_expression
will look like:
DiLog((a**2*x + a**2*y - a**2*z + b**2*x - b**2*y + b**2*z - 2*c**2*x - x**2 + x*y + x*z + (-a**2 + b**2 - x)*cmath.sqrt(Kallen(x, y, z)))/(a**2*x + a**2*y - a**2*z + b**2*x - b**2*y + b**2*z - 2*c**2*x - x**2 + x*y + x*z - cmath.sqrt(Kallen(a**2, b**2, x))*cmath.sqrt(Kallen(x, y, z))), -x*(a**2*(-x - y + z + cmath.sqrt(Kallen(x, y, z))) - b**2*(x - y + z + cmath.sqrt(Kallen(x, y, z))) + x*(2*c**2 + x - y - z + cmath.sqrt(Kallen(x, y, z)))))
Of course, you can save this expression in a .py
file and call it later or do whatever you want. To define a function from this expression, we can do:
from sympy import var
variables = var(
['x', 'y', 'z', 'a', 'b', 'c'])
x, y, z, a, b, c = variables
def our_function(a, b, c, x, y, z):
return eval(python_expression)
ToString[InputForm[Kallen[a^2, b^2, c^2 + d^2]]]
will turn that into a string and I think do pretty much everything except[]
to()
to be ready for Python. Then you canPrint
or do anything else with an ordinary string to put it into a file. ChangingInputForm
toTraditionalForm
LOOKS like it does more of what you want BUT that is only for looking at while inside MMA and that is not what you want. $\endgroup$