GeographicLib  1.21
EllipticFunction.hpp
Go to the documentation of this file.
00001 /**
00002  * \file EllipticFunction.hpp
00003  * \brief Header for GeographicLib::EllipticFunction class
00004  *
00005  * Copyright (c) Charles Karney (2008-2011) <charles@karney.com> and licensed
00006  * under the MIT/X11 License.  For more information, see
00007  * http://geographiclib.sourceforge.net/
00008  **********************************************************************/
00009 
00010 #if !defined(GEOGRAPHICLIB_ELLIPTICFUNCTION_HPP)
00011 #define GEOGRAPHICLIB_ELLIPTICFUNCTION_HPP \
00012   "$Id: 30ac447643e48afcaf5ab4671fbf2b235008dabe $"
00013 
00014 #include <GeographicLib/Constants.hpp>
00015 
00016 namespace GeographicLib {
00017 
00018   /**
00019    * \brief Elliptic functions needed for TransverseMercatorExact
00020    *
00021    * This provides the subset of elliptic functions needed for
00022    * TransverseMercatorExact.  For a given ellipsoid, only parameters
00023    * <i>e</i><sup>2</sup> and 1 - <i>e</i><sup>2</sup> are needed.  This class
00024    * taken the parameter as a constructor parameters and caches the values of
00025    * the required complete integrals.  A method is provided for Jacobi elliptic
00026    * functions and for the incomplete elliptic integral of the second kind in
00027    * terms of the amplitude.
00028    *
00029    * The computation of the elliptic integrals uses the algorithms given in
00030    * - B. C. Carlson,
00031    *   <a href="http://dx.doi.org/10.1007/BF02198293"> Computation of elliptic
00032    *   integrals</a>, Numerical Algorithms 10, 13&ndash;26 (1995).
00033    * .
00034    * The computation of the Jacobi elliptic functions uses the algorithm given
00035    * in
00036    * - R. Bulirsch,
00037    *   <a href="http://dx.doi.org/10.1007/BF01397975"> Numerical Calculation of
00038    *   Elliptic Integrals and Elliptic Functions</a>, Numericshe Mathematik 7,
00039    *   78&ndash;90 (1965).
00040    * .
00041    * The notation follows Abramowitz and Stegun, Chapters 16 and 17.
00042    *
00043    * Example of use:
00044    * \include example-EllipticFunction.cpp
00045    **********************************************************************/
00046   class GEOGRAPHIC_EXPORT EllipticFunction {
00047   private:
00048     typedef Math::real real;
00049     static const real tol_;
00050     static const real tolRF_;
00051     static const real tolRD_;
00052     static const real tolRG0_;
00053     static const real tolJAC_;
00054     static const real tolJAC1_;
00055     enum { num_ = 10 }; // Max depth required for sncndn.  Probably 5 is enough.
00056     static real RF(real x, real y, real z) throw();
00057     static real RD(real x, real y, real z) throw();
00058     static real RG0(real x, real y) throw();
00059     real _m, _m1;
00060     mutable bool _init;
00061     mutable real _kc, _ec, _kec;
00062     bool Init() const throw();
00063   public:
00064 
00065     /**
00066      * Constructor.
00067      *
00068      * @param[in] m the parameter which must lie in [0, 1].  (No checking
00069      *   is done.)
00070      **********************************************************************/
00071     explicit EllipticFunction(real m) throw();
00072 
00073     /**
00074      * @return the parameter \e m.
00075      **********************************************************************/
00076     Math::real m() const throw() { return _m; }
00077 
00078     /**
00079      * @return the complementary parameter \e m' = (1 - \e m).
00080      **********************************************************************/
00081     Math::real m1() const throw() { return _m1; }
00082 
00083     /**
00084      * @return the complete integral of first kind, \e K(\e m).
00085      **********************************************************************/
00086     Math::real K() const throw() { _init || Init(); return _kc; }
00087 
00088     /**
00089      * @return the complete integral of second kind, \e E(\e m).
00090      **********************************************************************/
00091     Math::real E() const throw() { _init || Init(); return _ec; }
00092 
00093     /**
00094      * @return the difference \e K(\e m) - \e E(\e m) (which can be computed
00095      *   directly).
00096      **********************************************************************/
00097     Math::real KE() const throw() { _init || Init(); return _kec; }
00098 
00099     /**
00100      * The Jacobi elliptic functions.
00101      *
00102      * @param[in] x the argument.
00103      * @param[out] sn sn(<i>x</i>|<i>m</i>).
00104      * @param[out] cn cn(<i>x</i>|<i>m</i>).
00105      * @param[out] dn dn(<i>x</i>|<i>m</i>).
00106      **********************************************************************/
00107     void sncndn(real x, real& sn, real& cn, real& dn) const throw();
00108 
00109     /**
00110      * The incomplete integral of the second kind.
00111      *
00112      * @param[in] phi
00113      * @return int sqrt(1 -  \e m sin<sup>2</sup>(\e phi)) \e dphi.
00114      **********************************************************************/
00115     Math::real E(real phi) const throw();
00116 
00117     /**
00118      * The incomplete integral of the second kind in terms of Jacobi elliptic
00119      * functions
00120      *
00121      * @param[in] sn
00122      * @param[in] cn
00123      * @param[in] dn
00124      * @return int dn(\e w)<sup>2</sup> \e dw (A+S 17.2.10).
00125      *
00126      * Instead of specifying the amplitude \e phi, we provide \e sn = sin(\e
00127      * phi), \e cn = cos(\e phi), \e dn = sqrt(1 - \e m sin<sup>2</sup>(\e
00128      * phi)).
00129      **********************************************************************/
00130     Math::real E(real sn, real cn, real dn) const throw();
00131   };
00132 
00133 
00134 } // namespace GeographicLib
00135 
00136 #endif  // GEOGRAPHICLIB_ELLIPTICFUNCTION_HPP