MovingAverage#

Description#

Finite-impulse-response (FIR) filter with arbitrary user-supplied tap coefficients:

\[ y[t] = \sum_{k=0}^{L-1} \text{taps}[k] \cdot x[t - k] \]

taps[0] is the coefficient on the current sample; taps[L-1] is on the oldest. Pre-compute the coefficient vector with numpy (np.hamming(n), np.bartlett(n), np.blackman(n), np.kaiser(n, beta)) or scipy.signal.firwin and pass it in. The user is responsible for any normalisation (e.g. dividing by taps.sum() for a unity-gain low-pass smoother).

Parameters:

  • taps (sequence of float): the FIR coefficients.

Warmup: NaN for the first len(taps) - 1 samples.

Implementation Details#

Circular buffer of the last L = len(taps) samples plus an in-order convolution sweep. O(L) per step.

NaN handling#

Policy: ignore. A NaN in any input at index t causes the function to skip that step: output at t is NaN and internal state is unchanged. Subsequent finite samples are processed as if step t had not occurred.

Examples#

Usage example#

import numpy as np
from screamer import MovingAverage

# Hamming-windowed low-pass smoother (unity gain).
taps = np.hamming(11)
taps /= taps.sum()
out = MovingAverage(list(taps))(signal)

# Uniform taps -> simple rolling mean (equivalent to RollingMean).
out = MovingAverage([1/7] * 7)(signal)

Reference#

Matches numpy.convolve(x, taps, mode='full')[:len(x)] post-warmup to floating-point precision. With uniform 1/n taps it is bit-exact to RollingMean(n).