Skip to main content

radiate_utils/stats/
distribution.rs

1use crate::{Float, Statistic};
2#[cfg(feature = "serde")]
3use serde::{Deserialize, Serialize};
4
5#[derive(Clone, PartialEq)]
6#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7pub struct Distribution<F: Float> {
8    statistic: Statistic<F>,
9    values: Vec<F>,
10}
11
12impl<F: Float> Distribution<F> {
13    pub fn with_capacity(capacity: usize) -> Self {
14        Distribution {
15            statistic: Statistic::default(),
16            values: Vec::with_capacity(capacity),
17        }
18    }
19
20    #[inline(always)]
21    pub fn add(&mut self, value: F) {
22        if self.values.capacity() == self.values.len() {
23            panic!(
24                "Distribution capacity exceeded: {}. Consider increasing the capacity or using a different data structure.",
25                self.values.capacity()
26            );
27        }
28
29        self.statistic.add(value);
30        self.values.push(value);
31    }
32
33    pub fn count(&self) -> usize {
34        self.values.len()
35    }
36
37    pub fn min(&self) -> F {
38        self.statistic.min()
39    }
40
41    pub fn max(&self) -> F {
42        self.statistic.max()
43    }
44
45    pub fn mean(&self) -> F {
46        self.statistic.mean()
47    }
48
49    pub fn sum(&self) -> F {
50        self.statistic.sum()
51    }
52
53    pub fn variance(&self) -> Option<F> {
54        self.statistic.variance()
55    }
56
57    pub fn std_dev(&self) -> Option<F> {
58        self.statistic.std_dev()
59    }
60
61    pub fn skewness(&self) -> Option<F> {
62        self.statistic.skewness()
63    }
64
65    pub fn kurtosis(&self) -> Option<F> {
66        self.statistic.kurtosis()
67    }
68
69    pub fn clear(&mut self) {
70        self.statistic.clear();
71        self.values.clear();
72    }
73}
74
75impl<F> Extend<F> for Distribution<F>
76where
77    F: Float,
78{
79    fn extend<T: IntoIterator<Item = F>>(&mut self, iter: T) {
80        self.clear();
81        self.values.extend(iter);
82
83        for &value in &self.values {
84            self.statistic.add(value);
85        }
86    }
87}
88
89impl From<&[f32]> for Distribution<f32> {
90    fn from(value: &[f32]) -> Self {
91        let mut result = Distribution::with_capacity(value.len());
92        for &v in value {
93            result.add(v);
94        }
95
96        result
97    }
98}
99
100impl From<Vec<f32>> for Distribution<f32> {
101    fn from(value: Vec<f32>) -> Self {
102        let mut result = Distribution::with_capacity(value.len());
103        for v in value {
104            result.add(v);
105        }
106        result
107    }
108}
109
110impl From<&Vec<usize>> for Distribution<f32> {
111    fn from(value: &Vec<usize>) -> Self {
112        let mut dist = Distribution::with_capacity(value.len());
113        for v in value.iter().map(|&v| v as f32) {
114            dist.add(v);
115        }
116
117        dist
118    }
119}