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