GeographicLib 2.1.2
CircularEngine.hpp
Go to the documentation of this file.
1/**
2 * \file CircularEngine.hpp
3 * \brief Header for GeographicLib::CircularEngine class
4 *
5 * Copyright (c) Charles Karney (2011-2015) <charles@karney.com> and licensed
6 * under the MIT/X11 License. For more information, see
7 * https://geographiclib.sourceforge.io/
8 **********************************************************************/
9
10#if !defined(GEOGRAPHICLIB_CIRCULARENGINE_HPP)
11#define GEOGRAPHICLIB_CIRCULARENGINE_HPP 1
12
13#include <vector>
16
17#if defined(_MSC_VER)
18// Squelch warnings about dll vs vector
19# pragma warning (push)
20# pragma warning (disable: 4251)
21#endif
22
23namespace GeographicLib {
24
25 /**
26 * \brief Spherical harmonic sums for a circle
27 *
28 * The class is a companion to SphericalEngine. If the results of a
29 * spherical harmonic sum are needed for several points on a circle of
30 * constant latitude \e lat and height \e h, then SphericalEngine::Circle can
31 * compute the inner sum, which is independent of longitude \e lon, and
32 * produce a CircularEngine object. CircularEngine::operator()() can
33 * then be used to perform the outer sum for particular vales of \e lon.
34 * This can lead to substantial improvements in computational speed for high
35 * degree sum (approximately by a factor of \e N / 2 where \e N is the
36 * maximum degree).
37 *
38 * CircularEngine is tightly linked to the internals of SphericalEngine. For
39 * that reason, the constructor for this class is private. Use
40 * SphericalHarmonic::Circle, SphericalHarmonic1::Circle, and
41 * SphericalHarmonic2::Circle to create instances of this class.
42 *
43 * CircularEngine stores the coefficients needed to allow the summation over
44 * order to be performed in 2 or 6 vectors of length \e M + 1 (depending on
45 * whether gradients are to be calculated). For this reason the constructor
46 * may throw a std::bad_alloc exception.
47 *
48 * Example of use:
49 * \include example-CircularEngine.cpp
50 **********************************************************************/
51
53 private:
54 typedef Math::real real;
55 enum normalization {
58 };
59 int _mM;
60 bool _gradp;
61 unsigned _norm;
62 real _a, _r, _u, _t;
63 std::vector<real> _wc, _ws, _wrc, _wrs, _wtc, _wts;
64 real _q, _uq, _uq2;
65
66 Math::real Value(bool gradp, real sl, real cl,
67 real& gradx, real& grady, real& gradz) const;
68
69 friend class SphericalEngine;
70 CircularEngine(int M, bool gradp, unsigned norm,
71 real a, real r, real u, real t)
72 : _mM(M)
73 , _gradp(gradp)
74 , _norm(norm)
75 , _a(a)
76 , _r(r)
77 , _u(u)
78 , _t(t)
79 , _wc(std::vector<real>(_mM + 1, 0))
80 , _ws(std::vector<real>(_mM + 1, 0))
81 , _wrc(std::vector<real>(_gradp ? _mM + 1 : 0, 0))
82 , _wrs(std::vector<real>(_gradp ? _mM + 1 : 0, 0))
83 , _wtc(std::vector<real>(_gradp ? _mM + 1 : 0, 0))
84 , _wts(std::vector<real>(_gradp ? _mM + 1 : 0, 0))
85 {
86 _q = _a / _r;
87 _uq = _u * _q;
88 _uq2 = Math::sq(_uq);
89 }
90
91 void SetCoeff(int m, real wc, real ws)
92 { _wc[m] = wc; _ws[m] = ws; }
93
94 void SetCoeff(int m, real wc, real ws,
95 real wrc, real wrs, real wtc, real wts) {
96 _wc[m] = wc; _ws[m] = ws;
97 if (_gradp) {
98 _wrc[m] = wrc; _wrs[m] = wrs;
99 _wtc[m] = wtc; _wts[m] = wts;
100 }
101 }
102
103 public:
104
105 /**
106 * A default constructor. CircularEngine::operator()() on the resulting
107 * object returns zero. The resulting object can be assigned to the result
108 * of SphericalHarmonic::Circle.
109 **********************************************************************/
111 : _mM(-1)
112 , _gradp(true)
113 , _u(0)
114 , _t(1)
115 {}
116
117 /**
118 * Evaluate the sum for a particular longitude given in terms of its
119 * sine and cosine.
120 *
121 * @param[in] sinlon the sine of the longitude.
122 * @param[in] coslon the cosine of the longitude.
123 * @return \e V the value of the sum.
124 *
125 * The arguments must satisfy <i>sinlon</i><sup>2</sup> +
126 * <i>coslon</i><sup>2</sup> = 1.
127 **********************************************************************/
128 Math::real operator()(real sinlon, real coslon) const {
129 real dummy;
130 return Value(false, sinlon, coslon, dummy, dummy, dummy);
131 }
132
133 /**
134 * Evaluate the sum for a particular longitude.
135 *
136 * @param[in] lon the longitude (degrees).
137 * @return \e V the value of the sum.
138 **********************************************************************/
139 Math::real operator()(real lon) const {
140 real sinlon, coslon;
141 Math::sincosd(lon, sinlon, coslon);
142 return (*this)(sinlon, coslon);
143 }
144
145 /**
146 * Evaluate the sum and its gradient for a particular longitude given in
147 * terms of its sine and cosine.
148 *
149 * @param[in] sinlon the sine of the longitude.
150 * @param[in] coslon the cosine of the longitude.
151 * @param[out] gradx \e x component of the gradient.
152 * @param[out] grady \e y component of the gradient.
153 * @param[out] gradz \e z component of the gradient.
154 * @return \e V the value of the sum.
155 *
156 * The gradients will only be computed if the CircularEngine object was
157 * created with this capability (e.g., via \e gradp = true in
158 * SphericalHarmonic::Circle). If not, \e gradx, etc., will not be
159 * touched. The arguments must satisfy <i>sinlon</i><sup>2</sup> +
160 * <i>coslon</i><sup>2</sup> = 1.
161 **********************************************************************/
162 Math::real operator()(real sinlon, real coslon,
163 real& gradx, real& grady, real& gradz) const {
164 return Value(true, sinlon, coslon, gradx, grady, gradz);
165 }
166
167 /**
168 * Evaluate the sum and its gradient for a particular longitude.
169 *
170 * @param[in] lon the longitude (degrees).
171 * @param[out] gradx \e x component of the gradient.
172 * @param[out] grady \e y component of the gradient.
173 * @param[out] gradz \e z component of the gradient.
174 * @return \e V the value of the sum.
175 *
176 * The gradients will only be computed if the CircularEngine object was
177 * created with this capability (e.g., via \e gradp = true in
178 * SphericalHarmonic::Circle). If not, \e gradx, etc., will not be
179 * touched.
180 **********************************************************************/
182 real& gradx, real& grady, real& gradz) const {
183 real sinlon, coslon;
184 Math::sincosd(lon, sinlon, coslon);
185 return (*this)(sinlon, coslon, gradx, grady, gradz);
186 }
187 };
188
189} // namespace GeographicLib
190
191#if defined(_MSC_VER)
192# pragma warning (pop)
193#endif
194
195#endif // GEOGRAPHICLIB_CIRCULARENGINE_HPP
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.
Math::real operator()(real sinlon, real coslon, real &gradx, real &grady, real &gradz) const
Math::real operator()(real lon, real &gradx, real &grady, real &gradz) const
Math::real operator()(real lon) const
Math::real operator()(real sinlon, real coslon) const
static void sincosd(T x, T &sinx, T &cosx)
Definition: Math.cpp:106
static T sq(T x)
Definition: Math.hpp:212
The evaluation engine for SphericalHarmonic.
Namespace for GeographicLib.
Definition: Accumulator.cpp:12