How can I more fully vectorize to eliminate for loops?

2 ビュー (過去 30 日間)
Christopher Smith
Christopher Smith 2022 年 11 月 26 日
コメント済み: Christopher Smith 2022 年 11 月 26 日
I have three vectors that must be comined to form a forth vector as where . I want to completely vectorize this computation to save time since these three vectors can become large. I have done half of the vectorization to eliminate a for-loop for the j-index by employing the sum function and .* functionality, but I can't figure out the last bit to get rid of the for-loop for the i-index (see the sample code below). The time savings with the partially vectorized version is substantial, but hoping for more with further vectorization. One last thing to note is that this situation is a part of a marching scheme, which means that a "parfor" loop for the i-index would probably not work. Any help would be appreciated!
V = linspace(1,10,100);
G = linspace(1,10,100);
W = linspace(11,20,500);
Wans = 0*W;
Wans2 = 0*W;
tic
% For-loop version
for i = 1:length(W)
sumdum = 0;
for j = 1:length(V)
sumdum = G(j)*(W(i)-V(j));
Wans(i) = Wans(i) + sumdum;
end
end
toc
Elapsed time is 0.005329 seconds.
% Partially Vectorized version
tic
for i = 1:length(W)
Wans2(i) = sum(G.*(W(i)-V));
end
toc
Elapsed time is 0.003530 seconds.
% Check to make sure the partially vectorized version gives the same answer
% as the for-loop version, display the difference if there is one
dW = diff([Wans;Wans2],1);
if any(abs(dW) > 1e-3)
dW
end
% Fully vectorized version is hopefully a single line...

採用された回答

Torsten
Torsten 2022 年 11 月 26 日
編集済み: Torsten 2022 年 11 月 26 日
Wans2 = (sum(G.*(W.'-V),2)).'
  1 件のコメント
Christopher Smith
Christopher Smith 2022 年 11 月 26 日
Wow, this is great! I implemented this and am finding that this fully vectorized version is taking consistently longer than the partially vectorized version. Does anyone have any insight as to why? I put the code of my implementation below. Thanks again!
clearvars
V = linspace(1,10,10000);
G = linspace(1,10,10000);
W = linspace(11,20,10000);
Wans = 0*W;
Wans2 = 0*W;
tic
% For-loop version
for i = 1:length(W)
sumdum = 0;
for j = 1:length(V)
sumdum = G(j)*(W(i)-V(j));
Wans(i) = Wans(i) + sumdum;
end
end
toc
Elapsed time is 0.468906 seconds.
% Partially Vectorized version
tic
for i = 1:length(W)
Wans2(i) = sum(G.*(W(i)-V));
end
toc
Elapsed time is 0.097496 seconds.
% Check to make sure the partially vectorized version gives the same answer
% as the for-loop version
dW = diff([Wans;Wans2],1);
if any(abs(dW) > 1e-3)
dW
end
% Fully vectorized version is hopefully a single line...
tic
Wans3 = (sum(G.*(W.'-V),2)).';
toc
Elapsed time is 0.254932 seconds.
dW = diff([Wans;Wans3],1);
if any(abs(dW) > 1e-3)
dW
end

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

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeArgument Definitions についてさらに検索

製品

Community Treasure Hunt

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

Start Hunting!

Translated by