00001 /** 00002 * \file EllipticFunction.hpp 00003 * \brief Header for GeographicLib::EllipticFunction class 00004 * 00005 * Copyright (c) Charles Karney (2008) <charles@karney.com> 00006 * and licensed under the LGPL. 00007 **********************************************************************/ 00008 00009 #if !defined(ELLIPTICFUNCTION_HPP) 00010 #define ELLIPTICFUNCTION_HPP "$Id: EllipticFunction.hpp 6535 2009-02-10 22:37:07Z ckarney $" 00011 00012 00013 namespace GeographicLib { 00014 00015 /** 00016 * \brief Elliptic functions needed for TransverseMercatorExact 00017 * 00018 * This provides the subset of elliptic functions needed for 00019 * TransverseMercatorExact. For a given ellipsoid, only parameters \e 00020 * e<sup>2</sup> and 1 - \e e<sup>2</sup> are needed. This class taken the 00021 * parameter as a constructor parameters and caches the values of the 00022 * required complete integrals. A method is provided for Jacobi elliptic 00023 * functions and for the incomplete elliptic integral of the second kind in 00024 * terms of the amplitude. 00025 * 00026 * The computation of the elliptic integrals uses the algorithms given in 00027 * - B. C. Carlson, 00028 * <a href="http://dx.doi.org/10.1007/BF02198293"> Computation of elliptic 00029 * integrals</a>, Numerical Algorithms 10, 13–26 (1995). 00030 * . 00031 * The computation of the Jacobi elliptic functions uses the algorithm given 00032 * in 00033 * - R. Bulirsch, 00034 * <a href="http://dx.doi.org/10.1007/BF01397975"> Numerical Calculation of 00035 * Elliptic Integrals and Elliptic Functions</a>, Numericshe Mathematik 7, 00036 * 78–90 (1965). 00037 * . 00038 * The notation follows Abramowitz and Stegun, Chapters 16 and 17. 00039 **********************************************************************/ 00040 class EllipticFunction { 00041 private: 00042 static const double tol, tolRF, tolRD, tolRG0, tolJAC, tolJAC1; 00043 enum { num = 10 }; // Max depth required for sncndn. Probably 5 is enough. 00044 static double RF(double x, double y, double z) throw(); 00045 static double RD(double x, double y, double z) throw(); 00046 static double RG0(double x, double y) throw(); 00047 const double _m, _m1; 00048 mutable bool _init; 00049 mutable double _kc, _ec, _kec; 00050 bool Init() const throw(); 00051 public: 00052 00053 /** 00054 * Constructor with parameter \e m. 00055 **********************************************************************/ 00056 EllipticFunction(double m) throw(); 00057 00058 /** 00059 * The parameter \e m. 00060 **********************************************************************/ 00061 double m() const throw() { return _m; } 00062 00063 /** 00064 * The complementary parameter \e m' = (1 - \e m). 00065 **********************************************************************/ 00066 double m1() const throw() { return _m1; } 00067 00068 /** 00069 * The complete integral of first kind, \e K(\e m). 00070 **********************************************************************/ 00071 double K() const throw() { _init || Init(); return _kc; } 00072 00073 /** 00074 * The complete integral of second kind, \e E(\e m). 00075 **********************************************************************/ 00076 double E() const throw() { _init || Init(); return _ec; } 00077 00078 /** 00079 * The difference \e K(\e m) - \e E(\e m) (which can be computed directly). 00080 **********************************************************************/ 00081 double KE() const throw() { _init || Init(); return _kec; } 00082 00083 /** 00084 * The Jacobi elliptic functions sn(<i>x</i>|<i>m</i>), 00085 * cn(<i>x</i>|<i>m</i>), and dn(<i>x</i>|<i>m</i>) with argument \e x. 00086 * The results are returned in \e sn, \e cn, and \e dn. 00087 **********************************************************************/ 00088 void sncndn(double x, double& sn, double& cn, double& dn) const throw(); 00089 00090 /** 00091 * The incomplete integral of the second kind = int dn(\e w)<sup>2</sup> \e 00092 * dw (A+S 17.2.10). Instead of specifying the ampltiude \e phi, we 00093 * provide \e sn = sin(\e phi), \e cn = cos(\e phi), \e dn = sqrt(1 - \e m 00094 * sin<sup>2</sup>(\e phi)). 00095 **********************************************************************/ 00096 double E(double sn, double cn, double dn) const throw(); 00097 }; 00098 00099 00100 } // namespace GeographicLib 00101 00102 #endif