GeographicLib  1.21
Public Types | Public Member Functions
GeographicLib::SphericalHarmonic Class Reference

Spherical Harmonic series. More...

#include <GeographicLib/SphericalHarmonic.hpp>

List of all members.

Public Types

enum  normalization { FULL, SCHMIDT }

Public Member Functions

 SphericalHarmonic (const std::vector< real > &C, const std::vector< real > &S, int N, real a, unsigned norm=FULL)
 SphericalHarmonic (const std::vector< real > &C, const std::vector< real > &S, int N, int nmx, int mmx, real a, unsigned norm=FULL)
 SphericalHarmonic ()
Math::real operator() (real x, real y, real z) const throw ()
Math::real operator() (real x, real y, real z, real &gradx, real &grady, real &gradz) const throw ()
CircularEngine Circle (real p, real z, bool gradp) const
const SphericalEngine::coeffCoefficients () const throw ()

Detailed Description

Spherical Harmonic series.

This class evaluates the spherical harmonic sum

 V(x, y, z) = sum(n = 0..N)[ q^(n+1) * sum(m = 0..n)[
   (C[n,m] * cos(m*lambda) + S[n,m] * sin(m*lambda)) *
   P[n,m](cos(theta)) ] ]

where

Two normalizations are supported for Pnm

Clenshaw summation is used for the sums over both n and m. This allows the computation to be carried out without the need for any temporary arrays. See SphericalEngine.cpp for more information on the implementation.

References:

Example of use:

// Example of using the GeographicLib::SphericalHarmonic class
// $Id: b7e4a45d66787db49d40aa7bc991ab686cc32d44 $

#include <iostream>
#include <exception>
#include <vector>
#include <GeographicLib/SphericalHarmonic.hpp>

using namespace std;
using namespace GeographicLib;

int main() {
  try {
    int N = 3;                  // The maxium degree
    double ca[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; // cosine coefficients
    vector<double> C(ca, ca + (N + 1) * (N + 2) / 2);
    double sa[] = {6, 5, 4, 3, 2, 1}; // sine coefficients
    vector<double> S(sa, sa + N * (N + 1) / 2);
    double a = 1;
    SphericalHarmonic h(C, S, N, a);
    double x = 2, y = 3, z = 1;
    double v, vx, vy, vz;
    v = h(x, y, z, vx, vy, vz);
    cout << v << " " << vx << " " << vy << " " << vz << "\n";
  }
  catch (const exception& e) {
    cerr << "Caught exception: " << e.what() << "\n";
    return 1;
  }
  return 0;
}

Member Enumeration Documentation

Supported normalizations for the associated Legendre polynomials.

Enumerator:
FULL 

Fully normalized associated Legendre polynomials.

These are defined by Pnmfull(z) = (-1)m sqrt(k (2n + 1) (n - m)! / (n + m)!) Pnm(z), where Pnm(z) is Ferrers function (also known as the Legendre function on the cut or the associated Legendre polynomial) http://dlmf.nist.gov/14.7.E10 and k = 1 for m = 0 and k = 2 otherwise.

The mean squared value of Pnmfull(cos theta) cos(m lambda) and Pnmfull(cos theta) sin(m lambda) over the sphere is 1.

SCHMIDT 

Schmidt semi-normalized associated Legendre polynomials.

These are defined by Pnmschmidt(z) = (-1)m sqrt(k (n - m)! / (n + m)!) Pnm(z), where Pnm(z) is Ferrers function (also known as the Legendre function on the cut or the associated Legendre polynomial) http://dlmf.nist.gov/14.7.E10 and k = 1 for m = 0 and k = 2 otherwise.

The mean squared value of Pnmschmidt(cos theta) cos(m lambda) and Pnmschmidt(cos theta) sin(m lambda) over the sphere is 1/(2n + 1).

Definition at line 71 of file SphericalHarmonic.hpp.


Constructor & Destructor Documentation

GeographicLib::SphericalHarmonic::SphericalHarmonic ( const std::vector< real > &  C,
const std::vector< real > &  S,
int  N,
real  a,
unsigned  norm = FULL 
) [inline]

Constructor with a full set of coefficients specified.

Parameters:
[in]Cthe coefficients Cnm.
[in]Sthe coefficients Snm.
[in]Nthe maximum degree and order of the sum
[in]athe reference radius appearing in the definition of the sum.
[in]normthe normalization for the associated Legendre polynomials, either SphericalHarmonic::full (the default) or SphericalHarmonic::schmidt.

The coefficients Cnm and Snm are stored in the one-dimensional vectors C and S which must contain (N + 1)(N + 2)/2 and N (N + 1)/2 elements, respectively, stored in "column-major" order. Thus for N = 3, the order would be: C00, C10, C20, C30, C11, C21, C31, C22, C32, C33. In general the (n,m) element is at index m*N - m*(m - 1)/2 + n. The layout of S is the same except that the first column is omitted (since the m = 0 terms never contribute to the sum) and the 0th element is S11

The class stores pointers to the first elements of C and S. These arrays should not be altered or destroyed during the lifetime of a SphericalHarmonic object.

Definition at line 159 of file SphericalHarmonic.hpp.

GeographicLib::SphericalHarmonic::SphericalHarmonic ( const std::vector< real > &  C,
const std::vector< real > &  S,
int  N,
int  nmx,
int  mmx,
real  a,
unsigned  norm = FULL 
) [inline]

Constructor with a subset of coefficients specified.

Parameters:
[in]Cthe coefficients Cnm.
[in]Sthe coefficients Snm.
[in]Nthe degree used to determine the layout of C and S.
[in]nmxthe maximum degree used in the sum. The sum over n is from 0 thru nmx.
[in]mmxthe maximum order used in the sum. The sum over m is from 0 thru min(n, mmx).
[in]athe reference radius appearing in the definition of the sum.
[in]normthe normalization for the associated Legendre polynomials, either SphericalHarmonic::FULL (the default) or SphericalHarmonic::SCHMIDT.

The class stores pointers to the first elements of C and S. These arrays should not be altered or destroyed during the lifetime of a SphericalHarmonic object.

Definition at line 186 of file SphericalHarmonic.hpp.

GeographicLib::SphericalHarmonic::SphericalHarmonic ( ) [inline]

A default constructor so that the object can be created when the constructor for another object is initialized. This default object can then be reset with the default copy assignment operator.

Definition at line 199 of file SphericalHarmonic.hpp.


Member Function Documentation

Math::real GeographicLib::SphericalHarmonic::operator() ( real  x,
real  y,
real  z 
) const throw () [inline]

Compute the spherical harmonic sum.

Parameters:
[in]xcartesian coordinate.
[in]ycartesian coordinate.
[in]zcartesian coordinate.
Returns:
V the spherical harmonic sum.

This routine requires constant memory and thus never throws an exception.

Definition at line 212 of file SphericalHarmonic.hpp.

Math::real GeographicLib::SphericalHarmonic::operator() ( real  x,
real  y,
real  z,
real &  gradx,
real &  grady,
real &  gradz 
) const throw () [inline]

Compute a spherical harmonic sum and its gradient.

Parameters:
[in]xcartesian coordinate.
[in]ycartesian coordinate.
[in]zcartesian coordinate.
[out]gradxx component of the gradient
[out]gradyy component of the gradient
[out]gradzz component of the gradient
Returns:
V the spherical harmonic sum.

This is the same as the previous function, except that the components of the gradients of the sum in the x, y, and z directions are computed. This routine requires constant memory and thus never throws an exception.

Definition at line 245 of file SphericalHarmonic.hpp.

CircularEngine GeographicLib::SphericalHarmonic::Circle ( real  p,
real  z,
bool  gradp 
) const [inline]

Create a CircularEngine to allow the efficient evaluation of several points on a circle of latitude.

Parameters:
[in]pthe radius of the circle.
[in]zthe height of the circle above the equatorial plane.
[in]gradpif true the returned object will be able to compute the gradient of the sum.
Returns:
the CircularEngine object.

SphericalHarmonic::operator()() exchanges the order of the sums in the definition, i.e., sum(n = 0..N)[sum(m = 0..n)[...]] becomes sum(m = 0..N)[sum(n = m..N)[...]]. SphericalHarmonic::Circle performs the inner sum over degree n (which entails about N2 operations). Calling CircularEngine::operator()() on the returned object performs the outer sum over the order m (about N operations). This routine may throw a bad_alloc exception in the CircularEngine constructor.

Here's an example of computing the spherical sum at a sequence of longitudes without using a CircularEngine object

  SphericalHarmonic h(...);     // Create the SphericalHarmonic object
  double r = 2, lat = 33, lon0 = 44, dlon = 0.01;
  double
    phi = lat * Math::degree<double>(),
    z = r * sin(phi), p = r * cos(phi);
  for (int i = 0; i <= 100; ++i) {
    real
      lon = lon0 + i * dlon,
      lam = lon * Math::degree<double>();
    std::cout << lon << " " << h(p * cos(lam), p * sin(lam), z) << "\n";
  }

Here is the same calculation done using a CircularEngine object. This will be about N/2 times faster.

  SphericalHarmonic h(...);     // Create the SphericalHarmonic object
  double r = 2, lat = 33, lon0 = 44, dlon = 0.01;
  double
    phi = lat * Math::degree<double>(),
    z = r * sin(phi), p = r * cos(phi);
  CircularEngine c(h(p, z, false)); // Create the CircularEngine object
  for (int i = 0; i <= 100; ++i) {
    real
      lon = lon0 + i * dlon;
    std::cout << lon << " " << c(lon) << "\n";
  }

Definition at line 312 of file SphericalHarmonic.hpp.

Referenced by GeographicLib::GravityModel::Circle().

const SphericalEngine::coeff& GeographicLib::SphericalHarmonic::Coefficients ( ) const throw () [inline]
Returns:
the zeroth SphericalEngine::coeff object.

Definition at line 336 of file SphericalHarmonic.hpp.

Referenced by GeographicLib::GravityModel::GravityModel().


The documentation for this class was generated from the following file: