问题
I have the following (slow) piece of code:
% A is n-by-m matrix
% B is n-by-m-by-d matrix
% C is n-by-m-by-d matrix
% R is 1-by-d vector
A=zeros(n,m);
for i=1:d
A = A + sum(B(:,:,1:i),3).*(R(i)-C(:,:,i));
end
I would like to make it more efficient by using the magical bsxfun to lose the loop. Can you show me how to do that?
回答1:
This way -
A = sum(cumsum(B,3).*bsxfun(@minus,permute(R,[1 3 2]),C),3)
With size parameters n,m,d
as 200
each, the runtimes were
----------------------------------- With Proposed Approach
Elapsed time is 0.054771 seconds.
----------------------------------- With Original Approach
Elapsed time is 2.514884 seconds.
More reasons to use bsxfun and vectorization!!
Benchmarking
Benchmarking Code -
n = 10;
m = 1000;
d = 3;
num_iter = 10000;
B = rand(n,m,d);
C = rand(n,m,d);
R = rand(1,d);
%// Warm up tic/toc.
for k = 1:100000
tic(); elapsed = toc();
end
disp(['********************* d = ' num2str(d) ' ************************'])
disp('----------------------------------- With Proposed Approach')
tic
for iter = 1:num_iter
A1 = sum(cumsum(B,3).*bsxfun(@minus,permute(R,[1 3 2]),C),3);
end
toc
disp('----------------------------------- With Original Approach')
tic
for iter = 1:num_iter
A = zeros(n,m);
for i=1:d
A = A + sum(B(:,:,1:i),3).*(R(i)-C(:,:,i));
end
end
toc
Runtimes at my end were -
********************* d = 3 ************************
----------------------------------- With Proposed Approach
Elapsed time is 0.856972 seconds.
----------------------------------- With Original Approach
Elapsed time is 1.703564 seconds.
********************* d = 9 ************************
----------------------------------- With Proposed Approach
Elapsed time is 2.098253 seconds.
----------------------------------- With Original Approach
Elapsed time is 9.518418 seconds.
来源:https://stackoverflow.com/questions/29620713/how-to-use-matlabs-bsxfun-to-solve-cumulative-sum