2017-03-07 92 views
0

我想用符号生成方程,然后在值与类型的子从库等uncertainties(但也可以是使用自定义类型的任何库),但是,似乎使用.evalf(subs={...})方法失败,而奇错误信息:评估与Python等效的操作sympy表达

>>> 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)) sympy被转换我的价值用绳子给'5.0+/-1.0'所以它显然想我的替代值的字符串表示会看起来像一个象征性的表达。

我知道很多sympy操作(如分化)将不可能支持这一点,它只会是可能的,如果所有的自由符号所取代,因为这两种类型的不玩好:

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

也许你想多了,但你可以创建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 
+0

清楚,既更容易,更迂回,然后我期待,这(与一个以上参数)正是我所需要的,所以我实际上要使用的代码是'return lambdify(subs.keys(),expr)(* subs.values())'非常感谢你! –

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而不是默认的数学模块。