Nested for loops newbie question

1 回表示 (過去 30 日間)
ttopal
ttopal 2016 年 8 月 1 日
編集済み: Stephen23 2016 年 8 月 1 日
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 件のコメント
Stephen23
Stephen23 2016 年 8 月 1 日
What are fun, t, T, coef, and temp ?
ttopal
ttopal 2016 年 8 月 1 日
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.

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

採用された回答

Stephen23
Stephen23 2016 年 8 月 1 日
編集済み: Stephen23 2016 年 8 月 1 日
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)))

その他の回答 (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