NETGeographicLib  1.38
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Pages
SphericalHarmonic.h
Go to the documentation of this file.
1 #pragma once
2 /**
3  * \file NETGeographicLib/SphericalHarmonic.h
4  * \brief Header for NETGeographicLib::SphericalHarmonic class
5  *
6  * NETGeographicLib is copyright (c) Scott Heiman (2013)
7  * GeographicLib is Copyright (c) Charles Karney (2010-2012)
8  * <charles@karney.com> and licensed under the MIT/X11 License.
9  * For more information, see
10  * http://geographiclib.sourceforge.net/
11  **********************************************************************/
12 
13 namespace NETGeographicLib
14 {
15  ref class CircularEngine;
16  ref class SphericalCoefficients;
17  /**
18  * \brief .NET wrapper for GeographicLib::SphericalHarmonic.
19  *
20  * This class allows .NET applications to access GeographicLib::SphericalHarmonic.
21  *
22  * This class evaluates the spherical harmonic sum \verbatim
23  V(x, y, z) = sum(n = 0..N)[ q^(n+1) * sum(m = 0..n)[
24  (C[n,m] * cos(m*lambda) + S[n,m] * sin(m*lambda)) *
25  P[n,m](cos(theta)) ] ]
26  \endverbatim
27  * where
28  * - <i>p</i><sup>2</sup> = <i>x</i><sup>2</sup> + <i>y</i><sup>2</sup>,
29  * - <i>r</i><sup>2</sup> = <i>p</i><sup>2</sup> + <i>z</i><sup>2</sup>,
30  * - \e q = <i>a</i>/<i>r</i>,
31  * - &theta; = atan2(\e p, \e z) = the spherical \e colatitude,
32  * - &lambda; = atan2(\e y, \e x) = the longitude.
33  * - P<sub>\e nm</sub>(\e t) is the associated Legendre polynomial of degree
34  * \e n and order \e m.
35  *
36  * Two normalizations are supported for P<sub>\e nm</sub>
37  * - fully normalized denoted by SphericalHarmonic::FULL.
38  * - Schmidt semi-normalized denoted by SphericalHarmonic::SCHMIDT.
39  *
40  * Clenshaw summation is used for the sums over both \e n and \e m. This
41  * allows the computation to be carried out without the need for any
42  * temporary arrays. See GeographicLib::SphericalEngine.cpp for more
43  * information on the implementation.
44  *
45  * References:
46  * - C. W. Clenshaw, A note on the summation of Chebyshev series,
47  * %Math. Tables Aids Comput. 9(51), 118--120 (1955).
48  * - R. E. Deakin, Derivatives of the earth's potentials, Geomatics
49  * Research Australasia 68, 31--60, (June 1998).
50  * - W. A. Heiskanen and H. Moritz, Physical Geodesy, (Freeman, San
51  * Francisco, 1967). (See Sec. 1-14, for a definition of Pbar.)
52  * - S. A. Holmes and W. E. Featherstone, A unified approach to the Clenshaw
53  * summation and the recursive computation of very high degree and order
54  * normalised associated Legendre functions, J. Geodesy 76(5),
55  * 279--299 (2002).
56  * - C. C. Tscherning and K. Poder, Some geodetic applications of Clenshaw
57  * summation, Boll. Geod. Sci. Aff. 41(4), 349--375 (1982).
58  *
59  * C# Example:
60  * \include example-SphericalHarmonic.cs
61  * Managed C++ Example:
62  * \include example-SphericalHarmonic.cpp
63  * Visual Basic Example:
64  * \include example-SphericalHarmonic.vb
65  *
66  * <B>INTERFACE DIFFERENCES:</B><BR>
67  * This class replaces the GeographicLib::SphericalHarmonic::operator() with
68  * HarmonicSum.
69  *
70  * Coefficients returns a SphericalCoefficients object.
71  *
72  * The Normalization parameter in the constructors is passed in as an
73  * enumeration rather than an unsigned.
74  **********************************************************************/
75  public ref class SphericalHarmonic
76  {
77  private:
78  // a pointer to the unmanaged GeographicLib::SphericalHarmonic
79  const GeographicLib::SphericalHarmonic* m_pSphericalHarmonic;
80  // the finalizer frees the unmanaged memory when the object is destroyed.
82  // local containers for the cosine and sine coefficients. The
83  // GeographicLib::SphericalEngine::coeffs class uses a
84  // std::vector::iterator to access these vectors.
85  std::vector<double> *m_C, *m_S;
86  public:
87  /**
88  * Supported normalizations for the associated Legendre polynomials.
89  **********************************************************************/
90  enum class Normalization {
91  /**
92  * Fully normalized associated Legendre polynomials.
93  *
94  * These are defined by <i>P</i><sub><i>nm</i></sub><sup>full</sup>(\e z)
95  * = (&minus;1)<sup><i>m</i></sup> sqrt(\e k (2\e n + 1) (\e n &minus; \e
96  * m)! / (\e n + \e m)!)
97  * <b>P</b><sub><i>n</i></sub><sup><i>m</i></sup>(\e z), where
98  * <b>P</b><sub><i>n</i></sub><sup><i>m</i></sup>(\e z) is Ferrers
99  * function (also known as the Legendre function on the cut or the
100  * associated Legendre polynomial) http://dlmf.nist.gov/14.7.E10 and \e k
101  * = 1 for \e m = 0 and \e k = 2 otherwise.
102  *
103  * The mean squared value of
104  * <i>P</i><sub><i>nm</i></sub><sup>full</sup>(cos&theta;)
105  * cos(<i>m</i>&lambda;) and
106  * <i>P</i><sub><i>nm</i></sub><sup>full</sup>(cos&theta;)
107  * sin(<i>m</i>&lambda;) over the sphere is 1.
108  *
109  * @hideinitializer
110  **********************************************************************/
112  /**
113  * Schmidt semi-normalized associated Legendre polynomials.
114  *
115  * These are defined by <i>P</i><sub><i>nm</i></sub><sup>schmidt</sup>(\e
116  * z) = (&minus;1)<sup><i>m</i></sup> sqrt(\e k (\e n &minus; \e m)! /
117  * (\e n + \e m)!) <b>P</b><sub><i>n</i></sub><sup><i>m</i></sup>(\e z),
118  * where <b>P</b><sub><i>n</i></sub><sup><i>m</i></sup>(\e z) is Ferrers
119  * function (also known as the Legendre function on the cut or the
120  * associated Legendre polynomial) http://dlmf.nist.gov/14.7.E10 and \e k
121  * = 1 for \e m = 0 and \e k = 2 otherwise.
122  *
123  * The mean squared value of
124  * <i>P</i><sub><i>nm</i></sub><sup>schmidt</sup>(cos&theta;)
125  * cos(<i>m</i>&lambda;) and
126  * <i>P</i><sub><i>nm</i></sub><sup>schmidt</sup>(cos&theta;)
127  * sin(<i>m</i>&lambda;) over the sphere is 1/(2\e n + 1).
128  *
129  * @hideinitializer
130  **********************************************************************/
132  };
133 
134  /**
135  * Constructor with a full set of coefficients specified.
136  *
137  * @param[in] C the coefficients \e C<sub>\e nm</sub>.
138  * @param[in] S the coefficients \e S<sub>\e nm</sub>.
139  * @param[in] N the maximum degree and order of the sum
140  * @param[in] a the reference radius appearing in the definition of the
141  * sum.
142  * @param[in] norm the normalization for the associated Legendre
143  * polynomials, either SphericalHarmonic::full (the default) or
144  * SphericalHarmonic::schmidt.
145  * @exception GeographicErr if \e N does not satisfy \e N &ge; &minus;1.
146  * @exception GeographicErr if \e C or \e S is not big enough to hold the
147  * coefficients.
148  *
149  * The coefficients \e C<sub>\e nm</sub> and \e S<sub>\e nm</sub> are
150  * stored in the one-dimensional vectors \e C and \e S which must contain
151  * (\e N + 1)(\e N + 2)/2 and N (\e N + 1)/2 elements, respectively, stored
152  * in "column-major" order. Thus for \e N = 3, the order would be:
153  * <i>C</i><sub>00</sub>,
154  * <i>C</i><sub>10</sub>,
155  * <i>C</i><sub>20</sub>,
156  * <i>C</i><sub>30</sub>,
157  * <i>C</i><sub>11</sub>,
158  * <i>C</i><sub>21</sub>,
159  * <i>C</i><sub>31</sub>,
160  * <i>C</i><sub>22</sub>,
161  * <i>C</i><sub>32</sub>,
162  * <i>C</i><sub>33</sub>.
163  * In general the (\e n,\e m) element is at index \e m \e N &minus; \e m
164  * (\e m &minus; 1)/2 + \e n. The layout of \e S is the same except that
165  * the first column is omitted (since the \e m = 0 terms never contribute
166  * to the sum) and the 0th element is <i>S</i><sub>11</sub>
167  *
168  * The class stores <i>pointers</i> to the first elements of \e C and \e S.
169  * These arrays should not be altered or destroyed during the lifetime of a
170  * SphericalHarmonic object.
171  **********************************************************************/
172  SphericalHarmonic(array<double>^ C,
173  array<double>^ S,
174  int N, double a, Normalization norm );
175 
176  /**
177  * Constructor with a subset of coefficients specified.
178  *
179  * @param[in] C the coefficients \e C<sub>\e nm</sub>.
180  * @param[in] S the coefficients \e S<sub>\e nm</sub>.
181  * @param[in] N the degree used to determine the layout of \e C and \e S.
182  * @param[in] nmx the maximum degree used in the sum. The sum over \e n is
183  * from 0 thru \e nmx.
184  * @param[in] mmx the maximum order used in the sum. The sum over \e m is
185  * from 0 thru min(\e n, \e mmx).
186  * @param[in] a the reference radius appearing in the definition of the
187  * sum.
188  * @param[in] norm the normalization for the associated Legendre
189  * polynomials, either SphericalHarmonic::FULL (the default) or
190  * SphericalHarmonic::SCHMIDT.
191  * @exception GeographicErr if \e N, \e nmx, and \e mmx do not satisfy
192  * \e N &ge; \e nmx &ge; \e mmx &ge; &minus;1.
193  * @exception GeographicErr if \e C or \e S is not big enough to hold the
194  * coefficients.
195  *
196  * The class stores <i>pointers</i> to the first elements of \e C and \e S.
197  * These arrays should not be altered or destroyed during the lifetime of a
198  * SphericalHarmonic object.
199  **********************************************************************/
200  SphericalHarmonic(array<double>^ C,
201  array<double>^ S,
202  int N, int nmx, int mmx,
203  double a, Normalization norm);
204 
205  /**
206  * The destructor calls the finalizer
207  **********************************************************************/
209 
210  /**
211  * Compute the spherical harmonic sum.
212  *
213  * @param[in] x cartesian coordinate.
214  * @param[in] y cartesian coordinate.
215  * @param[in] z cartesian coordinate.
216  * @return \e V the spherical harmonic sum.
217  *
218  * This routine requires constant memory and thus never throws an
219  * exception.
220  **********************************************************************/
221  double HarmonicSum(double x, double y, double z);
222 
223  /**
224  * Compute a spherical harmonic sum and its gradient.
225  *
226  * @param[in] x cartesian coordinate.
227  * @param[in] y cartesian coordinate.
228  * @param[in] z cartesian coordinate.
229  * @param[out] gradx \e x component of the gradient
230  * @param[out] grady \e y component of the gradient
231  * @param[out] gradz \e z component of the gradient
232  * @return \e V the spherical harmonic sum.
233  *
234  * This is the same as the previous function, except that the components of
235  * the gradients of the sum in the \e x, \e y, and \e z directions are
236  * computed. This routine requires constant memory and thus never throws
237  * an exception.
238  **********************************************************************/
239  double HarmonicSum(double x, double y, double z,
240  [System::Runtime::InteropServices::Out] double% gradx,
241  [System::Runtime::InteropServices::Out] double% grady,
242  [System::Runtime::InteropServices::Out] double% gradz);
243 
244  /**
245  * Create a CircularEngine to allow the efficient evaluation of several
246  * points on a circle of latitude.
247  *
248  * @param[in] p the radius of the circle.
249  * @param[in] z the height of the circle above the equatorial plane.
250  * @param[in] gradp if true the returned object will be able to compute the
251  * gradient of the sum.
252  * @exception std::bad_alloc if the memory for the CircularEngine can't be
253  * allocated.
254  * @return the CircularEngine object.
255  *
256  * SphericalHarmonic::operator()() exchanges the order of the sums in the
257  * definition, i.e., &sum;<sub>n = 0..N</sub> &sum;<sub>m = 0..n</sub>
258  * becomes &sum;<sub>m = 0..N</sub> &sum;<sub>n = m..N</sub>.
259  * SphericalHarmonic::Circle performs the inner sum over degree \e n (which
260  * entails about <i>N</i><sup>2</sup> operations). Calling
261  * CircularEngine::operator()() on the returned object performs the outer
262  * sum over the order \e m (about \e N operations).
263  **********************************************************************/
264  CircularEngine^ Circle(double p, double z, bool gradp);
265 
266  /**
267  * @return the zeroth SphericalCoefficients object.
268  **********************************************************************/
270  };
271 } // namespace NETGeographicLib