Search guides and the APICtrl K
  1. API reference
  2. DSP

statistics.h

Running mean, variance, minimum, maximum and RMS of a stream of values.

#include <sonore/statistics.h>
On this page

Design notes

Why Welford, not sums

The obvious version keeps a sum and a sum of squares and computes the variance as E[x^2] - E[x]^2 at the end. That subtraction is catastrophic cancellation: for values near 1e9 with a spread of 1, both terms are about 1e18 and their difference is below a double's resolution, so the variance comes out as zero, or negative, or noise. A DC offset with a small ripple on it -- exactly what a meter measures -- is that case.

Welford's update keeps the running mean and the sum of squared deviations FROM it, so nothing large is ever subtracted from anything large: one division per value, and the variance is as accurate as a two-pass computation over the stored data. The RMS comes out of the same two numbers (mean squared plus variance), and two accumulators merge exactly (Chan et al.), so per-block statistics can be summed into per-second ones.

float input is accumulated in double: a float running mean over a few million values drifts visibly, and the extra precision costs nothing that shows. Every member is allocation-free and noexcept -- usable on the audio thread.

Types 1

template <typename FloatType> class StatisticsAccumulator

Running statistics of the values added to it.

With no values, the mean, variance and RMS are 0, the minimum is +infinity and the maximum -infinity (which is what makes merging an empty accumulator a no-op). A NaN added poisons the mean, variance and RMS -- the honest answer to "what is the average of these" when one of them is not a number -- but is skipped by the minimum and maximum.

↑↓ to move↵ to openEvery public name in the headers, and every guide