Symbolic indefinite integral of piecewise function gives wrong results

15 visualizaciones (últimos 30 días)
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 comentarios
Greg
Greg el 29 de Ag. de 2018
Editada: Greg el 29 de Ag. de 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 el 29 de Ag. de 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.

Iniciar sesión para comentar.

Respuestas (3)

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

Iniciar sesión para comentar.


Walter Roberson
Walter Roberson el 29 de Ag. de 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 comentarios
Walter Roberson
Walter Roberson el 29 de Ag. de 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 el 29 de Ag. de 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.

Iniciar sesión para comentar.


John D'Errico
John D'Errico el 3 de Dic. de 2018
Editada: John D'Errico el 3 de Dic. de 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.

Productos


Versión

R2018a

Community Treasure Hunt

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

Start Hunting!

Translated by