How do I vectorize this code?

1 回表示 (過去 30 日間)
Navneet
Navneet 2013 年 3 月 10 日
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

採用された回答

Cedric
Cedric 2013 年 3 月 10 日
編集済み: Cedric 2013 年 3 月 10 日
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 件のコメント
Navneet
Navneet 2013 年 3 月 10 日
Hi..Thanks :) Worked like a charm. could you please explain it though?
Cedric
Cedric 2013 年 3 月 10 日
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!

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeLoops and Conditional Statements についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by