Symbolic indefinite integral of piecewise function gives wrong results
18 views (last 30 days)
Show older comments
I encountered this somewhat strange behaviour, where I seem to get an erroneous result.
Consider the piecewise function defined by:
x=sym('x');
f=piecewise(abs(x)<0.5,1,0);
which is a simple rectangular pulse.
Attempting to calculate the indefinite integral,
F=int(f);
and plotting it gives this result:
which obviously is not a correct antiderivative of the given function.
I also tried to calculate a definite integral with a variable in the limit, with mixed results:
F=int(f,-Inf,x)
seems to work and gives the expected result:
However trying it with 0 as the lower limit gives a wrong result again:
F=int(f,0,x);
Is this a bug in Matlab, or somehow a mistake on my side?
2 Comments
Greg
on 29 Aug 2018
Edited: Greg
on 29 Aug 2018
I just spent 20 minutes typing up a very nicely detailed answer, then my computer arbitrarily refreshed the page and I lost it all. I'm not particularly motivated to start over, but in short:
I think you're confusing yourself (and the anti-derivatives) by using x as an integration bound.
Answers (3)
Greg
on 29 Aug 2018
Edited: Greg
on 29 Aug 2018
I disagree that the second attached image "obviously is not a correct antiderivative of the given function." If you take its derivative (simply look at the slope of the line), you get 0 outside x = +/- 1/2, and 1 inside. That smells like a proper answer to me.
As for your "definite integrals," I'm not entirely sure what's going on. But, if you manually integrate a few discrete values, it gives a proper area-under-the-curve (from what I can tell).
area_curve = []; % I NEVER recommend growing loops this way...
for ival = -2:.05:2
area_curve(end+1,1) = int(f,x,[0,ival]);
end
figure;
plot(area_curve);
5 Comments
Walter Roberson
on 29 Aug 2018
syms x a b
f = piecewise(abs(x)<0.5,1,0);
F = int(f, a, b);
FF = subs(F, a, 0);
fplot(FF, [0 2])
3 Comments
Walter Roberson
on 29 Aug 2018
The plot is intended for the case where the lower bound, a, is set to 0, corresponding to your
F=int(f,0,x);
Remember if you were to try to plot that below 0 then you would be plotting with a lower bound larger than the upper bound, and the definition for that would involve negatives.
The basic plot is the case
FF = subs(F, a, -2);
fplot(FF, [-2 2])
John D'Errico
on 3 Dec 2018
Edited: John D'Errico
on 3 Dec 2018
Personally, I'd suggest trying to define a piecewise function using abs is a dangerous thing, something that will only get you into trouble. I would suggest a more direct approach, one that will be far more readable, and so safer for all concerned. Thus...
syms x
f = piecewise(x<-0.5,0,x >= -0.5 & x < 0.5,1,x >= .5,0)
f =
piecewise(x < -1/2, 0, x in Dom::Interval([-1/2], 1/2), 1, 1/2 <= x, 0)
Which as you see, MATLAB translates into a simple expression, where it recognizes the explicit domains each segment lives on.
MATLAB has no trouble with a definite integral here, a matter of no dispute.
int(f,[-2,-.4])
ans =
1/10
But what happens when you just use int, in an indefinite form?
g = int(f)
g =
piecewise(x < -1/2, 0, x in Dom::Interval([-1/2], 1/2), x, 1/2 <= x, 0)
So each segment of the integral is correct, on its own, except that MATLAB does not introduce a constant of integration. That is consistent with how MATLAB works. It never writes in that blasted constant as we were taught to do in beginning calc. Thus, the integral of each term is...
int(0) = C1
int(1) = x + C2
But since this is a piecewise function, MATLAB integrates each piece separately, as we see in g, but again, we don't see those blasted constants. Now, what happens when we try to turn that indefinite integral into a definite one? Again, we learned in early calc to do so simply, substituting the limits of integration in, and subtracting the results.
subs(g,-.4) - subs(g,-2)
ans =
-2/5
So why does this fail? Because MATLAB forgot that those constants of integration were actually important. In fact, the piecewise integral should arguably have been:
g = piecewise(x < -1/2, 0, x in Dom::Interval([-1/2], 1/2), x + 1/2, 1/2 <= x, 1)
The difference is purely in the constants of integration, so easily ignored and so easily forgotten. Each constant of integration in an interval should be adjusted based on the constant from the prior segment, and the integral of the function over the prior segment.
Is this a bug? Perhaps. At least, it is a significant feature. ;-) You say potato, others say worm ridden tuber.
Now, lets go back to my initial comment, that use of piecewise properly is a far better thing to do. As you should see, there are two segments in this expression where f was constant, at 0. A proper definition of this integral as a piecewise function will have a DIFFERENT constant of integration in each interval, in order that the integral be well defined. So we would properly have g defined as:
g(x) = { C1 where x < -0.5
x+C2 where -.5 <= x < .5
C3 where x >= 0.5}
(I've used an easier to read form to write g here, although not valid MATLAB syntax.) This applies for unknown constants C1,C2,C3. A careful choice of constants to make the above expression consistent and continuous would now yield this well-posed indefinite integral expression
g(x) = { 0 where x < -0.5
x+.5 where -.5 <= x < .5
1 where x >= 0.5}
As you can see, we needed to have different constants of integration in the two distinct sub-intervals where f(x) was zero.
However, when you tried to get tricky, you created a function with only TWO explicit intervals, depending on where abs(x) lives. The problem is that constant of integration needs to change, depending on where x actually lives.
So, as I said, even if we ignore the issue that MATLAB's int command seems to have a problem for piecewise functions, by defining the function in a tricky way, int will never be able to get the answer right. At the very least, you are asking for trouble.
0 Comments
See Also
Categories
Find more on Assumptions in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!