isce3 0.25.0
Loading...
Searching...
No Matches
Kernels.icc
1#include <vector>
2
3#include <isce3/except/Error.h>
4#include <isce3/math/Sinc.h>
5
6namespace isce3 { namespace cuda { namespace core {
7
8namespace detail {
9
10template<typename T>
11CUDA_HOSTDEV inline T samplingWindow(T t, T halfwidth, T bandwidth)
12{
13 auto c = T(M_PI) * halfwidth * (1 - bandwidth);
14 auto tf = t / halfwidth;
15 auto y = std::sqrt(1 - tf * tf);
16 return std::cosh(c * y) / std::cosh(c);
17}
18
19} // namespace detail
20
21template<typename T, class Derived>
22CUDA_HOSTDEV T Kernel<T, Derived>::operator()(double t) const
23{
24 return static_cast<const Derived*>(this)->eval(t);
25}
26
27template<typename T>
28constexpr T BartlettKernel<T>::eval(double t) const
29{
30 double t2 = std::abs(t / Base::halfwidth());
31 return (t2 > 1.) ? T(0.) : T(1. - t2);
32}
33
34template<typename T>
35constexpr KnabKernel<T>::KnabKernel(double width, double bandwidth)
36 : Base(width), _bandwidth(bandwidth)
37{
39 throw isce3::except::RuntimeError(ISCE_SRCINFO(),
40 "Require 0 < bandwidth < 1");
41 }
42}
43
44template<typename T>
45CUDA_HOSTDEV inline T KnabKernel<T>::eval(double t) const
46{
47 using isce3::math::sinc;
48 auto x = static_cast<T>(t);
49 return sinc(x) * detail::samplingWindow(t, Base::halfwidth(), bandwidth());
50}
51
52template<typename T>
53TabulatedKernelView<T>::TabulatedKernelView(const TabulatedKernel<T>& kernel)
54 : Base(kernel.width()), _table(kernel._table.data().get()),
55 _imax(kernel._imax), _rdx(kernel._rdx)
56{}
57
58template<typename T>
59CUDA_DEV inline T TabulatedKernelView<T>::eval(double t) const
60{
61 // return zero outside table
62 auto at = std::abs(t);
63 if (at > Base::halfwidth()) {
64 return T(0.);
65 }
66
67 // normalize to table sample index
68 auto x = at * _rdx;
69
70 // determine left side of interval
71 auto i = static_cast<int>(std::floor(x));
72 i = std::min(i, _imax);
73
74 // linear interpolation
75 auto y0 = _table[i];
76 auto y1 = _table[i + 1];
77 return y0 + (x - i) * (y1 - y0);
78}
79
80template<typename T>
81template<class OtherKernel>
82TabulatedKernel<T>::TabulatedKernel(const OtherKernel& kernel, int n)
83 : Base(kernel.width())
84{
85 if (n < 2) {
86 throw isce3::except::LengthError(ISCE_SRCINFO(),
87 "Require table size >= 2");
88 }
89
90 // need i+1 < n so linear interp doesn't run off of table
91 _imax = n - 2;
92
93 // assume kernel is even and fill table with f(x) for 0 <= x <= halfwidth
94 auto dx = Base::halfwidth() / (n - 1.);
95 _rdx = 1. / dx;
96
97 std::vector<T> h_table(n);
98 for (int i = 0; i < n; ++i) {
99 double x = i * dx;
100 h_table[i] = static_cast<T>(kernel(x));
101 }
102
103 // copy table to device
104 _table = h_table;
105}
106
107template<typename T>
109 : Base(other.width()), _table(other.table())
110{
111 auto n = static_cast<int>(other.table().size());
112 _imax = n - 2;
113
114 auto dx = Base::halfwidth() / (n - 1.);
115 _rdx = 1. / dx;
116}
117
118template<typename T>
119CUDA_DEV inline T TabulatedKernel<T>::eval(double t) const
120{
121 return TabulatedKernelView<T>(*this).eval(t);
122}
123
124template<typename T>
125ChebyKernelView<T>::ChebyKernelView(const ChebyKernel<T>& kernel)
126 : Base(kernel.width()), _coeffs(kernel._coeffs.data().get()),
127 _n(static_cast<int>(kernel._coeffs.size())), _scale(kernel._scale)
128{}
129
130template<typename T>
131CUDA_DEV inline T ChebyKernelView<T>::eval(double t) const
132{
133 // careful to avoid weird stuff outside [-1, 1] definition
134 auto at = std::abs(t);
135 if (at > Base::halfwidth()) {
136 return T(0.);
137 }
138
139 // map [0, L/2] to [-1, 1]
140 auto q = (T(at) * _scale) - T(1.);
141 auto twoq = T(2.) * q;
142
143 // Clenshaw algorithm for two term recurrence
144 T bk = 0., bk1 = 0., bk2 = 0.;
145 for (int i = _n - 1; i > 0; --i) {
146 bk = _coeffs[i] + twoq * bk1 - bk2;
147 bk2 = bk1;
148 bk1 = bk;
149 }
150 return _coeffs[0] + q * bk1 - bk2;
151}
152
153template<typename T>
154template<class OtherKernel>
155ChebyKernel<T>::ChebyKernel(const OtherKernel& kernel, int n)
156 : Base(kernel.width()), _scale(4. / kernel.width())
157{
158 if (n < 2) {
159 throw isce3::except::LengthError(ISCE_SRCINFO(),
160 "Need at least one coefficient");
161 }
162
163 // Fit a kernel with DCT of fn at Chebyshev zeros.
164 // Assume evenfunction and fit on interval [0, width/2] to avoid a bunch
165 // of zero coefficients.
166 std::vector<T> q(n), fx(n);
167 for (int i = 0; i < n; ++i) {
168 q[i] = M_PI * (2. * i + 1.) / (2. * n);
169
170 // shift & scale [-1, 1] to [0, width/2]
171 auto x = (std::cos(q[i]) + 1.) / _scale;
172
173 fx[i] = static_cast<T>(kernel(x));
174 }
175
176 std::vector<T> h_coeffs(n);
177 for (int i = 0; i < n; ++i) {
178 h_coeffs[i] = 0.;
179 for (int j = 0; j < n; ++j) {
180 T w = std::cos(i * q[j]);
181 h_coeffs[i] += w * fx[j];
182 }
183 h_coeffs[i] *= 2. / n;
184 }
185 h_coeffs[0] *= 0.5;
186
187 // copy coeffs to device
188 _coeffs = h_coeffs;
189}
190
191template<typename T>
192CUDA_DEV inline T ChebyKernel<T>::eval(double t) const
193{
194 return ChebyKernelView<T>(*this).eval(t);
195}
196
197}}} // namespace isce3::cuda::core
Tabulated Kernel.
Definition Kernels.h:133
A non-owning reference to a ChebyKernel object.
Definition Kernels.h:204
ChebyKernel(const OtherKernel &kernel, int n)
Construct a new ChebyKernel object by computing a fit to another kernel.
Definition Kernels.icc:155
CUDA_HOSTDEV T operator()(double t) const
Evaluate the kernel at a given location in [-halfwidth, halfwidth].
Definition Kernels.icc:22
constexpr double width() const noexcept
Definition Kernels.h:41
constexpr double halfwidth() const noexcept
Definition Kernels.h:34
constexpr KnabKernel(double width, double bandwidth)
Construct a new KnabKernel object.
Definition Kernels.icc:35
constexpr double bandwidth() const noexcept
Get bandwidth of the kernel.
Definition Kernels.h:118
A non-owning reference to a TabulatedKernel object.
Definition Kernels.h:130
Tabulated kernel.
Definition Kernels.h:161
TabulatedKernel(const OtherKernel &kernel, int n)
Construct a new TabulatedKernel object.
Definition Kernels.icc:82
base interpolator is an abstract base class
Definition BinarySearchFunc.cpp:5

Generated for ISCE3.0 by doxygen 1.13.2.