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

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

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

in all of yr answers,the sizes of x,y,z are all different ..so how can i plot a 3D figure??
@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.
Thank you! all of this has helped me a great deal wit my programmin!!thank you!!

Sign in to comment.

More Answers (1)

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

I assume, this creates the wanted output, although the sizes of x,y,z differ from the original. The OP's arrays have the size [3600 x 1800], but contain mostly zeros.
I noticed this and has ignored
@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.
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

Asked:

on 6 Oct 2011

Community Treasure Hunt

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

Start Hunting!