Create python code from sympy expression?

Question : Given a simplex expression, is there an easy way to generate python code (at the end, I want a .py file, or perhaps a .pyc file)? I am assuming this code will contain a function that receives any required inputs and returns the value of the expression.

Why

I very often have to generate python code to compute something that is unpleasant to output, like Jacobian matrices from a nasty non-linear function.

I can use sympy to output an expression for the non-linear thing I want: very good. What I then want is to generate python code from the resulting sympy expression and store that python code in its own module. I've done this before, but I had to:

  • Calling str (sympyResult)
  • Do custom stuff with regex to make this line look like valid python code.
  • write this python code to file

I note that sympy has code generation capabilities for several other languages, but not python. Is there an easy way to get python code from sympy?

I know of several possible but problematic ways to solve this problem:

  • I know that I can just call evalf on the sympy expression and plug in the numbers I want. This has several adverse side effects:

    • dependency: my code now depends on how sympy is started. This is bad.
    • Efficiency: sympy should now run every time I quantify: even if I'm parsing and flattening the expression, I still need it evalf

      every time.
  • I also know that I could generate, say, C code and then port that code using a variety of tools (python / C api, cython, weave, swig, etc.). This, however, means that my code now depends on having an appropriate C compiler.

Edit: summary It seems that sympy.python or maybe just str (expression) is what it is (see answer from smichr and comment from Oliver W.) and they work for simple scalar expressions.

It doesn't help much with things like Jacobians, but then it seems like sympy.printing.print_ccode throttles on matrices too. My guess is that code that can handle printing matrices in another language would have to assume matrix support in the target language, which for python would probably mean relying on the presence of things like numpy. It would be nice if this way of generating numpy code existed, but it doesn't seem to be the case.

+3


source to share


2 answers


The function you are looking for to generate python code is python

. While it generates python code, this code needs some tweaking to remove the dependency on SymPy objects as pointed out by Oliver W.



>>> import sympy as sp
>>> x = sp.Symbol('x')
>>> y = sp.Symbol('y')
>>> print(sp.python(sp.Matrix([[x**2,sp.exp(y) + x]]).jacobian([x, y])))
x = Symbol('x')
y = Symbol('y')
e = MutableDenseMatrix([[2*x, 0], [1, exp(y)]])

      

+4


source


If you don't mind having a SymPy dependency in your code, the best solution is to generate a SymPy expression in your code and use lambdify

it to evaluate it. It will be much faster than using evalf, especially if you are using numpy.



You can also directly use the printer in sympy.printing.lambdarepr

, which is used lambdify

to convert the expression to a lambda function.

+3


source







All Articles