//! # [Exponential moving average](https://en.wikipedia.org/wiki/Exponential_smoothing) estimator.

use crate::{Estimator, glam::Vec3};

#[derive(Clone)]
#[repr(C, align(16))]
pub struct ExpEstimator3 {
    pub mean: Vec3,
    ///Smoothing-factor α, usually something small, like 0.01.
    pub smoothing: f32,
}

impl Default for ExpEstimator3 {
    fn default() -> Self {
        ExpEstimator3 {
            mean: Vec3::ZERO,
            smoothing: 0.03,
        }
    }
}

impl Estimator for ExpEstimator3 {
    type Val = Vec3;
    fn push(&mut self, new: Self::Val) -> Self::Val {
        let new_mean = new * self.smoothing + (1.0 - self.smoothing) * self.mean;
        self.mean = new_mean;
        new_mean
    }
}

#[derive(Clone)]
#[repr(C, align(16))]
pub struct ExpEstimatorS {
    pub mean: f32,
    ///Smoothing-factor α, usually something small, like 0.01.
    pub smoothing: f32,
}

impl Default for ExpEstimatorS {
    fn default() -> Self {
        ExpEstimatorS {
            mean: 0.0,
            smoothing: 0.03,
        }
    }
}

impl Estimator for ExpEstimatorS {
    type Val = f32;
    fn push(&mut self, new: Self::Val) -> Self::Val {
        let new_mean = new * self.smoothing + (1.0 - self.smoothing) * self.mean;
        self.mean = new_mean;
        new_mean
    }
}
