# [Haskell-cafe] Help to create a function to calculate a n element moving average ??

Henning Thielemann schlepptop at henning-thielemann.de
Wed Sep 29 16:10:07 EDT 2010

```S. Doaitse Swierstra schrieb:
>
> movingAverage :: Int -> [Float] -> [Float]
> movingAverage n l = runSums (sum . take n \$l) l (drop n l)
>      where n'     = fromIntegral n
>            runSums sum (h:hs) (t:ts) = sum / n' : runSums (sum-h+t) hs ts
>            runSums _   _     []      = []

Moving average can be interpreted as convolution (*):
[1/n,1/n,1/n,...,1/n] * xs

You may drop the first (n-1) values, since they average over initial

Convolution is associative and you can decompose the first operand into
simpler parts:

1/n · [1,1,1,...] * [1,0,0,....,0,0,-1] * xs
= 1/n · integrate ([1,0,0,....,0,0,-1] * xs)

Convolution is commutative, thus you could also write
= 1/n · [1,0,0,....,0,0,-1] * integrate xs
but then integration of xs will yield unbounded values and thus higher
rounding errors.

This yields:

movingAverage :: Int -> [Float] -> [Float]
movingAverage n =
drop (n-1) .
map (/ fromIntegral n) .
scanl1 (+) .
(\xs -> zipWith (-) xs (replicate n 0 ++ xs))

This should be the same as the implementation above, but maybe a bit
nicer. :-)

```