use super::count_to_f64;
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct RunningMoments {
count: u64,
mean: f64,
m2: f64,
}
impl RunningMoments {
#[must_use]
pub const fn new() -> Self {
Self {
count: 0,
mean: 0.0,
m2: 0.0,
}
}
pub fn update(&mut self, x: f64) {
self.count += 1;
let n = count_to_f64(self.count);
let delta = x - self.mean;
self.mean += delta / n;
let delta2 = x - self.mean;
self.m2 = delta.mul_add(delta2, self.m2);
}
#[must_use]
pub const fn mean(&self) -> f64 {
self.mean
}
#[must_use]
pub fn variance(&self) -> f64 {
if self.count < 2 {
return 0.0;
}
self.m2 / count_to_f64(self.count - 1)
}
#[must_use]
pub fn std_dev(&self) -> f64 {
self.variance().sqrt()
}
#[must_use]
pub const fn count(&self) -> u64 {
self.count
}
}
impl Default for RunningMoments {
fn default() -> Self {
Self::new()
}
}