解析的SymPy表达式的导数始终为0

时间:2017-04-22 02:43:19

标签: python math sympy

我正在编写一个程序,要求用户输入表达式。此表达式作为字符串输入,并使用parse_expr转换为Sympy表达式。然后我需要获取用户输入的表达式的偏导数。但是,diff对我正在测试的每个表达式返回0。

例如,如果用户使用以下代码输入a*exp(-b*(x-c)**(2)),则diff会返回0的时间(就我所知diff而言)返回{{ 1}}在取2*a*b*(c - x)*exp(-b*(x - c)**2)

时的偏导数时
x

我做错了什么?

4 个答案:

答案 0 :(得分:1)

底线:使用 parse_expr(str_expr,locals())

如果表达式可能使用未导入到本地名称空间且无法访问with the default from sympy import *的任何实体,也可以添加global_dict=<dict of allowed entities to use>

根据Calculus — SymPy Tutorial - SymPy 1.0.1.dev documentation,您可以按原样在diff()参数中键入符号表达式。由于这些字母是Symbol个对象(具有重写的运算符),因此在评估参数时,Python会被欺骗构造对应于表达式的SymPy对象!

因此,如果你把它作为一个字符串,你eval它会触发相同的行为:

<...>
>>> s="a*exp(-b*(x-c)**(2))"
>>> diff(eval(s), x)
−ab(−2c+2x)e−b(−c+x)2

eval如果与不受信任的输入一起使用会带来安全隐患,因为它接受任意Python代码。

这就是像parse_expr这样的替代品发挥作用的地方。但是,由于表达式的解析方式(如上所述),它需要访问表达式中使用的外部实体 - 比如Symbol对象的变量和所用命名函数的函数对象 - 通过{{1} }和local_dict参数。

否则,它会动态创建global_dict个对象。这意味着,它在表达式中为Symbol创建的Symbol对象与变量x不同!难怪它的衍生物是0!

x

答案 1 :(得分:1)

正在开展工作,使sympifyeval更安全。最好使用以下内容:

from sympy import *

var ('a b c x')

str_expr = "a*exp(-b*(x-c)**(2))"
parsed_expr = sympify(str_expr)
result = diff(parsed_expr, x)
print(result) 

结果:

-a*b*(-2*c + 2*x)*exp(-b*(-c + x)**2)

答案 2 :(得分:0)

a, b, c, x = symbols('a b c x', real=True)替换为:

a = Symbol('a')
b = Symbol('b')
c = Symbol('c')
x = Symbol('x')

答案 3 :(得分:0)

具有不同假设的符号比较不等:

>>> Symbol('x') == Symbol('x', real=True)
False

当您使用sympifyparse_expr时,它会将未知变量解析为符号而不进行假设。在您的情况下,这会创建Symbol('x'),这与您已创建的Symbol('x', real=True)不同。

解决方案是删除假设,或者在解析时包含locals()字典,以便它将名称x识别为您已定义的Symbol('x', real=True),例如

parse_expr(str_expr,locals())

sympify(str_expr, locals())