Anyway to reduce the precision of solving symbolic equations?
17 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
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
0 commentaires
Réponse acceptée
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
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.
Voir également
Catégories
En savoir plus sur Equation Solving dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!