【问题标题】:Integral of piecewise function gives incorrect result分段函数的积分给出不正确的结果
【发布时间】:2015-05-10 18:33:25
【问题描述】:

使用最新版本的 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&gt;=y)|(x&lt;0)),(a,True)) 来删除条件 (b&gt;c) 时,我得到一个 TypeError:

TypeError: cannot determine truth value of
-oo < y

我是在错误地使用库还是这实际上是一个严重的 sympy 错误?

【问题讨论】:

    标签: python sympy integral


    【解决方案1】:

    是的,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,处理

    inner = Piecewise( (0, (x>=y)|(x<0)), (a,True) )
    

    没有 TypeError,产生正确的结果(以不同的形式):

    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&lt;xx&gt;z

    【讨论】:

    • 谢谢,这证实了我的怀疑。关于为什么符号数学包与分段定义的函数如此困难的任何见解?我相信这只是拆分积分和选择正确的积分限制的问题。如果这是已知的错误行为,sympy 不应该在分段函数上引发 NotImplementedError 吗?
    • 我不知道 sympy 的内部结构。我只是凭经验知道 CAS 与此类事情作斗争,例如 Wolfram Alpha 得到 |sin x| 的不定积分错误的。如果您可以访问 Maple 或 Mathematica(我目前没有),您可能希望将结果与他们的结果进行比较。
    • 实际上,我从 wolfram alpha 得到的结果是 -cos(x)sign(sin(x)) + c ,这是正确的反导数(请注意,在确定的情况下 c 必须每半周期增加 2)。
    • 如果某物增加 2,它就不再是一个常数了。无论如何,WA没有告诉你这个增加,你必须自己找到它。如果你只是简单地把它的答案用于计算而没有重新检查,结果会是错误的。
    • wolfram documentation for indefinite integrals 声明 c 只是一个分段常数函数。无论哪种方式,反导数都是正确的。要确定定积分,您必须使用仅适用于连续函数的First Fundamental Theorem of Calculus,因此您必须相应地选择此分段常数。我同意 WA 应该更清楚地说明这一点,但在我看来,他们对分段函数没有任何问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多