当输入是字符串时,Sympy会给出意外的区分结果

时间:2018-02-06 13:01:00

标签: sympy

为什么区分结果不是2*x0在以下代码中:

In [54]: import sympy

In [55]: x = [sympy.Symbol('x%d' % i, real=True) for i in range(3)]

In [56]: x
Out[56]: [x0, x1, x2]

In [57]: sympy.diff('x0*x0 + x1*x1 + x2*x2',x[0])
Out[57]: 0

2 个答案:

答案 0 :(得分:2)

首先,使用

创建多个编号的符号更简单
x = sympy.symbols('x0:3', real=True)     # returns (x0, x1, x2)

其次,将字符串转换为SymPy表达式的SymPy函数是sympify。当您以字符串形式提供输入时,将自动调用此函数;但是,这使您无法控制字符串的解释,并且可能会出现“意外结果”。

在这种情况下,SymPy不确定字符串中出现的“x0”是否与您之前创建的x0相同。毕竟,你的x0具有真实的附加属性,并且字符串中的符号没有这样的假设。它是Symbol('x0') vs Symbol('x0', real=True);不匹配。

这是为什么在SymPy函数中抛出字符串是一个坏主意的众多原因之一。使用sympify,并阅读其控制输入解析的参数。具体来说,locals参数是一个字典,它将字符串的各个部分映射到SymPy中已有的对象,这里正是需要的。

locals = {'x{}'.format(i): x[i] for i in range(3)}  #  {'x0': x0, 'x1': x1, 'x2': x2}
expr = sympy.sympify('x0*x0 + x1*x1 + x2*x2', locals=locals)

现在,您可以根据任何符号区分expr并获得预期结果

[expr.diff(sym) for sym in x]   #  [2*x0, 2*x1, 2*x2]

(在尝试diff之前使用表达式的另一个好处是,您可以调用diff作为表达式的方法,从而省去了键入sympy.前缀的麻烦。)

答案 1 :(得分:1)

在您的声明中,您应该使用sympy.symbols作为参考方法(来自文档和教程)来声明变量。

x = [sympy.symbols('x%d' % i, real=True) for i in range(3)]

除此之外,您必须(在我做的实验中)选择两个参数中的字符串,如下所示:

sympy.diff('x0*x0 + x1*x1 + x2*x2',str(x[0]))

或双方的符号表达:

sympy.diff(x[0]*x[0] + x[1]*x[1] + x[2]*x[2], x[0])