Sympy比较失败与同情表达

时间:2014-01-18 01:07:14

标签: python sympy

我最近遇到SympPy的问题,我无法解决;我是图书馆的初学者,我花了很长时间在网上寻找解决方案而没有找到解决方案,这就是我来这里的原因。

问题在于:我有一个来自javascript网络应用的输出,它为我提供了表达式(x**2)**(1/3)而不是x**(2/3)。 “没问题”,我想,“SymPy会解析那个”......除非没有。如果我比较,我会得到那个结果:

>>> sympify("(x**2)**(1/3)") == sympify("x**(2/3)")
False

我进行了一些测试,而我只是用同义词中的指数来表达。例如:

>>> (x**(1/3))**2 == x**(2/3)
True

即使更奇怪,如果我反转两个指数,我得到一个正确的结果:

>>> sympify("(x**(1/3))**2") == sympify("x**(2/3)")
True

我尝试使用simplifyextend,但它也没有用。我获得良好结果的唯一方法是使用eval,但这需要首先创建一个符号“x”,这是我不能做的事情,因为我无法准确知道哪些符号将是在表达式中使用。

所以这就是问题:是SymPy中的错误,还是我做错了什么?

请原谅我这个问题是众所周知的,我自己找不到任何相关内容。

2 个答案:

答案 0 :(得分:1)

正如the SymPy issue所指出的,这是故意的。对于一般复杂x,这两个表达式不相等。例如x = -1((-1)**2)**(1/3) == 1**(1/3) == 1,而(-1)**(2/3) = -1/2 + sqrt(3)/2*I。有关详细信息,请参阅http://docs.sympy.org/0.7.3/tutorial/simplification.html#powers。 SymPy只会在知道完整域名的情况下才会简化这些指数。

特别是,如果x是非负的,则 为真。如果(x**a)**b == x**(a*b)是整数,b也是如此,这就是您的其他测试有效的原因。

如果您想强制简化,有两个主要选项。一个(最好的选择),就是假设x是非负的或正面的。

>>> x = symbols('x', positive=True)
>>> (x**2)**(S(1)/3)
x**(2/3)

如果您想在从字符串解析后用正面版本替换符号,可以使用posify

>>> posify((x**2)**(S(1)/3))
(_x**(2/3), {_x: x})

或者您可以使用locals参数sympify手动设置{'x': Symbol('x', positive=True}

另一种方式,如果这不能完全满足您的需求,请使用powdenest强制简化:

>>> x = symbols('x') # No assumptions on x
>>> (x**2)**(S(1)/3)
(x**2)**(1/3)
>>> powdenest((x**2)**(S(1)/3), force=True)
x**(2/3)

如果你这样做,你需要小心,因为你正在应用并非总是如此的身份,所以你最终可能会得到数学上不正确的结果。

答案 1 :(得分:0)

这是同情的错误。

指数层次结构没有正确的展开(参见https://github.com/sympy/sympy/blob/master/sympy/core/power.py#L445