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