Skip to main content

numeric_statistics/f32/
average.rs

1//! Statistics module for calculating various statistical measures.
2//! 
3//! These are simple naive implementations, just enough to work for
4//! this crate's purpose of network monitoring, such as for latency.
5
6/// Calculate statistical average for values.
7///
8/// Return NaN if the values are empty.
9/// 
10/// Filter NaN values in the stream.
11/// 
12/// # Example
13///
14/// ```rust
15/// #[macro_use]
16/// use numeric_statistics::assert_eq_f32;
17/// use numeric_statistics::f32::average::*;
18/// let values = &[1.0, 2.0, 4.0];
19/// let average = average(values);
20/// assert_eq_f32!(average, 2.3333333 as f32);
21/// ```
22/// 
23pub fn average<T: AsRef<[f32]>>(values: T) -> f32 {
24    let values = values.as_ref();
25    if values.is_empty() { return f32::NAN; }
26    let mut sum: f32 = 0.0;
27    let mut len: usize = 0;
28    values.iter().for_each(|x|
29        if !x.is_nan() {
30            sum += *x;
31            len += 1;
32        }
33    );
34    sum / (len as f32)
35}
36
37#[cfg(test)]
38mod test {
39    use super::*;
40    use crate::assert_eq_f32;
41
42    #[test]
43    fn test_empty() {
44        let x: &[f32] = &[];
45        assert!(average(x).is_nan());
46    }
47
48    #[test]
49    fn test_nan() {
50        let x: &[f32] = &[f32::NAN];
51        assert!(average(x).is_nan());
52    }
53
54    #[test]
55    fn test_value() {
56        let x: &[f32] = &[1.0];
57        assert_eq_f32!(average(x), 1.0);
58    }
59
60    #[test]
61    fn test_values_ascending() {
62        let x = &[1.0, 2.0, 4.0];
63        assert_eq_f32!(average(x), 2.3333333 as f32);
64    }
65
66    #[test]
67    fn test_values_ascending_and_nans() {
68        let x = &[1.0, f32::NAN, 2.0, f32::NAN, 4.0];
69        assert_eq_f32!(average(x), 2.3333333 as f32);
70    }
71
72    #[test]
73    fn test_values_descending() {
74        let x = &[4.0, 2.0, 1.0];
75        assert_eq_f32!(average(x), 2.3333333 as f32);
76    }
77
78    #[test]
79    fn test_values_descending_and_nans() {
80        let x = &[4.0, f32::NAN, 2.0, f32::NAN, 1.0];
81        assert_eq_f32!(average(x), 2.3333333 as f32);
82    }
83
84}
85