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