我正在处理一些长方程但并不复杂,我想使用 sympy 来简化和“分解”它们。但是我遇到了一些问题。以下是一些最小示例的列表:
问题一:对称性
from sympy import *
from __future__ import division
a = symbols('a')
b = symbols('b')
expr = 1/12*b + 1
expr.subs(1/12*b, a)
expr.subs(b*1/12, a)
第一行给出预期结果(即。a+1),而第二行没有替换。
问题 2:因式分解
表达式的某些部分被分解,当我展开表达式时,它们会得到简化,因此无法进行替换。例如
(((x+1)**2-x).expand()).subs(x**2+2*x, y+1)
将给出 x^2+x+1 而我正在寻找的是 y+2-x。
问题
有没有办法解决这些问题?或者也许我应该使用另一种符号数学工具?欢迎提出任何建议。
请您参考如下方法:
在 SymPy 中有一个主要问题,那就是,由于 Python 的工作方式,number/number 给出一个 float (或者如果您使用 Python 2 而不是进行整数除法来自 __future__ 导入部门)。
在第一种情况下,在您的原始表达式中,Python 从左到右计算 1/12*b。 1/12 由 Python 计算得到 0.08333333333333333,然后乘以 b。在第二种情况下,b*1 被评估为 b。然后 b/12 被 SymPy 求值(因为 b 是一个 SymPy 对象),得到 Rational(1, 12)*b。
由于 float 的不精确性,SymPy 不会将 float 0.08333333333333333 视为等于有理数 1/12。
这个问题还有一些讨论here .作为解决方法,您应该避免直接 integer/integer 而不以某种方式包装它,以便 SymPy 可以创建有理数。以下都将创建一个有理数:
b/12
Rational(1, 12)*b
S(1)/12*b
对于 (((x+1)**2-x).expand()).subs(x**2+2*x, y+1) 问题是 x**2 + 2*x 没有准确出现在表达式中,即 x**2 + x + 1。 SymPy 通常只替换它准确看到的东西。
看来您不介意添加和减去 x 来使替换工作正常进行。所以我建议改为 (((x+1)**2-x).expand()).subs(x**2, y+1 - 2*x)。通过仅替换单个项 (x**2),替换将始终有效,并且 2*x 将取消以留下任何 x 术语保留(在本例中为 -x)。
