how to reduce computation time for nested loops
14 views (last 30 days)
Show older comments
abdelelah alzahed
on 2 Jan 2020
Commented: abdelelah alzahed
on 2 Jan 2020
[N,M] = size(fft_img_test(:,:,1));
B = zeros(N,M,N,M);
for k=1:No_frames
for vy = 1:N
for vx = 1:M
for uy = 1:N
for ux = 1:M
u = uy+vy-2; v = ux+vx-2;
u = mod(u,N); v = mod(v,M);
u = u + 1; v = v + 1;
B(uy,ux,vy,vx) = B(uy,ux,vy,vx) + fft_img_test(uy,ux,k) * fft_img_test(vy,vx,k)...
* conj(fft_img_test(u,v,k));
end
end
end
end
end
phase_B = (angle(B/k));
5 Comments
Adam Danz
on 2 Jan 2020
"Therefore, once u or v are greater than N and M, respectively, the command lines, as stated above, will restart the calculation of the conjugate term to the starting point (1,1). "
Then shouldn't u and v always equal uy and ux (which isn't the case)?
Accepted Answer
Adam Danz
on 2 Jan 2020
Your loops sum to over 536.8 million iterations but due to the size of your variables (B has >268.4 million elements) the expansion that would be required to vectorize this would very likely exceed memory capacity.
One thing I changed below to slightly speed up the code is to move the complex conjugate calculations outside of the loop and index the results rather than performing the complex conjugate within the loop.
I've also added a multi-loop waitbar found on the file exchange (here) that will show you the progress of each loop so you don't have to wonder about the progress of the execution.
function [phase_B]=Bispec(fft_img_test, No_frames)
[N,M] = size(fft_img_test(:,:,1));
B = zeros(N,M,N,M);
multiWaitbar('k-loop',0);
multiWaitbar('vy-loop',0);
multiWaitbar('vx-loop',0);
multiWaitbar('uy-loop',0);
multiWaitbar('ux-loop',0);
fft_img_testConj = conj(fft_img_test);
for k=1:No_frames
multiWaitbar( 'k-loop', k/No_frames);
for vy = 1:N
multiWaitbar( 'vy-loop', vy/N);
for vx = 1:M
multiWaitbar( 'vx-loop', vx/M);
for uy = 1:N
multiWaitbar( 'uy-loop', uy/N);
for ux = 1:M
multiWaitbar( 'ux-loop', ux/M);
u = uy+vy-2;
u = mod(u,N);
v = ux+vx-2;
v = mod(v,M);
u = u + 1;
v = v + 1;
B(uy,ux,vy,vx) = B(uy,ux,vy,vx) + fft_img_test(uy,ux,k) * fft_img_test(vy,vx,k) * fft_img_testConj(u,v,k);
% Show current indices
% fprintf('uy,ux,vy,vx,u,v = %d %d %d %d %d %d\n', uy,ux,vy,vx,u,v);
end
end
end
end
end
multiWaitbar('closeall')
phase_B = angle(B/No_frames); % old version: (angle(B/k))
I played around with some vectorization which does speed up the code but since I'm not certain about how the last term using the u and v indices fit in, I stopped here.
fft_img_testConj = conj(fft_img_test);
for k=1:No_frames
multiWaitbar( 'k-loop', k/No_frames);
for vy = 1:N
multiWaitbar( 'vy-loop', vy/N);
for vx = 1:M
multiWaitbar( 'vx-loop', vx/M);
% Vectorization attempt
u = (1:N)+vy-2;
u = mod(u,N);
v = (1:N)+vx-2;
v = mod(v,M);
u = u + 1;
v = v + 1;
B(:,:,vy,vx) = B(:,:,vy,vx) + fft_img_test(:,:,k) .* fft_img_test(vy,vx,k) .* fft_img_testConj(u,v,k);
end
end
end
More Answers (0)
See Also
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!