我最近遇到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
我尝试使用simplify
和extend
,但它也没有用。我获得良好结果的唯一方法是使用eval
,但这需要首先创建一个符号“x”,这是我不能做的事情,因为我无法准确知道哪些符号将是在表达式中使用。
所以这就是问题:是SymPy中的错误,还是我做错了什么?
请原谅我这个问题是众所周知的,我自己找不到任何相关内容。
答案 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)