concision_math/stats/
summary.rs1use crate::Root;
6use core::iter::{Product, Sum};
7use ndarray::{ArrayBase, Data, Dimension};
8use num::traits::{FromPrimitive, Num, NumOps, Pow};
9
10pub trait SummaryStatistics
13where
14 Self::Item: FromPrimitive,
15 Self::Output: NumOps<Self::Item, Self::Output>,
16{
17 type Item;
18 type Output;
19
20 fn elems(&self) -> Self::Item {
21 Self::Item::from_usize(self.len()).unwrap()
22 }
23
24 fn len(&self) -> usize;
25
26 fn mean(&self) -> Self::Output {
27 self.sum() / self.elems()
28 }
29
30 fn product(&self) -> Self::Output;
31
32 fn sum(&self) -> Self::Output;
33
34 fn std(&self) -> Self::Output;
35
36 fn var(&self) -> Self::Output;
37}
38
39impl<'a, T, I> SummaryStatistics for &'a I
43where
44 I: Clone + ExactSizeIterator<Item = T>,
45 T: Copy + FromPrimitive + Num + Pow<i32, Output = T> + Product + Root<Output = T> + Sum,
46{
47 type Item = T;
48 type Output = T;
49
50 fn len(&self) -> usize {
51 ExactSizeIterator::len(*self)
52 }
53
54 fn product(&self) -> Self::Output {
55 (*self).clone().product()
56 }
57
58 fn sum(&self) -> Self::Output {
59 (*self).clone().sum()
60 }
61
62 fn std(&self) -> Self::Output {
63 let mean = self.mean();
64 let sum = (*self).clone().map(|x| (x - mean).pow(2)).sum::<T>();
65 (sum / self.elems()).sqrt()
66 }
67
68 fn var(&self) -> Self::Output {
69 let mean = self.mean();
70 let sum = (*self).clone().map(|x| (x - mean).pow(2)).sum::<T>();
71 sum / self.elems()
72 }
73}
74
75macro_rules! impl_summary {
76 ($($T:ty),* $(,)?) => {
77 $(
78 impl_summary!(@impl $T);
79 )*
80 };
81 (@impl $T:ty) => {
82
83 impl<T> SummaryStatistics for $T
84 where
85 T: Copy + FromPrimitive + Num + Pow<i32, Output = T> + Product + Root<Output = T> + Sum,
86 {
87 type Item = T;
88 type Output = T;
89
90 fn len(&self) -> usize {
91 self.len()
92 }
93
94 fn product(&self) -> Self::Output {
95 self.iter().copied().product::<T>()
96 }
97
98 fn sum(&self) -> Self::Output {
99 self.iter().copied().sum::<T>()
100 }
101
102 fn std(&self) -> Self::Output {
103 let mean = self.mean();
104 let sum = self.iter().copied().map(|x| (x - mean).pow(2)).sum::<T>();
105 (sum / self.elems()).sqrt()
106 }
107
108 fn var(&self) -> Self::Output {
109 let mean = self.mean();
110 let sum = self.iter().copied().map(|x| (x - mean).pow(2)).sum::<T>();
111 sum / self.elems()
112 }
113 }
114 };
115}
116
117impl_summary!([T]);
118
119#[cfg(feature = "alloc")]
120impl_summary!(alloc::vec::Vec<T>);
121
122impl<A, S, D> SummaryStatistics for ArrayBase<S, D>
123where
124 A: Copy + FromPrimitive + Num + Pow<i32, Output = A> + Product + Root<Output = A> + Sum,
125 D: Dimension,
126 S: Data<Elem = A>,
127 for<'a> &'a A: Product,
128{
129 type Item = A;
130 type Output = A;
131
132 fn len(&self) -> usize {
133 self.len()
134 }
135
136 fn product(&self) -> Self::Output {
137 self.iter().copied().product::<A>()
138 }
139
140 fn sum(&self) -> Self::Output {
141 self.iter().copied().sum::<A>()
142 }
143
144 fn std(&self) -> Self::Output {
145 let mean = self.mean().unwrap_or_else(A::zero);
146 let sum = self.iter().copied().map(|x| (x - mean).pow(2)).sum::<A>();
147 (sum / self.elems()).sqrt()
148 }
149
150 fn var(&self) -> Self::Output {
151 let mean = self.mean().unwrap_or_else(A::zero);
152 let sum = self.iter().copied().map(|x| (x - mean).pow(2)).sum::<A>();
153 sum / self.elems()
154 }
155}