radiate_utils/stats/
distribution.rs1use 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}