How to improve calculation time for a huge matrix?

3 views (last 30 days)
Ulas Dogan
Ulas Dogan on 17 Jan 2022
Commented: Ulas Dogan on 17 Jan 2022
syms Q1 Q2 D3
EndEffectorVariables (Q1,Q2,D3) = [
(cos(Q1)*cos(Q2))/2 + cos(Q1)*cos(Q2)*(D3 + 3/4);
sin(Q2)/2 + sin(Q2)*(D3 + 3/4) + 1;
- (cos(Q2)*sin(Q1))/2 - cos(Q2)*sin(Q1)*(D3 + 3/4)];
SS = 50; %Step number. 0~360 divided into 50 different points.
n = 1;
skip = [360]; %Skipping the values for 360 because it's equal to 0 degrees.
for angle1 = 0:(360/(SS)):360
if ~ismember(angle1,skip)
angle1rad = deg2rad (angle1);
for angle2 = 0:(360/(SS)):360
if ~ismember(angle2,skip)
angle2rad = deg2rad (angle2);
for distance = 0:(1/(SS-1)):1 %SS-1 to have 50 different values between 0~1 meters
EndEffectorPosition = EndEffectorVariables (angle1rad,angle2rad,distance);
PositionMatrix(n,:) = EndEffectorPosition;
n = n+1;
end
end
end
fprintf('Calculated for Q1=%.2f\n', angle1)
end
end
fprintf('Already calculated for Q1=%.2f=0.00\nFinished!', angle1)
Mechatronics eng. student. Supposed to get the positions of the end effector of a RRP manipulator. Here I wrote a nested for loop to calculate all X Y Z positions regarding to the end effector position equations given in the first part. Need to get a 125000x3 matrix. Tried yesterday but this code takes hours and hours. Is there another method I can use to improve the calculation time?

Accepted Answer

_
_ on 17 Jan 2022
The original method but with SS = 5 to reduce the time (takes ~3.5 seconds):
tic
syms Q1 Q2 D3
EndEffectorVariables (Q1,Q2,D3) = [
(cos(Q1)*cos(Q2))/2 + cos(Q1)*cos(Q2)*(D3 + 3/4);
sin(Q2)/2 + sin(Q2)*(D3 + 3/4) + 1;
- (cos(Q2)*sin(Q1))/2 - cos(Q2)*sin(Q1)*(D3 + 3/4)];
SS = 5; %Step number. 0~360 divided into 50 different points.
n = 1;
skip = [360]; %Skipping the values for 360 because it's equal to 0 degrees.
for angle1 = 0:(360/(SS)):360
if ~ismember(angle1,skip)
angle1rad = deg2rad (angle1);
for angle2 = 0:(360/(SS)):360
if ~ismember(angle2,skip)
angle2rad = deg2rad (angle2);
for distance = 0:(1/(SS-1)):1 %SS-1 to have 50 different values between 0~1 meters
EndEffectorPosition = EndEffectorVariables (angle1rad,angle2rad,distance);
PositionMatrix(n,:) = EndEffectorPosition;
n = n+1;
end
end
end
fprintf('Calculated for Q1=%.2f\n', angle1)
end
end
Calculated for Q1=0.00 Calculated for Q1=72.00 Calculated for Q1=144.00 Calculated for Q1=216.00 Calculated for Q1=288.00
toc
Elapsed time is 3.549845 seconds.
Another method with no loops (takes ~0.02 seconds):
tic
SS = 5; %Step number. 0~360 divided into 50 different points.
angle1 = deg2rad(0:(360/(SS)):360);
angle2 = deg2rad(0:(360/(SS)):360);
distance = 0:(1/(SS-1)):1;
angle1(end) = []; % skip the 360
angle2(end) = [];
[D3,Q2,Q1] = ndgrid(distance,angle2,angle1);
Q1 = Q1(:);
Q2 = Q2(:);
D3 = D3(:);
PositionMatrix_new = [
(cos(Q1).*cos(Q2))/2 + cos(Q1).*cos(Q2).*(D3 + 3/4) ...
sin(Q2)/2 + sin(Q2).*(D3 + 3/4) + 1 ...
-(cos(Q2).*sin(Q1))/2 - cos(Q2).*sin(Q1).*(D3 + 3/4)];
toc
Elapsed time is 0.021408 seconds.
isequal(PositionMatrix_new,double(PositionMatrix))
ans = logical
0
max(abs(PositionMatrix_new(:) - double(PositionMatrix(:))))
ans = 4.4409e-16
Same new method but now with SS back to 50 (takes ~0.03 seconds):
tic
SS = 50; %Step number. 0~360 divided into 50 different points.
angle1 = deg2rad(0:(360/(SS)):360);
angle2 = deg2rad(0:(360/(SS)):360);
distance = 0:(1/(SS-1)):1;
angle1(end) = [];
angle2(end) = [];
[D3,Q2,Q1] = ndgrid(distance,angle2,angle1);
Q1 = Q1(:);
Q2 = Q2(:);
D3 = D3(:);
PositionMatrix_new = [
(cos(Q1).*cos(Q2))/2 + cos(Q1).*cos(Q2).*(D3 + 3/4) ...
sin(Q2)/2 + sin(Q2).*(D3 + 3/4) + 1 ...
-(cos(Q2).*sin(Q1))/2 - cos(Q2).*sin(Q1).*(D3 + 3/4)];
toc
Elapsed time is 0.031613 seconds.

More Answers (1)

Matt J
Matt J on 17 Jan 2022
Edited: Matt J on 17 Jan 2022
When speed matters, avoid symbolic math. Also, download
skip=360;
SS = 50; %Step number. 0~360 divided into 50 different points.
angle1=setdiff(0:(360/(SS)):360, skip);
tic;
[Q1,Q2,D3]=ndgridVecs(angle1,angle1, 0:(1/(SS-1)):1 );
e=ones(size(Q1));
PositionMatrix={
(cosd(Q1).*cosd(Q2))/2+cosd(Q1).*cosd(Q2).*(D3 + 3/4),...
sind(Q2)/2+sind(Q2).*(D3 + 3/4) + e,...
-(cosd(Q2).*sind(Q1))/2-cosd(Q2).*sind(Q1).*(D3 + 3/4)};
PositionMatrix=cell2mat(cellfun( @(x) x(:),PositionMatrix,'uni',0));
toc%Elapsed time is 0.003500 seconds.

Products


Release

R2021b

Community Treasure Hunt

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

Start Hunting!