同情的比较与同情的表达不一样

  • 本文关键字:不一样 比较 python sympy
  • 更新时间 :
  • 英文 :


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

问题是:我有一个javascript web应用程序的输出,它给了我表达式(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中的一个错误,还是我做错了什么?

如果这个问题是众所周知的,并且我自己找不到任何关于它的信息,请原谅我。

正如在SymPy问题上指出的那样,这是有意的。这两个表达式对于一般复数CCD_ 6是不相等的。例如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是非负的,则真。如果b是一个整数,那么(x**a)**b == x**(a*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})

或者,可以使用sympifylocals参数手动设置{'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)

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

这是sympy中的一个bug。

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

最新更新