GeographicLib  2.1.1
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 
18 namespace 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 & Coefficients() const
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
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