Anyway to reduce the precision of solving symbolic equations?

17 vues (au cours des 30 derniers jours)
xingjian yang
xingjian yang le 20 Mai 2018
Commenté : xingjian yang le 21 Mai 2018
I try to solve a system of symbolic equations, and the result is far more accurate than I actually need. In fact, 3-digits should be relatively good enough for me while it ends up offering 32 digits, which takes too long as I need to repeat the process hundreds of times. Is there any way to reduce the solve accuracy?
syms x y z t 'real'
warning('off')
line_p=[3,2,1]; % point on the line
line_d=[1,2,3]; % line direction
surf=x+y^2+z^3-10;
[x,y,z]=itsct_solve(line_p,line_d,surf)
function [x,y,z]=itsct_solve(line_p,line_d,surf)
syms x y z t 'real'
eq1=x-line_p(1)+line_d(1)*t;
eq2=y-line_p(2)+line_d(2)*t;
eq3=z-line_p(3)+line_d(3)*t;
eq4=surf;
[x,y,z,t]=solve(eq1==0,eq2==0,eq3==0,eq4==0,'x','y','z','t');
x=vpa(x);
y=vpa(y);
z=vpa(z);
t=vpa(t);
end

Réponse acceptée

Ameer Hamza
Ameer Hamza le 20 Mai 2018
You are using solve() which solve equation analytically and therefore takes a long time. Since you don't need very high precision, use vpasolve() to numerically solve the equation. It will increase speed several times. Also, each time you define syms inside a function, it will take a lot of time to create these symbolic variables. It is better to create them once outside the function and then pass it as input to function. For example, try this
syms x y z t 'real'
line_p=[3,2,1]; % point on the line
line_d=[1,2,3]; % line direction
surf=x+y^2+z^3-10;
tic
[x,y,z]=itsct_solve(x,y,z,t,line_p,line_d,surf);
toc
function [x,y,z]=itsct_solve(x,y,z,t,line_p,line_d,surf)
eq1=x-line_p(1)+line_d(1)*t;
eq2=y-line_p(2)+line_d(2)*t;
eq3=z-line_p(3)+line_d(3)*t;
eq4=surf;
[x,y,z,t]=vpasolve(eq1==0,eq2==0,eq3==0,eq4==0,x,y,z,t);
end
Speed Comparison:
On my machine, your original code takes time
Elapsed time is 0.496555 seconds.
The optimized code takes time
Elapsed time is 0.048141 seconds.
There is above 10x speed improvement.
  7 commentaires
Ameer Hamza
Ameer Hamza le 21 Mai 2018
To further increase the speed, you need to avoid the symbolic toolbox. The following method is based on fsolve() and will give you huge speedup as compared to solve or vpasolve()
toSolve = @(x, line_p, line_d) [x(1)-line_p(1)+line_d(1)*x(4);...
x(2)-line_p(2)+line_d(2)*x(4); ...
x(3)-line_p(3)+line_d(3)*x(4);
x(1)+x(2)^2+x(3)^3-10];
line_p=[3,2,1]; % point on the line
line_d=[1,2,3]; % line direction
opts = optimoptions('fsolve', 'Display', 'off');
x_ = fsolve(@(x) toSolve(x, line_p, line_d), zeros(1,4), opts);
You can write the last line for fsolve in a separate function if you like. Also, you can go through documentation of these function to understand the code.
Speed Comparison: The following will show the time taken for 1000 iteration for each method
1) Your original method using solve()
tic
for i=1:1000
[x,y,z]=itsct_solve(line_p,line_d,surf); % itsct_solve is same as question
end
toc
Elapsed time is 403.281158 seconds.
2) The method in question using vpasolve()
tic
for i=1:1000
[x_,y_,z_]=itsct_solve(x,y,z,t,line_p,line_d,surf); % itsct_solve use vpasolve
end
toc
Elapsed time is 56.301697 seconds.
This is around 7x speedup for 1000 iteration as compared solve()
3) The method in this comment using fsolve().
tic
for i=1:1000
x_ = fsolve(@(x) toSolve(x, line_p, line_d), zeros(1,4), opts);
end
toc
Elapsed time is 2.961301 seconds.
This is about 136x improvement from your original code and around 19x improvement over vpasolve.
xingjian yang
xingjian yang le 21 Mai 2018
Thank you! The improvement is impressive!

Connectez-vous pour commenter.

Plus de réponses (1)

Stephan
Stephan le 20 Mai 2018
Modifié(e) : Stephan le 20 Mai 2018
Hi,
the standard number of digits when using
vpa (x)
is 32. You can decrease this value by using:
digits(d)
and speed up computations. See more to this topic here:
Best regards
Stephan
  2 commentaires
xingjian yang
xingjian yang le 20 Mai 2018
Thank you for the answer! It seems that changing the digits probably only affect the final output, the calculation takes the same period though.
Stephan
Stephan le 20 Mai 2018
Nice solution provided by Ameer.

Connectez-vous pour commenter.

Tags

Community Treasure Hunt

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

Start Hunting!

Translated by