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
btw。
[目前,我总是将这些怪兽复制到Wolfram Alpha,以获取合适的公式并删除重复项。
每次比较也得到False
吗?我使用Python 3.6.8和SymPy 1.4。
在Python中有没有一种方法可以进行实际上有效的符号计算?SymPy似乎无法执行它应做的事情。
我想您要简化这些表达式,所以只需使用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