1use crate::error::{Result, StatsError};
2
3#[derive(Default)]
4pub struct Stats {
5 n_int: u32, n: f64,
7 min: f64,
8 max: f64,
9 sum: f64,
10 mean: f64,
11 m2: f64,
12 m3: f64,
13 m4: f64,
14}
15
16impl Stats {
17 pub fn new() -> Self {
18 Stats {
19 ..Default::default()
20 }
21 }
22
23 pub fn update(&mut self, x: f64) -> Result<()> {
25 if f64::is_nan(x) || f64::is_infinite(x) {
26 return Err(StatsError::InvalidData);
27 }
28 if self.n_int == 0 || x < self.min {
29 self.min = x
30 }
31 if self.n_int == 0 || x > self.max {
32 self.max = x
33 }
34 self.sum += x;
37 let n_ = self.n; self.n_int += 1;
39 self.n += 1.0;
40 let delta = x - self.mean; let delta_n = delta / self.n;
42 let delta_n2 = delta_n * delta_n;
43 let term1 = delta * delta_n * n_;
44 self.m4 += term1 * delta_n2 * (self.n * self.n - 3.0 * self.n + 3.0)
46 + 6.0 * delta_n2 * self.m2
47 - 4.0 * delta_n * self.m3;
48 self.m3 += term1 * delta_n * (self.n - 2.0) - 3.0 * delta_n * self.m2;
50 self.m2 += term1;
52 self.mean += delta_n;
54
55 Ok(())
56 }
57
58 pub fn count(&self) -> u32 {
59 self.n_int
60 }
61
62 pub fn min(&self) -> Result<f64> {
63 if self.n_int == 0 {
64 return Err(StatsError::NotEnoughData);
65 }
66 Ok(self.min)
67 }
68
69 pub fn max(&self) -> Result<f64> {
70 if self.n_int == 0 {
71 return Err(StatsError::NotEnoughData);
72 }
73 Ok(self.max)
74 }
75
76 pub fn sum(&self) -> Result<f64> {
77 if self.n_int == 0 {
78 return Err(StatsError::NotEnoughData);
79 }
80 Ok(self.sum)
81 }
82
83 pub fn mean(&self) -> Result<f64> {
84 if self.n_int == 0 {
85 return Err(StatsError::NotEnoughData);
86 }
87 Ok(self.mean)
88 }
89
90 pub fn array_update(&mut self, data: &[f64]) -> Result<()> {
94 for v in data {
95 self.update(*v)?;
96 }
97 Ok(())
98 }
99
100 pub fn population_variance(&self) -> Result<f64> {
104 if self.n_int == 0 || self.n_int == 1 {
105 return Err(StatsError::NotEnoughData);
106 }
107 Ok(self.m2 / self.n)
108 }
109
110 pub fn sample_variance(&self) -> Result<f64> {
114 if self.n_int == 0 || self.n_int == 1 {
115 return Err(StatsError::NotEnoughData);
116 }
117 Ok(self.m2 / (self.n - 1.0))
118 }
119
120 pub fn population_standard_deviation(&self) -> Result<f64> {
124 if self.n_int == 0 || self.n_int == 1 {
125 return Err(StatsError::NotEnoughData);
126 }
127 Ok(f64::sqrt(self.population_variance()?))
128 }
129
130 pub fn sample_standard_deviation(&self) -> Result<f64> {
134 if self.n_int <= 1 {
135 return Err(StatsError::NotEnoughData);
136 }
137 Ok(f64::sqrt(self.sample_variance()?))
138 }
139
140 pub fn population_skewness(&self) -> Result<f64> {
145 if self.n_int <= 1 {
146 return Err(StatsError::NotEnoughData);
147 }
148 if self.m2 == 0.0 {
149 return Err(StatsError::Undefined);
150 }
151 Ok(f64::sqrt(self.n / (self.m2 * self.m2 * self.m2)) * self.m3)
152 }
153
154 pub fn sample_skewness(&self) -> Result<f64> {
158 if self.n_int <= 2 {
159 return Err(StatsError::NotEnoughData);
160 }
161 Ok(f64::sqrt(self.n * (self.n - 1.0)) / (self.n - 2.0) * self.population_skewness()?)
162 }
163
164 pub fn population_kurtosis(&self) -> Result<f64> {
174 if self.n_int <= 1 {
175 return Err(StatsError::NotEnoughData);
176 }
177 if self.m2 == 0.0 {
178 return Err(StatsError::Undefined);
179 }
180 let k = (self.n * self.m4) / (self.m2 * self.m2) - 3.0;
181 Ok(k)
182 }
183
184 pub fn sample_kurtosis(&self) -> Result<f64> {
188 if self.n_int <= 3 {
189 return Err(StatsError::NotEnoughData);
190 }
191 let k = self.population_kurtosis()?;
192 Ok((self.n - 1.0) / ((self.n - 2.0) * (self.n - 3.0)) * ((self.n + 1.0) * k + 6.0))
193 }
194}