Moving Average
Overview
The moving_average is the simplest and most efficient FIR filter. It is also the most common filter in DSP primarily due to its simplicity. But while it is technically a low pass FIR filter, it performs poorly in the frequency domain with very slow roll-off and dreadful stopband attenuation. On the other hand, it performs admirably in the time domain. The moving average filter is optimal in reducing random noise while retaining a sharp step response.
Averaging N samples (the moving average window size) increases the SNR by the square root of N. For example, N=16 improves SNR by 4 (12dB). The filter delay is exactly (N−1)/2.
When data is pushed into a moving average, the element indices are shifted by one position to accommodate the incoming data. This logical shifting ensures that the newest data is stored in the first index (index 0), while the oldest data is pushed out of the buffer. The physical location of data does not actually change, only the indices.
The data type, T
, is a template parameter, allowing both floating point as well as integer computations. Integers are typically faster than floating point and are not prone to round-off errors.
moving_average
is a subclass of the moving_sum
.
Declaration
template <typename T>
struct basic_moving_average : basic_moving_sum<T>
{
using basic_moving_sum<T>::basic_moving_sum;
using value_type = T;
T operator()(T s);
T operator()() const;
};
using moving_average = basic_moving_average<float>;
Expressions
As a subclass of Moving Sum
, moving_average
inherits all the publicly accessible member functions, member variables, and types of its base class.
In addition to valid expressions for Moving Sum, moving_average
allows these expressions.
Notation
T
-
Element type, e.g.
float
. ma
-
Object of type
basic_moving_average<T>
. s
-
Object of type
ma_type::value_type
.