SymPy中的简单计算会很快产生笨拙的结果,例如下面的三个should_be
值。
与正确值的比较得出False
(尽管math.isclose
得到True
)。
from sympy import sqrt
phi = (1 + sqrt(5)) / 2
should_be_phi = -(1/2 + sqrt(5)/2)**2 + (1/2 + sqrt(5)/2)**3
should_be_half = -sqrt(5)/8 + 1/8 + (1/2 + sqrt(5)/2)**2/4
should_be_one = -sqrt(5)/4 + 1/4 + (1/2 + sqrt(5)/2)**2/2
print(should_be_phi == phi, should_be_half == 1/2, should_be_one == 1)
这些是Wolfram Alpha格式化的相同公式:
phi:
半数:
一:
should_be_phi
的创建时间为phi**3 - phi**2
。
目前,我总是将这些怪兽复制到Wolfram Alpha中,以获取体面的公式并删除重复项。
每次比较您还获得False
吗?我使用的是Python 3.6.8和SymPy 1.4。
在Python中有没有一种方法可以真正起作用?
SymPy似乎无法执行它应做的事情。
答案 0 :(得分:1)
我假设您要简化这些表达式,所以只需使用simplify
函数:
In [6]: from sympy import *
In [7]: phi = (1 + sqrt(5)) / 2
In [8]: should_be_phi = -(S(1)/2 + sqrt(5)/2)**2 + (S(1)/2 + sqrt(5)/2)**3
In [9]: should_be_phi
Out[9]:
2 3
⎛1 √5⎞ ⎛1 √5⎞
- ⎜─ + ──⎟ + ⎜─ + ──⎟
⎝2 2 ⎠ ⎝2 2 ⎠
In [10]: simplify(should_be_phi)
Out[10]:
1 √5
─ + ──
2 2
请注意,您应该使用S(1)/2
而不是1/2
来产生浮点数。
如果要比较表达式,则显而易见的方法是使用==
,但这是SymPy中的“结构相等”。这意味着expr1 == expr2
仅在表达式具有完全相同的形式时才给出True
。如果要测试数学相等性,则应使用Eq(lhs, rhs)
或simplify(lhs-rhs)
:
In [11]: should_be_phi == phi # Expressions are not in the same form
Out[11]: False
In [12]: Eq(should_be_phi, phi)
Out[12]: True
In [13]: simplify(should_be_phi - phi)
Out[13]: 0
有没有一种方法可以在Python中进行实际有效的符号计算? SymPy似乎无法执行它应做的事情。
与Wolfram Alpha不同,SymPy的设计宗旨是使未读过任何文档的人无法使用或理解。如果您已阅读SymPy教程的前几页,将会回答上面的问题: https://docs.sympy.org/latest/tutorial/index.html#tutorial