use std::ops::{AddAssign, Div, Sub};
use num_traits::{One, Zero};
pub struct WelfordOnline<T> {
pub mean: T,
pub count: T,
pub sum_of_squares: T,
}
pub fn welford_online<T, I>(iter: I) -> WelfordOnline<T>
where
T: Copy + Zero + One + AddAssign + Sub<Output = T> + Div<Output = T>,
I: Iterator<Item = T>,
{
let mut sst = T::zero();
let mut mean = T::zero();
let mut counter = T::zero();
for item in iter {
counter += T::one();
let newmean = mean + (item - mean) / counter;
sst += (item - mean) * (item - newmean);
mean = newmean;
}
WelfordOnline {
mean,
count: counter,
sum_of_squares: sst,
}
}