필터 지우기
필터 지우기

piecewise function evaluation using if-else statement

조회 수: 2 (최근 30일)
cgo
cgo 2015년 3월 16일
답변: Sally Al Khamees 2017년 2월 21일
Hi, I have this code for a 'piecewise function' to be evaluated.
t = -10:0.01:10;
if t<0
F(1,:) = 2.*t;
elseif t<8
F(1,:) = sqrt(t);
else F(1,:) = t+1;
end
I was wondering why the output is different from the one I was expecting.
Expected output: all numbers below 0 must be twice that number.
Output:
-9 -8.99000000000000 -8.98000000000000 -8.97000000000000 -8.96000000000000 -8.95000000000000 -8.94000000000000 -8.93000000000000 -8.92000000000000 -8.91000000000000 -8.90000000000000 -8.89000000000000 -8.88000000000000 -8.87000000000000 -8.86000000000000…….

채택된 답변

Roger Stafford
Roger Stafford 2015년 3월 16일
Matlab's 'if' statement requires that if the following condition is a multiple-element logical vector, then every one of these must be true for it to be executed. The same applies to the 'elseif' statement. The consequence for your example is that only the 'else' part is executed, which accounts for your results.
What I believe you want is:
F(1,:) = (t<0).*(2*t)+(t>=8).*(t+1)+(t>=0).*(t<8).*sqrt(t);
Either that, or you can use a for-loop to apply your original tests to the elements of t one at a time.
You can read about this in:
http://www.mathworks.com/help/matlab/ref/if.html
where it states that "An expression is true when its result is nonempty and contains only nonzero elements (logical or real numeric). Otherwise, the expression is false."
  댓글 수: 2
cgo
cgo 2015년 3월 16일
Wow, this is even more elegant that I thought. Thanks!
Walter Roberson
Walter Roberson 2017년 1월 10일
This condition .* value method often works really well. There is, however, a situation where it can give the wrong answer.
In each expression, the value is calculated for an element even if the condition is false for the element.
If the resulting value is finite, then it gets multiplied by the 0 corresponding to the condition being false for that element, and 0 .* finite gives 0 so you get out a 0 in that position, which is perfect for continuing on with the rest of the expression (one of the remaining expressions might give true and a non-zero value for that element.)
But if the resulting value calculation comes out as NaN or +/- inf, then when that is multiplied by 0, the result is NaN. And then when that NaN is added to anything else, the result is NaN, so you will get NaN in that position instead of some useful value.
A simple example is
(x == 0) .* 1 + (x ~= 0) .* (1./x)
The intent here is to give the value 1 at x = 0, and give 1/x otherwise. But the 1/x is calculated at all positions without checking the condition first, and so gives inf for 0, and the 0 (false) of x ~= 0, multiplied by inf, gives Nan instead of 0.
Karan's suggestion of using the new symbolic piecewise does not have this difficulty, but it does require that the input expression be symbolic, not plain numeric. If you have a numeric expression you might need to sym() it to use with piecewise()

댓글을 달려면 로그인하십시오.

추가 답변 (2개)

Adam
Adam 2015년 3월 16일
You can't use an if statement on a vector (or rather you can, but it is usually not the effect you wish to achieve, as in this case).
if t < 0
will test if the entire vector t is less than zero. It isn't. The else will test if the entire vector is less than 8. It isn't. Therefore the final else clause will be the one that kicks in and simply add 1 to all elements.
You can use vectorisation to achieve this as e.g.
t = -10:0.01:10;
F = t + 1;
F( t < 0 ) = 2 .* t( t < 0 );
F( t >= 0 & t < 8 ) = sqrt( t( t >= 0 & t < 8 ) );
Personally I would probably factor out that ugly condition that is used twice in the same line, but that is just semantics and personal preference.

Sally Al Khamees
Sally Al Khamees 2017년 2월 21일
If you have R2016b and the Symbolic Math Toolbox installed, you can just use the piecewise function:
t = -10:0.01:10;
syms y(t);
y(t) = piecewise(t<0, 2*t, 0 <= t <= 8, sqrt(t), t+1);
fplot(y,t)

카테고리

Help CenterFile Exchange에서 Assumptions에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by