fast_stats/
fstats_f64.rs

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}