Symbolic indefinite integral of piecewise function gives wrong results

35 ビュー (過去 30 日間)
Markus Wirsing
Markus Wirsing 2018 年 8 月 28 日
編集済み: John D'Errico 2018 年 12 月 3 日
I encountered this somewhat strange behaviour, where I seem to get an erroneous result.
Consider the piecewise function defined by:
which is a simple rectangular pulse.
Attempting to calculate the indefinite integral,
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:
seems to work and gives the expected result:
However trying it with 0 as the lower limit gives a wrong result again:
Is this a bug in Matlab, or somehow a mistake on my side?
  2 件のコメント
Markus Wirsing
Markus Wirsing 2018 年 8 月 29 日
I disagree with that hypothesis. I just tested substituting the x in the bound with another symbolic variabel that does not coincide with the integration variable. The result is still the same.


回答 (3 件)

Greg 2018 年 8 月 29 日
編集済み: Greg 2018 年 8 月 29 日
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]);
  5 件のコメント
Greg 2018 年 8 月 29 日
Is there a better answer, yes. Does that make your answer wrong? Maybe not.


Walter Roberson
Walter Roberson 2018 年 8 月 29 日
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 件のコメント
Markus Wirsing
Markus Wirsing 2018 年 8 月 29 日
After rechecking the documentation, I noticed that the documentation for "int" says:
"If one or both integration bounds a and b are not numeric, int assumes that a <= b unless you explicitly specify otherwise.",
so the plot I get for int(f,0,x) is actually conforming to what the documentation says. However, I still do not understand why the indefinite integral without the given limits gives the wrong answer.


John D'Errico
John D'Errico 2018 年 12 月 3 日
編集済み: John D'Errico 2018 年 12 月 3 日
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.
ans =
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 =
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.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by