Lars Melchior
Lars Melchior

Reputation: 302

Integral of piecewise function gives incorrect result

Using the recent version of sympy (0.7.6) I get the following bad result when determining the integral of a function with support [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())

This is incorrect as the actual result should have the last two cases swapped. This can be confirmed by checking the derivative:

Derivative(I.doit(),z).doit().simplify().subs(z,x)

which reduces to 0 everywhere.

Interestingly, when dropping the condition (b>c) by substituting inner = Piecewise((0,(x>=y)|(x<0)),(a,True)) I get a TypeError:

TypeError: cannot determine truth value of
-oo < y

Am I using the library incorrectly or is this actually a serious sympy bug?

Upvotes: 6

Views: 1065

Answers (1)

user3717023
user3717023

Reputation:

Yes, sympy 0.7.6 is wrong in this case, and in some other such cases. Generally, I don't know any symbolic math package that I would trust to do calculus with piecewise defined functions.

Note that although

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

throws a TypeError at integration time, a logically equivalent definition

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

leads to the correct result

Piecewise((a*z, And(z < y, z >= 0)), (0, And(z <= 0, z >= -oo)), (a*y, True))

By the way, the previous version, sympy 0.7.5, handles

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

without a TypeError, producing the correct result (in a different form):

Piecewise((0, z <= 0), (a*y, z >= y), (a*z, True))

Here is another, simpler example of buggy behavior:

>>> 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

The first result is incorrect (it fails for z=0, for example). The second is correct. The only difference between two formulas is z<x vs x>z.

Upvotes: 4

Related Questions