使用python等效操作评估sympy表达式

时间:2017-03-07 21:57:40

标签: python sympy

我想象征性地生成方程,然后使用像uncertainties这样的库中的类型的子值(但可以是任何具有自定义类型的库),但似乎使用.evalf(subs={...})方法失败了奇怪的错误信息:

>>> from uncertainties import ufloat
>>> from sympy.abc import x
>>> (x**2).evalf(subs={x: ufloat(5,1)})
Traceback (most recent call last):
  ...
  File "<string>", line 1
    Float ('5.0' )+/-Float ('1.0' )
                   ^
SyntaxError: invalid syntax

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<pyshell#116>", line 1, in <module>
    (x**2).evalf(subs={x: ufloat(5,1)})
  ...
sympy.core.sympify.SympifyError: Sympify of expression 'could not parse '5.0+/-1.0'' failed, because of exception being raised:
SyntaxError: invalid syntax (<string>, line 1)
  • 我知道,由于str(ufloat(5,1))给出了'5.0+/-1.0',因此我正在用字符串转换我的值,所以它显然希望我的替换值的字符串表示看起来像一个符号表达式。

我知道许多同情操作(如差异化)不可能支持这一点,只有当所有自由符号都被替换时才会有可能,因为这两种类型不能很好用:

>>> x + ufloat(5,1)
Traceback (most recent call last):
  File "<pyshell#117>", line 1, in <module>
    x + ufloat(5,1)
TypeError: unsupported operand type(s) for +: 'Symbol' and 'Variable'

但是假设我没有留下符号操作/变量,是否可以使用python等效操作简单地评估一个sympy表达式?

2 个答案:

答案 0 :(得分:2)

也许你想要更多,但你可以从sympy表达式创建普通函数然后使用不确定性

from uncertainties import ufloat
from sympy.abc import x
from sympy.utilities.lambdify import lambdify
expr = x**2
f = lambdify(x, expr)
f(ufloat(5,1))
Out[5]: 25.0+/-10.0

答案 1 :(得分:0)

我目前的解决方案是使用eval的松散调用,这似乎不是一个好主意,特别是因为Sympy is fine with Basic.__str__ method being monkey patched.

import math, operator
eval_globals = {"Mod":operator.mod}
eval_globals.update(vars(math))

def eval_sympy_expr(expr, **subs):
    return eval(str(expr), eval_globals, subs)

并且对于uncertainties支持我只会import uncertainties.umath as math而不是默认的数学模块。