vec_utilities/maths/
nan_stats.rs

1use crate::maths::stats::Statistics;
2
3/// Use this trait if you suspect you might have NaNs in your Vec and you want to
4/// ignore them for the computations
5pub trait NanStatistics<T> {
6    fn nan_mean(self) -> Option<T>;
7    fn nan_variance(self) -> Option<T>;
8    fn nan_std(self) -> Option<T>;
9    fn nan_median(self) -> Option<T>;
10    fn nan_max(self) -> T;
11    fn nan_min(self) -> T;
12
13    fn nan_difference(self) -> T;
14    fn nan_zero_crossings(self) -> usize;
15    fn nan_peak_average_ratio(self) -> Option<T>;
16}
17
18macro_rules! impl_nan_stat {
19    ($float:ty) => {
20        impl<'a, T: Iterator<Item = &'a $float>> NanStatistics<$float> for T {
21            fn nan_mean(self) -> Option<$float> {
22                self.filter(|x| !x.is_nan()).mean()
23            }
24
25            fn nan_variance(self) -> Option<$float> {
26                self.filter(|x| !x.is_nan()).variance()
27            }
28
29            fn nan_std(self) -> Option<$float> {
30                self.filter(|x| !x.is_nan()).std()
31            }
32
33            fn nan_median(self) -> Option<$float> {
34                self.filter(|x| !x.is_nan()).median()
35            }
36
37            fn nan_max(self) -> $float {
38                self.filter(|x| !x.is_nan()).float_max()
39            }
40
41            fn nan_min(self) -> $float {
42                self.filter(|x| !x.is_nan()).float_min()
43            }
44
45            fn nan_difference(self) -> $float {
46                self.filter(|x| !x.is_nan()).difference()
47            }
48
49            fn nan_zero_crossings(self) -> usize {
50                self.filter(|x| !x.is_nan()).zero_crossings()
51            }
52
53            fn nan_peak_average_ratio(self) -> Option<$float> {
54                self.filter(|x| !x.is_nan()).peak_average_ratio()
55            }
56        }
57    };
58}
59
60impl_nan_stat!(f64);
61impl_nan_stat!(f32);