how to reduce computation time for nested loops

14 views (last 30 days)
[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
abdelelah alzahed
abdelelah alzahed on 2 Jan 2020
Edited: abdelelah alzahed on 2 Jan 2020
ux and uy or vx and vy are two coordinates representing spatial frequencies of an image. Here, u and v are optimized coordinates for the calculation of the last term (the conjugate of an image) where v = ux+vx and u = uy+vy. They are modified as indicated above to maintain the sum within the maximum number of spatial frequency points N or M. 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). This calculation is also known as the image bispectrum.
Adam Danz
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)?

Sign in to comment.

Accepted Answer

Adam Danz
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)

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!