piecewise function evaluation using if-else statement

7 ビュー (過去 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.
  1 件のコメント
cgo
cgo 2015 年 3 月 16 日
Thanks for your answer.

サインインしてコメントする。


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 Center および File ExchangeAssumptions についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by