| EllipticFunction.hpp | | EllipticFunction.hpp | |
| /** | | /** | |
| * \file EllipticFunction.hpp | | * \file EllipticFunction.hpp | |
| * \brief Header for GeographicLib::EllipticFunction class | | * \brief Header for GeographicLib::EllipticFunction class | |
| * | | * | |
|
| * Copyright (c) Charles Karney (2008-2011) <charles@karney.com> and licens
ed | | * Copyright (c) Charles Karney (2008-2012) <charles@karney.com> and licens
ed | |
| * under the MIT/X11 License. For more information, see | | * under the MIT/X11 License. For more information, see | |
| * http://geographiclib.sourceforge.net/ | | * http://geographiclib.sourceforge.net/ | |
| **********************************************************************/ | | **********************************************************************/ | |
| | | | |
| #if !defined(GEOGRAPHICLIB_ELLIPTICFUNCTION_HPP) | | #if !defined(GEOGRAPHICLIB_ELLIPTICFUNCTION_HPP) | |
| #define GEOGRAPHICLIB_ELLIPTICFUNCTION_HPP 1 | | #define GEOGRAPHICLIB_ELLIPTICFUNCTION_HPP 1 | |
| | | | |
| #include <GeographicLib/Constants.hpp> | | #include <GeographicLib/Constants.hpp> | |
| | | | |
| namespace GeographicLib { | | namespace GeographicLib { | |
| | | | |
| /** | | /** | |
|
| * \brief Elliptic functions needed for TransverseMercatorExact | | * \brief Elliptic integrals and functions | |
| * | | * | |
|
| * This provides the subset of elliptic functions needed for | | * This provides the elliptic functions and integrals needed for Ellipsoi | |
| * TransverseMercatorExact. For a given ellipsoid, only parameters | | d, | |
| * <i>e</i><sup>2</sup> and 1 − <i>e</i><sup>2</sup> are needed. T | | * GeodesicExact, and TransverseMercatorExact. Two categories of functio | |
| his | | n | |
| * class taken the parameter as a constructor parameters and caches the | | * are provided: | |
| * values of the required complete integrals. A method is provided for | | * - \e static functions to compute symmetric elliptic integrals | |
| * Jacobi elliptic functions and for the incomplete elliptic integral of | | * (http://dlmf.nist.gov/19.16.i) | |
| the | | * - \e member functions to compute Legrendre's elliptic | |
| * second kind in terms of the amplitude. | | * integrals (http://dlmf.nist.gov/19.2.ii) and the | |
| | | * Jacobi elliptic functions (http://dlmf.nist.gov/22.2). | |
| | | * . | |
| | | * In the latter case, an object is constructed giving the modulus \e k ( | |
| | | and | |
| | | * optionally the parameter α<sup>2</sup>). The modulus is always | |
| | | * passed as its square <i>k</i><sup>2</sup> which allows \e k to be pure | |
| | | * imaginary (<i>k</i><sup>2</sup> < 0). (Confusingly, Abramowitz and | |
| | | * Stegun call \e m = <i>k</i><sup>2</sup> the "parameter" and \e n = | |
| | | * α<sup>2</sup> the "characteristic".) | |
| | | * | |
| | | * In geodesic applications, it is convenient to separate the incomplete | |
| | | * integrals into secular and periodic components, e.g., | |
| | | * \f[ | |
| | | * E(\phi, k) = (2 E(\phi) / \pi) [ \phi + \delta E(\phi, k) ] | |
| | | * \f] | |
| | | * where δ\e E(φ, \e k) is an odd periodic function with period | |
| | | * π. | |
| * | | * | |
| * The computation of the elliptic integrals uses the algorithms given in | | * The computation of the elliptic integrals uses the algorithms given in | |
| * - B. C. Carlson, | | * - B. C. Carlson, | |
| * <a href="http://dx.doi.org/10.1007/BF02198293"> Computation of ellip
tic | | * <a href="http://dx.doi.org/10.1007/BF02198293"> Computation of ellip
tic | |
|
| * integrals</a>, Numerical Algorithms 10, 13--26 (1995). | | * integrals</a>, Numerical Algorithms 10, 13--26 (1995) | |
| * . | | * . | |
|
| | | * with the additional optimizations given in http://dlmf.nist.gov/19.36.
i. | |
| * The computation of the Jacobi elliptic functions uses the algorithm gi
ven | | * The computation of the Jacobi elliptic functions uses the algorithm gi
ven | |
| * in | | * in | |
| * - R. Bulirsch, | | * - R. Bulirsch, | |
| * <a href="http://dx.doi.org/10.1007/BF01397975"> Numerical Calculatio
n of | | * <a href="http://dx.doi.org/10.1007/BF01397975"> Numerical Calculatio
n of | |
| * Elliptic Integrals and Elliptic Functions</a>, Numericshe Mathematik
7, | | * Elliptic Integrals and Elliptic Functions</a>, Numericshe Mathematik
7, | |
| * 78--90 (1965). | | * 78--90 (1965). | |
| * . | | * . | |
|
| * The notation follows Abramowitz and Stegun, Chapters 16 and 17. | | * The notation follows http://dlmf.nist.gov/19 and http://dlmf.nist.gov/
22 | |
| * | | * | |
| * Example of use: | | * Example of use: | |
| * \include example-EllipticFunction.cpp | | * \include example-EllipticFunction.cpp | |
| **********************************************************************/ | | **********************************************************************/ | |
| class GEOGRAPHIC_EXPORT EllipticFunction { | | class GEOGRAPHIC_EXPORT EllipticFunction { | |
| private: | | private: | |
| typedef Math::real real; | | typedef Math::real real; | |
| static const real tol_; | | static const real tol_; | |
| static const real tolRF_; | | static const real tolRF_; | |
| static const real tolRD_; | | static const real tolRD_; | |
| static const real tolRG0_; | | static const real tolRG0_; | |
| static const real tolJAC_; | | static const real tolJAC_; | |
|
| static const real tolJAC1_; | | enum { num_ = 13 }; // Max depth required for sncndn. Probably 5 is en | |
| enum { num_ = 10 }; // Max depth required for sncndn. Probably 5 is en | | ough. | |
| ough. | | real _k2, _kp2, _alpha2, _alphap2, _eps; | |
| static real RF(real x, real y, real z) throw(); | | | |
| static real RD(real x, real y, real z) throw(); | | | |
| static real RG0(real x, real y) throw(); | | | |
| real _m, _m1; | | | |
| mutable bool _init; | | mutable bool _init; | |
|
| mutable real _kc, _ec, _kec; | | mutable real _Kc, _Ec, _Dc, _Pic, _Gc, _Hc; | |
| bool Init() const throw(); | | bool Init() const throw(); | |
| public: | | public: | |
|
| | | /** \name Constructor | |
| | | ********************************************************************** | |
| | | / | |
| | | ///@{ | |
| | | /** | |
| | | * Constructor specifying the modulus and parameter. | |
| | | * | |
| | | * @param[in] k2 the square of the modulus <i>k</i><sup>2</sup>. | |
| | | * <i>k</i><sup>2</sup> must lie in (-∞, 1). (No checking is | |
| | | * done.) | |
| | | * @param[in] alpha2 the parameter α<sup>2</sup>. | |
| | | * α<sup>2</sup> must lie in (-∞, 1). (No checking is do | |
| | | ne.) | |
| | | * | |
| | | * If only elliptic integrals of the first and second kinds are needed, | |
| | | * then set α<sup>2</sup> = 0 (in which case we have Π(φ, | |
| | | 0, | |
| | | * \e k) = \e F(φ, \e k), \e G(φ, 0, \e k) = \e E(φ, \e k)) | |
| | | , | |
| | | * and \e H(φ, 0, \e k) = \e F(φ, \e k) - \e D(φ, \e k). | |
| | | ********************************************************************** | |
| | | / | |
| | | EllipticFunction(real k2, real alpha2) throw(); | |
| | | | |
| | | /** | |
| | | * Constructor specifying the modulus and parameter and their complemen | |
| | | ts. | |
| | | * | |
| | | * @param[in] k2 the square of the modulus <i>k</i><sup>2</sup>. | |
| | | * <i>k</i><sup>2</sup> must lie in (-∞, 1). (No checking is | |
| | | * done.) | |
| | | * @param[in] alpha2 the parameter α<sup>2</sup>. | |
| | | * α<sup>2</sup> must lie in (-∞, 1). (No checking is do | |
| | | ne.) | |
| | | * @param[in] kp2 the complementary modulus squared <i>k'</i><sup>2</su | |
| | | p> = | |
| | | * 1 − <i>k</i><sup>2</sup>. | |
| | | * @param[in] alphap2 the complementary parameter α'<sup>2</sup> | |
| | | = 1 | |
| | | * − α<sup>2</sup>. | |
| | | * | |
| | | * The arguments must satisfy \e k2 + \e kp2 = 1 and \e alpha2 + \e alp | |
| | | hap2 | |
| | | * = 1. (No checking is done that these conditions are met.) This | |
| | | * constructor is provided to enable accuracy to be maintained, e.g., w | |
| | | hen | |
| | | * \e k is very close to unity. | |
| | | ********************************************************************** | |
| | | / | |
| | | EllipticFunction(real k2, real alpha2, real kp2, real alphap2) throw(); | |
| | | | |
| /** | | /** | |
|
| * Constructor. | | * Constructor specifying the modulus only. | |
| | | * | |
| | | * @param[in] k2 the square of the modulus <i>k</i><sup>2</sup>. | |
| | | * <i>k</i><sup>2</sup> must lie in (-∞, 1). (No checking is | |
| | | * done.) | |
| * | | * | |
|
| * @param[in] m the parameter which must lie in [0, 1]. (No checking | | * <b>COMPATIBILITY NOTE:</b> This constructor calls EllipticFunction(r | |
| * is done.) | | eal, | |
| | | * real) with a 2nd argument of 0. At some point, EllipticFunction(rea | |
| | | l) | |
| | | * and will be withdrawn and the interface to EllipticFunction(real, re | |
| | | al) | |
| | | * changed so that its 2nd argument defaults to 0. This will preserve | |
| | | * source-level compatibility. | |
| | | ********************************************************************** | |
| | | / | |
| | | explicit EllipticFunction(real k2 = 0) throw(); | |
| | | | |
| | | /** | |
| | | * Reset the modulus and parameter. | |
| | | * | |
| | | * @param[in] k2 the new value of square of the modulus | |
| | | * <i>k</i><sup>2</sup> which must lie in (-∞, 1). (No checkin | |
| | | g is | |
| | | * done.) | |
| | | * @param[in] alpha2 the new value of parameter α<sup>2</sup>. | |
| | | * α<sup>2</sup> must lie in (-∞, 1). (No checking is do | |
| | | ne.) | |
| | | ********************************************************************** | |
| | | / | |
| | | void Reset(real k2, real alpha2 = 0) throw() | |
| | | { Reset(k2, alpha2, 1 - k2, 1 - alpha2); } | |
| | | | |
| | | /** | |
| | | * Reset the modulus and parameter supplying also their complements. | |
| | | * | |
| | | * @param[in] k2 the square of the modulus <i>k</i><sup>2</sup>. | |
| | | * <i>k</i><sup>2</sup> must lie in (-∞, 1). (No checking is | |
| | | * done.) | |
| | | * @param[in] alpha2 the parameter α<sup>2</sup>. | |
| | | * α<sup>2</sup> must lie in (-∞, 1). (No checking is do | |
| | | ne.) | |
| | | * @param[in] kp2 the complementary modulus squared <i>k'</i><sup>2</su | |
| | | p> = | |
| | | * 1 − <i>k</i><sup>2</sup>. | |
| | | * @param[in] alphap2 the complementary parameter α'<sup>2</sup> | |
| | | = 1 | |
| | | * − α<sup>2</sup>. | |
| | | * | |
| | | * The arguments must satisfy \e k2 + \e kp2 = 1 and \e alpha2 + \e alp | |
| | | hap2 | |
| | | * = 1. (No checking is done that these conditions are met.) This | |
| | | * constructor is provided to enable accuracy to be maintained, e.g., w | |
| | | hen | |
| | | * is very small. | |
| | | ********************************************************************** | |
| | | / | |
| | | void Reset(real k2, real alpha2, real kp2, real alphap2) throw(); | |
| | | | |
| | | ///@} | |
| | | | |
| | | /** \name Inspector functions. | |
| | | ********************************************************************** | |
| | | / | |
| | | ///@{ | |
| | | /** | |
| | | * @return the square of the modulus <i>k</i><sup>2</sup>. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| explicit EllipticFunction(real m) throw(); | | Math::real k2() const throw() { return _k2; } | |
| | | | |
| /** | | /** | |
|
| * @return the parameter \e m. | | * @return the square of the complementary modulus <i>k'</i><sup>2</sup | |
| | | > = | |
| | | * 1 − <i>k</i><sup>2</sup>. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| Math::real m() const throw() { return _m; } | | Math::real kp2() const throw() { return _kp2; } | |
| | | | |
| /** | | /** | |
|
| * @return the complementary parameter \e m' = (1 − \e m). | | * @return the parameter α<sup>2</sup>. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| Math::real m1() const throw() { return _m1; } | | Math::real alpha2() const throw() { return _alpha2; } | |
| | | | |
| /** | | /** | |
|
| * @return the complete integral of first kind, \e K(\e m). | | * @return the complementary parameter α'<sup>2</sup> = 1 − | |
| | | * α<sup>2</sup>. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| Math::real K() const throw() { _init || Init(); return _kc; } | | Math::real alphap2() const throw() { return _alphap2; } | |
| | | | |
| /** | | /** | |
|
| * @return the complete integral of second kind, \e E(\e m). | | * @return the square of the modulus <i>k</i><sup>2</sup>. | |
| * | | * | |
|
| * This function returns the correct result even when \e m is negative. | | * <b>DEPRECATED</b>, use k2() instead. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| Math::real E() const throw() { _init || Init(); return _ec; } | | Math::real m() const throw() { return _k2; } | |
| | | | |
| /** | | /** | |
|
| * @return the difference \e K(\e m) - \e E(\e m) (which can be compute | | * @return the square of the complementary modulus <i>k'</i><sup>2</sup | |
| d | | > = | |
| * directly). | | * 1 − <i>k</i><sup>2</sup>. | |
| | | * | |
| | | * <b>DEPRECATED</b>, use kp2() instead. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| Math::real KE() const throw() { _init || Init(); return _kec; } | | Math::real m1() const throw() { return _kp2; } | |
| | | ///@} | |
| | | | |
|
| | | /** \name Complete elliptic integrals. | |
| | | ********************************************************************** | |
| | | / | |
| | | ///@{ | |
| /** | | /** | |
|
| * The Jacobi elliptic functions. | | * The complete integral of the first kind. | |
| * | | * | |
|
| * @param[in] x the argument. | | * @return \e K(\e k). | |
| * @param[out] sn sn(<i>x</i>|<i>m</i>). | | * | |
| * @param[out] cn cn(<i>x</i>|<i>m</i>). | | * \e K(\e k) is defined in http://dlmf.nist.gov/19.2.E4 | |
| * @param[out] dn dn(<i>x</i>|<i>m</i>). | | * \f[ | |
| | | * K(k) = \int_0^{\pi/2} \frac1{\sqrt{1-k^2\sin^2\phi}}\,d\phi. | |
| | | * \f] | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| void sncndn(real x, real& sn, real& cn, real& dn) const throw(); | | Math::real K() const throw() { _init || Init(); return _Kc; } | |
| | | | |
| | | /** | |
| | | * The complete integral of the second kind. | |
| | | * | |
| | | * @return \e E(\e k) | |
| | | * | |
| | | * \e E(\e k) is defined in http://dlmf.nist.gov/19.2.E5 | |
| | | * \f[ | |
| | | * E(k) = \int_0^{\pi/2} \sqrt{1-k^2\sin^2\phi}\,d\phi. | |
| | | * \f] | |
| | | ********************************************************************** | |
| | | / | |
| | | Math::real E() const throw() { _init || Init(); return _Ec; } | |
| | | | |
| | | /** | |
| | | * Jahnke's complete integral. | |
| | | * | |
| | | * @return \e D(\e k). | |
| | | * | |
| | | * \e D(\e k) is defined in http://dlmf.nist.gov/19.2.E6 | |
| | | * \f[ | |
| | | * D(k) = \int_0^{\pi/2} \frac{\sin^2\phi}{\sqrt{1-k^2\sin^2\phi}}\,d | |
| | | \phi. | |
| | | * \f] | |
| | | ********************************************************************** | |
| | | / | |
| | | Math::real D() const throw() { _init || Init(); return _Dc; } | |
| | | | |
| | | /** | |
| | | * The difference between the complete integrals of the first and secon | |
| | | d | |
| | | * kinds. | |
| | | * | |
| | | * @return \e K(\e k) − \e E(\e k). | |
| | | ********************************************************************** | |
| | | / | |
| | | Math::real KE() const throw() { _init || Init(); return _k2 * _Dc; } | |
| | | | |
| | | /** | |
| | | * The complete integral of the third kind. | |
| | | * | |
| | | * @return Π(α<sup>2</sup>, \e k) | |
| | | * | |
| | | * Π(α<sup>2</sup>, \e k) is defined in | |
| | | * http://dlmf.nist.gov/19.2.E7 | |
| | | * \f[ | |
| | | * \Pi(\alpha^2, k) = \int_0^{\pi/2} | |
| | | * \frac1{\sqrt{1-k^2\sin^2\phi}(1 - \alpha^2\sin^2\phi_)}\,d\phi. | |
| | | * \f] | |
| | | ********************************************************************** | |
| | | / | |
| | | Math::real Pi() const throw() { _init || Init(); return _Pic; } | |
| | | | |
| | | /** | |
| | | * Legendre's complete geodesic longitude integral. | |
| | | * | |
| | | * @return \e G(α<sup>2</sup>, \e k) | |
| | | * | |
| | | * \e G(α<sup>2</sup>, \e k) is given by | |
| | | * \f[ | |
| | | * G(\alpha^2, k) = \int_0^{\pi/2} | |
| | | * \frac{\sqrt{1-k^2\sin^2\phi}}{1 - \alpha^2\sin^2\phi}\,d\phi. | |
| | | * \f] | |
| | | ********************************************************************** | |
| | | / | |
| | | Math::real G() const throw() { _init || Init(); return _Gc; } | |
| | | | |
| | | /** | |
| | | * Cayley's complete geodesic longitude difference integral. | |
| | | * | |
| | | * @return \e H(α<sup>2</sup>, \e k) | |
| | | * | |
| | | * \e H(α<sup>2</sup>, \e k) is given by | |
| | | * \f[ | |
| | | * H(\alpha^2, k) = \int_0^{\pi/2} | |
| | | * \frac{\cos^2\phi}{(1-\alpha^2\sin^2\phi)\sqrt{1-k^2\sin^2\phi}} | |
| | | * \,d\phi. | |
| | | * \f] | |
| | | ********************************************************************** | |
| | | / | |
| | | Math::real H() const throw() { _init || Init(); return _Hc; } | |
| | | ///@} | |
| | | | |
| | | /** \name Incomplete elliptic integrals. | |
| | | ********************************************************************** | |
| | | / | |
| | | ///@{ | |
| | | /** | |
| | | * The incomplete integral of the first kind. | |
| | | * | |
| | | * @param[in] phi | |
| | | * @return \e F(φ, \e k). | |
| | | * | |
| | | * \e F(φ, \e k) is defined in http://dlmf.nist.gov/19.2.E4 | |
| | | * \f[ | |
| | | * F(\phi, k) = \int_0^\phi \frac1{\sqrt{1-k^2\sin^2\theta}}\,d\theta | |
| | | . | |
| | | * \f] | |
| | | ********************************************************************** | |
| | | / | |
| | | Math::real F(real phi) const throw(); | |
| | | | |
| /** | | /** | |
| * The incomplete integral of the second kind. | | * The incomplete integral of the second kind. | |
| * | | * | |
| * @param[in] phi | | * @param[in] phi | |
|
| * @return ∫ sqrt(1 − \e m sin<sup>2</sup>φ) dφ. | | * @return \e E(φ, \e k). | |
| | | * | |
| | | * \e E(φ, \e k) is defined in http://dlmf.nist.gov/19.2.E5 | |
| | | * \f[ | |
| | | * E(\phi, k) = \int_0^\phi \sqrt{1-k^2\sin^2\theta}\,d\theta. | |
| | | * \f] | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real E(real phi) const throw(); | | Math::real E(real phi) const throw(); | |
| | | | |
| /** | | /** | |
| * The incomplete integral of the second kind with the argument given i
n | | * The incomplete integral of the second kind with the argument given i
n | |
| * degrees. | | * degrees. | |
| * | | * | |
| * @param[in] ang in <i>degrees</i>. | | * @param[in] ang in <i>degrees</i>. | |
|
| * @return ∫ sqrt(1 − \e m sin<sup>2</sup>φ) dφ. | | * @return \e E(π <i>ang</i>/180, \e k). | |
| * | | | |
| * \e ang must lie in [−90°, 90°]. This function | | | |
| * returns the correct result even when \e m is negative. | | | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real Ed(real ang) const throw(); | | Math::real Ed(real ang) const throw(); | |
| | | | |
| /** | | /** | |
|
| * The incomplete integral of the second kind in terms of Jacobi ellipt | | * The inverse of the incomplete integral of the second kind. | |
| ic | | | |
| * functions | | | |
| * | | * | |
|
| * @param[in] sn | | * @param[in] x | |
| * @param[in] cn | | * @return φ = <i>E</i><sup>−1</sup>(\e x, \e k); i.e., the | |
| * @param[in] dn | | * solution of such that \e E(φ, \e k) = \e x. | |
| * @return ∫ dn(\e w)<sup>2</sup> \e dw (A+S 17.2.10). | | ********************************************************************** | |
| | | / | |
| | | Math::real Einv(real x) const throw(); | |
| | | | |
| | | /** | |
| | | * The incomplete integral of the third kind. | |
| * | | * | |
|
| * Instead of specifying the amplitude φ, we provide \e sn = sin&ph | | * @param[in] phi | |
| i;, | | * @return Π(φ, α<sup>2</sup>, \e k). | |
| * \e cn = cosφ, \e dn = sqrt(1 − \e m sin<sup>2</sup>φ). | | * | |
| | | * Π(φ, α<sup>2</sup>, \e k) is defined in | |
| | | * http://dlmf.nist.gov/19.2.E7 | |
| | | * \f[ | |
| | | * \Pi(\phi, \alpha^2, k) = \int_0^\phi | |
| | | * \frac1{\sqrt{1-k^2\sin^2\theta}(1 - \alpha^2\sin^2\theta_)}\,d\t | |
| | | heta. | |
| | | * \f] | |
| | | ********************************************************************** | |
| | | / | |
| | | Math::real Pi(real phi) const throw(); | |
| | | | |
| | | /** | |
| | | * Jahnke's incomplete elliptic integral. | |
| | | * | |
| | | * @param[in] phi | |
| | | * @return \e D(φ, \e k). | |
| | | * | |
| | | * \e D(φ, \e k) is defined in http://dlmf.nist.gov/19.2.E4 | |
| | | * \f[ | |
| | | * D(\phi, k) = \int_0^\phi | |
| | | * \frac{\sin^2\theta}{\sqrt{1-k^2\sin^2\theta}}\,d\theta. | |
| | | * \f] | |
| | | ********************************************************************** | |
| | | / | |
| | | Math::real D(real phi) const throw(); | |
| | | | |
| | | /** | |
| | | * Legendre's geodesic longitude integral. | |
| | | * | |
| | | * @param[in] phi | |
| | | * @return \e G(φ, α<sup>2</sup>, \e k). | |
| | | * | |
| | | * \e G(φ, α<sup>2</sup>, \e k) is defined by | |
| | | * \f[ | |
| | | * \begin{aligned} | |
| | | * G(\phi, \alpha^2, k) &= | |
| | | * \frac{k^2}{\alpha^2} F(\phi, k) + | |
| | | * \biggl(1 - \frac{k^2}{\alpha^2}\biggr) \Pi(\phi, \alpha^2, k) \ | |
| | | \ | |
| | | * &= \int_0^\phi | |
| | | * \frac{\sqrt{1-k^2\sin^2\theta}}{1 - \alpha^2\sin^2\theta}\,d\the | |
| | | ta. | |
| | | * \end{aligned} | |
| | | * \f] | |
| | | * | |
| | | * Legendre expresses the longitude of a point on the geodesic in terms | |
| | | of | |
| | | * this combination of elliptic integrals in Exercices de Calcul | |
| | | * Intégral, Vol. 1 (1811), p. 181, | |
| | | * http://books.google.com/books?id=riIOAAAAQAAJ&pg=PA181. | |
| | | * | |
| | | * See \ref geodellip for the expression for the longitude in terms of | |
| | | this | |
| | | * function. | |
| | | ********************************************************************** | |
| | | / | |
| | | Math::real G(real phi) const throw(); | |
| | | | |
| | | /** | |
| | | * Cayley's geodesic longitude difference integral. | |
| | | * | |
| | | * @param[in] phi | |
| | | * @return \e H(φ, α<sup>2</sup>, \e k). | |
| | | * | |
| | | * \e H(φ, α<sup>2</sup>, \e k) is defined by | |
| | | * \f[ | |
| | | * \begin{aligned} | |
| | | * H(\phi, \alpha^2, k) &= | |
| | | * \frac1{\alpha^2} F(\phi, k) + | |
| | | * \biggl(1 - \frac1{\alpha^2}\biggr) \Pi(\phi, \alpha^2, k) \\ | |
| | | * &= \int_0^\phi | |
| | | * \frac{\cos^2\theta}{(1-\alpha^2\sin^2\theta)\sqrt{1-k^2\sin^2\th | |
| | | eta}} | |
| | | * \,d\theta. | |
| | | * \end{aligned} | |
| | | * \f] | |
| | | * | |
| | | * Cayley expresses the longitude difference of a point on the geodesic | |
| | | in | |
| | | * terms of this combination of elliptic integrals in Phil. Mag. <b>40< | |
| | | /b> | |
| | | * (1870), p. 333, http://books.google.com/books?id=Zk0wAAAAIAAJ&pg=PA3 | |
| | | 33. | |
| | | * | |
| | | * See \ref geodellip for the expression for the longitude in terms of | |
| | | this | |
| | | * function. | |
| | | ********************************************************************** | |
| | | / | |
| | | Math::real H(real phi) const throw(); | |
| | | ///@} | |
| | | | |
| | | /** \name Incomplete integrals in terms of Jacobi elliptic functions. | |
| | | ********************************************************************** | |
| | | / | |
| | | /** | |
| | | * The incomplete integral of the first kind in terms of Jacobi ellipti | |
| | | c | |
| | | * functions. | |
| | | * | |
| | | * @param[in] sn = sinφ | |
| | | * @param[in] cn = cosφ | |
| | | * @param[in] dn = sqrt(1 − <i>k</i><sup>2</sup> | |
| | | * sin<sup>2</sup>φ) | |
| | | * @return \e F(φ, \e k) as though φ ∈ (−π, π] | |
| | | . | |
| | | ********************************************************************** | |
| | | / | |
| | | Math::real F(real sn, real cn, real dn) const throw(); | |
| | | | |
| | | /** | |
| | | * The incomplete integral of the second kind in terms of Jacobi ellipt | |
| | | ic | |
| | | * functions. | |
| | | * | |
| | | * @param[in] sn = sinφ | |
| | | * @param[in] cn = cosφ | |
| | | * @param[in] dn = sqrt(1 − <i>k</i><sup>2</sup> | |
| | | * sin<sup>2</sup>φ) | |
| | | * @return \e E(φ, \e k) as though φ ∈ (−π, π] | |
| | | . | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real E(real sn, real cn, real dn) const throw(); | | Math::real E(real sn, real cn, real dn) const throw(); | |
|
| | | | |
| | | /** | |
| | | * The incomplete integral of the third kind in terms of Jacobi ellipti | |
| | | c | |
| | | * functions. | |
| | | * | |
| | | * @param[in] sn = sinφ | |
| | | * @param[in] cn = cosφ | |
| | | * @param[in] dn = sqrt(1 − <i>k</i><sup>2</sup> | |
| | | * sin<sup>2</sup>φ) | |
| | | * @return Π(φ, α<sup>2</sup>, \e k) as though φ &isin | |
| | | ; | |
| | | * (−π, π]. | |
| | | ********************************************************************** | |
| | | / | |
| | | Math::real Pi(real sn, real cn, real dn) const throw(); | |
| | | | |
| | | /** | |
| | | * Jahnke's incomplete elliptic integral in terms of Jacobi elliptic | |
| | | * functions. | |
| | | * | |
| | | * @param[in] sn = sinφ | |
| | | * @param[in] cn = cosφ | |
| | | * @param[in] dn = sqrt(1 − <i>k</i><sup>2</sup> | |
| | | * sin<sup>2</sup>φ) | |
| | | * @return \e D(φ, \e k) as though φ ∈ (−π, π] | |
| | | . | |
| | | ********************************************************************** | |
| | | / | |
| | | Math::real D(real sn, real cn, real dn) const throw(); | |
| | | | |
| | | /** | |
| | | * Legendre's geodesic longitude integral in terms of Jacobi elliptic | |
| | | * functions. | |
| | | * | |
| | | * @param[in] sn = sinφ | |
| | | * @param[in] cn = cosφ | |
| | | * @param[in] dn = sqrt(1 − <i>k</i><sup>2</sup> | |
| | | * sin<sup>2</sup>φ) | |
| | | * @return \e G(φ, α<sup>2</sup>, \e k) as though φ &isin | |
| | | ; | |
| | | * (−π, π]. | |
| | | ********************************************************************** | |
| | | / | |
| | | Math::real G(real sn, real cn, real dn) const throw(); | |
| | | | |
| | | /** | |
| | | * Cayley's geodesic longitude difference integral in terms of Jacobi | |
| | | * elliptic functions. | |
| | | * | |
| | | * @param[in] sn = sinφ | |
| | | * @param[in] cn = cosφ | |
| | | * @param[in] dn = sqrt(1 − <i>k</i><sup>2</sup> | |
| | | * sin<sup>2</sup>φ) | |
| | | * @return \e H(φ, α<sup>2</sup>, \e k) as though φ &isin | |
| | | ; | |
| | | * (−π, π]. | |
| | | ********************************************************************** | |
| | | / | |
| | | Math::real H(real sn, real cn, real dn) const throw(); | |
| | | ///@} | |
| | | | |
| | | /** \name Periodic versions of incomplete elliptic integrals. | |
| | | ********************************************************************** | |
| | | / | |
| | | ///@{ | |
| | | /** | |
| | | * The periodic incomplete integral of the first kind. | |
| | | * | |
| | | * @param[in] sn = sinφ | |
| | | * @param[in] cn = cosφ | |
| | | * @param[in] dn = sqrt(1 − <i>k</i><sup>2</sup> | |
| | | * sin<sup>2</sup>φ) | |
| | | * @return the periodic function π \e F(φ, \e k) / (2 \e K(\e k) | |
| | | ) - | |
| | | * φ | |
| | | ********************************************************************** | |
| | | / | |
| | | Math::real deltaF(real sn, real cn, real dn) const throw(); | |
| | | | |
| | | /** | |
| | | * The periodic incomplete integral of the second kind. | |
| | | * | |
| | | * @param[in] sn = sinφ | |
| | | * @param[in] cn = cosφ | |
| | | * @param[in] dn = sqrt(1 − <i>k</i><sup>2</sup> | |
| | | * sin<sup>2</sup>φ) | |
| | | * @return the periodic function π \e E(φ, \e k) / (2 \e E(\e k) | |
| | | ) - | |
| | | * φ | |
| | | ********************************************************************** | |
| | | / | |
| | | Math::real deltaE(real sn, real cn, real dn) const throw(); | |
| | | | |
| | | /** | |
| | | * The periodic inverse of the incomplete integral of the second kind. | |
| | | * | |
| | | * @param[in] stau = sinτ | |
| | | * @param[in] ctau = sinτ | |
| | | * @return the periodic function <i>E</i><sup>−1</sup>(τ (2 \ | |
| | | e | |
| | | * E(\e k)/π), \e k) - τ | |
| | | ********************************************************************** | |
| | | / | |
| | | Math::real deltaEinv(real stau, real ctau) const throw(); | |
| | | | |
| | | /** | |
| | | * The periodic incomplete integral of the third kind. | |
| | | * | |
| | | * @param[in] sn = sinφ | |
| | | * @param[in] cn = cosφ | |
| | | * @param[in] dn = sqrt(1 − <i>k</i><sup>2</sup> | |
| | | * sin<sup>2</sup>φ) | |
| | | * @return the periodic function π Π(φ, \e k) / (2 Π(\e k) | |
| | | ) - | |
| | | * φ | |
| | | ********************************************************************** | |
| | | / | |
| | | Math::real deltaPi(real sn, real cn, real dn) const throw(); | |
| | | | |
| | | /** | |
| | | * The periodic Jahnke's incomplete elliptic integral. | |
| | | * | |
| | | * @param[in] sn = sinφ | |
| | | * @param[in] cn = cosφ | |
| | | * @param[in] dn = sqrt(1 − <i>k</i><sup>2</sup> | |
| | | * sin<sup>2</sup>φ) | |
| | | * @return the periodic function π \e D(φ, \e k) / (2 \e D(\e k) | |
| | | ) - | |
| | | * φ | |
| | | ********************************************************************** | |
| | | / | |
| | | Math::real deltaD(real sn, real cn, real dn) const throw(); | |
| | | | |
| | | /** | |
| | | * Legendre's periodic geodesic longitude integral. | |
| | | * | |
| | | * @param[in] sn = sinφ | |
| | | * @param[in] cn = cosφ | |
| | | * @param[in] dn = sqrt(1 − <i>k</i><sup>2</sup> | |
| | | * sin<sup>2</sup>φ) | |
| | | * @return the periodic function π \e G(φ, \e k) / (2 \e G(\e k) | |
| | | ) - | |
| | | * φ | |
| | | ********************************************************************** | |
| | | / | |
| | | Math::real deltaG(real sn, real cn, real dn) const throw(); | |
| | | | |
| | | /** | |
| | | * Cayley's periodic geodesic longitude difference integral. | |
| | | * | |
| | | * @param[in] sn = sinφ | |
| | | * @param[in] cn = cosφ | |
| | | * @param[in] dn = sqrt(1 − <i>k</i><sup>2</sup> | |
| | | * sin<sup>2</sup>φ) | |
| | | * @return the periodic function π \e H(φ, \e k) / (2 \e H(\e k) | |
| | | ) - | |
| | | * φ | |
| | | ********************************************************************** | |
| | | / | |
| | | Math::real deltaH(real sn, real cn, real dn) const throw(); | |
| | | ///@} | |
| | | | |
| | | /** \name Elliptic functions. | |
| | | ********************************************************************** | |
| | | / | |
| | | ///@{ | |
| | | /** | |
| | | * The Jacobi elliptic functions. | |
| | | * | |
| | | * @param[in] x the argument. | |
| | | * @param[out] sn sn(\e x, \e k). | |
| | | * @param[out] cn cn(\e x, \e k). | |
| | | * @param[out] dn dn(\e x, \e k). | |
| | | ********************************************************************** | |
| | | / | |
| | | void sncndn(real x, real& sn, real& cn, real& dn) const throw(); | |
| | | | |
| | | /** | |
| | | * The Δ amplitude function. | |
| | | * | |
| | | * @param[in] sn sinφ | |
| | | * @param[in] cn cosφ | |
| | | * @return Δ = sqrt(1 − <i>k</i><sup>2</sup> | |
| | | * sin<sup>2</sup>φ) | |
| | | ********************************************************************** | |
| | | / | |
| | | Math::real Delta(real sn, real cn) const throw() | |
| | | { return std::sqrt(_k2 < 0 ? 1 - _k2 * sn*sn : _kp2 + _k2 * cn*cn); } | |
| | | ///@} | |
| | | | |
| | | /** \name Symmetric elliptic integrals. | |
| | | ********************************************************************** | |
| | | / | |
| | | ///@{ | |
| | | /** | |
| | | * Symmetric integral of the first kind <i>R<sub>F</sub></i>. | |
| | | * | |
| | | * @param[in] x | |
| | | * @param[in] y | |
| | | * @param[in] z | |
| | | * @return <i>R<sub>F</sub></i>(\e x, \e y, \e z) | |
| | | * | |
| | | * <i>R<sub>F</sub></i> is defined in http://dlmf.nist.gov/19.16.E1 | |
| | | * \f[ R_F(x, y, z) = \frac12 | |
| | | * \int_0^\infty\frac1{\sqrt{(t + x) (t + y) (t + z)}}\, dt \f] | |
| | | * If one of the arguments is zero, it is more efficient to call the | |
| | | * two-argument version of this function with the non-zero arguments. | |
| | | ********************************************************************** | |
| | | / | |
| | | static real RF(real x, real y, real z) throw(); | |
| | | | |
| | | /** | |
| | | * Complete symmetric integral of the first kind, <i>R<sub>F</sub></i> | |
| | | with | |
| | | * one argument zero. | |
| | | * | |
| | | * @param[in] x | |
| | | * @param[in] y | |
| | | * @return <i>R<sub>F</sub></i>(\e x, \e y, 0) | |
| | | ********************************************************************** | |
| | | / | |
| | | static real RF(real x, real y) throw(); | |
| | | | |
| | | /** | |
| | | * Degenerate symmetric integral of the first kind <i>R<sub>C</sub></i> | |
| | | . | |
| | | * | |
| | | * @param[in] x | |
| | | * @param[in] y | |
| | | * @return <i>R<sub>C</sub></i>(\e x, \e y) = <i>R<sub>F</sub></i>(\e x | |
| | | , \e | |
| | | * y, \e y) | |
| | | * | |
| | | * <i>R<sub>C</sub></i> is defined in http://dlmf.nist.gov/19.2.E17 | |
| | | * \f[ R_C(x, y) = \frac12 | |
| | | * \int_0^\infty\frac1{\sqrt{t + x}(t + y)}\,dt \f] | |
| | | ********************************************************************** | |
| | | / | |
| | | static real RC(real x, real y) throw(); | |
| | | | |
| | | /** | |
| | | * Symmetric integral of the second kind <i>R<sub>G</sub></i>. | |
| | | * | |
| | | * @param[in] x | |
| | | * @param[in] y | |
| | | * @param[in] z | |
| | | * @return <i>R<sub>G</sub></i>(\e x, \e y, \e z) | |
| | | * | |
| | | * <i>R<sub>G</sub></i> is defined in Carlson, eq 1.5 | |
| | | * \f[ R_G(x, y, z) = \frac14 | |
| | | * \int_0^\infty[(t + x) (t + y) (t + z)]^{-1/2} | |
| | | * \biggl( | |
| | | * \frac x{t + x} + \frac y{t + y} + \frac z{t + z} | |
| | | * \biggr)t\,dt \f] | |
| | | * See also http://dlmf.nist.gov/19.16.E3. | |
| | | * If one of the arguments is zero, it is more efficient to call the | |
| | | * two-argument version of this function with the non-zero arguments. | |
| | | ********************************************************************** | |
| | | / | |
| | | static real RG(real x, real y, real z) throw(); | |
| | | | |
| | | /** | |
| | | * Complete symmetric integral of the second kind, <i>R<sub>G</sub></i> | |
| | | * with one argument zero. | |
| | | * | |
| | | * @param[in] x | |
| | | * @param[in] y | |
| | | * @return <i>R<sub>G</sub></i>(\e x, \e y, 0) | |
| | | ********************************************************************** | |
| | | / | |
| | | static real RG(real x, real y) throw(); | |
| | | | |
| | | /** | |
| | | * Symmetric integral of the third kind <i>R<sub>J</sub></i>. | |
| | | * | |
| | | * @param[in] x | |
| | | * @param[in] y | |
| | | * @param[in] z | |
| | | * @param[in] p | |
| | | * @return <i>R<sub>J</sub></i>(\e x, \e y, \e z, \e p) | |
| | | * | |
| | | * <i>R<sub>J</sub></i> is defined in http://dlmf.nist.gov/19.16.E2 | |
| | | * \f[ R_J(x, y, z, p) = \frac32 | |
| | | * \int_0^\infty[(t + x) (t + y) (t + z)]^{-1/2} (t + p)^{-1}\, d | |
| | | t \f] | |
| | | ********************************************************************** | |
| | | / | |
| | | static real RJ(real x, real y, real z, real p) throw(); | |
| | | | |
| | | /** | |
| | | * Degenerate symmetric integral of the third kind <i>R<sub>D</sub></i> | |
| | | . | |
| | | * | |
| | | * @param[in] x | |
| | | * @param[in] y | |
| | | * @param[in] z | |
| | | * @return <i>R<sub>D</sub></i>(\e x, \e y, \e z) = <i>R<sub>J</sub></i | |
| | | >(\e | |
| | | * x, \e y, \e z, \e z) | |
| | | * | |
| | | * <i>R<sub>D</sub></i> is defined in http://dlmf.nist.gov/19.16.E5 | |
| | | * \f[ R_D(x, y, z) = \frac32 | |
| | | * \int_0^\infty[(t + x) (t + y)]^{-1/2} (t + z)^{-3/2}\, dt \f] | |
| | | ********************************************************************** | |
| | | / | |
| | | static real RD(real x, real y, real z) throw(); | |
| | | ///@} | |
| | | | |
| }; | | }; | |
| | | | |
| } // namespace GeographicLib | | } // namespace GeographicLib | |
| | | | |
| #endif // GEOGRAPHICLIB_ELLIPTICFUNCTION_HPP | | #endif // GEOGRAPHICLIB_ELLIPTICFUNCTION_HPP | |
| | | | |
End of changes. 33 change blocks. |
| 59 lines changed or deleted | | 734 lines changed or added | |
|
| Geodesic.hpp | | Geodesic.hpp | |
| /** | | /** | |
| * \file Geodesic.hpp | | * \file Geodesic.hpp | |
| * \brief Header for GeographicLib::Geodesic class | | * \brief Header for GeographicLib::Geodesic class | |
| * | | * | |
|
| * Copyright (c) Charles Karney (2009-2011) <charles@karney.com> and licens
ed | | * Copyright (c) Charles Karney (2009-2012) <charles@karney.com> and licens
ed | |
| * under the MIT/X11 License. For more information, see | | * under the MIT/X11 License. For more information, see | |
| * http://geographiclib.sourceforge.net/ | | * http://geographiclib.sourceforge.net/ | |
| **********************************************************************/ | | **********************************************************************/ | |
| | | | |
| #if !defined(GEOGRAPHICLIB_GEODESIC_HPP) | | #if !defined(GEOGRAPHICLIB_GEODESIC_HPP) | |
| #define GEOGRAPHICLIB_GEODESIC_HPP 1 | | #define GEOGRAPHICLIB_GEODESIC_HPP 1 | |
| | | | |
| #include <GeographicLib/Constants.hpp> | | #include <GeographicLib/Constants.hpp> | |
| | | | |
|
| #if !defined(GEOD_ORD) | | #if !defined(GEOGRAPHICLIB_GEODESIC_ORDER) | |
| /** | | /** | |
| * The order of the expansions used by Geodesic. | | * The order of the expansions used by Geodesic. | |
| **********************************************************************/ | | **********************************************************************/ | |
|
| # define GEOD_ORD \ | | # define GEOGRAPHICLIB_GEODESIC_ORDER \ | |
| (GEOGRAPHICLIB_PREC == 1 ? 6 : (GEOGRAPHICLIB_PREC == 0 ? 3 : 7)) | | (GEOGRAPHICLIB_PRECISION == 2 ? 6 : (GEOGRAPHICLIB_PRECISION == 1 ? 3 : 7 | |
| | | )) | |
| #endif | | #endif | |
| | | | |
| namespace GeographicLib { | | namespace GeographicLib { | |
| | | | |
| class GeodesicLine; | | class GeodesicLine; | |
| | | | |
| /** | | /** | |
| * \brief %Geodesic calculations | | * \brief %Geodesic calculations | |
| * | | * | |
| * The shortest path between two points on a ellipsoid at (\e lat1, \e lo
n1) | | * The shortest path between two points on a ellipsoid at (\e lat1, \e lo
n1) | |
| | | | |
| skipping to change at line 102 | | skipping to change at line 102 | |
| * then | | * then | |
| * - \e m13 = \e m12 \e M23 + \e m23 \e M21 | | * - \e m13 = \e m12 \e M23 + \e m23 \e M21 | |
| * - \e M13 = \e M12 \e M23 − (1 − \e M12 \e M21) \e m23 / \e
m12 | | * - \e M13 = \e M12 \e M23 − (1 − \e M12 \e M21) \e m23 / \e
m12 | |
| * - \e M31 = \e M32 \e M21 − (1 − \e M23 \e M32) \e m12 / \e
m23 | | * - \e M31 = \e M32 \e M21 − (1 − \e M23 \e M32) \e m12 / \e
m23 | |
| * | | * | |
| * Additional functionality is provided by the GeodesicLine class, which | | * Additional functionality is provided by the GeodesicLine class, which | |
| * allows a sequence of points along a geodesic to be computed. | | * allows a sequence of points along a geodesic to be computed. | |
| * | | * | |
| * The calculations are accurate to better than 15 nm (15 nanometers). S
ee | | * The calculations are accurate to better than 15 nm (15 nanometers). S
ee | |
| * Sec. 9 of | | * Sec. 9 of | |
|
| * <a href="http://arxiv.org/abs/1102.1215v1">arXiv:1102.1215v1</a> | | * <a href="http://arxiv.org/abs/1102.1215v1">arXiv:1102.1215v1</a> for | |
| * for details. | | * details. The algorithms used by this class are based on series expans | |
| | | ions | |
| | | * using the flattening \e f as a small parameter. These only accurate f | |
| | | or | |
| | | * |\e f| < 0.01; however reasonably accurate results will be obtained | |
| | | for | |
| | | * |\e f| < 0.1. For very eccentric ellipsoids, use GeodesicExact | |
| | | * instead. | |
| * | | * | |
| * The algorithms are described in | | * The algorithms are described in | |
| * - C. F. F. Karney, | | * - C. F. F. Karney, | |
| * <a href="http://dx.doi.org/10.1007/s00190-012-0578-z"> | | * <a href="http://dx.doi.org/10.1007/s00190-012-0578-z"> | |
| * Algorithms for geodesics</a>, | | * Algorithms for geodesics</a>, | |
| * J. Geodesy, 2012; | | * J. Geodesy, 2012; | |
| * DOI: <a href="http://dx.doi.org/10.1007/s00190-012-0578-z"> | | * DOI: <a href="http://dx.doi.org/10.1007/s00190-012-0578-z"> | |
| * 10.1007/s00190-012-0578-z</a>. | | * 10.1007/s00190-012-0578-z</a>. | |
| * . | | * . | |
| * For more information on geodesics see \ref geodesic. | | * For more information on geodesics see \ref geodesic. | |
| | | | |
| skipping to change at line 126 | | skipping to change at line 130 | |
| * \include example-Geodesic.cpp | | * \include example-Geodesic.cpp | |
| * | | * | |
| * <a href="Geod.1.html">Geod</a> is a command-line utility providing acc
ess | | * <a href="Geod.1.html">Geod</a> is a command-line utility providing acc
ess | |
| * to the functionality of Geodesic and GeodesicLine. | | * to the functionality of Geodesic and GeodesicLine. | |
| **********************************************************************/ | | **********************************************************************/ | |
| | | | |
| class GEOGRAPHIC_EXPORT Geodesic { | | class GEOGRAPHIC_EXPORT Geodesic { | |
| private: | | private: | |
| typedef Math::real real; | | typedef Math::real real; | |
| friend class GeodesicLine; | | friend class GeodesicLine; | |
|
| static const int nA1_ = GEOD_ORD; | | static const int nA1_ = GEOGRAPHICLIB_GEODESIC_ORDER; | |
| static const int nC1_ = GEOD_ORD; | | static const int nC1_ = GEOGRAPHICLIB_GEODESIC_ORDER; | |
| static const int nC1p_ = GEOD_ORD; | | static const int nC1p_ = GEOGRAPHICLIB_GEODESIC_ORDER; | |
| static const int nA2_ = GEOD_ORD; | | static const int nA2_ = GEOGRAPHICLIB_GEODESIC_ORDER; | |
| static const int nC2_ = GEOD_ORD; | | static const int nC2_ = GEOGRAPHICLIB_GEODESIC_ORDER; | |
| static const int nA3_ = GEOD_ORD; | | static const int nA3_ = GEOGRAPHICLIB_GEODESIC_ORDER; | |
| static const int nA3x_ = nA3_; | | static const int nA3x_ = nA3_; | |
|
| static const int nC3_ = GEOD_ORD; | | static const int nC3_ = GEOGRAPHICLIB_GEODESIC_ORDER; | |
| static const int nC3x_ = (nC3_ * (nC3_ - 1)) / 2; | | static const int nC3x_ = (nC3_ * (nC3_ - 1)) / 2; | |
|
| static const int nC4_ = GEOD_ORD; | | static const int nC4_ = GEOGRAPHICLIB_GEODESIC_ORDER; | |
| static const int nC4x_ = (nC4_ * (nC4_ + 1)) / 2; | | static const int nC4x_ = (nC4_ * (nC4_ + 1)) / 2; | |
|
| static const unsigned maxit_ = 50; | | static const unsigned maxit_ = 30; | |
| | | static const unsigned bisection_ = std::numeric_limits<real>::digits + | |
| | | 10; | |
| | | | |
| static const real tiny_; | | static const real tiny_; | |
| static const real tol0_; | | static const real tol0_; | |
| static const real tol1_; | | static const real tol1_; | |
| static const real tol2_; | | static const real tol2_; | |
| static const real xthresh_; | | static const real xthresh_; | |
| | | | |
| enum captype { | | enum captype { | |
| CAP_NONE = 0U, | | CAP_NONE = 0U, | |
| CAP_C1 = 1U<<0, | | CAP_C1 = 1U<<0, | |
| | | | |
| skipping to change at line 182 | | skipping to change at line 187 | |
| real r = Math::hypot(sinx, cosx); | | real r = Math::hypot(sinx, cosx); | |
| sinx /= r; | | sinx /= r; | |
| cosx /= r; | | cosx /= r; | |
| } | | } | |
| static real Astroid(real x, real y) throw(); | | static real Astroid(real x, real y) throw(); | |
| | | | |
| real _a, _f, _f1, _e2, _ep2, _n, _b, _c2, _etol2; | | real _a, _f, _f1, _e2, _ep2, _n, _b, _c2, _etol2; | |
| real _A3x[nA3x_], _C3x[nC3x_], _C4x[nC4x_]; | | real _A3x[nA3x_], _C3x[nC3x_], _C4x[nC4x_]; | |
| | | | |
| void Lengths(real eps, real sig12, | | void Lengths(real eps, real sig12, | |
|
| real ssig1, real csig1, real ssig2, real csig2, | | real ssig1, real csig1, real dn1, | |
| | | real ssig2, real csig2, real dn2, | |
| real cbet1, real cbet2, | | real cbet1, real cbet2, | |
| real& s12s, real& m12a, real& m0, | | real& s12s, real& m12a, real& m0, | |
| bool scalep, real& M12, real& M21, | | bool scalep, real& M12, real& M21, | |
| real C1a[], real C2a[]) const throw(); | | real C1a[], real C2a[]) const throw(); | |
|
| real InverseStart(real sbet1, real cbet1, real sbet2, real cbet2, | | real InverseStart(real sbet1, real cbet1, real dn1, | |
| | | real sbet2, real cbet2, real dn2, | |
| real lam12, | | real lam12, | |
| real& salp1, real& calp1, | | real& salp1, real& calp1, | |
| real& salp2, real& calp2, | | real& salp2, real& calp2, | |
| real C1a[], real C2a[]) const throw(); | | real C1a[], real C2a[]) const throw(); | |
|
| real Lambda12(real sbet1, real cbet1, real sbet2, real cbet2, | | real Lambda12(real sbet1, real cbet1, real dn1, | |
| | | real sbet2, real cbet2, real dn2, | |
| real salp1, real calp1, | | real salp1, real calp1, | |
| real& salp2, real& calp2, real& sig12, | | real& salp2, real& calp2, real& sig12, | |
| real& ssig1, real& csig1, real& ssig2, real& csig2, | | real& ssig1, real& csig1, real& ssig2, real& csig2, | |
| real& eps, real& domg12, bool diffp, real& dlam12, | | real& eps, real& domg12, bool diffp, real& dlam12, | |
| real C1a[], real C2a[], real C3a[]) | | real C1a[], real C2a[], real C3a[]) | |
| const throw(); | | const throw(); | |
| | | | |
| // These are Maxima generated functions to provide series approximation
s to | | // These are Maxima generated functions to provide series approximation
s to | |
| // the integrals for the ellipsoidal geodesic. | | // the integrals for the ellipsoidal geodesic. | |
| static real A1m1f(real eps) throw(); | | static real A1m1f(real eps) throw(); | |
| | | | |
| skipping to change at line 619 | | skipping to change at line 627 | |
| * @return \e a12 arc length of between point 1 and point 2 (degrees). | | * @return \e a12 arc length of between point 1 and point 2 (degrees). | |
| * | | * | |
| * \e lat1 and \e lat2 should be in the range [−90°, 90°]
; \e | | * \e lat1 and \e lat2 should be in the range [−90°, 90°]
; \e | |
| * lon1 and \e lon2 should be in the range [−540°, 540°). | | * lon1 and \e lon2 should be in the range [−540°, 540°). | |
| * The values of \e azi1 and \e azi2 returned are in the range | | * The values of \e azi1 and \e azi2 returned are in the range | |
| * [−180°, 180°). | | * [−180°, 180°). | |
| * | | * | |
| * If either point is at a pole, the azimuth is defined by keeping the | | * If either point is at a pole, the azimuth is defined by keeping the | |
| * longitude fixed and writing \e lat = 90° − ε or | | * longitude fixed and writing \e lat = 90° − ε or | |
| * −90° + ε and taking the limit ε → 0 f
rom | | * −90° + ε and taking the limit ε → 0 f
rom | |
|
| * above. If the routine fails to converge, then all the requested out | | * above. | |
| puts | | * | |
| * are set to Math::NaN(). (Test for such results with Math::isnan.) | | * The solution to the inverse problem is found using Newton's method. | |
| This | | If | |
| * is not expected to happen with ellipsoidal models of the earth; plea | | * this fails to converge (this is very unlikely in geodetic applicatio | |
| se | | ns | |
| * report all cases where this occurs. | | * but does occur for very eccentric ellipsoids), then the bisection me | |
| | | thod | |
| | | * is used to refine the solution. This should always converge to an | |
| | | * accurate solution. | |
| | | * | |
| | | * (If the routine fails to converge, then all the requested outputs ar | |
| | | e | |
| | | * set to Math::NaN() --- test for such results with Math::isnan. Plea | |
| | | se | |
| | | * report all cases where this occurs.) | |
| * | | * | |
| * The following functions are overloaded versions of Geodesic::Inverse | | * The following functions are overloaded versions of Geodesic::Inverse | |
| * which omit some of the output parameters. Note, however, that the a
rc | | * which omit some of the output parameters. Note, however, that the a
rc | |
| * length is always computed and returned as the function value. | | * length is always computed and returned as the function value. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real Inverse(real lat1, real lon1, real lat2, real lon2, | | Math::real Inverse(real lat1, real lon1, real lat2, real lon2, | |
| real& s12, real& azi1, real& azi2, real& m12, | | real& s12, real& azi1, real& azi2, real& m12, | |
| real& M12, real& M21, real& S12) const throw() { | | real& M12, real& M21, real& S12) const throw() { | |
| return GenInverse(lat1, lon1, lat2, lon2, | | return GenInverse(lat1, lon1, lat2, lon2, | |
| DISTANCE | AZIMUTH | | | DISTANCE | AZIMUTH | | |
| | | | |
End of changes. 12 change blocks. |
| 25 lines changed or deleted | | 47 lines changed or added | |
|
| GeodesicLine.hpp | | GeodesicLine.hpp | |
| /** | | /** | |
| * \file GeodesicLine.hpp | | * \file GeodesicLine.hpp | |
| * \brief Header for GeographicLib::GeodesicLine class | | * \brief Header for GeographicLib::GeodesicLine class | |
| * | | * | |
|
| * Copyright (c) Charles Karney (2009-2011) <charles@karney.com> and licens
ed | | * Copyright (c) Charles Karney (2009-2012) <charles@karney.com> and licens
ed | |
| * under the MIT/X11 License. For more information, see | | * under the MIT/X11 License. For more information, see | |
| * http://geographiclib.sourceforge.net/ | | * http://geographiclib.sourceforge.net/ | |
| **********************************************************************/ | | **********************************************************************/ | |
| | | | |
| #if !defined(GEOGRAPHICLIB_GEODESICLINE_HPP) | | #if !defined(GEOGRAPHICLIB_GEODESICLINE_HPP) | |
| #define GEOGRAPHICLIB_GEODESICLINE_HPP 1 | | #define GEOGRAPHICLIB_GEODESICLINE_HPP 1 | |
| | | | |
| #include <GeographicLib/Constants.hpp> | | #include <GeographicLib/Constants.hpp> | |
| #include <GeographicLib/Geodesic.hpp> | | #include <GeographicLib/Geodesic.hpp> | |
| | | | |
| | | | |
| skipping to change at line 34 | | skipping to change at line 34 | |
| * location of point 2 a distance \e s12 along the geodesic. Alternative
ly | | * location of point 2 a distance \e s12 along the geodesic. Alternative
ly | |
| * GeodesicLine.ArcPosition gives the position of point 2 an arc length \
e | | * GeodesicLine.ArcPosition gives the position of point 2 an arc length \
e | |
| * a12 along the geodesic. | | * a12 along the geodesic. | |
| * | | * | |
| * The default copy constructor and assignment operators work with this | | * The default copy constructor and assignment operators work with this | |
| * class. Similarly, a vector can be used to hold GeodesicLine objects. | | * class. Similarly, a vector can be used to hold GeodesicLine objects. | |
| * | | * | |
| * The calculations are accurate to better than 15 nm (15 nanometers). S
ee | | * The calculations are accurate to better than 15 nm (15 nanometers). S
ee | |
| * Sec. 9 of | | * Sec. 9 of | |
| * <a href="http://arxiv.org/abs/1102.1215v1">arXiv:1102.1215v1</a> for | | * <a href="http://arxiv.org/abs/1102.1215v1">arXiv:1102.1215v1</a> for | |
|
| * details. | | * details. The algorithms used by this class are based on series expans | |
| | | ions | |
| | | * using the flattening \e f as a small parameter. These only accurate f | |
| | | or | |
| | | * |\e f| < 0.01; however reasonably accurate results will be obtained | |
| | | for | |
| | | * |\e f| < 0.1. For very eccentric ellipsoids, use GeodesicLineExact | |
| | | * instead. | |
| * | | * | |
| * The algorithms are described in | | * The algorithms are described in | |
| * - C. F. F. Karney, | | * - C. F. F. Karney, | |
| * <a href="http://dx.doi.org/10.1007/s00190-012-0578-z"> | | * <a href="http://dx.doi.org/10.1007/s00190-012-0578-z"> | |
| * Algorithms for geodesics</a>, | | * Algorithms for geodesics</a>, | |
| * J. Geodesy, 2012; | | * J. Geodesy, 2012; | |
| * DOI: <a href="http://dx.doi.org/10.1007/s00190-012-0578-z"> | | * DOI: <a href="http://dx.doi.org/10.1007/s00190-012-0578-z"> | |
| * 10.1007/s00190-012-0578-z</a>. | | * 10.1007/s00190-012-0578-z</a>. | |
| * . | | * . | |
| * For more information on geodesics see \ref geodesic. | | * For more information on geodesics see \ref geodesic. | |
| | | | |
| skipping to change at line 65 | | skipping to change at line 69 | |
| typedef Math::real real; | | typedef Math::real real; | |
| friend class Geodesic; | | friend class Geodesic; | |
| static const int nC1_ = Geodesic::nC1_; | | static const int nC1_ = Geodesic::nC1_; | |
| static const int nC1p_ = Geodesic::nC1p_; | | static const int nC1p_ = Geodesic::nC1p_; | |
| static const int nC2_ = Geodesic::nC2_; | | static const int nC2_ = Geodesic::nC2_; | |
| static const int nC3_ = Geodesic::nC3_; | | static const int nC3_ = Geodesic::nC3_; | |
| static const int nC4_ = Geodesic::nC4_; | | static const int nC4_ = Geodesic::nC4_; | |
| | | | |
| real _lat1, _lon1, _azi1; | | real _lat1, _lon1, _azi1; | |
| real _a, _f, _b, _c2, _f1, _salp0, _calp0, _k2, | | real _a, _f, _b, _c2, _f1, _salp0, _calp0, _k2, | |
|
| _salp1, _calp1, _ssig1, _csig1, _stau1, _ctau1, _somg1, _comg1, | | _salp1, _calp1, _ssig1, _csig1, _dn1, _stau1, _ctau1, _somg1, _comg1, | |
| _A1m1, _A2m1, _A3c, _B11, _B21, _B31, _A4, _B41; | | _A1m1, _A2m1, _A3c, _B11, _B21, _B31, _A4, _B41; | |
| // index zero elements of _C1a, _C1pa, _C2a, _C3a are unused | | // index zero elements of _C1a, _C1pa, _C2a, _C3a are unused | |
| real _C1a[nC1_ + 1], _C1pa[nC1p_ + 1], _C2a[nC2_ + 1], _C3a[nC3_], | | real _C1a[nC1_ + 1], _C1pa[nC1p_ + 1], _C2a[nC2_ + 1], _C3a[nC3_], | |
| _C4a[nC4_]; // all the elements of _C4a are used | | _C4a[nC4_]; // all the elements of _C4a are used | |
| unsigned _caps; | | unsigned _caps; | |
| | | | |
| enum captype { | | enum captype { | |
| CAP_NONE = Geodesic::CAP_NONE, | | CAP_NONE = Geodesic::CAP_NONE, | |
| CAP_C1 = Geodesic::CAP_C1, | | CAP_C1 = Geodesic::CAP_C1, | |
| CAP_C1p = Geodesic::CAP_C1p, | | CAP_C1p = Geodesic::CAP_C1p, | |
| | | | |
| skipping to change at line 157 | | skipping to change at line 161 | |
| /** \name Constructors | | /** \name Constructors | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| ///@{ | | ///@{ | |
| | | | |
| /** | | /** | |
| * Constructor for a geodesic line staring at latitude \e lat1, longitu
de | | * Constructor for a geodesic line staring at latitude \e lat1, longitu
de | |
| * \e lon1, and azimuth \e azi1 (all in degrees). | | * \e lon1, and azimuth \e azi1 (all in degrees). | |
| * | | * | |
| * @param[in] g A Geodesic object used to compute the necessary informa
tion | | * @param[in] g A Geodesic object used to compute the necessary informa
tion | |
| * about the GeodesicLine. | | * about the GeodesicLine. | |
|
| * | | | |
| * @param[in] lat1 latitude of point 1 (degrees). | | * @param[in] lat1 latitude of point 1 (degrees). | |
| * @param[in] lon1 longitude of point 1 (degrees). | | * @param[in] lon1 longitude of point 1 (degrees). | |
| * @param[in] azi1 azimuth at point 1 (degrees). | | * @param[in] azi1 azimuth at point 1 (degrees). | |
| * @param[in] caps bitor'ed combination of GeodesicLine::mask values | | * @param[in] caps bitor'ed combination of GeodesicLine::mask values | |
| * specifying the capabilities the GeodesicLine object should possess
, | | * specifying the capabilities the GeodesicLine object should possess
, | |
| * i.e., which quantities can be returned in calls to | | * i.e., which quantities can be returned in calls to | |
| * GeodesicLib::Position. | | * GeodesicLib::Position. | |
| * | | * | |
| * \e lat1 should be in the range [−90°, 90°]; \e lon1 an
d \e | | * \e lat1 should be in the range [−90°, 90°]; \e lon1 an
d \e | |
| * azi1 should be in the range [−540°, 540°). | | * azi1 should be in the range [−540°, 540°). | |
| | | | |
End of changes. 4 change blocks. |
| 4 lines changed or deleted | | 10 lines changed or added | |
|
| Math.hpp | | Math.hpp | |
| | | | |
| skipping to change at line 36 | | skipping to change at line 36 | |
| #endif | | #endif | |
| | | | |
| #if !defined(WORDS_BIGENDIAN) | | #if !defined(WORDS_BIGENDIAN) | |
| # define WORDS_BIGENDIAN 0 | | # define WORDS_BIGENDIAN 0 | |
| #endif | | #endif | |
| | | | |
| #if !defined(HAVE_LONG_DOUBLE) | | #if !defined(HAVE_LONG_DOUBLE) | |
| # define HAVE_LONG_DOUBLE 0 | | # define HAVE_LONG_DOUBLE 0 | |
| #endif | | #endif | |
| | | | |
|
| #if !defined(GEOGRAPHICLIB_PREC) | | #if !defined(GEOGRAPHICLIB_PRECISION) | |
| /** | | /** | |
|
| * The precision of floating point numbers used in %GeographicLib. 0 means | | * The precision of floating point numbers used in %GeographicLib. 1 means | |
| * float; 1 (default) means double; 2 means long double. Nearly all the | | * float (single precision); 2 (the default) means double; 3 means long dou | |
| * testing has been carried out with doubles and that's the recommended | | ble; | |
| * configuration. In order for long double to be used, HAVE_LONG_DOUBLE ne | | * 4 is reserved for quadruple precision. Nearly all the testing has been | |
| eds | | * carried out with doubles and that's the recommended configuration. In o | |
| * to be defined. Note that with Microsoft Visual Studio, long double is t | | rder | |
| he | | * for long double to be used, HAVE_LONG_DOUBLE needs to be defined. Note | |
| * same as double. | | that | |
| | | * with Microsoft Visual Studio, long double is the same as double. | |
| **********************************************************************/ | | **********************************************************************/ | |
|
| # define GEOGRAPHICLIB_PREC 1 | | # define GEOGRAPHICLIB_PRECISION 2 | |
| #endif | | #endif | |
| | | | |
| #include <cmath> | | #include <cmath> | |
| #include <limits> | | #include <limits> | |
| #include <algorithm> | | #include <algorithm> | |
| #include <vector> | | #include <vector> | |
| | | | |
| namespace GeographicLib { | | namespace GeographicLib { | |
| | | | |
| /** | | /** | |
| | | | |
| skipping to change at line 68 | | skipping to change at line 68 | |
| * Define mathematical functions in order to localize system dependencies
and | | * Define mathematical functions in order to localize system dependencies
and | |
| * to provide generic versions of the functions. In addition define a re
al | | * to provide generic versions of the functions. In addition define a re
al | |
| * type to be used by %GeographicLib. | | * type to be used by %GeographicLib. | |
| * | | * | |
| * Example of use: | | * Example of use: | |
| * \include example-Math.cpp | | * \include example-Math.cpp | |
| **********************************************************************/ | | **********************************************************************/ | |
| class GEOGRAPHIC_EXPORT Math { | | class GEOGRAPHIC_EXPORT Math { | |
| private: | | private: | |
| void dummy() { | | void dummy() { | |
|
| STATIC_ASSERT(GEOGRAPHICLIB_PREC >= 0 && GEOGRAPHICLIB_PREC <= 2, | | STATIC_ASSERT(GEOGRAPHICLIB_PRECISION >= 1 && | |
| | | GEOGRAPHICLIB_PRECISION <= 3, | |
| "Bad value of precision"); | | "Bad value of precision"); | |
| } | | } | |
| Math(); // Disable constructor | | Math(); // Disable constructor | |
| public: | | public: | |
| | | | |
| #if HAVE_LONG_DOUBLE | | #if HAVE_LONG_DOUBLE | |
| /** | | /** | |
| * The extended precision type for real numbers, used for some testing. | | * The extended precision type for real numbers, used for some testing. | |
| * This is long double on computers with this type; otherwise it is dou
ble. | | * This is long double on computers with this type; otherwise it is dou
ble. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| typedef long double extended; | | typedef long double extended; | |
| #else | | #else | |
| typedef double extended; | | typedef double extended; | |
| #endif | | #endif | |
| | | | |
|
| #if GEOGRAPHICLIB_PREC == 1 | | #if GEOGRAPHICLIB_PRECISION == 2 | |
| /** | | /** | |
| * The real type for %GeographicLib. Nearly all the testing has been do
ne | | * The real type for %GeographicLib. Nearly all the testing has been do
ne | |
| * with \e real = double. However, the algorithms should also work wit
h | | * with \e real = double. However, the algorithms should also work wit
h | |
| * float and long double (where available). (<b>CAUTION</b>: reasonabl
e | | * float and long double (where available). (<b>CAUTION</b>: reasonabl
e | |
| * accuracy typically cannot be obtained using floats.) | | * accuracy typically cannot be obtained using floats.) | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| typedef double real; | | typedef double real; | |
|
| #elif GEOGRAPHICLIB_PREC == 0 | | #elif GEOGRAPHICLIB_PRECISION == 1 | |
| typedef float real; | | typedef float real; | |
|
| #elif GEOGRAPHICLIB_PREC == 2 | | #elif GEOGRAPHICLIB_PRECISION == 3 | |
| typedef extended real; | | typedef extended real; | |
| #else | | #else | |
| typedef double real; | | typedef double real; | |
| #endif | | #endif | |
| | | | |
| /** | | /** | |
| * true if the machine is big-endian. | | * true if the machine is big-endian. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static const bool bigendian = WORDS_BIGENDIAN; | | static const bool bigendian = WORDS_BIGENDIAN; | |
| | | | |
| | | | |
| skipping to change at line 169 | | skipping to change at line 170 | |
| # if _MSC_VER < 1400 | | # if _MSC_VER < 1400 | |
| // Visual C++ 7.1/VS .NET 2003 does not have _hypotf() | | // Visual C++ 7.1/VS .NET 2003 does not have _hypotf() | |
| static inline float hypot(float x, float y) throw() | | static inline float hypot(float x, float y) throw() | |
| { return float(_hypot(x, y)); } | | { return float(_hypot(x, y)); } | |
| # else | | # else | |
| static inline float hypot(float x, float y) throw() | | static inline float hypot(float x, float y) throw() | |
| { return _hypotf(x, y); } | | { return _hypotf(x, y); } | |
| # endif | | # endif | |
| # if HAVE_LONG_DOUBLE | | # if HAVE_LONG_DOUBLE | |
| static inline long double hypot(long double x, long double y) throw() | | static inline long double hypot(long double x, long double y) throw() | |
|
| { return _hypot(x, y); } | | { return _hypot(double(x), double(y)); } // Suppress loss of data warni
ng | |
| # endif | | # endif | |
| #else | | #else | |
| // Use overloading to define generic versions | | // Use overloading to define generic versions | |
| static inline double hypot(double x, double y) throw() | | static inline double hypot(double x, double y) throw() | |
| { return ::hypot(x, y); } | | { return ::hypot(x, y); } | |
| static inline float hypot(float x, float y) throw() | | static inline float hypot(float x, float y) throw() | |
| { return ::hypotf(x, y); } | | { return ::hypotf(x, y); } | |
| # if HAVE_LONG_DOUBLE | | # if HAVE_LONG_DOUBLE | |
| static inline long double hypot(long double x, long double y) throw() | | static inline long double hypot(long double x, long double y) throw() | |
| { return ::hypotl(x, y); } | | { return ::hypotl(x, y); } | |
| | | | |
| skipping to change at line 339 | | skipping to change at line 340 | |
| * | | * | |
| * @tparam T the type of the argument and returned value. | | * @tparam T the type of the argument and returned value. | |
| * @param[in] x the angle in degrees. | | * @param[in] x the angle in degrees. | |
| * @return the angle reduced to the range [−180°, | | * @return the angle reduced to the range [−180°, | |
| * 180°). | | * 180°). | |
| * | | * | |
| * \e x must lie in [−540°, 540°). | | * \e x must lie in [−540°, 540°). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| template<typename T> static inline T AngNormalize(T x) throw() | | template<typename T> static inline T AngNormalize(T x) throw() | |
| { return x >= 180 ? x - 360 : (x < -180 ? x + 360 : x); } | | { return x >= 180 ? x - 360 : (x < -180 ? x + 360 : x); } | |
|
| | | | |
| /** | | /** | |
| * Normalize an arbitrary angle. | | * Normalize an arbitrary angle. | |
| * | | * | |
| * @tparam T the type of the argument and returned value. | | * @tparam T the type of the argument and returned value. | |
| * @param[in] x the angle in degrees. | | * @param[in] x the angle in degrees. | |
| * @return the angle reduced to the range [−180°, | | * @return the angle reduced to the range [−180°, | |
| * 180°). | | * 180°). | |
| * | | * | |
| * The range of \e x is unrestricted. | | * The range of \e x is unrestricted. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| | | | |
| skipping to change at line 363 | | skipping to change at line 365 | |
| * Test for finiteness. | | * Test for finiteness. | |
| * | | * | |
| * @tparam T the type of the argument. | | * @tparam T the type of the argument. | |
| * @param[in] x | | * @param[in] x | |
| * @return true if number is finite, false if NaN or infinite. | | * @return true if number is finite, false if NaN or infinite. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| template<typename T> static inline bool isfinite(T x) throw() { | | template<typename T> static inline bool isfinite(T x) throw() { | |
| #if defined(DOXYGEN) | | #if defined(DOXYGEN) | |
| return std::abs(x) <= (std::numeric_limits<T>::max)(); | | return std::abs(x) <= (std::numeric_limits<T>::max)(); | |
| #elif (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS11_MATH) | | #elif (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS11_MATH) | |
|
| return _finite(x) != 0; | | return _finite(double(x)) != 0; | |
| #else | | #else | |
| return std::isfinite(x); | | return std::isfinite(x); | |
| #endif | | #endif | |
| } | | } | |
| | | | |
| /** | | /** | |
| * The NaN (not a number) | | * The NaN (not a number) | |
| * | | * | |
| * @tparam T the type of the returned value. | | * @tparam T the type of the returned value. | |
|
| * @return NaN if available, otherwise return the max real. | | * @return NaN if available, otherwise return the max real of type T. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| template<typename T> static inline T NaN() throw() { | | template<typename T> static inline T NaN() throw() { | |
| return std::numeric_limits<T>::has_quiet_NaN ? | | return std::numeric_limits<T>::has_quiet_NaN ? | |
| std::numeric_limits<T>::quiet_NaN() : | | std::numeric_limits<T>::quiet_NaN() : | |
| (std::numeric_limits<T>::max)(); | | (std::numeric_limits<T>::max)(); | |
| } | | } | |
| /** | | /** | |
| * A synonym for NaN<real>(). | | * A synonym for NaN<real>(). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static inline real NaN() throw() { return NaN<real>(); } | | static inline real NaN() throw() { return NaN<real>(); } | |
| | | | |
End of changes. 11 change blocks. |
| 17 lines changed or deleted | | 20 lines changed or added | |
|