Nested for loops newbie question

1 view (last 30 days)
ttopal
ttopal on 1 Aug 2016
Edited: Stephen23 on 1 Aug 2016
Hi,
I know this might be nested for loops question 1000. I have read most of other posts, even the newbie questions seems little bit advanced. My code is simple, yet I don't know where to look at to improve its speed. This loops takes more than 170 sec for N=512 M=128.
Thanks
for n = 1:M
for m = 1:M
for k = 1:N
for l = 1:N
temp=temp+fun(k,l)*exp(-i*2*pi*( n*t(k)/T + m*t(l)/T));
end
end
c(n,m) = coef*temp;
temp=0;
end
end
  2 Comments
Stephen23
Stephen23 on 1 Aug 2016
What are fun, t, T, coef, and temp ?
ttopal
ttopal on 1 Aug 2016
Hi Stephen, I am trying to solve numerical 2D integration, I have parameters t(k) and t(l) as intervals and fun is 2DArray values as fun(t(k),t(l)). T is period. Coefficient is double. Temp is complex for storing temporary sum.

Sign in to comment.

Accepted Answer

Stephen23
Stephen23 on 1 Aug 2016
Edited: Stephen23 on 1 Aug 2016
So you have some nested loops and you want to make your code faster.
The first step is to read this page:
and in particular you need to understand when arrays need to be preallocated before loops:
and the importance of code vectorization:
In general there is no magic solution for speeding up some looped code: it depends on the operations being performed. In your case the operations are quite simple, and could be vectorized quite easily. Here is a vectorized version that runs in a quarter of the time (I did not test it on the full size matrices):
% Constants:
Mn = 128;
Nn = 51;
%Mn = 128;
%Nn = 512;
temp = 0;
fun = randi(9,Nn,Nn);
t = 1:Nn;
T = 10;
coef = 3;
old = NaN(Mn);
% Your code:
tic
for M1 = 1:Mn
for M2 = 1:Mn
for N1 = 1:Nn
for N2 = 1:Nn
temp=temp+fun(N1,N2)*exp(-1i*2*pi*( M1*t(N1)/T + M2*t(N2)/T));
end
end
old(M1,M2) = coef*temp;
temp=0;
end
end
toc
% Vectorized version:
tic
[N1m,~,M1m,~] = ndgrid(1:Nn,1,1:Mn,1);
[~,N2m,~,M2m] = ndgrid(1,1:Nn,1,1:Mn);
tmp = bsxfun(@plus,M1m.*t(N1m)/T,M2m.*t(N2m)/T);
tmp = bsxfun(@times,fun,exp(-1i*2*pi*tmp));
new = coef * permute(sum(sum(tmp,1),2),[3,4,1,2]);
toc
% Maximum difference in outputs:
max(max(abs(old-new)))

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!