isce3 0.25.0
Loading...
Searching...
No Matches
Kernels.icc
1#include <cmath>
2#include <complex>
3#include <type_traits>
4
5#include <isce3/except/Error.h>
6#include <isce3/math/Sinc.h>
7
8namespace isce3 { namespace core {
9
10/*
11 * Bartlett
12 */
13
14// call
15template<typename T>
17{
18 double t2 = fabs(t / this->_halfwidth);
19 if (t2 > 1.0) {
20 return T(0.0);
21 }
22 return T(1.0 - t2);
23}
24
25/*
26 * Knab, sampling window from 1983 paper
27 */
28
29template<typename T>
30T _sampling_window(T t, T halfwidth, T bandwidth)
31{
32 using isce3::except::RuntimeError;
33 if (!((0.0 < bandwidth) && (bandwidth < 1.0))) {
34 throw RuntimeError(ISCE_SRCINFO(), "Require 0 < bandwidth < 1");
35 }
36 const T c = M_PI * halfwidth * (1.0 - bandwidth);
37 const T tf = t / halfwidth;
38 std::complex<T> y = sqrt((std::complex<T>) (1.0 - tf * tf));
39 T window = std::real<T>(cosh(c * y) / cosh(c));
40 if (!std::isfinite(window)) {
41 throw RuntimeError(ISCE_SRCINFO(), "Invalid window parameters.");
42 }
43 return window;
44}
45
46// call
47template<typename T>
49{
50 auto st = isce3::math::sinc<T>(t);
51 return _sampling_window(t, this->_halfwidth, this->_bandwidth) * st;
52}
53
54/*
55 * NFFT
56 */
57
58// constructor
59template<typename T>
60NFFTKernel<T>::NFFTKernel(int m, int n, int fft_size)
61 : Kernel<T>(2 * m + 1), _m(m), _n(n), _fft_size(fft_size)
62{
63 if ((m < 1) || (n < 1) || (fft_size < 1)) {
64 throw isce3::except::LengthError(ISCE_SRCINFO(),
65 "NFFT parameters must be positive.");
66 }
67 _b = M_PI * (2.0 - 1.0 * n / fft_size);
68 _scale = 1.0 / (M_PI * isce3::math::bessel_i0(_m * _b));
69}
70
71// call
72template<typename T>
74{
75 T x2 = t * t - _m * _m;
76 // x=0
77 if (std::abs(x2) < std::numeric_limits<double>::epsilon()) {
78 return _b * _scale;
79 }
80 T out = 1.0;
81 if (x2 < 0.0) {
82 T x = std::sqrt(std::abs(x2));
83 out = std::sinh(_b * x) / x;
84 } else {
85 T x = std::sqrt(x2);
86 out = std::sin(_b * x) / x;
87 }
88 return _scale * out;
89}
90
91/*
92 * Azimuth autocorrelation
93 */
94template<typename T>
96{
97 const double x = std::abs(t * 2 / this->_halfwidth);
98 if (x > 2.0) {
99 return T(0.0);
100 }
101 // Use Horner's method to save a few multiplies.
102 if (x < 1.0) {
103 return x * x * (0.75 * x - 1.5) + 1.0;
104 }
105 // else 1 <= abs(x) <= 2
106 return x * (x * (-0.25 * x + 1.5) - 3.0) + 2.0;
107}
108
109/*
110 * Tabulated kernel.
111 */
112
113// Constructor
114template<typename T>
115template<typename TI>
117 : Kernel<T>(kernel.width())
118{
119 // Need at least two points for linear interpolation.
120 if (n < 2) {
121 throw isce3::except::LengthError(ISCE_SRCINFO(),
122 "Require table size >= 2.");
123 }
124 // Need i+1 < n so linear interp doesn't run off of table.
125 _imax = n - 2;
126 // Allocate table.
127 _table.resize(n);
128 // Assume Kernel is even and fill table with f(x) for 0 <= x <= halfwidth.
129 const double dx = this->_halfwidth / (n - 1.0);
130 _1_dx = 1.0 / dx;
131 for (int i = 0; i < n; ++i) {
132 double x = i * dx;
133 _table[i] = static_cast<T>(kernel(x));
134 }
135}
136
137// call
138template<typename T>
140{
141 // Return zero outside table.
142 auto ax = std::abs(x);
143 if (ax > this->_halfwidth) {
144 return T(0);
145 }
146 // Normalize to table sample index.
147 auto axn = ax * _1_dx;
148 // Determine left side of interval.
149 int i = std::floor(axn);
150 // Make sure floating point multiply doesn't cause off-by-one.
151 i = std::min(i, _imax);
152 // Linear interpolation.
153 return _table[i] + (axn - i) * (_table[i + 1] - _table[i]);
154}
155
156template<typename T>
157template<typename Tin>
158ChebyKernel<T>::ChebyKernel(const Kernel<Tin>& kernel, int n)
159 : Kernel<T>(kernel.width())
160{
161 if (n < 1) {
162 throw isce3::except::LengthError(ISCE_SRCINFO(),
163 "Need at least one coefficient.");
164 }
165 // Fit a kernel with DCT of fn at Chebyshev zeros.
166 // Assume even function and fit on interval [0,width/2] to avoid a bunch
167 // of zero coefficients.
168 std::vector<T> q(n), fx(n);
169 _scale = 4.0 / kernel.width();
170 for (int i = 0; i < n; ++i) {
171 q[i] = M_PI * (2.0 * i + 1.0) / (2.0 * n);
172 // shift & scale [-1,1] to [0,width/2].
173 T x = (std::cos(q[i]) + 1.0) / _scale;
174 fx[i] = static_cast<T>(kernel(x));
175 }
176 // FFTW provides DCT with plan_r2r(REDFT10) but this isn't exposed in
177 // isce3::core::signal. Typically we're only fitting a few coefficients
178 // anyway so just implement O(n^2) algorithm.
179 _coeffs.resize(n);
180 for (int i = 0; i < n; ++i) {
181 _coeffs[i] = 0.0;
182 for (int j = 0; j < n; ++j) {
183 T w = std::cos(i * q[j]);
184 _coeffs[i] += w * fx[j];
185 }
186 _coeffs[i] *= 2.0 / n;
187 }
188 _coeffs[0] *= 0.5;
189}
190
191template<typename T>
193{
194 // Careful to avoid weird stuff outside [-1,1] definition.
195 const auto ax = std::abs(x);
196 if (ax > this->_halfwidth) {
197 return T(0);
198 }
199 // Map [0,L/2] to [-1,1]
200 const T q = (ax * _scale) - T(1);
201 const T twoq = T(2) * q;
202 const int n = _coeffs.size();
203 // Clenshaw algorithm for two term recurrence.
204 T bk = 0, bk1 = 0, bk2 = 0;
205 for (int i = n - 1; i > 0; --i) {
206 bk = _coeffs[i] + twoq * bk1 - bk2;
207 bk2 = bk1;
208 bk1 = bk;
209 }
210 return _coeffs[0] + q * bk1 - bk2;
211}
212
213}} // namespace isce3::core
T operator()(double x) const override
Evaluate kernel at given location in [-halfwidth, halfwidth].
Definition Kernels.icc:95
T operator()(double x) const override
Evaluate kernel at given location in [-halfwidth, halfwidth].
Definition Kernels.icc:16
T operator()(double x) const override
Evaluate kernel at given location in [-halfwidth, halfwidth].
Definition Kernels.icc:192
ChebyKernel(const Kernel< Tin > &kernel, int n)
Constructor that computes fit of another Kernel.
Definition Kernels.icc:158
Abstract base class for all kernels.
Definition Kernels.h:19
double width() const
Get width of kernel.
Definition Kernels.h:35
T operator()(double x) const override
Evaluate kernel at given location in [-halfwidth, halfwidth].
Definition Kernels.icc:48
T operator()(double x) const override
Evaluate kernel at given location in [-halfwidth, halfwidth].
Definition Kernels.icc:73
NFFTKernel(int m, int n, int fft_size)
Constructor of NFFT kernel.
Definition Kernels.icc:60
TabulatedKernel(const Kernel< Tin > &kernel, int n)
Constructor of tabulated kernel.
T operator()(double x) const override
Evaluate kernel at given location in [-halfwidth, halfwidth].
Definition Kernels.icc:139
base interpolator is an abstract base class
Definition BinarySearchFunc.cpp:5

Generated for ISCE3.0 by doxygen 1.13.2.