fast_stats/
fstats_float.rs

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}