GeographicLib  1.50.1
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 
18 namespace 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  v = SphericalEngine::Value<false, SphericalEngine::SCHMIDT, 3>
208  (_c, f, x, y, z, _a, dummy, dummy, dummy);
209  break;
210  }
211  return v;
212  }
213 
214  /**
215  * Compute a spherical harmonic sum with two correction terms and its
216  * gradient.
217  *
218  * @param[in] tau1 multiplier for correction coefficients \e C' and \e S'.
219  * @param[in] tau2 multiplier for correction coefficients \e C'' and \e
220  * S''.
221  * @param[in] x cartesian coordinate.
222  * @param[in] y cartesian coordinate.
223  * @param[in] z cartesian coordinate.
224  * @param[out] gradx \e x component of the gradient
225  * @param[out] grady \e y component of the gradient
226  * @param[out] gradz \e z component of the gradient
227  * @return \e V the spherical harmonic sum.
228  *
229  * This is the same as the previous function, except that the components of
230  * the gradients of the sum in the \e x, \e y, and \e z directions are
231  * computed. This routine requires constant memory and thus never throws
232  * an exception.
233  **********************************************************************/
234  Math::real operator()(real tau1, real tau2, real x, real y, real z,
235  real& gradx, real& grady, real& gradz) const {
236  real f[] = {1, tau1, tau2};
237  real v = 0;
238  switch (_norm) {
239  case FULL:
240  v = SphericalEngine::Value<true, SphericalEngine::FULL, 3>
241  (_c, f, x, y, z, _a, gradx, grady, gradz);
242  break;
243  case SCHMIDT:
244  v = SphericalEngine::Value<true, SphericalEngine::SCHMIDT, 3>
245  (_c, f, x, y, z, _a, gradx, grady, gradz);
246  break;
247  }
248  return v;
249  }
250 
251  /**
252  * Create a CircularEngine to allow the efficient evaluation of several
253  * points on a circle of latitude at fixed values of \e tau1 and \e tau2.
254  *
255  * @param[in] tau1 multiplier for correction coefficients \e C' and \e S'.
256  * @param[in] tau2 multiplier for correction coefficients \e C'' and \e
257  * S''.
258  * @param[in] p the radius of the circle.
259  * @param[in] z the height of the circle above the equatorial plane.
260  * @param[in] gradp if true the returned object will be able to compute the
261  * gradient of the sum.
262  * @exception std::bad_alloc if the memory for the CircularEngine can't be
263  * allocated.
264  * @return the CircularEngine object.
265  *
266  * SphericalHarmonic2::operator()() exchanges the order of the sums in the
267  * definition, i.e., &sum;<sub><i>n</i> = 0..<i>N</i></sub>
268  * &sum;<sub><i>m</i> = 0..<i>n</i></sub> becomes &sum;<sub><i>m</i> =
269  * 0..<i>N</i></sub> &sum;<sub><i>n</i> = <i>m</i>..<i>N</i></sub>..
270  * SphericalHarmonic2::Circle performs the inner sum over degree \e n
271  * (which entails about <i>N</i><sup>2</sup> operations). Calling
272  * CircularEngine::operator()() on the returned object performs the outer
273  * sum over the order \e m (about \e N operations).
274  *
275  * See SphericalHarmonic::Circle for an example of its use.
276  **********************************************************************/
277  CircularEngine Circle(real tau1, real tau2, real p, real z, bool gradp)
278  const {
279  real f[] = {1, tau1, tau2};
280  switch (_norm) {
281  case FULL:
282  return gradp ?
283  SphericalEngine::Circle<true, SphericalEngine::FULL, 3>
284  (_c, f, p, z, _a) :
285  SphericalEngine::Circle<false, SphericalEngine::FULL, 3>
286  (_c, f, p, z, _a);
287  break;
288  case SCHMIDT:
289  default: // To avoid compiler warnings
290  return gradp ?
291  SphericalEngine::Circle<true, SphericalEngine::SCHMIDT, 3>
292  (_c, f, p, z, _a) :
293  SphericalEngine::Circle<false, SphericalEngine::SCHMIDT, 3>
294  (_c, f, p, z, _a);
295  break;
296  }
297  }
298 
299  /**
300  * @return the zeroth SphericalEngine::coeff object.
301  **********************************************************************/
303  { return _c[0]; }
304  /**
305  * @return the first SphericalEngine::coeff object.
306  **********************************************************************/
308  { return _c[1]; }
309  /**
310  * @return the second SphericalEngine::coeff object.
311  **********************************************************************/
313  { return _c[2]; }
314  };
315 
316 } // namespace GeographicLib
317 
318 #endif // GEOGRAPHICLIB_SPHERICALHARMONIC2_HPP
real
GeographicLib::Math::real real
Definition: GeodSolve.cpp:31
GeographicLib::SphericalHarmonic2::operator()
Math::real operator()(real tau1, real tau2, real x, real y, real z, real &gradx, real &grady, real &gradz) const
Definition: SphericalHarmonic2.hpp:234
GeographicLib::SphericalHarmonic2::normalization
normalization
Definition: SphericalHarmonic2.hpp:40
SphericalEngine.hpp
Header for GeographicLib::SphericalEngine class.
GeographicLib
Namespace for GeographicLib.
Definition: Accumulator.cpp:12
CircularEngine.hpp
Header for GeographicLib::CircularEngine class.
GeographicLib::SphericalEngine::SCHMIDT
Definition: SphericalEngine.hpp:84
GeographicLib::GeographicErr
Exception handling for GeographicLib.
Definition: Constants.hpp:390
GeographicLib::SphericalHarmonic2::Coefficients
const SphericalEngine::coeff & Coefficients() const
Definition: SphericalHarmonic2.hpp:302
GeographicLib::Math::real
double real
Definition: Math.hpp:121
GeographicLib::SphericalEngine::coeff
Package up coefficients for SphericalEngine.
Definition: SphericalEngine.hpp:99
GeographicLib::SphericalHarmonic2::SCHMIDT
Definition: SphericalHarmonic2.hpp:54
GeographicLib::CircularEngine
Spherical harmonic sums for a circle.
Definition: CircularEngine.hpp:52
GeographicLib::SphericalHarmonic2::Coefficients1
const SphericalEngine::coeff & Coefficients1() const
Definition: SphericalHarmonic2.hpp:307
GeographicLib::SphericalEngine::FULL
Definition: SphericalEngine.hpp:77
Constants.hpp
Header for GeographicLib::Constants class.
GeographicLib::SphericalHarmonic2::operator()
Math::real operator()(real tau1, real tau2, real x, real y, real z) const
Definition: SphericalHarmonic2.hpp:196
GeographicLib::SphericalHarmonic2::SphericalHarmonic2
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)
Definition: SphericalHarmonic2.hpp:154
GeographicLib::SphericalHarmonic2
Spherical harmonic series with two corrections to the coefficients.
Definition: SphericalHarmonic2.hpp:35
GeographicLib::SphericalHarmonic2::Coefficients2
const SphericalEngine::coeff & Coefficients2() const
Definition: SphericalHarmonic2.hpp:312
GeographicLib::SphericalHarmonic2::SphericalHarmonic2
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)
Definition: SphericalHarmonic2.hpp:97
GeographicLib::SphericalHarmonic2::Circle
CircularEngine Circle(real tau1, real tau2, real p, real z, bool gradp) const
Definition: SphericalHarmonic2.hpp:277
GeographicLib::SphericalHarmonic2::FULL
Definition: SphericalHarmonic2.hpp:47
GeographicLib::SphericalHarmonic2::SphericalHarmonic2
SphericalHarmonic2()
Definition: SphericalHarmonic2.hpp:180