1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// Author: Roman Hayn
// MIT License

pub fn mean(data: &Vec<i16>) -> Option<i16> {
    let sum = data.iter().sum::<i16>() as i16;
    let count = data.len() as i16;

    match count {
        positive if positive > 0 => Some(sum / count),
        _ => None,
    }
}

pub fn variance(data: &Vec<i16>) -> Option<f32> {
    match (mean(data), data.len()) {
        (Some(d_mean), count) if count > 0 => {
            Some(data.iter().map(|val| {
                let diff = d_mean - (*val);
                diff as f32 * diff as f32
            }).sum::<f32>() / count as f32)
        },
        _ => None,
    }
}

pub fn std_deviation(data: &Vec<i16>) -> Option<f32> {
    match (mean(data), data.len()) {
        (Some(_mean), count) if count > 0 => {
            let var = data.iter().map(|val| {
                let diff = _mean - (*val );
                diff as f32 * diff as f32
            }).sum::<f32>() / count as f32;

            Some(var.sqrt())
        },
        _ => None
    }
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn test_mean() {
        let vec = vec![0,1,2,4,5,6];
        assert_eq!(mean(&vec).unwrap(), 3);
    }

    #[test]
    fn test_variance() {
        let vec = vec![66,30,40,64];
        let res = variance(&vec).unwrap();
        assert_eq!(res, 238.0);

        let vec2 = vec![51,21,79,49];
        let res2 = variance(&vec2).unwrap();
        assert_eq!(res2, 421.0);
    }

    #[test]
    fn test_std_deviation() {
        let vec = vec![66,30,40,64];
        println!("{:?}", std_deviation(&vec).unwrap());
        let res = format!("{:.2}", std_deviation(&vec).unwrap());
        assert_eq!(res, "15.43"); // 15.427

        let vec2 = vec![51,21,79,49];
        println!("{:?}", std_deviation(&vec2).unwrap());
        let res2 = format!("{:.2}", std_deviation(&vec2).unwrap());
        assert_eq!(res2, "20.52"); // 20.518
    }
}