- 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.
- "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.
how can i modify this short program so that it executes faster?
6 views (last 30 days)
Show older comments
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)
0 Comments
Accepted Answer
Jan
on 6 Oct 2011
The original program has two problems:
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
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.
More Answers (1)
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
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.
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!