GeographicLib  1.47
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  };
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  v = SphericalEngine::Value<false, SphericalEngine::SCHMIDT, 2>
181  (_c, f, x, y, z, _a, dummy, dummy, dummy);
182  break;
183  }
184  return v;
185  }
186 
187  /**
188  * Compute a spherical harmonic sum with a correction term and its
189  * gradient.
190  *
191  * @param[in] tau multiplier for correction coefficients \e C' and \e S'.
192  * @param[in] x cartesian coordinate.
193  * @param[in] y cartesian coordinate.
194  * @param[in] z cartesian coordinate.
195  * @param[out] gradx \e x component of the gradient
196  * @param[out] grady \e y component of the gradient
197  * @param[out] gradz \e z component of the gradient
198  * @return \e V the spherical harmonic sum.
199  *
200  * This is the same as the previous function, except that the components of
201  * the gradients of the sum in the \e x, \e y, and \e z directions are
202  * computed. This routine requires constant memory and thus never throws
203  * an exception.
204  **********************************************************************/
205  Math::real operator()(real tau, real x, real y, real z,
206  real& gradx, real& grady, real& gradz) const {
207  real f[] = {1, tau};
208  real v = 0;
209  switch (_norm) {
210  case FULL:
211  v = SphericalEngine::Value<true, SphericalEngine::FULL, 2>
212  (_c, f, x, y, z, _a, gradx, grady, gradz);
213  break;
214  case SCHMIDT:
215  v = SphericalEngine::Value<true, SphericalEngine::SCHMIDT, 2>
216  (_c, f, x, y, z, _a, gradx, grady, gradz);
217  break;
218  }
219  return v;
220  }
221 
222  /**
223  * Create a CircularEngine to allow the efficient evaluation of several
224  * points on a circle of latitude at a fixed value of \e tau.
225  *
226  * @param[in] tau the multiplier for the correction coefficients.
227  * @param[in] p the radius of the circle.
228  * @param[in] z the height of the circle above the equatorial plane.
229  * @param[in] gradp if true the returned object will be able to compute the
230  * gradient of the sum.
231  * @exception std::bad_alloc if the memory for the CircularEngine can't be
232  * allocated.
233  * @return the CircularEngine object.
234  *
235  * SphericalHarmonic1::operator()() exchanges the order of the sums in the
236  * definition, i.e., &sum;<sub><i>n</i> = 0..<i>N</i></sub>
237  * &sum;<sub><i>m</i> = 0..<i>n</i></sub> becomes &sum;<sub><i>m</i> =
238  * 0..<i>N</i></sub> &sum;<sub><i>n</i> = <i>m</i>..<i>N</i></sub>.
239  * SphericalHarmonic1::Circle performs the inner sum over degree \e n
240  * (which entails about <i>N</i><sup>2</sup> operations). Calling
241  * CircularEngine::operator()() on the returned object performs the outer
242  * sum over the order \e m (about \e N operations).
243  *
244  * See SphericalHarmonic::Circle for an example of its use.
245  **********************************************************************/
246  CircularEngine Circle(real tau, real p, real z, bool gradp) const {
247  real f[] = {1, tau};
248  switch (_norm) {
249  case FULL:
250  return gradp ?
251  SphericalEngine::Circle<true, SphericalEngine::FULL, 2>
252  (_c, f, p, z, _a) :
253  SphericalEngine::Circle<false, SphericalEngine::FULL, 2>
254  (_c, f, p, z, _a);
255  break;
256  case SCHMIDT:
257  default: // To avoid compiler warnings
258  return gradp ?
259  SphericalEngine::Circle<true, SphericalEngine::SCHMIDT, 2>
260  (_c, f, p, z, _a) :
261  SphericalEngine::Circle<false, SphericalEngine::SCHMIDT, 2>
262  (_c, f, p, z, _a);
263  break;
264  }
265  }
266 
267  /**
268  * @return the zeroth SphericalEngine::coeff object.
269  **********************************************************************/
271  { return _c[0]; }
272  /**
273  * @return the first SphericalEngine::coeff object.
274  **********************************************************************/
276  { return _c[1]; }
277  };
278 
279 } // namespace GeographicLib
280 
281 #endif // GEOGRAPHICLIB_SPHERICALHARMONIC1_HPP
const SphericalEngine::coeff & Coefficients1() const
#define GEOGRAPHICLIB_EXPORT
Definition: Constants.hpp:90
GeographicLib::Math::real real
Definition: GeodSolve.cpp:31
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:388
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.