GeographicLib  2.6
DST.hpp
Go to the documentation of this file.
1 /**
2  * \file DST.hpp
3  * \brief Header for GeographicLib::DST class
4  *
5  * Copyright (c) Charles Karney (2022-2024) <karney@alum.mit.edu> and licensed
6  * under the MIT/X11 License. For more information, see
7  * https://geographiclib.sourceforge.io/
8  **********************************************************************/
9 
10 #if !defined(GEOGRAPHICLIB_DST_HPP)
11 #define GEOGRAPHICLIB_DST_HPP 1
12 
14 
15 #include <functional>
16 #include <memory>
17 
18 /// \cond SKIP
19 template<typename scalar_t>
20 class kissfft;
21 /// \endcond
22 
23 namespace GeographicLib {
24 
25  /**
26  * \brief Discrete sine transforms
27  *
28  * This decomposes periodic functions \f$ f(\sigma) \f$ (period \f$ 2\pi \f$)
29  * which are odd about \f$ \sigma = 0 \f$ and even about \f$ \sigma = \frac12
30  * \pi \f$ into a Fourier series
31  * \f[
32  * f(\sigma) = \sum_{l=0}^\infty F_l \sin\bigl((2l+1)\sigma\bigr).
33  * \f]
34  *
35  * The first \f$ N \f$ components of \f$ F_l \f$, for \f$0 \le l < N\f$ may
36  * be approximated by
37  * \f[
38  * F_l = \frac2N \sum_{j=1}^{N}
39  * p_j f(\sigma_j) \sin\bigl((2l+1)\sigma_j\bigr),
40  * \f]
41  * where \f$ \sigma_j = j\pi/(2N) \f$ and \f$ p_j = \frac12 \f$ for \f$ j = N
42  * \f$ and \f$ 1 \f$ otherwise. \f$ F_l \f$ is a discrete sine transform of
43  * type DST-III and may be conveniently computed using the fast Fourier
44  * transform, FFT; this is implemented with the DST::transform method.
45  *
46  * Having computed \f$ F_l \f$ based on \f$ N \f$ evaluations of \f$
47  * f(\sigma) \f$ at \f$ \sigma_j = j\pi/(2N) \f$, it is possible to
48  * refine these transform values and add another \f$ N \f$ coefficients by
49  * evaluating \f$ f(\sigma) \f$ at \f$ (j-\frac12)\pi/(2N) \f$; this is
50  * implemented with the DST::refine method.
51  *
52  * Here we compute FFTs using the kissfft package
53  * https://github.com/mborgerding/kissfft by Mark Borgerding.
54  *
55  * Example of use:
56  * \include example-DST.cpp
57  *
58  * \note The FFTW package https://www.fftw.org/ can also be used. However
59  * this is a more complicated dependency, its CMake support is broken, and it
60  * doesn't work with mpreals (GEOGRAPHICLIB_PRECISION = 5).
61  *
62  * \deprecated The functionality offered by this class is also provided by
63  * the more general class Trigfun. It is recommended to use Trigfun for
64  * new applications.
65  **********************************************************************/
66 
67  class DST {
68  private:
69  typedef Math::real real;
70  int _nN;
71  typedef kissfft<real> fft_t;
72  std::shared_ptr<fft_t> _fft;
73  // Implement DST-III (centerp = false) or DST-IV (centerp = true)
74  void fft_transform(real data[], real F[], bool centerp) const;
75  // Add another N terms to F
76  void fft_transform2(real data[], real F[]) const;
77  public:
78  /**
79  * Constructor specifying the number of points to use.
80  *
81  * @param[in] N the number of points to use.
82  **********************************************************************/
83  GEOGRAPHICLIB_EXPORT DST(int N = 0);
84 
85  /**
86  * Reset the given number of points.
87  *
88  * @param[in] N the number of points to use.
89  **********************************************************************/
90  void GEOGRAPHICLIB_EXPORT reset(int N);
91 
92  /**
93  * Return the number of points.
94  *
95  * @return the number of points to use.
96  **********************************************************************/
97  int N() const { return _nN; }
98 
99  /**
100  * Determine first \e N terms in the Fourier series
101  *
102  * @param[in] f the function used for evaluation.
103  * @param[out] F the first \e N coefficients of the Fourier series.
104  *
105  * The evaluates \f$ f(\sigma) \f$ at \f$ \sigma = (j + 1) \pi / (2 N) \f$
106  * for integer \f$ j \in [0, N) \f$. \e F should be an array of length at
107  * least \e N.
108  **********************************************************************/
109  void GEOGRAPHICLIB_EXPORT transform(std::function<real(real)> f, real F[])
110  const;
111 
112  /**
113  * Refine the Fourier series by doubling the number of points sampled
114  *
115  * @param[in] f the function used for evaluation.
116  * @param[inout] F on input the first \e N coefficents of the Fourier
117  * series; on output the refined transform based on 2\e N points, i.e.,
118  * the first 2\e N coefficents.
119  *
120  * The evaluates \f$ f(\sigma) \f$ at additional points \f$ \sigma = (j +
121  * \frac12) \pi / (2 N) \f$ for integer \f$ j \in [0, N) \f$, computes the
122  * DST-IV transform of these, and combines this with the input \e F to
123  * compute the 2\e N term DST-III discrete sine transform. This is
124  * equivalent to calling transform with twice the value of \e N but is more
125  * efficient, given that the \e N term coefficients are already known. See
126  * the example code above.
127  **********************************************************************/
128  void GEOGRAPHICLIB_EXPORT refine(std::function<real(real)> f, real F[])
129  const;
130 
131  /**
132  * Evaluate the Fourier sum given the sine and cosine of the angle
133  *
134  * @param[in] sinx sin&sigma;.
135  * @param[in] cosx cos&sigma;.
136  * @param[in] F the array of Fourier coefficients.
137  * @param[in] N the number of Fourier coefficients.
138  * @return the value of the Fourier sum.
139  **********************************************************************/
140  static real GEOGRAPHICLIB_EXPORT eval(real sinx, real cosx,
141  const real F[], int N);
142 
143  /**
144  * Evaluate the integral of Fourier sum given the sine and cosine of the
145  * angle
146  *
147  * @param[in] sinx sin&sigma;.
148  * @param[in] cosx cos&sigma;.
149  * @param[in] F the array of Fourier coefficients.
150  * @param[in] N the number of Fourier coefficients.
151  * @return the value of the integral.
152  *
153  * The constant of integration is chosen so that the integral is zero at
154  * \f$ \sigma = \frac12\pi \f$.
155  **********************************************************************/
156  static real GEOGRAPHICLIB_EXPORT integral(real sinx, real cosx,
157  const real F[], int N);
158 
159  /**
160  * Evaluate the definite integral of Fourier sum given the sines and
161  * cosines of the angles at the endpoints.
162  *
163  * @param[in] sinx sin&sigma;<sub>1</sub>.
164  * @param[in] cosx cos&sigma;<sub>1</sub>.
165  * @param[in] siny sin&sigma;<sub>2</sub>.
166  * @param[in] cosy cos&sigma;<sub>2</sub>.
167  * @param[in] F the array of Fourier coefficients.
168  * @param[in] N the number of Fourier coefficients.
169  * @return the value of the integral.
170  *
171  * The integral is evaluated between limits &sigma;<sub>1</sub> and
172  * &sigma;<sub>2</sub>.
173  **********************************************************************/
174  static real GEOGRAPHICLIB_EXPORT integral(real sinx, real cosx,
175  real siny, real cosy,
176  const real F[], int N);
177  };
178 
179 } // namespace GeographicLib
180 
181 #endif // GEOGRAPHICLIB_DST_HPP
#define GEOGRAPHICLIB_EXPORT
Definition: Constants.hpp:59
void transform(std::function< real(real)> f, real F[]) const
Definition: DST.cpp:79
DST(int N=0)
Definition: DST.cpp:19
static real eval(real sinx, real cosx, const real F[], int N)
Definition: DST.cpp:95
Namespace for GeographicLib.
Definition: Accumulator.cpp:12
GeographicLib::Math::real real
Definition: Geod3Solve.cpp:25
Header for GeographicLib::Constants class.
void refine(std::function< real(real)> f, real F[]) const
Definition: DST.cpp:87
void reset(int N)
Definition: DST.cpp:24
static real integral(real sinx, real cosx, const real F[], int N)
Definition: DST.cpp:112
Discrete sine transforms.
Definition: DST.hpp:67
int N() const
Definition: DST.hpp:97