how can i modify this short program so that it executes faster?

6 views (last 30 days)
i have writen this program to vary theta between 0 to 180 n phi btw to 360 in steps of 0.5..n store those values from loop n plot..but this takes a really long time to execute..how can i modify so that it executes faster.
for j=10:5:3600
for i=10:5:1800
theta=(i/10)-1;
phi=(j/10)-1;
if (theta == 90)
r=1;
else
r=(((sind(270*cosd(theta))).^2))/((3* (sind(90*cosd(theta)))).^2);
end
x(j,i)=r*cosd(phi)*sind(theta);
y(j,i)=r*sind(phi)*sind(theta);
z(j,i)=r*cosd(theta);
end
end
plot3(x,y,z)

Accepted Answer

Jan
Jan on 6 Oct 2011
The original program has two problems:
  1. x,y,z are not pre-allocated. Letting these arrays grow in each iteration consumes enormous resources. Look for "pre-allocation" in this forum or ask Google to learn more.
  2. "for j=10:5:3600, for i=10:5:1800, ... x(j,i) = ...": Now only every 5th row and column of x contains non-zero values.
Andrei's solution solves both problems. In addition the vectorization is much faster, even if a proper pre-allocation is added to the original program:
Theta = 0.5:0.5:360;
cosTheta = cosd(Theta); % Calcutlate once only
phi = (0:0.5:180)';
r = sind(270 * cosTheta) ./ (3 * sind(90 * cosTheta));
r = r .* r; % Faster than ^2 for numerator and denominator
r(isnan(r)) = 1;
rSinTheta = r .* sind(Theta);
x = cosd(phi) * rSinTheta;
y = sind(phi) * rSinTheta;
z = r .* cosTheta;
[EDITED, JSimon, 08-Oct-2011 10:56 UTC]
% Expand z:
z = z(ones(361, 1), :); % or: repmat(z, 361, 1)
plot3(x, y, z)
[END: EDITED]
Andrei's version is nicer and easier to debug, but slower. This is the old dilemma for the optimization: It is not useful to accelerate the program by some seconds, if the debugging or later modification needs hours.
Although the modified lines are much faster now, the complete program is only 3% faster - what a pitty. This is caused by the fact, that 89% of the processing time are spent in the dyadic products cosd(phi) * rSinTheta and sind(phi) * rSinTheta, and these lines are not modified in my version. This is another valuable hint for efficient optimizations: Care about the lines or parts, which consume the most processing time. Example:
One line needs 90% of the processing time, all other lines need the other 10%. If you make the later running a million times faster, the complete program is running less than 10% faster only.
  4 Comments
Jan
Jan on 8 Oct 2011
@Varshitha: x and y are matrices, z is a row-vector. To get matching dimensions, expand z to a matrix. This is a standard operation in Matlab.
yashaswi
yashaswi on 11 Oct 2011
Thank you! all of this has helped me a great deal wit my programmin!!thank you!!

Sign in to comment.

More Answers (1)

Andrei Bobrov
Andrei Bobrov on 6 Oct 2011
theta =.5:.5:360;
phi =(0:.5:180)';
r = sind(270*cosd(theta)).^2./(3*sind(90*cosd(theta))).^2;
r(isnan(r)) = 1;
x = cosd(phi)*(r.*sind(theta));
y = sind(phi)*(r.*sind(theta));
z = r.*cosd(theta);
  4 Comments
Jan
Jan on 6 Oct 2011
@Andrei: By avoiding the growing of the array, this solution needs 0.026 seconds, instead of 38.2 seconds of the original version. +1!
@Varshitha: The original version suffers from growing arrays: Increasing the size of an array in each iteration consumes a lot of time. Look for "pre-allocation" in this forum to learn more about this.
yashaswi
yashaswi on 8 Oct 2011
in all of yr answers,the sizes of x,y,z are all different ..so how can i plot a 3D figure??

Sign in to comment.

Categories

Find more on Programming 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!