分段函数的积分给出不正确的结果
Integral of piecewise function gives incorrect result
使用最新版本的 sympy (0.7.6) 在确定支持 [0,y] 的函数的积分时,我得到以下错误结果:
from sympy import *
a,b,c,x,z = symbols("a,b,c,x,z",real = True)
y = Symbol("y",real=True,positive=True)
inner = Piecewise((0,(x>=y)|(x<0)|(b>c)),(a,True))
I = Integral(inner,(x,0,z))
Eq(I,I.doit())
这是不正确的,因为实际结果应该交换最后两种情况。这可以通过检查导数来确认:
Derivative(I.doit(),z).doit().simplify().subs(z,x)
到处都减少到 0。
有趣的是,当通过替换 inner = Piecewise((0,(x>=y)|(x<0)),(a,True))
来删除条件 (b>c)
时,我得到一个 TypeError:
TypeError: cannot determine truth value of
-oo < y
我是否错误地使用了这个库,或者这实际上是一个严重的 sympy 错误?
是的,sympy 0.7.6 在这种情况下是错误的,在其他一些此类情况下也是如此。一般来说,我不知道有什么符号数学包可以信任用分段定义的函数进行微积分。
请注意,虽然
inner = Piecewise((0, (x>=y)|(x<0)), (a,True))
在集成时抛出 TypeError,逻辑上等效的定义
inner = Piecewise((a, (x<y)&(x>=0)), (0,True))
导致正确的结果
Piecewise((a*z, And(z < y, z >= 0)), (0, And(z <= 0, z >= -oo)), (a*y, True))
对了,之前的版本,sympy 0.7.5,handles
inner = Piecewise( (0, (x>=y)|(x<0)), (a,True) )
没有类型错误,产生正确的结果(以不同的形式):
Piecewise((0, z <= 0), (a*y, z >= y), (a*z, True))
这是另一个更简单的错误行为示例:
>>> Integral(Piecewise((1,(x<1)|(z<x)), (0,True)) ,(x,0,2)).doit()
-Max(0, Min(2, Max(0, z))) + 3
>>> Integral(Piecewise((1,(x<1)|(x>z)), (0,True)) ,(x,0,2)).doit()
-Max(0, Min(2, Max(1, z))) + 3
第一个结果不正确(例如,z=0 时失败)。第二个是正确的。两个公式之间的唯一区别是 z<x
与 x>z
。
使用最新版本的 sympy (0.7.6) 在确定支持 [0,y] 的函数的积分时,我得到以下错误结果:
from sympy import *
a,b,c,x,z = symbols("a,b,c,x,z",real = True)
y = Symbol("y",real=True,positive=True)
inner = Piecewise((0,(x>=y)|(x<0)|(b>c)),(a,True))
I = Integral(inner,(x,0,z))
Eq(I,I.doit())
这是不正确的,因为实际结果应该交换最后两种情况。这可以通过检查导数来确认:
Derivative(I.doit(),z).doit().simplify().subs(z,x)
到处都减少到 0。
有趣的是,当通过替换 inner = Piecewise((0,(x>=y)|(x<0)),(a,True))
来删除条件 (b>c)
时,我得到一个 TypeError:
TypeError: cannot determine truth value of
-oo < y
我是否错误地使用了这个库,或者这实际上是一个严重的 sympy 错误?
是的,sympy 0.7.6 在这种情况下是错误的,在其他一些此类情况下也是如此。一般来说,我不知道有什么符号数学包可以信任用分段定义的函数进行微积分。
请注意,虽然
inner = Piecewise((0, (x>=y)|(x<0)), (a,True))
在集成时抛出 TypeError,逻辑上等效的定义
inner = Piecewise((a, (x<y)&(x>=0)), (0,True))
导致正确的结果
Piecewise((a*z, And(z < y, z >= 0)), (0, And(z <= 0, z >= -oo)), (a*y, True))
对了,之前的版本,sympy 0.7.5,handles
inner = Piecewise( (0, (x>=y)|(x<0)), (a,True) )
没有类型错误,产生正确的结果(以不同的形式):
Piecewise((0, z <= 0), (a*y, z >= y), (a*z, True))
这是另一个更简单的错误行为示例:
>>> Integral(Piecewise((1,(x<1)|(z<x)), (0,True)) ,(x,0,2)).doit()
-Max(0, Min(2, Max(0, z))) + 3
>>> Integral(Piecewise((1,(x<1)|(x>z)), (0,True)) ,(x,0,2)).doit()
-Max(0, Min(2, Max(1, z))) + 3
第一个结果不正确(例如,z=0 时失败)。第二个是正确的。两个公式之间的唯一区别是 z<x
与 x>z
。