MATLAB Answers

Hi Everyone, I need your help on my problem.

1 view (last 30 days)
Engdaw Chane
Engdaw Chane on 7 Mar 2018
Commented: Walter Roberson on 7 Mar 2018
I have a 3D matrix (abc), and I need to do if and elseif conditions to this matrix. However, the only the first expression(aa=abc-5) is applied to all elements. %
%
ab=[10,2,2;4,12,6;7,5,9];
abc=repmat(ab,1,1,3);
if 1<abc<=5
aa=abc-5;
elseif 6<abc<=10
aa=abc+10;
end
How can I make the elseif expression work?
Thank you.
Chane

  0 Comments

Sign in to comment.

Accepted Answer

Jan
Jan on 7 Mar 2018
Edited: Jan on 7 Mar 2018
1 < abc <= 5
This will not do, what you expect. Matlab processes this expression from left to right:
  1. 1 < abc. This is either TRUE or FALSE, which is interpreted as 1 or 0
  2. 1 <= 5 or 0 <= 5. This is TRUE in both cases.
You want:
1 < abc && abc <= 5
Then your if and elseif will work.
For productive code using logical indexing as suggested by Birdman is usually more efficient and nicer. But understanding why a<b<c fails is essential.

  3 Comments

Engdaw Chane
Engdaw Chane on 7 Mar 2018
Jan Saimon, Thank you for your explanatory answer. However,I am getting the error ” Operands to the and && operators must be convertible to logical scalar values.” on the following.
% code
if (0<Hx20_50 && Hx20_50<=0.5);
t20_50=sqrt(log(1./(Hx20_50.^2)));
elseif (0.5<Hx20_50 && Hx20_50<=1);
t20_50=sqrt(log(1./(1-Hx20_50).^2));
end
Thank you.
Jan
Jan on 7 Mar 2018
If your Hx20_50 is a vector, you cannot use && but need &. But then the condition of the if command is a vector also. Because if requires a scalar condition, a all() is inserted automatically. This is most likely not, what you want.
Either use a loop:
t20_50 = zeros(size(Hx20_50)); % Pre-allocate!
for k = 1:numel(Hx20_50)
if 0<Hx20_50(k) && Hx20_50(k)<=0.5
t20_50(k) = sqrt(log(1 ./ (Hx20_50(k) .^ 2)));
elseif 0.5<Hx20_50(k) && Hx20_50(k)<=1
t20_50(k) = sqrt(log(1 ./ (1-Hx20_50(k)) .^ 2));
end
end
or use the logical indexing shown by Walter.
Engdaw Chane
Engdaw Chane on 7 Mar 2018
@Jan This was what I have been looking for. The others also work but I wasn't getting the dimensions I needed because of a reason in my code. Thank you.

Sign in to comment.

More Answers (1)

Birdman
Birdman on 7 Mar 2018
Edited: Birdman on 7 Mar 2018
Actually, you do not need a ifelse statement. Simple logical indexing will give you what you want.
ab=[10,2,2;4,12,6;7,5,9];
abc=repmat(ab,1,1,3);
abc(abc>1 & abc<=5)=abc(abc>1 & abc<=5)-5;
abc(abc>6 & abc<=10)=abc(abc>6 & abc<=10)+10

  6 Comments

Show 3 older comments
Walter Roberson
Walter Roberson on 7 Mar 2018
mask = 0<Hx20_50 & Hx20_50<=0.5;
t20_50(mask) = sqrt(log(1./(Hx20_50(mask).^2)));
mask = 0.5<Hx20_50 & Hx20_50<=1;
t20_50(mask) = sqrt(log(1./(1-Hx20_50(mask)).^2));
What do you want to do for the cases where Hx20_50 <= 0 or Hx20_50 > 1 ?
Engdaw Chane
Engdaw Chane on 7 Mar 2018
@Walter Hx20_50 is probability of elements, and the values are just between 0 and 1. just the dimensions are missing. Thank you.
Walter Roberson
Walter Roberson on 7 Mar 2018
If the inputs are certain to be in that range then you can simplify to
mask = Hx20_50 <= 0.5;
t20_50(mask) = sqrt(log(1./(Hx20_50(mask).^2)));
t20_50(~mask) = sqrt(log(1./(1-Hx20_50(~mask)).^2));

Sign in to comment.

Sign in to answer this question.