![](/img/trans.png)
[英]What exactly is the `subs` argument of the `evalf` method of SymPy Expression for? Like `s.evalf(subs={…})`?
[英]Sympy's subs limitations
我正在处理一些较长的方程式,但并不是很复杂,我想使用sympy来简化和“分解”它们。 但是我遇到了一些问题。 以下是一些最小示例的列表:
问题1:对称
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
会给出一个浮点数(如果使用Python 2而不是from __future__ import division
则整数from __future__ import division
)。
在第一种情况下,在您的原始表达式中,Python从左到右求值1/12*b
。 Python将1/12
评估为0.08333333333333333
,然后将其乘以b
。 在第二种情况下, b*1
被评估为b
。 然后b/12
由SymPy评估(因为b
是SymPy对象),从而给出Rational(1, 12)*b
1,12 Rational(1, 12)*b
。
由于浮点数的不精确特性,SymPy认为浮点数0.08333333333333333
等于有理数1/12
。
有这个问题的一些更多的讨论在这里 。 解决方法是,应避免直接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
)。
这是您的问题的可能解决方案:
from sympy import *
a = symbols('a')
b = symbols('b')
expr = 1 / 12 * b + 1
print(expr.subs((1 / 12) * b, a))
print(expr.subs(b * (1 / 12), a))
x = symbols('x')
y = symbols('y')
expr = ((x + 1)**2 - x).expand()
print(expr.subs(x**2 + x, y - x + 1))
关于问题1,请注意, 1/12*b
和b*1/12
1/12在sympy中不是同一件事。 第一个是由符号组成的浮点数,而第二个是精确的符号表达式(您可以通过简单的print语句将其检出)。 由于expr
包含expr
1/12*b
,因此第二subs
不起作用也就不足为奇了。
关于问题2,您提供的subs
规则不明确。 特别地,替换规则意味着等式x**2+2*x==y+1
。 但是,此等式有许多解释,例如
x**2 == y + 1 - 2*x
(这是您考虑的值),
x**2 + x == y + 1 - x
,
x == (y + 1 - x**2)/2
,
因此,我认为sympy拒绝执行替换实际上是一种正确的方法。
如果它是您想要的第一个解释,则最好在subs
规则中明确提供它,即
(((x+1)**2-x).expand()).subs(x**2, -2*x + y + 1)
-x + y + 2
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.