1 /**
2  * \file NETGeographicLib/CircularEngine.h
3  * \brief Header for NETGeographicLib::CircularEngine class
4  *
5  * NETGeographicLib is copyright (c) Scott Heiman (2013)
6  * GeographicLib is Copyright (c) Charles Karney (2010-2012)
7  * <charles@karney.com> and licensed under the MIT/X11 License.
8  * For more information, see
9  * https://geographiclib.sourceforge.io/
10  **********************************************************************/
11 #pragma once
12 
13 namespace NETGeographicLib
14 {
15   /**
16    * \brief .NET wrapper for GeographicLib::CircularEngine.
17    *
18    * This class allows .NET applications to access GeographicLib::CircularEngine.
19    *
20    * The class is a companion to SphericalEngine.  If the results of a
21    * spherical harmonic sum are needed for several points on a circle of
22    * constant latitude \e lat and height \e h, then SphericalEngine::Circle can
23    * compute the inner sum, which is independent of longitude \e lon, and
24    * produce a CircularEngine object.  CircularEngine::LongitudeSum() can
25    * then be used to perform the outer sum for particular values of \e lon.
26    * This can lead to substantial improvements in computational speed for high
27    * degree sum (approximately by a factor of \e N / 2 where \e N is the
28    * maximum degree).
29    *
30    * CircularEngine is tightly linked to the internals of SphericalEngine.  For
31    * that reason, the constructor for this class is for internal use only.  Use
32    * SphericalHarmonic::Circle, SphericalHarmonic1::Circle, and
33    * SphericalHarmonic2::Circle to create instances of this class.
34    *
35    * CircularEngine stores the coefficients needed to allow the summation over
36    * order to be performed in 2 or 6 vectors of length \e M + 1 (depending on
37    * whether gradients are to be calculated).  For this reason the constructor
38    * may throw a GeographicErr exception.
39    *
40    * C# Example:
41    * \include example-CircularEngine.cs
42    * Managed C++ Example:
43    * \include example-CircularEngine.cpp
44    * Visual Basic Example:
45    * \include example-CircularEngine.vb
46    *
47    * <B>INTERFACE DIFFERENCES:</B><BR>
48    * The () operator has been replaced with with LongitudeSum.
49    *
50    * This class does not have a constructor that can be used in a .NET
51    * application.  Use SphericalHarmonic::Circle, SphericalHarmonic1::Circle or
52    * SphericalHarmonic2::Circle to create instances of this class.
53    **********************************************************************/
54     public ref class CircularEngine
55     {
56         private:
57         // pointer to the unmanaged GeographicLib::CircularEngine
58         const GeographicLib::CircularEngine* m_pCircularEngine;
59 
60         // The finalizer frees the unmanaged memory when the object is destroyed.
61         !CircularEngine();
62     public:
63         /**
64          * The constructor.
65          *
66          * This constructor should not be used in .NET applications.
67          * Use SphericalHarmonic::Circle, SphericalHarmonic1::Circle or
68          * SphericalHarmonic2::Circle to create instances of this class.
69          *
70          * @param[in] c The unmanaged CircularEngine to be copied.
71          **********************************************************************/
72         CircularEngine( const GeographicLib::CircularEngine& c );
73 
74         /**
75          * The destructor calls the finalizer
76          **********************************************************************/
~CircularEngine()77         ~CircularEngine()
78         { this->!CircularEngine(); }
79 
80         /**
81          * Evaluate the sum for a particular longitude given in terms of its
82          * cosine and sine.
83          *
84          * @param[in] coslon the cosine of the longitude.
85          * @param[in] sinlon the sine of the longitude.
86          * @return \e V the value of the sum.
87          *
88          * The arguments must satisfy <i>coslon</i><sup>2</sup> +
89          * <i>sinlon</i><sup>2</sup> = 1.
90          **********************************************************************/
91         double LongitudeSum(double coslon, double sinlon);
92 
93         /**
94          * Evaluate the sum for a particular longitude.
95          *
96          * @param[in] lon the longitude (degrees).
97          * @return \e V the value of the sum.
98          **********************************************************************/
99         double LongitudeSum(double lon);
100 
101         /**
102          * Evaluate the sum and its gradient for a particular longitude given in
103          * terms of its cosine and sine.
104          *
105          * @param[in] coslon the cosine of the longitude.
106          * @param[in] sinlon the sine of the longitude.
107          * @param[out] gradx \e x component of the gradient.
108          * @param[out] grady \e y component of the gradient.
109          * @param[out] gradz \e z component of the gradient.
110          * @return \e V the value of the sum.
111          *
112          * The gradients will only be computed if the CircularEngine object was
113          * created with this capability (e.g., via \e gradp = true in
114          * SphericalHarmonic::Circle).  If not, \e gradx, etc., will not be
115          * touched.  The arguments must satisfy <i>coslon</i><sup>2</sup> +
116          * <i>sinlon</i><sup>2</sup> = 1.
117          **********************************************************************/
118         double LongitudeSum(double coslon, double sinlon,
119                         [System::Runtime::InteropServices::Out] double% gradx,
120                         [System::Runtime::InteropServices::Out] double% grady,
121                         [System::Runtime::InteropServices::Out] double% gradz);
122 
123         /**
124          * Evaluate the sum and its gradient for a particular longitude.
125          *
126          * @param[in] lon the longitude (degrees).
127          * @param[out] gradx \e x component of the gradient.
128          * @param[out] grady \e y component of the gradient.
129          * @param[out] gradz \e z component of the gradient.
130          * @return \e V the value of the sum.
131          *
132          * The gradients will only be computed if the CircularEngine object was
133          * created with this capability (e.g., via \e gradp = true in
134          * SphericalHarmonic::Circle).  If not, \e gradx, etc., will not be
135          * touched.
136          **********************************************************************/
137         double LongitudeSum(double lon,
138                     [System::Runtime::InteropServices::Out] double% gradx,
139                     [System::Runtime::InteropServices::Out] double% grady,
140                     [System::Runtime::InteropServices::Out] double% gradz);
141     };
142 } //namespace NETGeographicLib
143