Symbolic indefinite integral of piecewise function gives wrong results

9 Ansichten (letzte 30 Tage)
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 Kommentare
Greg
Greg am 29 Aug. 2018
Bearbeitet: Greg am 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.
Markus Wirsing
Markus Wirsing am 29 Aug. 2018
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.

Melden Sie sich an, um zu kommentieren.

Antworten (3)

Greg
Greg am 29 Aug. 2018
Bearbeitet: Greg am 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 Kommentare
Markus Wirsing
Markus Wirsing am 29 Aug. 2018
The function, yes. The antiderivative however should not include discontinuities.
Greg
Greg am 29 Aug. 2018
Is there a better answer, yes. Does that make your answer wrong? Maybe not.

Melden Sie sich an, um zu kommentieren.


Walter Roberson
Walter Roberson am 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 Kommentare
Walter Roberson
Walter Roberson am 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])
Markus Wirsing
Markus Wirsing am 29 Aug. 2018
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.

Melden Sie sich an, um zu kommentieren.


John D'Errico
John D'Errico am 3 Dez. 2018
Bearbeitet: John D'Errico am 3 Dez. 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.

Produkte


Version

R2018a

Community Treasure Hunt

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

Start Hunting!

Translated by