## Thursday, June 25, 2015

### Cumulative moving average

We have $nA_{N} = s_{1} + \cdots + s_{n}$ and $(n + 1)A_{n + 1} = s_{1} + \cdots + s_{n + 1}$ so $s_{n + 1} = (n + 1)A_{n + 1} - nA_{n}$ from which we observe $A_{n + 1} = \frac{s_{n + 1} + nA_{n}}{n + 1} = A_{n} + \frac{s_{n + 1} + nA_{n}}{n + 1} - A_{n} = A_{n} + \frac{s_{n + 1} - A_{n}}{n + 1}$.

OCaml:

let cumulative_moving_average (l : float list) : float =
let f (s, i) x =
let k = i + 1 in
let s = (s +. (x -. s)/. (float_of_int k)) in
(s, k) in
fst @@ List.fold_left f (0., 0) l


Felix:

fun cumulative_moving_average (l : list[double]) : double = {
var f = fun (s : double, var i : int) (x : double) : double * int = {
++i;
return (s + ((x - s) / (double)i), i);
};

return (fold_left f (0.0, 0) l) .0 ;
}


C++03:

#include <numeric>
#include <utility>

namespace detail {
typedef std::pair<double, int> acc_t;
inline acc_t cumulative_moving_average (acc_t const& p, double x) {
double s = p.first;
int k = p.second + 1;
return std::make_pair (s + (x - s) / k, k);
}
}//namespace detail

template <class ItT>
double cumulative_moving_average (ItT begin, ItT end) {
return (
std::accumulate (
begin, end, std::make_pair (0.0, 0),
detail::cumulative_moving_average)
).first;
}


C++11:

template <class T>
auto cumulative_moving_average(T c) {
return accumulate (
std::begin (c), std::end (c), std::make_pair (0.0, 0),
[](auto p, auto x) {
++std::get<1> (p);
return std::make_pair (
std::get<0> (p) + (x - std::get<0> (p)) /
std::get<1> (p), std::get<1> (p));
}).first;
}

(credit : Juan Alday)