1use std::f64;
2use std::ops::{Bound, RangeBounds};
3
4#[derive(Default, Debug)]
5pub struct Stats {
6 data: Vec<f64>,
7 length: usize,
8 sum: f64,
9 sum_of_squares: f64,
10 max: Option<f64>,
11 min: Option<f64>,
12}
13
14impl Stats {
15 pub fn new() -> Self {
16 Default::default()
17 }
18
19 fn add_cache(&mut self, x: f64) {
20 self.sum += x;
21 self.sum_of_squares += x * x;
22 self.length += 1;
23
24 if self.max.is_none() || self.max < Some(x) {
25 self.max = Some(x)
26 };
27 if self.min.is_none() || self.min > Some(x) {
28 self.min = Some(x)
29 };
30 }
31
32 fn del_cache(&mut self, x: f64) {
33 self.sum -= x;
34 self.sum_of_squares -= x * x;
35 self.length -= 1;
36
37 if self.length == 0 {
38 self.max = None;
39 self.min = None;
40 } else if self.length == 1 {
41 self.max = Some(self.data[0]);
42 self.min = Some(self.data[0]);
43 } else if self.max == Some(x) || self.min == Some(x) {
44 let i = self.length - 1;
45 self.max = Some(self.data[i]);
46 self.min = Some(self.data[i]);
47 for j in (0..i).rev() {
48 if self.max < Some(self.data[j]) {
49 self.max = Some(self.data[j])
50 };
51 if self.min > Some(self.data[j]) {
52 self.min = Some(self.data[j])
53 };
54 }
55 }
56 }
57
58 pub fn reset(&mut self) {
59 self.data = vec![];
60 self.length = 0;
61 self.sum = 0.0;
62 self.sum_of_squares = 0.0;
63 self.max = None;
64 self.min = None;
65 }
66
67 pub fn mean(&mut self) -> Option<f64> {
68 if self.length > 0 {
69 Some(self.sum / self.length as f64)
70 } else {
71 None
72 }
73 }
74
75 pub fn stddev(&mut self) -> Option<f64> {
76 if self.length > 0 {
77 Some(f64::sqrt(f64::max(0.0,
78 self.length as f64 * self.sum_of_squares - self.sum * self.sum) / (self.length * self.length) as f64))
79 } else {
80 None
81 }
82 }
83
84 pub fn min(&self) -> Option<f64> {
85 if self.length > 0 {
86 self.min
87 } else {
88 None
89 }
90 }
91
92 pub fn max(&self) -> Option<f64> {
93 if self.length > 0 {
94 self.max
95 } else {
96 None
97 }
98 }
99
100 pub fn append(&mut self, other: &mut [f64]) {
101 other.iter().for_each(|x| self.push(*x));
102 }
103
104 pub fn count_in_range<R>(&mut self, range: &R) -> [usize; 2]
105 where
106 R: RangeBounds<usize>,
107 {
108 use Bound::*;
109 let start = range.start_bound();
110 let end = range.end_bound();
111 let start = match start {
112 Unbounded => 0,
113 Included(s) => *s,
114 Excluded(s) => s.saturating_add(1),
115 };
116 let end = match end {
117 Unbounded => self.data.len() - 1,
118 Included(&e) => e,
119 Excluded(e) => e.saturating_sub(1),
120 };
121 [start, end - start + 1]
122 }
123
124 pub fn data(&mut self) -> Vec<f64> {
125 self.data.to_vec()
126 }
127
128 pub fn drain<R>(&mut self, range: R) -> Vec<f64>
129 where
130 R: RangeBounds<usize>,
131 {
132 let start = self.count_in_range(&range)[0];
133 let count = self.count_in_range(&range)[1];
134 let mut del = vec![];
135 for _ in 0..count {
136 let x = self.remove(start);
137 del.push(x);
138 }
139 del
140 }
141
142 pub fn insert(&mut self, index: usize, element: f64) {
143 self.data.insert(index, element);
144 self.add_cache(element);
145 }
146
147 pub fn is_empty(&self) -> bool {
148 self.data.is_empty()
149 }
150
151 pub fn len(&self) -> usize {
152 self.data.len()
153 }
154
155 pub fn pop(&mut self) -> Option<f64> {
156 let option = self.data.pop();
157 if let Some(x) = option {
158 self.del_cache(x);
159 }
160 option
161 }
162
163 pub fn push(&mut self, x: f64) {
164 self.data.push(x);
165 self.add_cache(x);
166 }
167
168 pub fn push_vec(&mut self, v: Vec<f64>) {
169 v.iter().for_each(|x| self.push(*x));
170 }
171
172 pub fn remove(&mut self, index: usize) -> f64 {
173 let x = self.data.remove(index);
174 self.del_cache(x);
175 x
176 }
177
178 pub fn resize(&mut self, new_len: usize, value: f64) {
179 let old_length = self.length;
180 if new_len > old_length {
181 for _ in 0..(new_len - old_length) {
182 self.push(value);
183 }
184 } else if new_len < old_length {
185 for _ in new_len..old_length {
186 self.pop();
187 }
188 }
189 }
190
191 pub fn splice<R>(&mut self, range: R, replace_with: Vec<f64>) -> Vec<f64>
192 where
193 R: RangeBounds<usize>,
194 {
195 let mut start = self.count_in_range(&range)[0];
196 let count = self.count_in_range(&range)[1];
197 let mut del = vec![];
198 for _ in 0..count {
199 let x = self.remove(start);
200 del.push(x);
201 }
202 for x in replace_with.iter() {
203 self.insert(start, *x);
204 start += 1;
205 }
206 del
207 }
208
209 pub fn split_off(&mut self, at: usize) -> Vec<f64> {
210 let length = self.length;
211 let mut del = vec![];
212 for _ in at..length {
213 let x = self.remove(at);
214 del.push(x);
215 }
216 del
217 }
218
219 pub fn swap_remove(&mut self, index: usize) -> f64 {
220 let x = self.remove(index);
221 let last_val = self.data[self.length-1];
222 self.insert(index, last_val);
223 self.pop();
224 x
225 }
226
227 pub fn trim(&mut self, index: usize) {
228 let length = self.length;
229 if index < length {
230 for _ in 0..index {
231 self.remove(0);
232 }
233 }
234 }
235
236 pub fn truncate(&mut self, len: usize) {
237 let length = self.length;
238 if len < length {
239 for _ in len..length {
240 self.remove(len);
241 }
242 }
243 }
244
245}
246
247#[cfg(test)]
248mod tests {
249 use float_cmp::approx_eq;
250 use super::Stats;
251 use crate::stats::{mean, stddev, min, max};
252
253 #[test]
254 fn reset_test() {
255 let mut vfs = Stats::new();
256 vfs.push_vec(vec![1.0, 2.0, 3.0]);
257 vfs.reset();
258
259 assert_eq!(vfs.data(), vec![])
260 }
261
262 #[test]
263 fn mean_test() {
264 let vs = vec![1.0, 2.0];
265 let mean_s = mean(&vs);
266
267 let mut vfs = Stats::new();
268 vfs.push(1.0);
269 vfs.push(2.0);
270 let mean_fs = vfs.mean();
271
272 assert_eq!(mean_s, mean_fs);
273 }
274
275 #[test]
276 fn stddev_test() {
277 let vs = vec![1.0, 2.0];
278 let stddev_s = stddev(&vs);
279
280 let mut vfs = Stats::new();
281 vfs.push(1.0);
282 vfs.push(2.0);
283 let stddev_fs = vfs.stddev();
284
285 assert_eq!(stddev_s, stddev_fs);
286 }
287
288 #[test]
289 fn min_max_test() {
290 let vs = vec![1.0, 2.0, 3.0];
291 let min_s = min(&vs);
292 let max_s = max(&vs);
293
294 let mut vfs = Stats::new();
295 vfs.push_vec(vec![1.0, 2.0, 3.0]);
296 let min_fs = vfs.min();
297 let max_fs = vfs.max();
298
299 assert_eq!(min_s, min_fs);
300 assert_eq!(max_s, max_fs);
301 }
302
303 #[test]
304 fn append_test() {
305 let mut vs = vec![1.0, 2.0, 3.0];
306 let new_s = &mut vec![4.0, 3.0, 2.0];
307 vs.append(new_s);
308
309 let mut vfs = Stats::new();
310 vfs.push_vec(vec![1.0, 2.0, 3.0]);
311 let new_fs = &mut vec![4.0, 3.0, 2.0];
312 vfs.append(new_fs);
313
314 assert_eq!(vs, vfs.data());
315 assert_eq!(mean(&vs), vfs.mean());
316 assert_eq!(stddev(&vs), vfs.stddev());
317 assert_eq!(min(&vs), vfs.min());
318 assert_eq!(max(&vs), vfs.max());
319 }
320
321 #[test]
322 fn drain_test() {
323 let mut vs = vec![1.0, -2.0, 3.0, -4.0, 1.0, 4.0];
324 vs.drain(3..4);
325
326 let mut vfs = Stats::new();
327 let vf = vec![1.0, -2.0, 3.0, -4.0, 1.0, 4.0];
328 vfs.push_vec(vf);
329 vfs.drain(3..4);
330
331 assert_eq!(vs, vfs.data);
332 assert_eq!(mean(&vs), vfs.mean());
333 assert!( approx_eq!(f64, stddev(&vs).unwrap(), vfs.stddev().unwrap(), epsilon = 1e-15) );
334 assert_eq!(min(&vs), vfs.min());
335 assert_eq!(max(&vs), vfs.max());
336 }
337
338 #[test]
339 fn insert_test() {
340 let mut vs = vec![1.0, 2.0, 3.0];
341 vs.insert(1, 4.0);
342
343 let mut vfs = Stats::new();
344 vfs.push_vec(vec![1.0, 2.0, 3.0]);
345 vfs.insert(1, 4.0);
346
347 assert_eq!(vs, vfs.data());
348 assert_eq!(mean(&vs), vfs.mean());
349 assert_eq!(stddev(&vs), vfs.stddev());
350 assert_eq!(min(&vs), vfs.min());
351 assert_eq!(max(&vs), vfs.max());
352 }
353
354 #[test]
355 fn is_empty_test() {
356 let vs: Vec<f64> = vec![];
357 let bs = vs.is_empty();
358 let vfs = Stats::new();
359 let bfs = vfs.is_empty();
360
361 assert_eq!(bs, bfs);
362 }
363
364 #[test]
365 fn len_test() {
366 let vs = vec![1.0, 2.0, 3.0];
367 let len_s = vs.len();
368
369 let mut vfs = Stats::new();
370 vfs.push_vec(vec![1.0, 2.0, 3.0]);
371 let len_fs = vfs.len();
372
373 assert_eq!(len_s, len_fs)
374 }
375
376 #[test]
377 fn remove_test() {
378 let mut vs = vec![1.0, 2.0, 3.0];
379 vs.remove(1);
380
381 let mut vfs = Stats::new();
382 vfs.push_vec(vec![1.0, 2.0, 3.0]);
383 vfs.remove(1);
384
385 assert_eq!(vs, vfs.data());
386 assert_eq!(mean(&vs), vfs.mean());
387 assert_eq!(stddev(&vs), vfs.stddev());
388 assert_eq!(min(&vs), vfs.min());
389 assert_eq!(max(&vs), vfs.max());
390 }
391
392 #[test]
393 pub fn resize_test() {
394 let mut vs = vec![1.0, 2.0, 3.0];
395 vs.resize(8, 0.0);
396
397 let mut vfs = Stats::new();
398 vfs.push_vec(vec![1.0, 2.0, 3.0]);
399 vfs.resize(8, 0.0);
400
401 assert_eq!(vs, vfs.data);
402
403 vs.resize(2, 0.0);
404 vfs.resize(2, 0.0);
405
406 assert_eq!(vs, vfs.data());
407 assert_eq!(mean(&vs), vfs.mean());
408 assert_eq!(stddev(&vs), vfs.stddev());
409 assert_eq!(min(&vs), vfs.min());
410 assert_eq!(max(&vs), vfs.max());
411 }
412
413 #[test]
414 fn splice_test() {
415 let mut vs = vec![1.0, 2.0, 3.0];
416 let new_s = vec![4.0, 5.0, 6.0];
417 vs.splice(1..3, new_s);
418
419 let mut vfs = Stats::new();
420 vfs.push_vec(vec![1.0, 2.0, 3.0]);
421 let new_fs = vec![4.0, 5.0, 6.0];
422 vfs.splice(1..3, new_fs);
423
424 assert_eq!(vs, vfs.data());
425 assert_eq!(mean(&vs), vfs.mean());
426 assert_eq!(stddev(&vs), vfs.stddev());
427 assert_eq!(min(&vs), vfs.min());
428 assert_eq!(max(&vs), vfs.max());
429 }
430
431 #[test]
432 fn split_off_test() {
433 let mut vs = vec![1.0, 2.0, 3.0];
434 let del_s = vs.split_off(0);
435
436 let mut vfs = Stats::new();
437 vfs.push_vec(vec![1.0, 2.0, 3.0]);
438 let del_fs = vfs.split_off(0);
439
440 assert_eq!(del_s, del_fs);
441 assert_eq!(mean(&vs), vfs.mean());
442 assert_eq!(stddev(&vs), vfs.stddev());
443 assert_eq!(min(&vs), vfs.min());
444 assert_eq!(max(&vs), vfs.max());
445 }
446
447 #[test]
448 fn swap_remove_test() {
449 let mut vs = vec![1.0, 2.0, 3.0];
450 vs.swap_remove(0);
451
452 let mut vfs = Stats::new();
453 vfs.push_vec(vec![1.0, 2.0, 3.0]);
454 vfs.swap_remove(0);
455
456 assert_eq!(vs, vfs.data());
457 assert_eq!(mean(&vs), vfs.mean());
458 assert_eq!(stddev(&vs), vfs.stddev());
459 assert_eq!(min(&vs), vfs.min());
460 assert_eq!(max(&vs), vfs.max());
461 }
462
463 #[test]
464 fn truncate_test() {
465 let mut vs = vec![1.0, 2.0, 3.0];
466 vs.truncate(2);
467
468 let mut vfs = Stats::new();
469 let vf = vec![1.0, 2.0, 3.0];
470 vfs.push_vec(vf);
471 vfs.truncate(2);
472
473 assert_eq!(vs, vfs.data());
474 assert_eq!(mean(&vs), vfs.mean());
475 assert_eq!(stddev(&vs), vfs.stddev());
476 assert_eq!(min(&vs), vfs.min());
477 assert_eq!(max(&vs), vfs.max());
478 }
479
480}