How can I more fully vectorize to eliminate for loops?

5 views (last 30 days)
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...

Accepted Answer

Torsten
Torsten on 26 Nov 2022
Edited: Torsten on 26 Nov 2022
Wans2 = (sum(G.*(W.'-V),2)).'
  1 Comment
Christopher Smith
Christopher Smith on 26 Nov 2022
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

Sign in to comment.

More Answers (0)

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Products

Community Treasure Hunt

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

Start Hunting!