radiate_core/stats/
distribution.rs

1use crate::Statistic;
2
3#[derive(Clone, PartialEq, Default)]
4pub struct Distribution {
5    pub statistic: Statistic,
6    pub last_sequence: Vec<f32>,
7}
8
9impl Distribution {
10    pub fn push(&mut self, value: f32) {
11        self.statistic.add(value);
12        self.last_sequence.push(value);
13    }
14
15    pub fn add(&mut self, value: &[f32]) {
16        self.clear();
17        for v in value {
18            self.statistic.add(*v);
19            self.last_sequence.push(*v);
20        }
21    }
22
23    pub fn last_sequence(&self) -> &Vec<f32> {
24        &self.last_sequence
25    }
26
27    pub fn count(&self) -> i32 {
28        self.statistic.count()
29    }
30
31    pub fn mean(&self) -> f32 {
32        self.statistic.mean()
33    }
34
35    pub fn variance(&self) -> f32 {
36        self.statistic.variance()
37    }
38
39    pub fn standard_deviation(&self) -> f32 {
40        self.statistic.std_dev()
41    }
42
43    pub fn skewness(&self) -> f32 {
44        self.statistic.skewness()
45    }
46
47    pub fn kurtosis(&self) -> f32 {
48        self.statistic.kurtosis()
49    }
50
51    pub fn min(&self) -> f32 {
52        self.statistic.min()
53    }
54
55    pub fn max(&self) -> f32 {
56        self.statistic.max()
57    }
58
59    pub fn clear(&mut self) {
60        // self.statistic.clear();
61        self.last_sequence.clear();
62    }
63
64    pub fn percentile(&self, p: f32) -> f32 {
65        if p < 0.0 || p > 100.0 {
66            panic!("Percentile must be between 0 and 100");
67        }
68
69        // Calculate the index for the percentile
70        let count = self.last_sequence.len() as f32;
71        if count == 0 as f32 {
72            panic!("Cannot calculate percentile for an empty distribution");
73        }
74        let index = (p / 100.0) * count;
75        let sorted_values = {
76            let mut values = self.last_sequence.clone();
77            values.sort_by(|a, b| a.partial_cmp(b).unwrap());
78            values
79        };
80
81        // Ensure the index is within bounds
82        let index = index as usize;
83        if index >= sorted_values.len() {
84            panic!("Index out of bounds for the sorted values");
85        }
86        // Return the value at the calculated index
87        sorted_values[index]
88    }
89}
90
91impl From<&[f32]> for Distribution {
92    fn from(value: &[f32]) -> Self {
93        let mut result = Distribution::default();
94        result.add(value);
95        result
96    }
97}
98
99impl From<Vec<f32>> for Distribution {
100    fn from(value: Vec<f32>) -> Self {
101        let mut result = Distribution::default();
102        result.add(&value);
103        result
104    }
105}