从sympy表达式生成python代码?

时间:2014-12-04 21:37:51

标签: python sympy

问题: 给出一个sympy表达式,是否有一种简单的方法来生成python代码(最后我想要一个.py或者.pyc文件)?我想这个代码将包含一个给出任何必要输入的函数,并返回表达式的值。

为什么

我发现自己经常需要生成python代码来计算一些令人讨厌的东西,例如令人讨厌的非线性函数的雅可比矩阵。

我可以用sympy来得到我想要的非线性事物的表达式:非常好。我当时想要的是从生成的sympy表达式生成python代码,并将该python代码保存到它自己的模块中。我以前做过这个,但我不得不:

  1. 致电str(sympyResult)
  2. 使用正则表达式自定义事物以使此字符串看起来像有效的python代码
  3. 将此python代码写入文件
  4. 我注意到sympy具有其他几种语言的代码生成功能,但不支持python。有没有一种简单的方法可以让python代码脱离同情?

    我知道围绕这个问题的几种可能但有问题的方法:

    1. 我知道我可以在sympy表达式上调用evalf并插入我想要的数字。这有几个不幸的副作用:

      • 依赖:我的代码现在依赖于同意运行。这很糟糕。
      • 效率:每次我在数字上评估时,必须运行同情:即使我挑剔表达式,我每次仍然需要evalf
    2. 我也知道我可以生成C代码,然后使用大量工具(python / C api,cython,weave,swig等等)包装该代码。但是,这意味着我的代码现在依赖于有适当的C编译器。

    3. 修改:摘要 似乎sympy.python,或者可能只是str(表达式)是有的(参见smichr的回答和Oliver W.的评论),它们适用于简单的标量表达式。

      这对Jacobians这样的事情没什么帮助,但似乎sympy.printing.print_ccode也在矩阵上窒息。我认为可以处理将矩阵打印到另一种语言的代码必须假定目标语言中的矩阵支持,对于python而言可能意味着依赖于像numpy这样的东西。如果存在生成numpy代码的这种方式会很好,但它似乎没有。

2 个答案:

答案 0 :(得分:7)

如果您不介意在代码本身中使用SymPy依赖项,则更好的解决方案是在代码中生成SymPy表达式并使用lambdify对其进行评估。这比使用evalf快得多,特别是如果你使用numpy。

您还可以直接在sympy.printing.lambdarepr中查看打印机,这是lambdify用于将表达式转换为lambda函数的方法。

答案 1 :(得分:6)

您正在寻找生成python代码的函数是python。虽然它生成了python代码,但是正如Oliver W指出的那样,该代码需要进行一些调整以消除对SymPy对象的依赖。

>>> 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)]])