26 static const real tolRF =
27 pow(3 * numeric_limits<real>::epsilon() *
real(0.01), 1/
real(8));
31 Q = fmax(fmax(fabs(A0-x), fabs(A0-y)), fabs(A0-z)) / tolRF,
36 while (Q >= mul * fabs(An)) {
38 real lam = sqrt(x0)*sqrt(y0) + sqrt(y0)*sqrt(z0) + sqrt(z0)*sqrt(x0);
46 X = (A0 - x) / (mul * An),
47 Y = (A0 - y) / (mul * An),
56 return (E3 * (6930 * E3 + E2 * (15015 * E2 - 16380) + 17160) +
57 E2 * ((10010 - 5775 * E2) * E2 - 24024) + 240240) /
63 static const real tolRG0 =
64 real(2.7) * sqrt((numeric_limits<real>::epsilon() *
real(0.01)));
65 real xn = sqrt(x), yn = sqrt(y);
66 if (xn < yn)
swap(xn, yn);
67 while (fabs(xn-yn) > tolRG0 * xn) {
69 real t = (xn + yn) /2;
80 atan(sqrt((y - x) / x)) / sqrt(y - x) :
81 ( x == y ? 1 / sqrt(y) :
88 sqrt(-x / y) ) / sqrt(x - y) ) );
92 return (x == 0 ?
RG(y, z) :
96 (z *
RF(x, y, z) - (x-z) * (y-z) *
RD(x, y, z) / 3
97 + sqrt(x * y / z)) / 2 )));
102 static const real tolRG0 =
103 real(2.7) * sqrt((numeric_limits<real>::epsilon() *
real(0.01)));
105 x0 = sqrt(fmax(x, y)),
106 y0 = sqrt(fmin(x, y)),
111 while (fabs(xn-yn) > tolRG0 * xn) {
113 real t = (xn + yn) /2;
126 tolRD = pow(
real(0.2) * (numeric_limits<real>::epsilon() *
real(0.01)),
129 A0 = (x + y + z + 2*p)/5,
131 delta = (p-x) * (p-y) * (p-z),
132 Q = fmax(fmax(fabs(A0-x), fabs(A0-y)),
133 fmax(fabs(A0-z), fabs(A0-p))) / tolRD,
141 while (Q >= mul * fabs(An)) {
144 lam = sqrt(x0)*sqrt(y0) + sqrt(y0)*sqrt(z0) + sqrt(z0)*sqrt(x0),
145 d0 = (sqrt(p0)+sqrt(x0)) * (sqrt(p0)+sqrt(y0)) * (sqrt(p0)+sqrt(z0)),
147 s +=
RC(1, 1 + e0)/(mul * d0);
157 X = (A0 - x) / (mul * An),
158 Y = (A0 - y) / (mul * An),
159 Z = (A0 - z) / (mul * An),
160 P = -(X + Y + Z) / 2,
161 E2 = X*Y + X*Z + Y*Z - 3*P*P,
162 E3 = X*Y*Z + 2*P * (E2 + 2*P*P),
163 E4 = (2*X*Y*Z + P * (E2 + 3*P*P)) * P,
170 return ((471240 - 540540 * E2) * E5 +
171 (612612 * E2 - 540540 * E3 - 556920) * E4 +
172 E3 * (306306 * E3 + E2 * (675675 * E2 - 706860) + 680680) +
173 E2 * ((417690 - 255255 * E2) * E2 - 875160) + 4084080) /
174 (4084080 * mul * An * sqrt(An)) + 6 * s;
180 tolRD = pow(
real(0.2) * (numeric_limits<real>::epsilon() *
real(0.01)),
183 A0 = (x + y + 3*z)/5,
185 Q = fmax(fmax(fabs(A0-x), fabs(A0-y)), fabs(A0-z)) / tolRD,
191 while (Q >= mul * fabs(An)) {
193 real lam = sqrt(x0)*sqrt(y0) + sqrt(y0)*sqrt(z0) + sqrt(z0)*sqrt(x0);
194 s += 1/(mul * sqrt(z0) * (z0 + lam));
202 X = (A0 - x) / (mul * An),
203 Y = (A0 - y) / (mul * An),
206 E3 = (3*X*Y - 8*Z*Z)*Z,
207 E4 = 3 * (X*Y - Z*Z) * Z*Z,
214 return ((471240 - 540540 * E2) * E5 +
215 (612612 * E2 - 540540 * E3 - 556920) * E4 +
216 E3 * (306306 * E3 + E2 * (675675 * E2 - 706860) + 680680) +
217 E2 * ((417690 - 255255 * E2) * E2 - 875160) + 4084080) /
218 (4084080 * mul * An * sqrt(An)) + 3 * s;
236 _eps = _k2/
Math::sq(sqrt(_kp2) + 1);
265 _eEc = _kp2 != 0 ? 2 *
RG(_kp2, 1) : 1;
270 _kKc = _eEc =
Math::pi()/2; _dDc = _kKc/2;
274 real rj = (_kp2 != 0 && _alphap2 != 0) ?
RJ(0, _kp2, 1, _alphap2) :
282 _gGc = _kp2 != 0 ? _kKc + (_alpha2 - _k2) * rj / 3 : rc;
284 _hHc = _kp2 != 0 ? _kKc - (_alphap2 != 0 ? _alphap2 * rj : 0) / 3 : rc;
286 _pPic = _kKc; _gGc = _eEc;
303 (_kp2 == 0 ? 1 : _kp2 *
RD(0, 1, _kp2) / 3);
317 static const real tolJAC =
318 sqrt(numeric_limits<real>::epsilon() *
real(0.01));
320 real mc = _kp2, d = 0;
331 real m[num_], n[num_];
336 (
"Convergence failure in EllipticFunction::sncndn");
340 n[l] = mc = sqrt(mc);
342 if (!(fabs(a - mc) > tolJAC * a)) {
360 dn = (n[l] + a) / (b + a);
363 a = 1 / sqrt(c*c + 1);
364 sn = signbit(sn) ? -a : a;
374 dn = cn = 1 / cosh(x);
381 static const real tolJAC =
382 pow(numeric_limits<real>::epsilon(),
real(0.75));
383 real
k2 = _k2,
kp2 = _kp2;
386 else if (_kp2 == 0) {
387 return atan(sinh(x));
388 }
else if (_k2 < 0) {
390 k2 = -_k2 / _kp2;
kp2 = 1 / _kp2;
393 real a[num_], b, c[num_];
394 a[0] = 1; b = sqrt(
kp2); c[0] = sqrt(
k2);
398 (
"Convergence failure in EllipticFunction::am");) {
399 a[l] = (a[l-1] + b) / 2;
400 c[l] = (a[l-1] - b) / 2;
401 b = sqrt(a[l-1] * b);
402 if (!(c[l] > tolJAC * a[l]))
break;
407 real phi = a[l] * x *
real(1 << l), phi1 = 0;
410 phi = (phi + asin(c[l] * sin(phi) / a[l])) / 2;
413 return _k2 < 0 ? phi1 - phi : phi;
421 sn = tanh(x); cn = dn = 1 / cosh(x);
423 sn = sin(phi); cn = cos(phi);
434 real cn2 = cn*cn, dn2 = dn*dn,
435 fi = cn2 != 0 ? fabs(sn) *
RF(cn2, dn2, 1) :
K();
439 return copysign(fi, sn);
444 cn2 = cn*cn, dn2 = dn*dn, sn2 = sn*sn,
446 fabs(sn) * ( _k2 <= 0 ?
449 RF(cn2, dn2, 1) - _k2 * sn2 *
RD(cn2, dn2, 1) / 3 :
452 _kp2 *
RF(cn2, dn2, 1) +
453 _k2 * _kp2 * sn2 *
RD(cn2, 1, dn2) / 3 +
454 _k2 * fabs(cn) / dn :
456 - _kp2 * sn2 *
RD(dn2, 1, cn2) / 3 +
462 return copysign(ei, sn);
469 cn2 = cn*cn, dn2 = dn*dn, sn2 = sn*sn,
470 di = cn2 != 0 ? fabs(sn) * sn2 *
RD(cn2, dn2, 1) / 3 :
D();
474 return copysign(di, sn);
481 cn2 = cn*cn, dn2 = dn*dn, sn2 = sn*sn,
482 pii = cn2 != 0 ? fabs(sn) * (
RF(cn2, dn2, 1) +
484 RJ(cn2, dn2, 1, cn2 + _alphap2 * sn2) / 3) :
488 pii = 2 *
Pi() - pii;
489 return copysign(pii, sn);
494 cn2 = cn*cn, dn2 = dn*dn, sn2 = sn*sn,
495 gi = cn2 != 0 ? fabs(sn) * (
RF(cn2, dn2, 1) +
496 (_alpha2 - _k2) * sn2 *
497 RJ(cn2, dn2, 1, cn2 + _alphap2 * sn2) / 3) :
502 return copysign(gi, sn);
507 cn2 = cn*cn, dn2 = dn*dn, sn2 = sn*sn,
509 hi = cn2 != 0 ? fabs(sn) * (
RF(cn2, dn2, 1) -
511 RJ(cn2, dn2, 1, cn2 + _alphap2 * sn2) / 3) :
516 return copysign(hi, sn);
521 if (signbit(cn)) { cn = -cn; sn = -sn; }
522 return F(sn, cn, dn) * (
Math::pi()/2) /
K() - atan2(sn, cn);
527 if (signbit(cn)) { cn = -cn; sn = -sn; }
528 return E(sn, cn, dn) * (
Math::pi()/2) /
E() - atan2(sn, cn);
533 if (signbit(cn)) { cn = -cn; sn = -sn; }
534 return Pi(sn, cn, dn) * (
Math::pi()/2) /
Pi() - atan2(sn, cn);
539 if (signbit(cn)) { cn = -cn; sn = -sn; }
540 return D(sn, cn, dn) * (
Math::pi()/2) /
D() - atan2(sn, cn);
545 if (signbit(cn)) { cn = -cn; sn = -sn; }
546 return G(sn, cn, dn) * (
Math::pi()/2) /
G() - atan2(sn, cn);
551 if (signbit(cn)) { cn = -cn; sn = -sn; }
552 return H(sn, cn, dn) * (
Math::pi()/2) /
H() - atan2(sn, cn);
559 return asinh(tan(phi));
560 real sn = sin(phi), cn = cos(phi), dn =
Delta(sn, cn);
561 return fabs(phi) <
Math::pi() ?
F(sn, cn, dn) :
572 real sn = sin(phi), cn = cos(phi), dn =
Delta(sn, cn);
573 return fabs(phi) <
Math::pi() ?
E(sn, cn, dn) :
582 return E(sn, cn,
Delta(sn, cn)) + 4 *
E() * n;
586 real sn = sin(phi), cn = cos(phi), dn =
Delta(sn, cn);
587 return fabs(phi) <
Math::pi() ?
Pi(sn, cn, dn) :
592 real sn = sin(phi), cn = cos(phi), dn =
Delta(sn, cn);
593 return fabs(phi) <
Math::pi() ?
D(sn, cn, dn) :
598 real sn = sin(phi), cn = cos(phi), dn =
Delta(sn, cn);
599 return fabs(phi) <
Math::pi() ?
G(sn, cn, dn) :
604 real sn = sin(phi), cn = cos(phi), dn =
Delta(sn, cn);
605 return fabs(phi) <
Math::pi() ?
H(sn, cn, dn) :
610 static const real tolJAC =
611 sqrt(numeric_limits<real>::epsilon() /
real(100));
612 real n = floor(x / (2 * _eEc) +
real(0.5));
615 real phi =
Math::pi() * x / (2 * _eEc);
617 phi -= _eps * sin(2 * phi) / 2;
629 err = (
E(sn, cn, dn) - x)/dn;
631 if (!(fabs(err) > tolJAC))
639 if (signbit(ctau)) { ctau = -ctau; stau = -stau; }
640 real tau = atan2(stau, ctau);
Header for GeographicLib::EllipticFunction class.
GeographicLib::Math::real real
#define GEOGRAPHICLIB_PANIC(msg)
void sncndn(real x, real &sn, real &cn, real &dn) const
static real RJ(real x, real y, real z, real p)
Math::real deltaG(real sn, real cn, real dn) const
static real RG(real x, real y, real z)
Math::real deltaE(real sn, real cn, real dn) const
Math::real F(real phi) const
static real RC(real x, real y)
Math::real Einv(real x) const
static real RD(real x, real y, real z)
Math::real alphap2() const
void Reset(real k2=0, real alpha2=0)
Math::real am(real x) const
Math::real Delta(real sn, real cn) const
Math::real deltaD(real sn, real cn, real dn) const
Math::real Ed(real ang) const
Math::real deltaH(real sn, real cn, real dn) const
Math::real deltaF(real sn, real cn, real dn) const
static real RF(real x, real y, real z)
Math::real deltaPi(real sn, real cn, real dn) const
Math::real deltaEinv(real stau, real ctau) const
Math::real alpha2() const
Exception handling for GeographicLib.
static void sincosd(T x, T &sinx, T &cosx)
static T AngNormalize(T x)
static constexpr int td
degrees per turn
Namespace for GeographicLib.
void swap(GeographicLib::NearestNeighbor< dist_t, pos_t, distfun_t > &a, GeographicLib::NearestNeighbor< dist_t, pos_t, distfun_t > &b)