online_statistics/
mean.rs

1use num::{Float, FromPrimitive};
2use std::ops::{AddAssign, SubAssign};
3
4use crate::count::Count;
5use crate::stats::{Revertable, RollableUnivariate, Univariate};
6use serde::{Deserialize, Serialize};
7
8/// Running mean.
9/// # Examples
10/// ```
11/// use online_statistics::mean::Mean;
12/// use online_statistics::stats::{Univariate, Revertable};
13/// let mut running_mean: Mean<f64> = Mean::new();
14/// for i in 0..10{
15///     running_mean.update(i as f64);
16/// }
17/// assert_eq!(running_mean.get(), 4.5);
18///
19/// // You can revert the mean
20/// for i in (0..10).rev(){
21///     running_mean.revert(i as f64);
22/// }
23/// assert_eq!(running_mean.get(), 0.);
24/// ```
25/// # References
26/// [^1]: [West, D. H. D. (1979). Updating mean and variance estimates: An improved method. Communications of the ACM, 22(9), 532-535.](https://dl.acm.org/doi/10.1145/359146.359153)
27///
28/// [^2]: [Finch, T., 2009. Incremental calculation of weighted mean and variance. University of Cambridge, 4(11-5), pp.41-42.](https://fanf2.user.srcf.net/hermes/doc/antiforgery/stats.pdf)
29///
30/// [^3]: [Chan, T.F., Golub, G.H. and LeVeque, R.J., 1983. Algorithms for computing the sample variance: Analysis and recommendations. The American Statistician, 37(3), pp.242-247.](https://amstat.tandfonline.com/doi/abs/10.1080/00031305.1983.10483115)
31#[derive(Clone, Copy, Default, Debug, Serialize, Deserialize)]
32pub struct Mean<F: Float + FromPrimitive + AddAssign + SubAssign> {
33    pub mean: F,
34    pub n: Count<F>,
35}
36impl<F: Float + FromPrimitive + AddAssign + SubAssign> Mean<F> {
37    pub fn new() -> Self {
38        Self {
39            mean: F::from_f64(0.0).unwrap(),
40            n: Count::new(),
41        }
42    }
43}
44
45impl<F: Float + FromPrimitive + AddAssign + SubAssign> Univariate<F> for Mean<F> {
46    fn update(&mut self, x: F) {
47        self.n.update(x);
48        self.mean += (F::from_f64(1.).unwrap() / self.n.get()) * (x - self.mean);
49    }
50    fn get(&self) -> F {
51        self.mean
52    }
53}
54
55impl<F: Float + FromPrimitive + AddAssign + SubAssign> Revertable<F> for Mean<F> {
56    fn revert(&mut self, x: F) -> Result<(), &'static str> {
57        match self.n.revert(x) {
58            Ok(it) => it,
59            Err(err) => return Err(err),
60        };
61
62        let count = self.n.get();
63        if count == F::from_f64(0.).unwrap() {
64            self.mean = F::from_f64(0.0).unwrap();
65        } else {
66            self.mean -= (F::from_f64(1.0).unwrap() / count) * (x - self.mean);
67        }
68        Ok(())
69    }
70}
71
72impl<F: Float + FromPrimitive + AddAssign + SubAssign> RollableUnivariate<F> for Mean<F> {}