4 #ifndef DP3_DDECAL_KERNEL_SMOOTHER_H_
5 #define DP3_DDECAL_KERNEL_SMOOTHER_H_
28 template <
typename DataType,
typename NumType>
58 NumType kernelBandwidth, NumType bandwidthRefFrequency,
59 NumType spectralExponent,
bool kernel_truncation)
60 : _frequencies(frequencies),
61 _scratch(frequencies.size()),
62 _kernelType(kernelType),
63 _bandwidth(kernelBandwidth),
64 _bandwidthRefFrequency(bandwidthRefFrequency),
65 _spectralExponent(spectralExponent),
66 _truncate(kernel_truncation) {}
75 NumType
Kernel(NumType distance)
const {
76 NumType x = distance / _bandwidth;
77 switch (_kernelType) {
80 if (x < NumType(-1.0) || x > NumType(1.0))
85 if (x < NumType(-1.0) || x > NumType(1.0))
88 return x >= NumType(0.0) ? (NumType(1.0) - x) : (NumType(1.0) + x);
91 if (_truncate && (x < NumType(-1.0) || x > NumType(1.0)))
94 return std::exp(-x * x * NumType(9.0));
97 if (_truncate && (x < NumType(-1.0) || x > NumType(1.0))) {
100 x = NumType(1.0) - x;
101 return (NumType(3.0) / NumType(4.0)) * x * x;
114 void Smooth(DataType* data,
const NumType* weight, NumType kernelSizeFactor) {
115 size_t n = _frequencies.size();
119 const size_t lbound =
120 std::lower_bound(_frequencies.begin(), _frequencies.end(),
121 _frequencies[0] + _bandwidth * 0.5) -
122 _frequencies.begin();
123 size_t bandRight = std::min(lbound + 1u, n);
124 for (
size_t i = 0; i != n; ++i) {
127 const NumType localBandwidth =
128 _bandwidthRefFrequency == 0.0
130 : _bandwidth * _frequencies[i] / _bandwidthRefFrequency;
133 while (_frequencies[bandLeft] < _frequencies[i] - localBandwidth * 0.5)
135 while (bandRight != n &&
136 _frequencies[bandRight] < _frequencies[i] + localBandwidth * 0.5)
142 start = bandLeft > 0 ? bandLeft - 1 : 0;
143 end = bandRight < n ? bandRight + 1 : n;
147 NumType weightSum(0.0);
148 const NumType frequencyCorrection =
149 std::pow(localBandwidth / _bandwidth, _spectralExponent);
150 const NumType kernelCorrection = frequencyCorrection * kernelSizeFactor;
151 for (
size_t j = start; j != end; ++j) {
152 NumType distance = _frequencies[i] - _frequencies[j];
153 double w =
Kernel(distance * kernelCorrection) * weight[j];
157 if (weightSum == 0.0)
158 _scratch[i] = quiet_NaN(_scratch[i]);
160 _scratch[i] = sum / weightSum;
162 std::copy(_scratch.begin(), _scratch.end(), data);
166 double quiet_NaN(
double) {
return std::numeric_limits<double>::quiet_NaN(); }
168 std::complex<double> quiet_NaN(std::complex<double>) {
169 return std::complex<double>(std::numeric_limits<double>::quiet_NaN(),
170 std::numeric_limits<double>::quiet_NaN());
173 std::vector<NumType> _frequencies;
174 std::vector<DataType> _scratch;
177 NumType _bandwidthRefFrequency;
178 NumType _spectralExponent;
179 bool _truncate =
true;
Smooths a series of possibly irregularly gridded values by a given kernel.
Definition: KernelSmoother.h:29
KernelType
Definition: KernelSmoother.h:31
@ EpanechnikovKernel
Definition: KernelSmoother.h:37
@ RectangularKernel
Definition: KernelSmoother.h:32
@ TriangularKernel
Definition: KernelSmoother.h:33
@ GaussianKernel
Definition: KernelSmoother.h:35
void Smooth(DataType *data, const NumType *weight, NumType kernelSizeFactor)
Definition: KernelSmoother.h:114
KernelSmoother(const std::vector< NumType > &frequencies, KernelType kernelType, NumType kernelBandwidth, NumType bandwidthRefFrequency, NumType spectralExponent, bool kernel_truncation)
Definition: KernelSmoother.h:57
NumType Kernel(NumType distance) const
Definition: KernelSmoother.h:75
This file has generic helper routines for testing steps.
Definition: AntennaConfig.h:53