average/moments/mean.rs
1/// Estimate the arithmetic mean of a sequence of numbers ("population").
2///
3///
4/// ## Example
5///
6/// ```
7/// use average::Mean;
8///
9/// let a: Mean = (1..6).map(f64::from).collect();
10/// println!("The mean is {}.", a.mean());
11/// ```
12#[derive(Debug, Clone)]
13#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
14pub struct Mean {
15 /// Mean value.
16 avg: f64,
17 /// Sample size.
18 n: u64,
19}
20
21impl Mean {
22 /// Create a new mean estimator.
23 #[inline]
24 pub fn new() -> Mean {
25 Mean { avg: 0., n: 0 }
26 }
27
28 /// Increment the sample size.
29 ///
30 /// This does not update anything else.
31 #[inline]
32 fn increment(&mut self) {
33 self.n += 1;
34 }
35
36 /// Add an observation given an already calculated difference from the mean
37 /// divided by the number of samples, assuming the inner count of the sample
38 /// size was already updated.
39 ///
40 /// This is useful for avoiding unnecessary divisions in the inner loop.
41 #[inline]
42 fn add_inner(&mut self, delta_n: f64) {
43 // This algorithm introduced by Welford in 1962 trades numerical
44 // stability for a division inside the loop.
45 //
46 // See https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance.
47 self.avg += delta_n;
48 }
49
50 /// Determine whether the sample is empty.
51 #[inline]
52 pub fn is_empty(&self) -> bool {
53 self.n == 0
54 }
55
56 /// Estimate the mean of the population.
57 ///
58 /// Returns NaN for an empty sample.
59 #[inline]
60 pub fn mean(&self) -> f64 {
61 if self.n > 0 { self.avg } else { f64::NAN }
62 }
63
64 /// Return the sample size.
65 #[inline]
66 pub fn len(&self) -> u64 {
67 self.n
68 }
69
70}
71
72impl core::default::Default for Mean {
73 fn default() -> Mean {
74 Mean::new()
75 }
76}
77
78impl Estimate for Mean {
79 #[inline]
80 fn add(&mut self, sample: f64) {
81 self.increment();
82 let delta_n = (sample - self.avg)
83 / self.n.to_f64().unwrap();
84 self.add_inner(delta_n);
85 }
86
87 fn estimate(&self) -> f64 {
88 self.mean()
89 }
90}
91
92impl Merge for Mean {
93 /// Merge another sample into this one.
94 ///
95 ///
96 /// ## Example
97 ///
98 /// ```
99 /// use average::{Mean, Merge};
100 ///
101 /// let sequence: &[f64] = &[1., 2., 3., 4., 5., 6., 7., 8., 9.];
102 /// let (left, right) = sequence.split_at(3);
103 /// let avg_total: Mean = sequence.iter().collect();
104 /// let mut avg_left: Mean = left.iter().collect();
105 /// let avg_right: Mean = right.iter().collect();
106 /// avg_left.merge(&avg_right);
107 /// assert_eq!(avg_total.mean(), avg_left.mean());
108 /// ```
109 #[inline]
110 fn merge(&mut self, other: &Mean) {
111 if other.is_empty() {
112 return;
113 }
114 if self.is_empty() {
115 *self = other.clone();
116 return;
117 }
118 // This algorithm was proposed by Chan et al. in 1979.
119 //
120 // See https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance.
121 let len_self = self.n.to_f64().unwrap();
122 let len_other = other.n.to_f64().unwrap();
123 let len_total = len_self + len_other;
124 self.n += other.n;
125 self.avg = (len_self * self.avg + len_other * other.avg) / len_total;
126 // Chan et al. use
127 //
128 // self.avg += delta * len_other / len_total;
129 //
130 // instead, but this results in cancellation if the number of samples are similar.
131 }
132}
133
134impl_from_iterator!(Mean);
135impl_from_par_iterator!(Mean);
136impl_extend!(Mean);