How do I vectorize this code?

1 view (last 30 days)
Navneet
Navneet on 10 Mar 2013
for k=1:1:3
for j=1:1:160
for i=1:1:160
for a=1:1:9
%Cover1 in Share1
if enshare1{i,j}(a)==1
enshare1{i,j}(a)=cover1(i,j,k);
else
enshare1{i,j}(a)=cover1(i,j,k)-1;
end
%Cover2 in Share2
if enshare2{i,j}(a)==1
enshare2{i,j}(a)=cover2(i,j,k);
else
enshare2{i,j}(a)=cover2(i,j,k)-1;
end
end
end
end
end
The i,j and k for loops are not in the same way as specified here. I added them so that one need not wonder where those 3 variables came from. I want to vectorize the inner 'a' for loop.
Thanks

Accepted Answer

Cedric
Cedric on 10 Mar 2013
Edited: Cedric on 10 Mar 2013
isOne = enshare1{i,j} == 1 ;
enshare1{i,j}(:) = cover1(i,j,k)-1 ;
enshare1{i,j}(isOne) = cover1(i,j,k) ;
and same for cover2/share2. The second line above should be
enshare1{i,j}(~isOne) = cover1(i,j,k)-1 ;
but I guess that is is more efficient to skip this indexing and let the 3rd line update relevant elements.
A more efficient but not as clean (up to me) way to do it would be
isOne = enshare1{i,j} == 1 ;
enshare1{i,j} = isOne * cover1(i,j,k) + ~isOne * (cover1(i,j,k)-1) ;
  2 Comments
Navneet
Navneet on 10 Mar 2013
Hi..Thanks :) Worked like a charm. could you please explain it though?
Cedric
Cedric on 10 Mar 2013
Hi, let's discuss a simple example to ilustrate..
>> x = 1:6
x =
1 2 3 4 5 6
is a simple array/vector of double elements. Using a relational operator to test its elements "outputs" an array of logical elements (true/false, symbolized by 1/0):
>> flag = x > 4
flag =
0 0 0 0 1 1
>> class(flag)
ans =
logical
Here, only the last two elements are true, because they correspond to numbers above 4 in x. You can use this array to address elements of x; it is called logical indexing:
>> x(flag) = 8
x =
1 2 3 4 8 8
It is more efficient than finding the indices of the last two elements and using them for subscript or linear indexing. You can use the logical negation of flag as well for addressing the other part of x:
>> ~flag
ans =
1 1 1 1 0 0
>> x(~flag) = 7
x =
7 7 7 7 8 8
You can also use these logicals as numbers 0 and 1 in computations (without having to perform an explicit type cast):
>> flag * 15
ans =
0 0 0 0 15 15
>> class(ans)
ans =
double
As you can see true/false are "understood" as doubles 1/0, and the result is double. Same with ~flag.
>> ~flag * 14
ans =
14 14 14 14 0 0
So you can use both to redefine elements of x:
>> x = flag*15 + ~flag*14
x =
14 14 14 14 15 15
The first solution that I gave was using the array of logical isOne for indexing, and the second is using it in a computation, similar to what we just saw with 14 and 15.
Hope it helps!

Sign in to comment.

More Answers (0)

Categories

Find more on Loops and Conditional Statements 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!