sac_base/operations/math/
max.rs

1use crate::network::node::Node;
2use alloc::boxed::Box;
3use core::any::Any;
4use alloc::collections::VecDeque;
5
6
7/// Calculates the max value over n samples given
8pub struct Max<T> {
9    samples: VecDeque<T>,
10}
11
12impl<T> Max<T>
13    where T: Copy + Default + 'static + PartialOrd
14{
15    /// Generate a new max operation
16    ///
17    /// ## Example
18    /// ```rust
19    /// use sac_base::operations::math::max::Max;
20    /// use sac_base::network::node::Node;
21    ///
22    /// let mut max = Max::new(3) as Node<f32>;
23    /// let mut inputs = Vec::new();
24    /// inputs.push(&[1.0, 5.0, 6.0, 2.0, 11.0, 12.0, 3.0][..]);
25    /// max.process((inputs, 7));
26    /// assert_eq!(max.poll(), &[12.0][..]);
27    /// let mut inputs = Vec::new();
28    /// inputs.push(&[1.0, 5.0][..]);
29    /// max.process((inputs, 2));
30    /// assert_eq!(max.poll(), &[5.0][..]);
31    /// ```
32    pub fn new(over_n: usize) -> Node<T> {
33        let mut max = Max {
34            samples: VecDeque::with_capacity(over_n),
35        };
36
37        for _i in 0..over_n {
38            max.samples.push_back(T::default());
39        }
40
41        let storage = Box::new(max) as Box<dyn Any>;
42        Node::new(storage,  |data_input, data_container, output| {
43            let max: &mut Max<T> = data_container.downcast_mut::<Max<T>>().unwrap();
44            let (inputs, max_len) = data_input;
45
46            inputs.into_iter().take(1).into_iter().for_each(|data| {
47                data.into_iter().take(max_len).into_iter().for_each(|v| {
48                    max.samples.pop_front();
49                    max.samples.push_back(*v);
50
51                    if let Some(start) = max.samples.get(0) {
52                        let mut current_max = *start;
53
54                        for i in 1..max.samples.len() {
55
56                            if let Some(v) = max.samples.get(i) {
57                                if *v > current_max {
58                                    current_max = *v;
59                                }
60                            }
61                        }
62
63                        output.clear();
64                        output.insert(0, current_max);
65                    }
66                })
67            })
68        })
69    }
70}
71
72#[cfg(test)]
73mod tests {
74    use super::*;
75    use alloc::vec::Vec;
76
77    #[test]
78    fn test_max() {
79        let mut max = Max::new(5) as Node<f32>;
80
81        let mut inputs = Vec::new();
82        inputs.push(&[1.0][..]);
83        max.process((inputs, 1));
84
85        let mut inputs = Vec::new();
86        inputs.push(&[5.0][..]);
87        max.process((inputs, 1));
88
89        let mut inputs = Vec::new();
90        inputs.push(&[6.0][..]);
91        max.process((inputs, 1));
92
93        let mut inputs = Vec::new();
94        inputs.push(&[2.0][..]);
95        max.process((inputs, 1));
96
97        let mut inputs = Vec::new();
98        inputs.push(&[11.0][..]);
99        max.process((inputs, 1));
100
101        let mut inputs = Vec::new();
102        inputs.push(&[12.0][..]);
103        max.process((inputs, 1));
104
105        let mut inputs = Vec::new();
106        inputs.push(&[3.0][..]);
107        max.process((inputs, 1));
108
109        assert_eq!(max.poll(), &[12.0][..]);
110    }
111
112    #[test]
113    fn test_max_slice() {
114        let mut max = Max::new(3) as Node<f32>;
115
116        let mut inputs = Vec::new();
117        inputs.push(&[1.0, 5.0, 6.0, 2.0, 11.0, 12.0, 3.0][..]);
118        max.process((inputs, 7));
119        assert_eq!(max.poll(), &[12.0][..]);
120
121        let mut inputs = Vec::new();
122        inputs.push(&[1.0, 5.0][..]);
123        max.process((inputs, 2));
124
125        assert_eq!(max.poll(), &[5.0][..]);
126    }
127
128    #[test]
129    fn test_max_integer() {
130        let mut max = Max::new(3) as Node<i16>;
131
132        let mut inputs = Vec::new();
133        inputs.push(&[1, 5, -6, 2, -11, 12, 3][..]);
134        max.process((inputs, 7));
135        assert_eq!(max.poll(), &[12][..]);
136
137        let mut inputs = Vec::new();
138        inputs.push(&[1, -5][..]);
139        max.process((inputs, 2));
140
141        assert_eq!(max.poll(), &[3][..]);
142    }
143}