How to make 2 for loops code to run faster?

Dear MATLAB Experts;
I want to make this part of code to run faster it takes hours to process. there are two for loops which take a lot of time to compile the code.
I need your guidance to make this code run faster.
Thank you so much.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
x_vect = (-5:0.02:5);
y_vect = (-5:0.02:5);
z_vect = 0;
[x_mat,y_mat,z_mat] = meshgrid(x_vect,y_vect,z_vect);
img = zeros(size(x_mat));
tic;
for ii = 1:2:length(angle)
dR = sqrt((R0*cos(alpha*pi/180).*cos(angle(ii)*pi/180) + x_mat).^2 ...
+ (R0*cos(alpha*pi/180).*sin(angle(ii)*pi/180) + y_mat).^2 +...
(z_mat - R0*sin(alpha*pi/180)).^2) - R0;
for jj = 1:length(Fvec)
img = img + data(ii,jj).*exp(1j*4*pi*Fvec(jj)/c0*dR);
end
end
toc;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

19 Comments

Please check this query. Thank you!
We need some additional information. In particular we need to know whether R0 and alpha and c0 are scalar.
Data matrix is large size file to attach, however size is (83348*235) = angle * points.
additional parameters are:
c0 = 3e8;
R0 = 135.16;
Fc = 9.6e9;
Bchirp = 0.5e9;
Nrange = size(data);
Fvec = Fc + (-0.5:1/Nrange:0.5-1/Nrange)*Bchirp;
I am left uncertain about the size of alpha ?
Also, you say Nrange = size(data) but size() with a single parameter returns a vector, and you then use the vector in a colon operation. Perhaps Nrange = size(data,1) ?
These are the all required parameters for loop operation. I have organized the code. Please check with given parameters if it reduce run time.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
data = rand(83348, 235);
Nrange = size(data,2);
alpha = 3;
win_ham = repmat(hamming(size(data,2)).',size(data,1),1); %
data = data.*win_ham;
c0 = 3e8;
R0 = 135.16;
Fc = 9.6e9;
Bchirp = 0.5e9;
Fvec = Fc + (-0.5:1/Nrange:0.5-1/Nrange)*Bchirp;
x_vect = (-5:0.02:5);
y_vect = (-5:0.02:5);
z_vect = 0;
[x_mat,y_mat,z_mat] = meshgrid(x_vect,y_vect,z_vect);
img = zeros(size(x_mat));
angle = size(data,1);
tic;
for ii = 1:2:length(angle)
dR = sqrt((R0*cos(alpha*pi/180).*cos(angle(ii)*pi/180) + x_mat).^2 ...
+ (R0*cos(alpha*pi/180).*sin(angle(ii)*pi/180) + y_mat).^2 +...
(z_mat - R0*sin(alpha*pi/180)).^2) - R0;
for jj = 1:length(Fvec)
img = img + data(ii,jj).*exp(1j*4*pi*Fvec(jj)/c0*dR);
end
end
toc;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
angle = size(data,1);
I guess you really want is to generate a (random) vector of size(data,1) NOT a scalar of value size(data,1)
its 2D data of size (83348, 235) which represents (angle, data_points)
Yes, I mentioned it in final version angle = size(data,1);
You don't understand: Angle is angle in degres NOT a size(data,1) as your code written. What you really mean is length(angle) is size(data,1), something like
angle = 2*pi*rand(1,size(data,1));
NOT obviously wrong statement
angle = size(data,1)
I'm affraid your code does a lot of calculations, very demanding. One can reduce a little bit by matrix multiplication but it is very very expansive.
Yes we can say like this, in my data number of angles are 83348 = 2π (0:360)
So yes, this is also right to say like this
angle = 2*pi*rand(1,size(data,1));
Yes, its very time consuming to process the code, I tired with "bsxfun" may be it needs again loops. If you can suggest using filter2 to process 2D data simultaneously?
It is NOT 2D filter or convolution. Your "kernel" change form. It is NOT Fourier transform either. There is perhaps no known fancy algorithms that can possibly reduce the flops of your calculation.
What does variables R0 and dR do? Are they dependent on each other?
What is angle in your code?
angle = size(data,1)
its 2D data of size (83348, 235) which represents (angle, data_points)
So matrix has angles information on dimension-1 and data points on dimension-2.
R0 is the distance from target to sensor, dR is compensating the distance in the wavefronts using R0 and angle information.
Then after compensation 2nd loop is projecting image on the grid "img" using dR and delay compensation factor data(ii,jj).*exp(1j*4*pi*Fvec(jj)/c0*dR)
@Amjad Iqbal "angle = size(data,1)
its 2D data of size (83348, 235) which represents (angle, data_points)
So matrix has angles information on dimension-1 and data points on dimension-2."
No I signaled already the problem but you did seem to grab it. By this statement
% angle = size(data,1)
you set angle to a scalar of value = 83348, this is NOT what you describe and obviously not intended behaviour. Your "loop" will run only once with ii = 1.
Your demo code is faulty
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
data = rand(83348, 235);
Nrange = size(data,2);
alpha = 3;
win_ham = repmat(hamming(size(data,2)).',size(data,1),1); %
data = data.*win_ham;
c0 = 3e8;
R0 = 135.16;
Fc = 9.6e9;
Bchirp = 0.5e9;
Fvec = Fc + (-0.5:1/Nrange:0.5-1/Nrange)*Bchirp;
x_vect = (-5:0.02:5);
y_vect = (-5:0.02:5);
z_vect = 0;
[x_mat,y_mat,z_mat] = meshgrid(x_vect,y_vect,z_vect);
img = zeros(size(x_mat));
angle = size(data,1),
angle = 83348
tic;
for ii = 1:2:length(angle)
ii
dR = sqrt((R0*cos(alpha*pi/180).*cos(angle(ii)*pi/180) + x_mat).^2 ...
+ (R0*cos(alpha*pi/180).*sin(angle(ii)*pi/180) + y_mat).^2 +...
(z_mat - R0*sin(alpha*pi/180)).^2) - R0;
for jj = 1:length(Fvec)
img = img + data(ii,jj).*exp(1j*4*pi*Fvec(jj)/c0*dR);
end
end
ii = 1
toc;
Elapsed time is 1.080209 seconds.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
As you have told earlier that "dR is compensating the distance in the wavefronts using R0 and angle information." So why are you using
for ii = 1:2:length(angle)
ii
dR = sqrt((R0*cos(alpha*pi/180).*cos(angle(ii)*pi/180) + x_mat).^2 ...
+ (R0*cos(alpha*pi/180).*sin(angle(ii)*pi/180) + y_mat).^2 +...
(z_mat - R0*sin(alpha*pi/180)).^2) - R0;
for jj = 1:length(Fvec)
img = img + data(ii,jj).*exp(1j*4*pi*Fvec(jj)/c0*dR);
end
end
In the above provided for loop variable ii is taking values 1,3,5,7,9,.... so on. But you wanted to compenstate distance for all values of R0 and all angle informations.
loop takes a lot of time and I used step 2 to reduce computational time.

Sign in to comment.

Answers (1)

Dear Amjad,
I understand that you are facing issues with two for loops and wants to run the code faster. There are a few errors in your code which are as follows:
  1. You were using angle = size(data,1), it’s all the angle points stored in data of size(83348,235) in which 83348 are the angles presented in data and 235 are the datapoints. But you have used “size” function which is wrong in your code as it is providing only one value for angle instead of all the angles present in first column of data.
  2. As your loop is taking a lot of time, so you have used a step size of 2 to reduce computation time which is also wrong as it will not cover all the points of your angle presented in data(:,1).
  3. Another troubleshooting error that you are facing is:
% x_vect = (-5:0.02:5);
% y_vect = (-5:0.02:5);
x_vect = linspace(-5,5,size(data,1));
You can use “linspace” function for generating linearly spaced vectors. “linspace” gives direct control over the number of points you want to create, and, in this case, it will be equal to the size of angles present in data.
To run the code faster in MATLAB, you can use the following optimizing techniques:
  1. Avoid Unnecessary Calculations: Analyse your code to identify and remove any unnecessary or redundant calculations to reduce the computational load.
  2. Preallocate arrays: Preallocate arrays before using them in for loops. This means allocating memory for the arrays to their final size before the loops start executing.
  3. Vectorization: Replace inner loops with vectorized operations in MATLAB for faster execution as it is optimized for vector and matrix operations. Vectorization can be used to run code much faster than the corresponding code containing loops.
Here is the code for your reference to show the difference of time taken by vectorization and for loop to solve the example:
% Generate two random arrays
array1 = rand(1, 100000);
array2 = rand(1, 100000);
% Method 1: Using for loops
tic;
sum1 = 0;
sum3 = 0;
for i = 1:length(array1)
sum1 = sum1 + array1(i)^2 + array2(i)^2;
for j = 1: length(array2)
sum3 = sum1 + array1(j)^2;
end
end
toc
Elapsed time is 17.322632 seconds.
% Method 2: Vectorization
tic;
sum2 = sum(array1.^2 + array2.^2);
sum4 = sum(sum2 + array2.^2);
toc;
Elapsed time is 0.004939 seconds.
You can refer to the below documentation for more information:
I hope this helps!

Products

Release

R2021a

Asked:

on 13 Sep 2022

Answered:

on 13 Sep 2023

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!