How to vectorize ?

3 views (last 30 days)
Arif Hoq
Arif Hoq on 3 Nov 2022
Answered: Walter Roberson on 3 Nov 2022
according to my vectorization the output should be = [0 ; 1 ; 0 ; 1 ; 0; 1]. What am I missing ?
a=[600 300 510 250 700 300]';
a(a >=520)=0;
a(a<=500)=1;
a(a >500 & a <520)=0;
output=a
output = 6×1
1 1 0 1 1 1
If I use loop, then it's fine
a=[600 300 510 250 700 300]';
for i=1:6
if a(i) >520
a(i)=0;
elseif a(i) <500
a(i)=1;
else
a(i)=0;
end
end
output=a
output = 6×1
0 1 0 1 0 1

Accepted Answer

DGM
DGM on 3 Nov 2022
Edited: DGM on 3 Nov 2022
You're overwriting the original values, so subsequent tests on the array will produce unexpected matches. Both 0 and 1 are <500.
You could do this by simply not working on the same array. Note also that in this case, the test simplify.
a=[600 300 510 250 700 300]';
output = a<=500
output = 6×1 logical array
0 1 0 1 0 1
If you were intending to assign different values for each test case, you could still do that.
a=[600 300 510 250 700 300]';
output = zeros(size(a));
output(a>=520) = 1;
output(a<=500) = 2;
output(a>500 & a<520) = 3
output = 6×1
1 2 3 2 1 2
  2 Comments
DGM
DGM on 3 Nov 2022
Edited: DGM on 3 Nov 2022
Consider that the assignments and individual tests are vectorized. If the question is whether you can perform all three tests with a single comparison against a vector of thresholds, the answer is "maybe, but why?". In order to do that, you'd have to write all four comparisons in a way that allows for the same relational operator to be used in all tests. Can you do that? Would it impact the complexity of the surrounding combinatorial logic? Would it still be readable?
If the question is whether they can just be combined into a common expression, they can. Again, it simplifies to a single test.
a = (480:10:540)';
output = ~(a>=520) & ~(a>500 & a<520) & (a<=500); % this is the saem
output2 = a<=500; % as this
[a output output2]
ans = 7×3
480 1 1 490 1 1 500 1 1 510 0 0 520 0 0 530 0 0 540 0 0

Sign in to comment.

More Answers (1)

Walter Roberson
Walter Roberson on 3 Nov 2022
output = 1*(a>=520) + 2*(a<=500) + 3*(a>500 & a<520)
Note: output will be 0 for any location that fails all three tests.
For finite real numbers, logically every number should fall into one of the three categories. When we extend to +inf and -inf, the tests will also succeed, calculating 1 for +inf and 2 for -inf -- so the test works for finite reals and for +inf and -inf.
Where can the test fail for real numbers? Answer: it can fail for nan . nan compared with anything is always false no matter what the other thing is (including nan). Well, except for the ~= case, since nan~=nan is true, since that is logically ~(nan == nan) and the == is false and ~false is true.
I mentioned real numbers. What about complex numbers? Well it happens that the < and <= and > and >= operators ignore imaginary parts, so for the purposes of the above expression if you have complex inputs, the expression above would effectively be the same as
output = 1*(real(a)>=520) + 2*(real(a)<=500) + 3*(real(a)>500 & real(a)<520)

Categories

Find more on Operators and Elementary Operations in Help Center and File Exchange

Products


Release

R2022a

Community Treasure Hunt

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

Start Hunting!

Translated by