vec_utilities/running/
mod.rs1use num::Float;
4
5pub struct RunningSum<'a, T: Float + 'a, I: Iterator<Item = &'a T>> {
9 iter: I,
10 sum: T,
11}
12
13impl<'a, T: Float + 'a, I: Iterator<Item = &'a T>> RunningSum<'a, T, I> {
14 pub fn new(iter: I) -> Self {
15 return Self {
16 iter: iter,
17 sum: T::zero(),
18 };
19 }
20}
21
22impl<'a, T: Float + 'a, I: Iterator<Item = &'a T>> Iterator for RunningSum<'a, T, I> {
23 type Item = T;
24
25 fn next(&mut self) -> Option<Self::Item> {
26 match self.iter.next() {
27 Some(x) => {
28 self.sum = self.sum + *x;
29
30 return Some(self.sum);
31 }
32 None => return None,
33 }
34 }
35}
36
37pub struct RunningMean<'a, T: Float + 'a, I: Iterator<Item = &'a T>> {
39 iter: I,
40 m: T,
41 k: T,
42}
43
44impl<'a, T: Float + 'a, I: Iterator<Item = &'a T>> RunningMean<'a, T, I> {
45 pub fn new(iter: I) -> Self {
46 return Self {
47 iter,
48 m: T::zero(),
49 k: T::one(),
50 };
51 }
52}
53
54impl<'a, T: Float + 'a, I: Iterator<Item = &'a T>> Iterator for RunningMean<'a, T, I> {
55 type Item = T;
56
57 fn next(&mut self) -> Option<Self::Item> {
58 match self.iter.next() {
59 Some(x) => {
60 self.m = self.m + (*x - self.m) / self.k;
61 self.k = self.k + T::one();
62
63 return Some(self.m);
64 }
65 None => return None,
66 }
67 }
68}
69
70pub struct RunningStd<'a, T: Float + 'a, I: Iterator<Item = &'a T>> {
72 iter: I,
73 n: T,
74 mean: T,
75 m2: T,
76}
77
78impl<'a, T: Float + 'a, I: Iterator<Item = &'a T>> RunningStd<'a, T, I> {
79 pub fn new(iter: I) -> Self {
80 return Self {
81 iter,
82 n: T::zero(),
83 mean: T::zero(),
84 m2: T::zero(),
85 };
86 }
87}
88
89impl<'a, T: Float + 'a, I: Iterator<Item = &'a T>> Iterator for RunningStd<'a, T, I> {
90 type Item = T;
91
92 fn next(&mut self) -> Option<Self::Item> {
93 match self.iter.next() {
94 Some(x) => {
95 self.n = self.n + T::one();
96 let delta = *x - self.mean;
97 self.mean = self.mean + (delta / self.n);
98 let delta2 = *x - self.mean;
99 self.m2 = self.m2 + (delta * delta2);
100
101 if self.n < T::from(2.0).unwrap() {
102 return Some(T::zero());
103 } else {
104 return Some((self.m2 / (self.n - T::one())).sqrt());
105 }
106 }
107 None => return None,
108 }
109 }
110}
111
112pub trait Running<'a, T: Float + 'a, I: Iterator<Item = &'a T>> {
114 fn running_sum(self) -> RunningSum<'a, T, I>;
115 fn running_mean(self) -> RunningMean<'a, T, I>;
116 fn running_std(self) -> RunningStd<'a, T, I>;
117}
118
119impl<'a, T: Float + 'a, I: Iterator<Item = &'a T>> Running<'a, T, I> for I {
120 fn running_sum(self) -> RunningSum<'a, T, I> {
121 RunningSum::new(self)
122 }
123
124 fn running_mean(self) -> RunningMean<'a, T, I> {
125 RunningMean::new(self)
126 }
127
128 fn running_std(self) -> RunningStd<'a, T, I> {
129 RunningStd::new(self)
130 }
131}