# Creating cell arrays and 'Operands to the || and && operators must be convertible to logical scalar values.'

3 views (last 30 days)
Maja Opitz on 3 Dec 2019
Answered: Max Murphy on 3 Dec 2019
Hey people,
I have one or two problems :(. I want to build 10 new cells arrays (P100,P90,P80,..) containing P-parameters and dateZeit-parameters. Currently i am having an vector with many P-parameters and an array with as many dateZeit-parameters as P-parameters. I want to spit them up and sort them depending on their P-value. The location of the suitable P-parameter defines the dateZeit-parameter which shall be written in the new cell array, too.
This is the code i wrote so far. Matlab tells me to change & to && but if I do so it doesnt work. And in general it doesnt work, too :(
Does anyone have a tip for me? Thank you in advance!
a=1;
for n=1:length(Pabs)
if (Pmax>=Pabs) & (Pabs>Pbin90)
P100={Pabs(a), dateZeit(a)};
elseif (Pbin90>=Pabs) & (Pabs>Pbin80)
P90={Pabs(a), dateZeit(a)};
elseif (Pbin80>=Pabs) & (Pabs>Pbin70)
P80={Pabs(a), dateZeit(a)};
elseif (Pbin70>=Pabs) & (Pabs>Pbin60)
P70={Pabs(a), dateZeit(a)};
elseif (Pbin60>=Pabs) & (Pabs>Pbin50)
P60={Pabs(a), dateZeit(a)};
elseif (Pbin50>=Pabs) & (Pabs>Pbin40)
P50={Pabs(a), dateZeit(a)};
elseif (Pbin40>=Pabs) & (Pabs>Pbin30)
P40={Pabs(a), dateZeit(a)};
elseif (Pbin30>=Pabs) & (Pabs>Pbin20)
P30={Pabs(a), dateZeit(a)};
elseif (Pbin20>=Pabs) & (Pabs>Pbin10)
P20={Pabs(a), dateZeit(a)};
elseif (Pbin10>=Pabs) & (Pabs>0)
P10={Pabs(a), dateZeit(a)};
end
a=a+1;
end

Guillaume on 3 Dec 2019
While an if expression can be non-scalar in matlab it's never a good idea as many people (I assume you included) do not know how if behaves when passed a non-scalar logical. What should the output of
if [true, false]
disp('true');
else
disp('false');
end
be? The above is valid, will always behave the same (displays false) but is very confusing. Hence, it's always better to pass a scalar logical expression, and for scalar expression && is advised over & (however they behave the same).
&& only works with scalar expressions, therefore if you get an error your expression is not scalar. Even if you ignore & vs &&, chances are that your expression doesn't behave the way you expect, see example above.
Secondly, you have numbered variables. Numbered variables are always a flawed design. You're embedding an index into the variable name which always complicate the code. Use proper indexing (e,g. P{10} or P(10)) instead.
It's also unclear what the purpose of the a variable is. It's always the same as n so why not use n everywhere.
In the end, it looks like you're trying to bin some data. I'm unclear on exactly what you're trying to do but whatever it is, it can be achieved with very few lines, without any loop, with discretize or similar functions.

Max Murphy on 3 Dec 2019
I am unfamiliar with the contents of the P-parameters that you have many variables for, so it is a little difficult to help troubleshoot. Here are some thoughts, hope it helps:
(Pbin10>=Pabs)
This comparator indicates that both Pabs and Pbin10 have multiple elements (for this comparison to work using vectors, the two need to have the same number of elements). Yet you are iterating on elements of Pabs:
P10={Pabs(a), dateZeit(a)}; % I guess a is an index from a larger loop in the code or something
So is it possible you just need to add indexing into your if ... elseif statements? e.g.
(Pbin10(a)>=Pabs(a))
Additionally, any time that a given criteria is met, you will overwrite the assignment statement because the left hand side needs indexing as well (if you do not want to overwrite each time you go through your loop).
P10={Pabs(a), dateZeit(a)}; % P10 will be over-written each time the elseif above it is met
So, you may need some kind of indexing into P10 that allows it to be added to instead of overwritten:
% At the top, initialize P10 as empty array
P10 = [];
% Other code in between...
P10 = [P10; {Pabs(a), dateZeit(a)}];
Please note that this is not really good coding practice, and would probably be slow if your dataset is large. But without knowing the structure exactly, this would at least allow P10 to create a "list" of each cell pair that meets your criteria. Of course, in that case, since you are selecting a single element from each vector (indexed by a), then you no longer need a cell:
P10 = [P10; [Pabs(a), dateZeit(a)]]; % This only works if Pabs and dateZeit are the same type
As a last point, when you do use a comparator for multiple elements, a logical vector is returned. if statement will only use the first element of that vector in making the decision. So, the behavior may not be what you are intending. To clarify this point:
if [false true]
disp('True');
else
disp('False');
end
% This prints False to the Command Window