Anyway to reduce the precision of solving symbolic equations?
17 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
xingjian yang
am 20 Mai 2018
Kommentiert: xingjian yang
am 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 Kommentare
Akzeptierte Antwort
Ameer Hamza
am 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 Kommentare
Ameer Hamza
am 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.
Siehe auch
Kategorien
Mehr zu Equation Solving finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!