8#include "MantidKernel/DllConfig.h"
26 virtual T
term(T
const &
x)
const = 0;
57 T
term(T
const &
x)
const override {
return x; }
63 T
term(T
const &
x)
const override {
return x *
x; }
69 T
term(T
const &
x)
const override {
return x *
x; }
77 if (
x != T(0) && !std::isnan(
x)) {
83 if (
x != T(0) && !std::isnan(
x)) {
88 T
term(T
const &
x)
const override {
return x; }
89 T
getAverage()
const override {
return std::pow(std::abs(this->total), 1. / this->npts); }
96 throw std::invalid_argument(
"Boxcar Smoothing requires at least 3 points in the moving average");
98 if (numPoints % 2 == 0) {
99 throw std::invalid_argument(
"Boxcar Smoothing requires an odd number of points in the moving average");
101 if (input.size() < numPoints) {
102 throw std::invalid_argument(
"Boxcar Smoothing requires the vector size to be greater than the smoothing window");
105 std::size_t
const vecSize = input.size();
106 std::vector<T> output(vecSize);
107 unsigned int const halfWidth = (numPoints - 1U) / 2U;
110 for (
unsigned int k = 0; k < halfWidth; k++) {
114 for (
unsigned int k = 0; k <= halfWidth; k++) {
115 unsigned int const kp = k + halfWidth;
121 for (std::size_t k = halfWidth + 1; k < vecSize - halfWidth; k++) {
122 std::size_t
const kp = k + halfWidth;
123 std::size_t
const km = k - halfWidth - 1;
131 for (std::size_t k = vecSize - halfWidth; k < vecSize; k++) {
132 std::size_t
const km = k - halfWidth;
141template <
typename T> std::vector<T>
boxcarSmooth(std::vector<T>
const &input,
unsigned int const numPoints) {
146template <
typename T> std::vector<T>
boxcarErrorSmooth(std::vector<T>
const &input,
unsigned int const numPoints) {
151template <
typename T> std::vector<T>
boxcarRMSESmooth(std::vector<T>
const &input,
unsigned int const numPoints) {
156template MANTID_KERNEL_DLL std::vector<double>
boxcarSmooth(std::vector<double>
const &,
unsigned int const);
157template MANTID_KERNEL_DLL std::vector<double>
boxcarRMSESmooth(std::vector<double>
const &,
unsigned int const);
158template MANTID_KERNEL_DLL std::vector<double>
boxcarErrorSmooth(std::vector<double>
const &,
unsigned int const);
188 : m_two_order(2U * o), m_invcutoff(1.0 / static_cast<
Y>(
n)) {}
190 return 1.0 / (1.0 + std::pow(m_invcutoff *
static_cast<Y>(
index), m_two_order));
199 std::size_t
const N = input.size();
200 std::vector<Y> output(input.cbegin(), input.cend());
205 gsl_fft_real_transform(output.data(), 1, N, real_wt.get(), real_ws.get());
210 bool const even = (N % 2 == 0);
211 std::size_t
const complex_size = (even ? N / 2 : (N - 1) / 2);
212 output[0] *= filter(0);
213 for (std::size_t fn = 1; fn < complex_size + (even ? 0UL : 1UL); fn++) {
214 output[2 * fn - 1] *= filter(fn);
215 output[2 * fn] *= filter(fn);
219 output[N - 1] *= filter(complex_size);
224 gsl_fft_halfcomplex_inverse(output.data(), 1, N, hc_wt.get(), real_ws.get());
234template <
typename Y> std::vector<Y>
fftSmooth(std::vector<Y>
const &input,
unsigned const cutoff) {
236 throw std::invalid_argument(
"The cutoff frequency must be greater than zero (" +
std::to_string(cutoff) +
" <= 0)");
237 }
else if (cutoff > input.size()) {
238 throw std::invalid_argument(
"The cutoff frequency must be less than the array size( " +
std::to_string(cutoff) +
243 return fftSmoothWithFilter(input, filter);
249 throw std::invalid_argument(
"The Butterworth cutoff frequency must be greater than zero (" +
252 if (cutoff > input.size()) {
253 throw std::invalid_argument(
"The Butterworth cutoff frequency must be less than the array size (" +
257 throw std::invalid_argument(
"The Butterworth order must be nonzero (" +
std::to_string(order) +
" <= 0)");
264template MANTID_KERNEL_DLL std::vector<double>
fftSmooth(std::vector<double>
const &,
unsigned const);
265template MANTID_KERNEL_DLL std::vector<double>
fftButterworthSmooth(std::vector<double>
const &,
unsigned const,
std::map< DeltaEMode::Type, std::string > index
std::vector< T > boxcarSmoothWithFunction(std::vector< T > const &input, unsigned int const numPoints, Averager< T > &averager)
std::vector< Y > fftSmoothWithFilter(std::vector< Y > const &input, FFTFilter< Y > const &filter)
std::vector< T > boxcarErrorSmooth(std::vector< T > const &input, unsigned int const numPoints)
Performs boxcar (moving average) smoothing on the input data, using error propagation formula.
std::vector< T > boxcarSmooth(std::vector< T > const &input, unsigned int const numPoints)
Performs boxcar (moving average) smoothing on the input data.
std::vector< Y > fftButterworthSmooth(std::vector< Y > const &input, unsigned const cutoff, unsigned const order)
Performs FFT smoothing on the input data, using a Butterworth filter NOTE: the input data MUST be def...
std::vector< T > boxcarRMSESmooth(std::vector< T > const &input, unsigned int const numPoints)
Performs boxcar (moving average) smoothing on the input data, using a RMSE average,...
std::vector< Y > fftSmooth(std::vector< Y > const &input, unsigned const cutoff)
Performs FFT smoothing on the input data, with high frequencies set to zero NOTE: the input data MUST...
real_wt_uptr make_gsl_real_wavetable(std::size_t dn)
std::unique_ptr< gsl_fft_halfcomplex_wavetable, GSLFree > hc_wt_uptr
std::unique_ptr< gsl_fft_real_workspace, GSLFree > real_ws_uptr
hc_wt_uptr make_gsl_hc_wavetable(std::size_t dn)
real_ws_uptr make_gsl_real_workspace(std::size_t dn)
std::unique_ptr< gsl_fft_real_wavetable, GSLFree > real_wt_uptr
std::string to_string(const wide_integer< Bits, Signed > &n)
Represents taking the arithmetic mean.
T getAverage() const override
Retrieve the average of all included values.
T term(T const &x) const override
A function returning a "term" in the average.
virtual T getAverage() const =0
Retrieve the average of all included values.
virtual void separate(T const &x)
Remove values from the average.
virtual T term(T const &x) const =0
A function returning a "term" in the average.
Averager()
A small ABC to represent taking an average over a few values.
virtual void accumulate(T const &x)
Include values in the average.
Represents propagating errors for values which had been arithmetically averaged.
T getAverage() const override
Retrieve the average of all included values.
T term(T const &x) const override
A function returning a "term" in the average.
Represents taking the geometric mean.
T getAverage() const override
Retrieve the average of all included values.
T term(T const &x) const override
A function returning a "term" in the average.
void separate(T const &x) override
Remove values from the average.
void accumulate(T const &x) override
Include values in the average.
Represents taking the root-mean-square averaege.
T getAverage() const override
Retrieve the average of all included values.
T term(T const &x) const override
A function returning a "term" in the average.
Y operator()(std::size_t const index) const override
ButterworthFilter(unsigned int const n, unsigned int const o)
virtual ~FFTFilter()=default
virtual Y operator()(std::size_t const index) const =0
ZeroFilter(std::size_t const n)
Y operator()(std::size_t const index) const override