I was assisting a coworker deal with some noisy real-world data. Normally my first instinct is to use some averaging algorithm. Frequently I’ve used something like this to output a smoothed value of frames-per-second (FPS) for a graphics program. An averaging algorithm is a good choice since you’ve got a fairly rapid number of samples-per-second and you want to get a smoothed value that doesn’t jump around but still seems responsive. However, I now usually use a better algorithm that eliminates a lot of the issues with trying to use an averaging algorithm. Ideally you’d really want a smoothing algorithm that allows you to weigh recent values higher than older values. Keeping weights and and array of values has all sorts of startup and storage problems, but there’s a much simpler way – it’s called simple exponential smoothing and it’s incredibly simple, yet able to be tuned to the desired amount of responsiveness.
The way it works is to denote a “smoothing constant” α. This constant is a number between 0 and 1. If α is small (i.e., close to 0), more weight is given to older observations. If α is large (i.e., close to 1), more weight is given to more recent observations.
Implementations typically define a series S that represents the current smoothed value (i.e., local mean value) of the series as estimated from data up to the present. The smoothed value of St is computed recursively from its own previous value and the current measured value Xt, like this:
St = αXt + (1-α) St-1
The calculation is pretty simple. You take the previous smoothed value, St-1, the current raw value, Xt, and use the function to get the current smoothed value, St. (This is called the component form, and there are other forms that are a little more complicated. There’s also a version that lets you predict the next value rather than just smoothing the values)
If we are using it for frequently updated raw values, like this graph of FPS, we can easily tune the constant like so. I’ve let it run at 60 FPS for about half a second then the rate drops to 30 FPS for half a second before returning to 60 FPS. There’s a single frame drop to 45 FPS towards the end. We can plot the simple exponential smoothed value with various values of α, and see how the smooth curves look.
You can see that for α = 0.10, the curve shows a very gradual drop, a little too slow for the purpose we want it for. Conversely even for values of 0.75 or greater, we still get a response that’s a bit too quick to show a smoothly changing FPS value. For FPS measurements I typically use α = 0.5.
The great thing about this function is that it’s simple to implement and use and fairly easy to tune. The value of α that’s optimal for your particular need depends upon the frequency of samples, plus the responsiveness you desire. The only tricky implementation detail is the initial smoothed value, which I usually ignore by providing the “expected” value as the initial St-1 value. It quickly gets smoothed to a more valid value.