GeographicLib  1.35
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  * http://geographiclib.sourceforge.net/
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  * \e C<sub>\e nm</sub> are replaced by \e C<sub>\e nm</sub> + \e tau
25  * C'<sub>\e nm</sub> (and similarly for \e S<sub>\e nm</sub>).
26  *
27  * Example of use:
28  * \include example-SphericalHarmonic1.cpp
29  **********************************************************************/
30 
32  public:
33  /**
34  * Supported normalizations for associate Legendre polynomials.
35  **********************************************************************/
37  /**
38  * Fully normalized associated Legendre polynomials. See
39  * SphericalHarmonic::FULL for documentation.
40  *
41  * @hideinitializer
42  **********************************************************************/
44  /**
45  * Schmidt semi-normalized associated Legendre polynomials. See
46  * SphericalHarmonic::SCHMIDT for documentation.
47  *
48  * @hideinitializer
49  **********************************************************************/
51  /// \cond SKIP
52  // These are deprecated...
53  full = FULL,
54  schmidt = SCHMIDT,
55  /// \endcond
56  };
57 
58  private:
59  typedef Math::real real;
61  real _a;
62  unsigned _norm;
63 
64  public:
65  /**
66  * Constructor with a full set of coefficients specified.
67  *
68  * @param[in] C the coefficients \e C<sub>\e nm</sub>.
69  * @param[in] S the coefficients \e S<sub>\e nm</sub>.
70  * @param[in] N the maximum degree and order of the sum
71  * @param[in] C1 the coefficients \e C'<sub>\e nm</sub>.
72  * @param[in] S1 the coefficients \e S'<sub>\e nm</sub>.
73  * @param[in] N1 the maximum degree and order of the correction
74  * coefficients \e C'<sub>\e nm</sub> and \e S'<sub>\e nm</sub>.
75  * @param[in] a the reference radius appearing in the definition of the
76  * sum.
77  * @param[in] norm the normalization for the associated Legendre
78  * polynomials, either SphericalHarmonic1::FULL (the default) or
79  * SphericalHarmonic1::SCHMIDT.
80  * @exception GeographicErr if \e N and \e N1 do not satisfy \e N &ge;
81  * \e N1 &ge; &minus;1.
82  * @exception GeographicErr if any of the vectors of coefficients is not
83  * large enough.
84  *
85  * See SphericalHarmonic for the way the coefficients should be stored.
86  *
87  * The class stores <i>pointers</i> to the first elements of \e C, \e S, \e
88  * C', and \e S'. These arrays should not be altered or destroyed during
89  * the lifetime of a SphericalHarmonic object.
90  **********************************************************************/
91  SphericalHarmonic1(const std::vector<real>& C,
92  const std::vector<real>& S,
93  int N,
94  const std::vector<real>& C1,
95  const std::vector<real>& S1,
96  int N1,
97  real a, unsigned norm = FULL)
98  : _a(a)
99  , _norm(norm) {
100  if (!(N1 <= N))
101  throw GeographicErr("N1 cannot be larger that N");
102  _c[0] = SphericalEngine::coeff(C, S, N);
103  _c[1] = SphericalEngine::coeff(C1, S1, N1);
104  }
105 
106  /**
107  * Constructor with a subset of coefficients specified.
108  *
109  * @param[in] C the coefficients \e C<sub>\e nm</sub>.
110  * @param[in] S the coefficients \e S<sub>\e nm</sub>.
111  * @param[in] N the degree used to determine the layout of \e C and \e S.
112  * @param[in] nmx the maximum degree used in the sum. The sum over \e n is
113  * from 0 thru \e nmx.
114  * @param[in] mmx the maximum order used in the sum. The sum over \e m is
115  * from 0 thru min(\e n, \e mmx).
116  * @param[in] C1 the coefficients \e C'<sub>\e nm</sub>.
117  * @param[in] S1 the coefficients \e S'<sub>\e nm</sub>.
118  * @param[in] N1 the degree used to determine the layout of \e C' and \e
119  * S'.
120  * @param[in] nmx1 the maximum degree used for \e C' and \e S'.
121  * @param[in] mmx1 the maximum order used for \e C' and \e S'.
122  * @param[in] a the reference radius appearing in the definition of the
123  * sum.
124  * @param[in] norm the normalization for the associated Legendre
125  * polynomials, either SphericalHarmonic1::FULL (the default) or
126  * SphericalHarmonic1::SCHMIDT.
127  * @exception GeographicErr if the parameters do not satisfy \e N &ge; \e
128  * nmx &ge; \e mmx &ge; &minus;1; \e N1 &ge; \e nmx1 &ge; \e mmx1 &ge;
129  * &minus;1; \e N &ge; \e N1; \e nmx &ge; \e nmx1; \e mmx &ge; \e mmx1.
130  * @exception GeographicErr if any of the vectors of coefficients is not
131  * large enough.
132  *
133  * The class stores <i>pointers</i> to the first elements of \e C, \e S, \e
134  * C', and \e S'. These arrays should not be altered or destroyed during
135  * the lifetime of a SphericalHarmonic object.
136  **********************************************************************/
137  SphericalHarmonic1(const std::vector<real>& C,
138  const std::vector<real>& S,
139  int N, int nmx, int mmx,
140  const std::vector<real>& C1,
141  const std::vector<real>& S1,
142  int N1, int nmx1, int mmx1,
143  real a, unsigned norm = FULL)
144  : _a(a)
145  , _norm(norm) {
146  if (!(nmx1 <= nmx))
147  throw GeographicErr("nmx1 cannot be larger that nmx");
148  if (!(mmx1 <= mmx))
149  throw GeographicErr("mmx1 cannot be larger that mmx");
150  _c[0] = SphericalEngine::coeff(C, S, N, nmx, mmx);
151  _c[1] = SphericalEngine::coeff(C1, S1, N1, nmx1, mmx1);
152  }
153 
154  /**
155  * A default constructor so that the object can be created when the
156  * constructor for another object is initialized. This default object can
157  * then be reset with the default copy assignment operator.
158  **********************************************************************/
160 
161  /**
162  * Compute a spherical harmonic sum with a correction term.
163  *
164  * @param[in] tau multiplier for correction coefficients \e C' and \e S'.
165  * @param[in] x cartesian coordinate.
166  * @param[in] y cartesian coordinate.
167  * @param[in] z cartesian coordinate.
168  * @return \e V the spherical harmonic sum.
169  *
170  * This routine requires constant memory and thus never throws
171  * an exception.
172  **********************************************************************/
173  Math::real operator()(real tau, real x, real y, real z) const throw() {
174  real f[] = {1, tau};
175  real v = 0;
176  real dummy;
177  switch (_norm) {
178  case FULL:
179  v = SphericalEngine::Value<false, SphericalEngine::FULL, 2>
180  (_c, f, x, y, z, _a, dummy, dummy, dummy);
181  break;
182  case SCHMIDT:
183  v = SphericalEngine::Value<false, SphericalEngine::SCHMIDT, 2>
184  (_c, f, x, y, z, _a, dummy, dummy, dummy);
185  break;
186  }
187  return v;
188  }
189 
190  /**
191  * Compute a spherical harmonic sum with a correction term and its
192  * gradient.
193  *
194  * @param[in] tau multiplier for correction coefficients \e C' and \e S'.
195  * @param[in] x cartesian coordinate.
196  * @param[in] y cartesian coordinate.
197  * @param[in] z cartesian coordinate.
198  * @param[out] gradx \e x component of the gradient
199  * @param[out] grady \e y component of the gradient
200  * @param[out] gradz \e z component of the gradient
201  * @return \e V the spherical harmonic sum.
202  *
203  * This is the same as the previous function, except that the components of
204  * the gradients of the sum in the \e x, \e y, and \e z directions are
205  * computed. This routine requires constant memory and thus never throws
206  * an exception.
207  **********************************************************************/
208  Math::real operator()(real tau, real x, real y, real z,
209  real& gradx, real& grady, real& gradz) const throw() {
210  real f[] = {1, tau};
211  real v = 0;
212  switch (_norm) {
213  case FULL:
214  v = SphericalEngine::Value<true, SphericalEngine::FULL, 2>
215  (_c, f, x, y, z, _a, gradx, grady, gradz);
216  break;
217  case SCHMIDT:
218  v = SphericalEngine::Value<true, SphericalEngine::SCHMIDT, 2>
219  (_c, f, x, y, z, _a, gradx, grady, gradz);
220  break;
221  }
222  return v;
223  }
224 
225  /**
226  * Create a CircularEngine to allow the efficient evaluation of several
227  * points on a circle of latitude at a fixed value of \e tau.
228  *
229  * @param[in] tau the multiplier for the correction coefficients.
230  * @param[in] p the radius of the circle.
231  * @param[in] z the height of the circle above the equatorial plane.
232  * @param[in] gradp if true the returned object will be able to compute the
233  * gradient of the sum.
234  * @exception std::bad_alloc if the memory for the CircularEngine can't be
235  * allocated.
236  * @return the CircularEngine object.
237  *
238  * SphericalHarmonic1::operator()() exchanges the order of the sums in the
239  * definition, i.e., &sum;<sub>n = 0..N</sub> &sum;<sub>m = 0..n</sub>
240  * becomes &sum;<sub>m = 0..N</sub> &sum;<sub>n = m..N</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  **********************************************************************/
272  const SphericalEngine::coeff& Coefficients() const throw()
273  { return _c[0]; }
274  /**
275  * @return the first SphericalEngine::coeff object.
276  **********************************************************************/
277  const SphericalEngine::coeff& Coefficients1() const throw()
278  { return _c[1]; }
279  };
280 
281 } // namespace GeographicLib
282 
283 #endif // GEOGRAPHICLIB_SPHERICALHARMONIC1_HPP
Math::real operator()(real tau, real x, real y, real z, real &gradx, real &grady, real &gradz) const
#define GEOGRAPHICLIB_EXPORT
Definition: Constants.hpp:52
GeographicLib::Math::real real
Definition: GeodSolve.cpp:40
const SphericalEngine::coeff & Coefficients1() const
CircularEngine Circle(real tau, real p, real z, bool gradp) const
Math::real operator()(real tau, real x, real y, real z) const
Package up coefficients for SphericalEngine.
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)
const SphericalEngine::coeff & Coefficients() const
Header for GeographicLib::CircularEngine class.
Spherical harmonic sums for a circle.
Exception handling for GeographicLib.
Definition: Constants.hpp:320
Header for GeographicLib::Constants class.
Spherical harmonic series with a correction to the coefficients.
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)
Header for GeographicLib::SphericalEngine class.