GeographicLib 2.1.2
SphericalHarmonic2.hpp
Go to the documentation of this file.
1/**
2 * \file SphericalHarmonic2.hpp
3 * \brief Header for GeographicLib::SphericalHarmonic2 class
4 *
5 * Copyright (c) Charles Karney (2011-2012) <charles@karney.com> and licensed
6 * under the MIT/X11 License. For more information, see
7 * https://geographiclib.sourceforge.io/
8 **********************************************************************/
9
10#if !defined(GEOGRAPHICLIB_SPHERICALHARMONIC2_HPP)
11#define GEOGRAPHICLIB_SPHERICALHARMONIC2_HPP 1
12
13#include <vector>
17
18namespace GeographicLib {
19
20 /**
21 * \brief Spherical harmonic series with two corrections to the coefficients
22 *
23 * This classes is similar to SphericalHarmonic, except that the coefficients
24 * <i>C</i><sub><i>nm</i></sub> are replaced by
25 * <i>C</i><sub><i>nm</i></sub> + \e tau' <i>C'</i><sub><i>nm</i></sub> + \e
26 * tau'' <i>C''</i><sub><i>nm</i></sub> (and similarly for
27 * <i>S</i><sub><i>nm</i></sub>).
28 *
29 * Example of use:
30 * \include example-SphericalHarmonic2.cpp
31 **********************************************************************/
32
33 // Don't include the GEOGRPAHIC_EXPORT because this header-only class isn't
34 // used by any other classes in the library.
35 class /*GEOGRAPHICLIB_EXPORT*/ SphericalHarmonic2 {
36 public:
37 /**
38 * Supported normalizations for associate Legendre polynomials.
39 **********************************************************************/
41 /**
42 * Fully normalized associated Legendre polynomials. See
43 * SphericalHarmonic::FULL for documentation.
44 *
45 * @hideinitializer
46 **********************************************************************/
48 /**
49 * Schmidt semi-normalized associated Legendre polynomials. See
50 * SphericalHarmonic::SCHMIDT for documentation.
51 *
52 * @hideinitializer
53 **********************************************************************/
55 };
56
57 private:
58 typedef Math::real real;
60 real _a;
61 unsigned _norm;
62
63 public:
64 /**
65 * Constructor with a full set of coefficients specified.
66 *
67 * @param[in] C the coefficients <i>C</i><sub><i>nm</i></sub>.
68 * @param[in] S the coefficients <i>S</i><sub><i>nm</i></sub>.
69 * @param[in] N the maximum degree and order of the sum
70 * @param[in] C1 the coefficients <i>C'</i><sub><i>nm</i></sub>.
71 * @param[in] S1 the coefficients <i>S'</i><sub><i>nm</i></sub>.
72 * @param[in] N1 the maximum degree and order of the first correction
73 * coefficients <i>C'</i><sub><i>nm</i></sub> and
74 * <i>S'</i><sub><i>nm</i></sub>.
75 * @param[in] C2 the coefficients <i>C''</i><sub><i>nm</i></sub>.
76 * @param[in] S2 the coefficients <i>S''</i><sub><i>nm</i></sub>.
77 * @param[in] N2 the maximum degree and order of the second correction
78 * coefficients <i>C'</i><sub><i>nm</i></sub> and
79 * <i>S'</i><sub><i>nm</i></sub>.
80 * @param[in] a the reference radius appearing in the definition of the
81 * sum.
82 * @param[in] norm the normalization for the associated Legendre
83 * polynomials, either SphericalHarmonic2::FULL (the default) or
84 * SphericalHarmonic2::SCHMIDT.
85 * @exception GeographicErr if \e N and \e N1 do not satisfy \e N &ge;
86 * \e N1 &ge; &minus;1, and similarly for \e N2.
87 * @exception GeographicErr if any of the vectors of coefficients is not
88 * large enough.
89 *
90 * See SphericalHarmonic for the way the coefficients should be stored. \e
91 * N1 and \e N2 should satisfy \e N1 &le; \e N and \e N2 &le; \e N.
92 *
93 * The class stores <i>pointers</i> to the first elements of \e C, \e S, \e
94 * C', \e S', \e C'', and \e S''. These arrays should not be altered or
95 * destroyed during the lifetime of a SphericalHarmonic object.
96 **********************************************************************/
97 SphericalHarmonic2(const std::vector<real>& C,
98 const std::vector<real>& S,
99 int N,
100 const std::vector<real>& C1,
101 const std::vector<real>& S1,
102 int N1,
103 const std::vector<real>& C2,
104 const std::vector<real>& S2,
105 int N2,
106 real a, unsigned norm = FULL)
107 : _a(a)
108 , _norm(norm) {
109 if (!(N1 <= N && N2 <= N))
110 throw GeographicErr("N1 and N2 cannot be larger that N");
111 _c[0] = SphericalEngine::coeff(C, S, N);
112 _c[1] = SphericalEngine::coeff(C1, S1, N1);
113 _c[2] = SphericalEngine::coeff(C2, S2, N2);
114 }
115
116 /**
117 * Constructor with a subset of coefficients specified.
118 *
119 * @param[in] C the coefficients <i>C</i><sub><i>nm</i></sub>.
120 * @param[in] S the coefficients <i>S</i><sub><i>nm</i></sub>.
121 * @param[in] N the degree used to determine the layout of \e C and \e S.
122 * @param[in] nmx the maximum degree used in the sum. The sum over \e n is
123 * from 0 thru \e nmx.
124 * @param[in] mmx the maximum order used in the sum. The sum over \e m is
125 * from 0 thru min(\e n, \e mmx).
126 * @param[in] C1 the coefficients <i>C'</i><sub><i>nm</i></sub>.
127 * @param[in] S1 the coefficients <i>S'</i><sub><i>nm</i></sub>.
128 * @param[in] N1 the degree used to determine the layout of \e C' and \e
129 * S'.
130 * @param[in] nmx1 the maximum degree used for \e C' and \e S'.
131 * @param[in] mmx1 the maximum order used for \e C' and \e S'.
132 * @param[in] C2 the coefficients <i>C''</i><sub><i>nm</i></sub>.
133 * @param[in] S2 the coefficients <i>S''</i><sub><i>nm</i></sub>.
134 * @param[in] N2 the degree used to determine the layout of \e C'' and \e
135 * S''.
136 * @param[in] nmx2 the maximum degree used for \e C'' and \e S''.
137 * @param[in] mmx2 the maximum order used for \e C'' and \e S''.
138 * @param[in] a the reference radius appearing in the definition of the
139 * sum.
140 * @param[in] norm the normalization for the associated Legendre
141 * polynomials, either SphericalHarmonic2::FULL (the default) or
142 * SphericalHarmonic2::SCHMIDT.
143 * @exception GeographicErr if the parameters do not satisfy \e N &ge; \e
144 * nmx &ge; \e mmx &ge; &minus;1; \e N1 &ge; \e nmx1 &ge; \e mmx1 &ge;
145 * &minus;1; \e N &ge; \e N1; \e nmx &ge; \e nmx1; \e mmx &ge; \e mmx1;
146 * and similarly for \e N2, \e nmx2, and \e mmx2.
147 * @exception GeographicErr if any of the vectors of coefficients is not
148 * large enough.
149 *
150 * The class stores <i>pointers</i> to the first elements of \e C, \e S, \e
151 * C', \e S', \e C'', and \e S''. These arrays should not be altered or
152 * destroyed during the lifetime of a SphericalHarmonic object.
153 **********************************************************************/
154 SphericalHarmonic2(const std::vector<real>& C,
155 const std::vector<real>& S,
156 int N, int nmx, int mmx,
157 const std::vector<real>& C1,
158 const std::vector<real>& S1,
159 int N1, int nmx1, int mmx1,
160 const std::vector<real>& C2,
161 const std::vector<real>& S2,
162 int N2, int nmx2, int mmx2,
163 real a, unsigned norm = FULL)
164 : _a(a)
165 , _norm(norm) {
166 if (!(nmx1 <= nmx && nmx2 <= nmx))
167 throw GeographicErr("nmx1 and nmx2 cannot be larger that nmx");
168 if (!(mmx1 <= mmx && mmx2 <= mmx))
169 throw GeographicErr("mmx1 and mmx2 cannot be larger that mmx");
170 _c[0] = SphericalEngine::coeff(C, S, N, nmx, mmx);
171 _c[1] = SphericalEngine::coeff(C1, S1, N1, nmx1, mmx1);
172 _c[2] = SphericalEngine::coeff(C2, S2, N2, nmx2, mmx2);
173 }
174
175 /**
176 * A default constructor so that the object can be created when the
177 * constructor for another object is initialized. This default object can
178 * then be reset with the default copy assignment operator.
179 **********************************************************************/
181
182 /**
183 * Compute a spherical harmonic sum with two correction terms.
184 *
185 * @param[in] tau1 multiplier for correction coefficients \e C' and \e S'.
186 * @param[in] tau2 multiplier for correction coefficients \e C'' and \e
187 * S''.
188 * @param[in] x cartesian coordinate.
189 * @param[in] y cartesian coordinate.
190 * @param[in] z cartesian coordinate.
191 * @return \e V the spherical harmonic sum.
192 *
193 * This routine requires constant memory and thus never throws an
194 * exception.
195 **********************************************************************/
196 Math::real operator()(real tau1, real tau2, real x, real y, real z)
197 const {
198 real f[] = {1, tau1, tau2};
199 real v = 0;
200 real dummy;
201 switch (_norm) {
202 case FULL:
203 v = SphericalEngine::Value<false, SphericalEngine::FULL, 3>
204 (_c, f, x, y, z, _a, dummy, dummy, dummy);
205 break;
206 case SCHMIDT:
207 default: // To avoid compiler warnings
208 v = SphericalEngine::Value<false, SphericalEngine::SCHMIDT, 3>
209 (_c, f, x, y, z, _a, dummy, dummy, dummy);
210 break;
211 }
212 return v;
213 }
214
215 /**
216 * Compute a spherical harmonic sum with two correction terms and its
217 * gradient.
218 *
219 * @param[in] tau1 multiplier for correction coefficients \e C' and \e S'.
220 * @param[in] tau2 multiplier for correction coefficients \e C'' and \e
221 * S''.
222 * @param[in] x cartesian coordinate.
223 * @param[in] y cartesian coordinate.
224 * @param[in] z cartesian coordinate.
225 * @param[out] gradx \e x component of the gradient
226 * @param[out] grady \e y component of the gradient
227 * @param[out] gradz \e z component of the gradient
228 * @return \e V the spherical harmonic sum.
229 *
230 * This is the same as the previous function, except that the components of
231 * the gradients of the sum in the \e x, \e y, and \e z directions are
232 * computed. This routine requires constant memory and thus never throws
233 * an exception.
234 **********************************************************************/
235 Math::real operator()(real tau1, real tau2, real x, real y, real z,
236 real& gradx, real& grady, real& gradz) const {
237 real f[] = {1, tau1, tau2};
238 real v = 0;
239 switch (_norm) {
240 case FULL:
241 v = SphericalEngine::Value<true, SphericalEngine::FULL, 3>
242 (_c, f, x, y, z, _a, gradx, grady, gradz);
243 break;
244 case SCHMIDT:
245 default: // To avoid compiler warnings
246 v = SphericalEngine::Value<true, SphericalEngine::SCHMIDT, 3>
247 (_c, f, x, y, z, _a, gradx, grady, gradz);
248 break;
249 }
250 return v;
251 }
252
253 /**
254 * Create a CircularEngine to allow the efficient evaluation of several
255 * points on a circle of latitude at fixed values of \e tau1 and \e tau2.
256 *
257 * @param[in] tau1 multiplier for correction coefficients \e C' and \e S'.
258 * @param[in] tau2 multiplier for correction coefficients \e C'' and \e
259 * S''.
260 * @param[in] p the radius of the circle.
261 * @param[in] z the height of the circle above the equatorial plane.
262 * @param[in] gradp if true the returned object will be able to compute the
263 * gradient of the sum.
264 * @exception std::bad_alloc if the memory for the CircularEngine can't be
265 * allocated.
266 * @return the CircularEngine object.
267 *
268 * SphericalHarmonic2::operator()() exchanges the order of the sums in the
269 * definition, i.e., &sum;<sub><i>n</i> = 0..<i>N</i></sub>
270 * &sum;<sub><i>m</i> = 0..<i>n</i></sub> becomes &sum;<sub><i>m</i> =
271 * 0..<i>N</i></sub> &sum;<sub><i>n</i> = <i>m</i>..<i>N</i></sub>..
272 * SphericalHarmonic2::Circle performs the inner sum over degree \e n
273 * (which entails about <i>N</i><sup>2</sup> operations). Calling
274 * CircularEngine::operator()() on the returned object performs the outer
275 * sum over the order \e m (about \e N operations).
276 *
277 * See SphericalHarmonic::Circle for an example of its use.
278 **********************************************************************/
279 CircularEngine Circle(real tau1, real tau2, real p, real z, bool gradp)
280 const {
281 real f[] = {1, tau1, tau2};
282 switch (_norm) {
283 case FULL:
284 return gradp ?
285 SphericalEngine::Circle<true, SphericalEngine::FULL, 3>
286 (_c, f, p, z, _a) :
287 SphericalEngine::Circle<false, SphericalEngine::FULL, 3>
288 (_c, f, p, z, _a);
289 break;
290 case SCHMIDT:
291 default: // To avoid compiler warnings
292 return gradp ?
293 SphericalEngine::Circle<true, SphericalEngine::SCHMIDT, 3>
294 (_c, f, p, z, _a) :
295 SphericalEngine::Circle<false, SphericalEngine::SCHMIDT, 3>
296 (_c, f, p, z, _a);
297 break;
298 }
299 }
300
301 /**
302 * @return the zeroth SphericalEngine::coeff object.
303 **********************************************************************/
305 { return _c[0]; }
306 /**
307 * @return the first SphericalEngine::coeff object.
308 **********************************************************************/
310 { return _c[1]; }
311 /**
312 * @return the second SphericalEngine::coeff object.
313 **********************************************************************/
315 { return _c[2]; }
316 };
317
318} // namespace GeographicLib
319
320#endif // GEOGRAPHICLIB_SPHERICALHARMONIC2_HPP
Header for GeographicLib::CircularEngine class.
Header for GeographicLib::Constants class.
GeographicLib::Math::real real
Definition: GeodSolve.cpp:31
Header for GeographicLib::SphericalEngine class.
Spherical harmonic sums for a circle.
Exception handling for GeographicLib.
Definition: Constants.hpp:316
Package up coefficients for SphericalEngine.
Spherical harmonic series with two corrections to the coefficients.
const SphericalEngine::coeff & Coefficients2() const
SphericalHarmonic2(const std::vector< real > &C, const std::vector< real > &S, int N, int nmx, int mmx, const std::vector< real > &C1, const std::vector< real > &S1, int N1, int nmx1, int mmx1, const std::vector< real > &C2, const std::vector< real > &S2, int N2, int nmx2, int mmx2, real a, unsigned norm=FULL)
CircularEngine Circle(real tau1, real tau2, real p, real z, bool gradp) const
const SphericalEngine::coeff & Coefficients() const
SphericalHarmonic2(const std::vector< real > &C, const std::vector< real > &S, int N, const std::vector< real > &C1, const std::vector< real > &S1, int N1, const std::vector< real > &C2, const std::vector< real > &S2, int N2, real a, unsigned norm=FULL)
const SphericalEngine::coeff & Coefficients1() const
Math::real operator()(real tau1, real tau2, real x, real y, real z) const
Math::real operator()(real tau1, real tau2, real x, real y, real z, real &gradx, real &grady, real &gradz) const
Namespace for GeographicLib.
Definition: Accumulator.cpp:12