NETGeographicLib 1.52
Loading...
Searching...
No Matches
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 * https://geographiclib.sourceforge.io/
11 **********************************************************************/
12
13namespace 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) https://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 **********************************************************************/
111 FULL = GeographicLib::SphericalEngine::FULL,
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) https://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 **********************************************************************/
131 SCHMIDT = GeographicLib::SphericalEngine::SCHMIDT,
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
.NET wrapper for GeographicLib::CircularEngine.
.NET wrapper for GeographicLib::SphericalEngine::coeff.
.NET wrapper for GeographicLib::SphericalHarmonic.
double HarmonicSum(double x, double y, double z)
double HarmonicSum(double x, double y, double z, [System::Runtime::InteropServices::Out] double% gradx, [System::Runtime::InteropServices::Out] double% grady, [System::Runtime::InteropServices::Out] double% gradz)
SphericalHarmonic(array< double >^ C, array< double >^ S, int N, int nmx, int mmx, double a, Normalization norm)
CircularEngine ^ Circle(double p, double z, bool gradp)
SphericalHarmonic(array< double >^ C, array< double >^ S, int N, double a, Normalization norm)
SphericalCoefficients ^ Coefficients()