pmrs/algo/transformation/ocel/features/
operator.rs1use std::fmt;
2use std::iter::Iterator;
3use itertools::Itertools;
4use num_traits::Num;
5use num_traits::{FromPrimitive, ToPrimitive};
6use stats;
7use strum::{EnumString, EnumIter};
8
9#[derive(Debug, EnumString, EnumIter)]
10pub enum Operator {
11 Mean,
12 Median,
13 Mode,
14 StdDev,
15 Variance,
16 Min,
17 Max,
18 Count
19}
20
21impl fmt::Display for Operator {
22 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
23 write!(f, "{:?}", self)
24 }
25}
26
27
28impl Operator {
29 pub fn execute<T, I>(&self, input_iter: I) -> Option<T>
30 where I: Iterator<Item = T>, T: Num + ToPrimitive + PartialOrd + Clone + FromPrimitive {
31
32 match self {
33 Operator::Mean => {
34 T::from_f64(stats::mean(input_iter))
35 },
36 Operator::Median => {
37 let ordered_iterator = input_iter.sorted_by(|a,b| a.partial_cmp(b).expect("A NaN value got into the iterator!"));
38 T::from_f64(stats::median(ordered_iterator).unwrap())
39 },
40 Operator::Mode => {
42 stats::mode(input_iter)
43 },
44 Operator::StdDev => {
45 T::from_f64(stats::stddev(input_iter))
46 },
47 Operator::Variance => {
48 T::from_f64(stats::variance(input_iter))
49 },
50 Operator::Min => {
51 input_iter.min_by(|a, b| a.partial_cmp(b).expect("A NaN value got into the iterator!"))
52 },
53 Operator::Max => {
54 input_iter.max_by(|a, b| a.partial_cmp(b).expect("A NaN value got into the iterator!"))
55 },
56 Operator::Count => {
57 T::from_usize(input_iter.count())
58 }
59 }
60 }
61
62}
63
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68 const ERROR: f64 = 0.00001;
69
70 fn get_int_ord_vec() -> Vec<i32>{
71 vec![1,3,5,7,9]
72 }
73
74 fn get_int_parord_vec() -> Vec<i32>{
75 vec![1,3,5,5,9]
76 }
77
78 fn get_float_ord_vec() -> Vec<f64> {
79 vec![1.5, 2.4, 3.3, 4.2, 5.1]
80 }
81
82 fn get_float_parord_vec() -> Vec<f64> {
83 vec![1.5, 2.4, 3.3, 3.3, 5.1]
84 }
85
86
87 #[test]
88 fn test_mean_operator() {
89 let op = Operator::Mean;
90
91 let iov = get_int_ord_vec();
92 let ipv = get_int_parord_vec();
93 let fov = get_float_ord_vec();
94 let fpv = get_float_parord_vec();
95
96 assert!((op.execute(iov.iter().map(|i| *i as f64)).unwrap().to_owned() - 5.0).abs() < ERROR);
97 assert!((op.execute(ipv.iter().map(|i| *i as f64)).unwrap().to_owned() - 4.6).abs() < ERROR);
98 assert!((op.execute(fov.iter().map(|i| *i)).unwrap().to_owned() - 3.3).abs() < ERROR);
99 assert!((op.execute(fpv.iter().map(|i| *i)).unwrap().to_owned() - 3.12).abs() < ERROR);
100
101 let riov: Vec<&i32> = iov.iter().rev().collect();
103 let ripv: Vec<&i32> = ipv.iter().rev().collect();
104 let rfov: Vec<&f64> = fov.iter().rev().collect();
105 let rfpv: Vec<&f64> = fpv.iter().rev().collect();
106
107 assert!((op.execute(riov.iter().map(|i| **i as f64)).unwrap().to_owned() - 5.0).abs() < ERROR);
108 assert!((op.execute(ripv.iter().map(|i| **i as f64)).unwrap().to_owned() - 4.6).abs() < ERROR);
109 assert!((op.execute(rfov.iter().map(|i| **i)).unwrap().to_owned() - 3.3).abs() < ERROR);
110 assert!((op.execute(rfpv.iter().map(|i| **i)).unwrap().to_owned() - 3.12).abs() < ERROR);
111 }
112
113 #[test]
114 fn test_median_operator() {
115 let op = Operator::Median;
116
117 let iov = get_int_ord_vec();
118 let ipv = get_int_parord_vec();
119 let fov = get_float_ord_vec();
120 let fpv = get_float_parord_vec();
121
122 assert!((op.execute(iov.iter().map(|i| *i as f64)).unwrap().to_owned() - 5.0).abs() < ERROR);
123 assert!((op.execute(ipv.iter().map(|i| *i as f64)).unwrap().to_owned() - 5.0).abs() < ERROR);
124 assert!((op.execute(fov.iter().map(|i| *i)).unwrap().to_owned() - 3.3).abs() < ERROR);
125 assert!((op.execute(fpv.iter().map(|i| *i)).unwrap().to_owned() - 3.3).abs() < ERROR);
126
127 let riov: Vec<&i32> = iov.iter().rev().collect();
129 let ripv: Vec<&i32> = ipv.iter().rev().collect();
130 let rfov: Vec<&f64> = fov.iter().rev().collect();
131 let rfpv: Vec<&f64> = fpv.iter().rev().collect();
132
133 assert!((op.execute(riov.iter().map(|i| **i as f64)).unwrap().to_owned() - 5.0).abs() < ERROR);
134 assert!((op.execute(ripv.iter().map(|i| **i as f64)).unwrap().to_owned() - 5.0).abs() < ERROR);
135 assert!((op.execute(rfov.iter().map(|i| **i)).unwrap().to_owned() - 3.3).abs() < ERROR);
136 assert!((op.execute(rfpv.iter().map(|i| **i)).unwrap().to_owned() - 3.3).abs() < ERROR);
137 }
138
139 #[test]
140 fn test_mode_operator() {
141 let op = Operator::Mode;
142
143 let iov = get_int_ord_vec();
144 let ipv = get_int_parord_vec();
145 let fov = get_float_ord_vec();
146 let fpv = get_float_parord_vec();
147
148 assert_eq!(op.execute(iov.iter().map(|i| *i as f64)), None);
149 assert!((op.execute(ipv.iter().map(|i| *i as f64)).unwrap().to_owned() - 5.0).abs() < ERROR);
150 assert_eq!(op.execute(fov.iter().map(|i| *i as f64)), None);
151 assert!((op.execute(fpv.iter().map(|i| *i)).unwrap().to_owned() - 3.3).abs() < ERROR);
152
153 let riov: Vec<&i32> = iov.iter().rev().collect();
155 let ripv: Vec<&i32> = ipv.iter().rev().collect();
156 let rfov: Vec<&f64> = fov.iter().rev().collect();
157 let rfpv: Vec<&f64> = fpv.iter().rev().collect();
158
159 assert_eq!(op.execute(riov.iter().map(|i| **i as f64)), None);
160 assert!((op.execute(ripv.iter().map(|i| **i as f64)).unwrap().to_owned() - 5.0).abs() < ERROR);
161 assert_eq!(op.execute(rfov.iter().map(|i| **i as f64)), None);
162 assert!((op.execute(rfpv.iter().map(|i| **i)).unwrap().to_owned() - 3.3).abs() < ERROR);
163 }
164
165 #[test]
166 fn test_stddev_operator() {
167 let op = Operator::StdDev;
168
169 let iov = get_int_ord_vec();
170 let ipv = get_int_parord_vec();
171 let fov = get_float_ord_vec();
172 let fpv = get_float_parord_vec();
173
174 assert!((op.execute(iov.iter().map(|i| *i as f64)).unwrap().to_owned() - 2.82842712).abs() < ERROR);
175 assert!((op.execute(ipv.iter().map(|i| *i as f64)).unwrap().to_owned() - 2.65329983).abs() < ERROR);
176 assert!((op.execute(fov.iter().map(|i| *i)).unwrap().to_owned() - 1.2727922061).abs() < ERROR);
177 assert!((op.execute(fpv.iter().map(|i| *i)).unwrap().to_owned() - 1.1939849245).abs() < ERROR);
178
179 let riov: Vec<&i32> = iov.iter().rev().collect();
181 let ripv: Vec<&i32> = ipv.iter().rev().collect();
182 let rfov: Vec<&f64> = fov.iter().rev().collect();
183 let rfpv: Vec<&f64> = fpv.iter().rev().collect();
184
185 assert!((op.execute(riov.iter().map(|i| **i as f64)).unwrap().to_owned() - 2.82842712).abs() < ERROR);
186 assert!((op.execute(ripv.iter().map(|i| **i as f64)).unwrap().to_owned() - 2.65329983).abs() < ERROR);
187 assert!((op.execute(rfov.iter().map(|i| **i)).unwrap().to_owned() - 1.2727922061).abs() < ERROR);
188 assert!((op.execute(rfpv.iter().map(|i| **i)).unwrap().to_owned() - 1.1939849245).abs() < ERROR);
189 }
190
191 #[test]
192 fn test_variance_operator() {
193 let op = Operator::Variance;
194
195 let iov = get_int_ord_vec();
196 let ipv = get_int_parord_vec();
197 let fov = get_float_ord_vec();
198 let fpv = get_float_parord_vec();
199
200 assert!((op.execute(iov.iter().map(|i| *i as f64)).unwrap().to_owned() - 8.0).abs() < ERROR);
201 assert!((op.execute(ipv.iter().map(|i| *i as f64)).unwrap().to_owned() - 7.04).abs() < ERROR);
202 assert!((op.execute(fov.iter().map(|i| *i)).unwrap().to_owned() - 1.62).abs() < ERROR);
203 assert!((op.execute(fpv.iter().map(|i| *i)).unwrap().to_owned() - 1.4256).abs() < ERROR);
204
205 let riov: Vec<&i32> = iov.iter().rev().collect();
207 let ripv: Vec<&i32> = ipv.iter().rev().collect();
208 let rfov: Vec<&f64> = fov.iter().rev().collect();
209 let rfpv: Vec<&f64> = fpv.iter().rev().collect();
210
211 assert!((op.execute(riov.iter().map(|i| **i as f64)).unwrap().to_owned() - 8.0).abs() < ERROR);
212 assert!((op.execute(ripv.iter().map(|i| **i as f64)).unwrap().to_owned() - 7.04).abs() < ERROR);
213 assert!((op.execute(rfov.iter().map(|i| **i)).unwrap().to_owned() - 1.62).abs() < ERROR);
214 assert!((op.execute(rfpv.iter().map(|i| **i)).unwrap().to_owned() - 1.4256).abs() < ERROR);
215 }
216
217 #[test]
218 fn test_min_operator() {
219 let op = Operator::Min;
220
221 let iov = get_int_ord_vec();
222 let ipv = get_int_parord_vec();
223 let fov = get_float_ord_vec();
224 let fpv = get_float_parord_vec();
225
226 assert_eq!(op.execute(iov.iter().map(|i| *i as f64)).unwrap() as i32, 1);
227 assert_eq!(op.execute(ipv.iter().map(|i| *i as f64)).unwrap() as i32, 1);
228 assert_eq!(op.execute(fov.iter().map(|i| *i as f64)).unwrap(), 1.5);
229 assert_eq!(op.execute(fpv.iter().map(|i| *i as f64)).unwrap(), 1.5);
230
231 let riov: Vec<&i32> = iov.iter().rev().collect();
233 let ripv: Vec<&i32> = ipv.iter().rev().collect();
234 let rfov: Vec<&f64> = fov.iter().rev().collect();
235 let rfpv: Vec<&f64> = fpv.iter().rev().collect();
236
237 assert_eq!(op.execute(riov.iter().map(|i| **i as f64)).unwrap() as i32, 1);
238 assert_eq!(op.execute(ripv.iter().map(|i| **i as f64)).unwrap() as i32, 1);
239 assert_eq!(op.execute(rfov.iter().map(|i| **i as f64)).unwrap(), 1.5);
240 assert_eq!(op.execute(rfpv.iter().map(|i| **i as f64)).unwrap(), 1.5);
241 }
242
243 #[test]
244 fn test_max_operator() {
245 let op = Operator::Max;
246
247 let iov = get_int_ord_vec();
248 let ipv = get_int_parord_vec();
249 let fov = get_float_ord_vec();
250 let fpv = get_float_parord_vec();
251
252 assert_eq!(op.execute(iov.iter().map(|i| *i as f64)).unwrap() as i32, 9);
253 assert_eq!(op.execute(ipv.iter().map(|i| *i as f64)).unwrap() as i32, 9);
254 assert_eq!(op.execute(fov.iter().map(|i| *i as f64)).unwrap(), 5.1);
255 assert_eq!(op.execute(fpv.iter().map(|i| *i as f64)).unwrap(), 5.1);
256
257 let riov: Vec<&i32> = iov.iter().rev().collect();
259 let ripv: Vec<&i32> = ipv.iter().rev().collect();
260 let rfov: Vec<&f64> = fov.iter().rev().collect();
261 let rfpv: Vec<&f64> = fpv.iter().rev().collect();
262
263 assert_eq!(op.execute(riov.iter().map(|i| **i as f64)).unwrap() as i32, 9);
264 assert_eq!(op.execute(ripv.iter().map(|i| **i as f64)).unwrap() as i32, 9);
265 assert_eq!(op.execute(rfov.iter().map(|i| **i as f64)).unwrap(), 5.1);
266 assert_eq!(op.execute(rfpv.iter().map(|i| **i as f64)).unwrap(), 5.1);
267 }
268
269 #[test]
270 fn test_count_operator() {
271 let op = Operator::Count;
272
273 let iov = get_int_ord_vec();
274 let ipv = get_int_parord_vec();
275 let fov = get_float_ord_vec();
276 let fpv = get_float_parord_vec();
277
278 assert_eq!(op.execute(iov.iter().map(|i| *i as usize)).unwrap(), 5);
279 assert_eq!(op.execute(ipv.iter().map(|i| *i as usize)).unwrap(), 5);
280 assert_eq!(op.execute(fov.iter().map(|i| *i as usize)).unwrap(), 5);
281 assert_eq!(op.execute(fpv.iter().map(|i| *i as usize)).unwrap(), 5);
282
283 let riov: Vec<&i32> = iov.iter().rev().collect();
285 let ripv: Vec<&i32> = ipv.iter().rev().collect();
286 let rfov: Vec<&f64> = fov.iter().rev().collect();
287 let rfpv: Vec<&f64> = fpv.iter().rev().collect();
288
289 assert_eq!(op.execute(riov.iter().map(|i| **i as usize)).unwrap(), 5);
290 assert_eq!(op.execute(ripv.iter().map(|i| **i as usize)).unwrap(), 5);
291 assert_eq!(op.execute(rfov.iter().map(|i| **i as usize)).unwrap(), 5);
292 assert_eq!(op.execute(rfpv.iter().map(|i| **i as usize)).unwrap(), 5);
293 }
294}