Reduce solve precision to lower run time required

2 vues (au cours des 30 derniers jours)
MikeStein
MikeStein le 24 Juil 2012
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);

Réponses (1)

Walter Roberson
Walter Roberson le 24 Juil 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 commentaires
Walter Roberson
Walter Roberson le 25 Juil 2012
Note: for the final step, if vpa() does not trigger calculating the solution, then try using feval() of numeric::solve
Muhammad Yasirroni
Muhammad Yasirroni le 3 Avr 2019
Is it possible to do any of that without using any Toolbox? Thank you.

Connectez-vous pour commenter.

Community Treasure Hunt

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

Start Hunting!

Translated by