Reduce solve precision to lower run time required
2 views (last 30 days)
Show older comments
Hello all!
I am using solve (code below) on a singe variable, single equation, and it currently takes ~15 min to solve on a fast computer. As is, I think it's doing great, but it solves to a huge number of decimal places. I only need accuracy to +/-0.0001. Is there a way to specify this to reduce the run time?
Thanks!
-Mike
function r0_sphere = calcHill_r0(Cn2, wvl, L0, l0, L)
%%Initialize:
k = 2*pi/wvl;
% Eq. 3.23 (pg 69):
kappa0 = 0; %4*pi/L0;
%%How to solve:
% r_0 is 2.1*rho_0 (Andrews and Phillips, pg 767)
% rho_0 = the exp(-1) point of the MCF
% MCF = exp(-1/2*D(r,r',L))
% rho_0 == D(r,r',L) = 2
% define rho as the independent variable and solve for 2:
syms rho real
assumeAlso(rho > 0 & rho < 1)
r0_sphere = 2.1*solve(0.9*Cn2*k^2*L*l0^(-1/3)*rho.^2 .* ...
[ 1./(1+0.311*rho.^2./l0^2).^(1/6) + 0.438./(1+0.183*rho.^2./l0^2).^(2/3) - 0.056./(1+0.149*rho.^2./l0^2).^(3/4) - 0.868*(kappa0*l0)^(1/3)] == 2);
0 Comments
Answers (1)
Walter Roberson
on 24 Jul 2012
An important point to remember is that in symbolic expressions, by default floating point values are converted to rational values. This can cause the solver to look for algebraic solutions instead of approximate solutions.
Each number that you want to leave in decimal form, you should sym() individually with the 'd' option. For example,
sym(0.056,'d')./(1+sym(0.149,'d')*rho.^2./l0^2)
Yes, this is a nuisance.
In some instances you can instead construct the expression without using sym) and then vpa() it, such as
vpa(0.056./(1+0.149*rho.^2./l0^2))
There are some cases where this is not equivalent to using sym(X,'d') on each individual number. vpa() will convert pi and arctan(1) in ways you might not want. Also I know from another package that this kind of operation might leave rational exponents of a symbol in rational form, which is not the same meaning as converting them to decimal.
Next, to adjust the decimal digits calculate, adjust the Digits setting, or give the optional number of digits if you call vpa() yourself.
When I use a different symbolic package, I found a strategy that is much more efficient than substituting in all the parameters and solving. Instead, substitute in all but one of the parameters and do the solving, getting out a symbolic expression (probably a RootOf() expression.) Then subs() in the actual value of the last parameter and evaluate numerically (e.g., vpa()). When I use this strategy, I get a numeric answer in a fraction of a second, whereas if I substitute in all the parameters and then solve, it takes a fair time.
2 Comments
Walter Roberson
on 25 Jul 2012
Note: for the final step, if vpa() does not trigger calculating the solution, then try using feval() of numeric::solve
Muhammad Yasirroni
on 3 Apr 2019
Is it possible to do any of that without using any Toolbox? Thank you.
See Also
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!