why if elseif statement is not working

25 views (last 30 days)
safi58
safi58 on 12 Nov 2021
Commented: safi58 on 28 Nov 2021
Hi,
I have this following code and attached data. only if statement is working but not the rest. can any please help?
clc
clear all
numdata = xlsread('data.xlsx');
va=numdata(:,1);
vb=numdata(:,2);
vc=numdata(:,3);
for i=1:length(va)
if((va(i)>207 | va(i) <253) &(vb(i)>207 | vb(i)<253) & (vc(i)>207 | vc(i)<253))
ma(i)=1;
mb(i)=1;
mc(i)=1;
elseif ((va(i)>253 | va(i) <260)&(vb(i)>253 | vb(i)<260)&(vc(i)>253 | vc(i)<260))
ma(i)=(260-va(i))/(260-253)
mb(i)=(260-vb(i))/(260-253);
mc(i)=(260-vc(i))/(260-253);
elseif ((va(i)>260)&& (vb(i)>260)&& (vc(i)>260))
ma(i)=0;
mb(i)=0;
mc(i)=0;
end
pmax=5000;
pa(i)=ma(i).*pmax;
pb(i)=mb(i).*pmax;
pc(i)=mc(i).*pmax;
plot(pa)
end

Accepted Answer

Dave B
Dave B on 12 Nov 2021
This expression:
va(i)>207 | va(i) <253
asks whether the value is greater than 207 or less than 253. All values (other than NaN) are greater than 207 or less than 253.
I'm going to guess a bit at the logic, and suspect you want AND instead of OR here?
if (va(i)>207 && va(i)<253) && (vb(i)>207 && vb(i)<253) && (vc(i)>207 && vc(i)<253)
and similar logic for the other two statements.
Alternatively, do this the MATLAB way and use a matrix (and we might as well take advantage of readmatrix along the way).
v=readmatrix('data.xlsx');
m=nan(size(v));
m(all(v>207 & v<253,2),:)=1;
m(all(v>260,2),:)=0;
ind = all(v>253 & v<260,2);
m(ind,:)=(260-v(ind,:)) / (260-253);
p = m*5000;
nexttile;plot(p)
Note 1: Several values not accounted for here: anything less than or equal to 207, as well as values exactly equal to 253 or 260, and rows of v (place where va, vb, cv) are not all in the same category.
Note 2: This looks like you wanted to flip the data and rescale it, if that's your goal there's an easy way (see rescale), and if the flip was not your intention just remove ther "5000-":
pp = 5000-rescale(v,0,5000,'InputMin',253,'InputMax',260);
nexttile;plot(pp)
  6 Comments
Dave B
Dave B on 26 Nov 2021
(first, I wasn't able to load your spreadsheet as attached, I adjusted it to have 3 columns)
The short answer to why you're getting NaN's is in my Note 1 above. Your logic described cases where all of the values in a row fall into a certain bin, but doesn't say what to do when the values don't fall into one of these bins.
Let's investigate how these ended up as NaN's (which really means: didn't fit in any of the conditions you described):
v=readmatrix('data1.xlsx');
A=v(:,1:3);
m=nan(size(A));
m(all(A<207,2),:)=0;
m(all(A>=207 & A<=253,2),:)=1;
m(all(A>=260,2),:)=0;
ind = all(A>253 & A<260,2);
m(ind,:)=(260-A(ind,:)) / (260-253)
m = 17×3
1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 NaN NaN NaN NaN NaN NaN NaN NaN NaN 0.9810 0.7906 0.6769 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
The third row is NaNs
A(3,:)
ans = 1×3
252.1310 253.2210 253.8550
We've listed 4 possibilities where they wouldn't be NaN's, let's look one at a time:
  1. Are all of the values less than 207? No, none of them are
  2. Are all of the values between 207 and 253? No...one of the values is between 207 and 253 and the other two values are >253
  3. Are all of the values greater than or equal to 260? No, none of them are
  4. Finally, are they all between 253 and 260? no.
So in short, there are 4 conditions, each looking at how all of the values in a row behave, and these NaN rows don't fit into any of the 4 conditions.
Did you genuinely want to handle this on a row-by-row basis? Or did you want to consider the values on a value-by-value basis? If the latter, the code would look something like this:
v=readmatrix('data1.xlsx');
A=v(:,1:3);
m=nan(size(A));
m(A<207)=0;
m(A>=207 & A<=253)=1;
m(A>=260)=0;
ind = A>253 & A<260;
m(ind)=(260-A(ind)) / (260-253)
m = 17×3
1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 0.9684 0.8779 1.0000 0.8176 0.7809 1.0000 0.8211 0.8156 0.9810 0.7906 0.6769 1.0000 0.8813 0.7999 1.0000 0.9336 0.8363 1.0000 0.8116 0.7800 1.0000 0.9030 0.8224
Otherwise, I think you just need to decide what to do with rows that don't fit into your categories....
safi58
safi58 on 28 Nov 2021
Hi Dave,
I think it would be better if it could be done on value by value basis. in that case latter one should be ok.
Thanks for your suggestion.

Sign in to comment.

More Answers (1)

DGM
DGM on 12 Nov 2021
Edited: DGM on 12 Nov 2021
It's doing exactly what you're telling it to do. Look at the range of the data. Look at the logical tests you're doing. Case 1 and 2 are always true.
I'm assuming this is closer to what you're trying to do:
pmax = 5000;
% v contains all three vectors [va vb vc]
v = xlsread('data.xlsx');
th = [207 253 260];
mask(:,1) = all(v>=th(1) & v<th(2),2);
mask(:,2) = all(v>=th(2) & v<th(3),2);
mask(:,3) = all(v>=th(3),2);
% m contains all three vectors [ma mb mc]
m = zeros(size(v,1),3);
m(mask(:,1),:) = 1;
m(mask(:,2),:) = (th(3)-v(mask(:,2),:))/(th(3)-th(2));
m(mask(:,3),:) = 0; % possibly redundant
% p contains all three vectors [pa pb pc]
p = m*pmax;
plot(p)
Otherwise, you'll have to clarify what the logical comparisons should be.

Categories

Find more on Entering Commands in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!