8 #ifndef __mx_astro_kepler_hpp__
9 #define __mx_astro_kepler_hpp__
28 #define KEPLER_TOL (1e-8)
33 #define KEPLER_ITMAX (1000)
49 template<
typename realT>
62 if(e == 1) e = 1.000001;
64 if(M == 0)
return( 0.);
66 err = e * sinh( curr) - curr - M;
67 while( fabs( err) > tol && n_iter < 10000)
70 curr -= err / (e * cosh( curr) - 1.);
71 err = e * sinh( curr) - curr - M;
74 E = ( is_negative ? -curr : curr);
78 std::cerr <<
"hyperbolic kepler failed to converge e=" << e <<
"\n";
88 template<
typename realT>
93 realT cosE, sinE, fi, fi1, fi2, fi3, di1, di2, di3;
105 di2 = -fi/(fi1 + 0.5*di1*fi2);
106 di3 = -fi/(fi1 + 0.5*di2*fi2 + di2*di2*fi3/6.0);
118 template<
typename realT>
128 realT lastE, sinE,
sign;
132 if(sinE < 0.0)
sign = -1.0;
136 for(i=0; i < itmax; i++)
143 if(i > 1 && fabs(E-lastE) < tol)
145 D = M - (E-e*sin(E));
160 template<
typename realT>
165 realT tol=KEPLER_TOL,
166 long itmax=KEPLER_ITMAX
190 template<
typename arithT>
193 arithT cosE0, sinE0, cosdE, sindE, fi, fi1, fi2, fi3, di1, di2, di3;
201 fi = dEi - EC*sindE + ES*(1-cosdE) - dM;
202 fi1 = 1.0 - EC*cosdE + ES*sindE;
203 fi2 = EC*sindE + ES*cosdE;
204 fi3 = EC*cosdE - ES*sindE;
207 di2 = -fi/(fi1 + 0.5*di1*fi2);
208 di3 = -fi/(fi1 + 0.5*di2*fi2 + di2*di2*fi3/6.0);
224 template<
typename arithT>
228 arithT lastdE, sindE,
sign;
230 sindE = ES*cos(dM-ES) + EC*sin(dM-ES);
232 if(sindE < 0.0)
sign = -1.0;
234 (*dE) = dM + 0.85*
sign*e-ES;
236 for(i=0; i < itmax; i++)
243 if(i > 0. && fabs((*dE)-lastdE) < tol)
245 (*D) = dM - (*dE - EC*sin(*dE) + ES*(1-cos(*dE)));
287 template<
typename arithT>
288 int get_W_1pt_z0(arithT &W, arithT x, arithT y, arithT r, arithT f, arithT w)
297 else if(w == DPI - f)
304 W = atan2(sinW, cosW);
T sign(T x)
The sign function.
long solve_kepler_danby(realT &E, realT &D, realT e, realT M, realT tol, long itmax)
Solve Kepler's equation using Danby's quartic Newton-Raphson method.
realT kepler_danby_1(realT e, realT M, realT Ei)
Calculate the next iteration of Danby's quartic Newton-Raphson method.
long hyperbolic_kepler(realT &E, realT &err, realT e, realT M, realT tol, long itmax)
Solve the hyperbolic kepler equation (for e> 1).
long solve_kepler(realT &E, realT &D, realT e, realT M, realT tol=KEPLER_TOL, long itmax=KEPLER_ITMAX)
Solve Kepler's equation for any e. Uses solve_kepler_danby if e < 1.0, hyperbolic_kepler otherwise.
arithT kepler_danby_diff_1(arithT EC, arithT ES, arithT dM, arithT dEi)
Calculate the next iteration of Danby's quartic Newton-Raphson method (difference form).
int get_W_1pt_z0(arithT &W, arithT x, arithT y, arithT r, arithT f, arithT w)
Calculate the inclination and the longitude of the ascending node given a point on the orbit projecte...
long solve_keplerdiff_danby(arithT *dE, arithT *D, arithT e, arithT EC, arithT ES, arithT dM, arithT tol, long itmax)
Solve Kepler's equation in difference form using Danby's quartic Newton-Raphson method.
Unit specifications and conversions.