符号定积分表达式不能产生与数值评估相同的结果

时间:2018-11-05 20:50:14

标签: sympy

我使用sympy解析了表达式的定积分,以获得积分的符号表达式。但是,当我在函数中使用yield表达式时,得到的结果与积分的数值计算所得出的结果不同:

>> from sympy import *
>> x, y, a, b, c, d, k = symbols ('x y a b c d k', positive=True)
>> res = integrate(exp(-k*abs(x-y)), (x, a, b), (y, c, d))

>> res
(-exp(a*k) + exp(b*k))*exp(-b*k)*exp(-k*(a - d))/k**2 - (-exp(a*k) + exp(b*k))*exp(-b*k)*exp(-k*(a - c))/k**2

>> def integral_1(k1, a1, b1, c1, d1):
>>     return (-exp(a1*k1) + exp(b1*k1))*exp(-b1*k1)*exp(-k1*(a1 - d1))/k1**2 - (-exp(a1*k1) + exp(b1*k1))*exp(-b1*k1)*exp(-k1*(a1 - c1))/k1**2

>> integral_1(0.6, 0, 1, 0, 1)
1.0303623235681536

>> integrate(exp(-0.6*abs(x-y)), (x, 0, 1), (y, 0, 1))
0.826731311633480

为什么会有这种区别?

1 个答案:

答案 0 :(得分:1)

由于SymPy错误,符号输出错误。另外:演示它的更好方法是res.subs({k: 0.6, a: 0, b: 1, c: 0, d: 1})返回1.03 ...,对于在单位平方上以1为界的函数的积分,这显然是不可能的。

问题是SymPy(从1.3版开始)没有正确处理此积分中的abs。如果您根本不包含res,则其输出abs将相同。一个简单的例子:

>>> integrate(exp(abs(x-y)), (x, a, b))
-exp(a - y) + exp(b - y)

这是不对的,因为积分必须取决于相对于a和b放置y的方式。

一种补救措施(直到错误已修复)是​​将rewrite(Piecewise)应用于被积数,用分段函数替换abs。例如,exp(abs(x-y)).rewrite(Piecewise)返回exp(Piecewise((x - y, x - y >= 0), (-x + y, True))),它已正确集成。

之后
res = integrate(exp(-k*abs(x-y)).rewrite(Piecewise), (x, a, b), (y, c, d))

结果冗长而丑陋,但正确的:

>>> res.subs({k: 0.6, a: 0, b: 1, c: 0, d: 1})
0.826731311633481

如果您告诉SymPy a

>>> res.subs({a < b: True})
-2*Min(d, Max(a, c))/k + 2*Min(d, Max(a, b, c))/k + (-exp(a*k) + exp(b*k))*exp(-b*k)*exp(-k*(a - Min(d, Max(a, c))))/k**2 - (-exp(a*k) + exp(b*k))*exp(-b*k)*exp(-k*(a - Min(c, d)))/k**2 - (exp(a*k) - exp(b*k))*exp(-a*k)*exp(-k*(-a + Min(d, Max(a, b, c))))/k**2 + (exp(a*k) - exp(b*k))*exp(-a*k)*exp(-k*(-a + d))/k**2 - (-k**2*exp(a*k)*exp(k*(-a + Min(d, Max(a, c)))) + k**2*exp(b*k)*exp(-k*(-a + Min(d, Max(a, c)))))*exp(-b*k)/k**4 + (-k**2*exp(a*k)*exp(k*(-a + Min(d, Max(a, b, c)))) + k**2*exp(b*k)*exp(-k*(-a + Min(d, Max(a, b, c)))))*exp(-b*k)/k**4