GeographicLib 2.6
Loading...
Searching...
No Matches
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
19template<typename scalar_t>
20class kissfft;
21/// \endcond
22
23namespace 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 **********************************************************************/
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
Header for GeographicLib::Constants class.
#define GEOGRAPHICLIB_EXPORT
Definition Constants.hpp:59
GeographicLib::Math::real real
void reset(int N)
Definition DST.cpp:24
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
int N() const
Definition DST.hpp:97
void refine(std::function< real(real)> f, real F[]) const
Definition DST.cpp:87
static real integral(real sinx, real cosx, const real F[], int N)
Definition DST.cpp:112
Namespace for GeographicLib.