Skip to main content

sac_base/operations/math/
integrate.rs

1use crate::network::node::Node;
2use core::ops;
3use alloc::boxed::Box;
4use core::any::Any;
5
6pub struct Integrate<T> {
7    last: T
8}
9
10impl<T> Integrate<T>
11    where T: Copy + ops::Add<Output=T> + Default + 'static
12{
13
14    /// Generate a new integration operation
15    ///
16    /// ## Example
17    /// ```rust
18    /// use sac_base::operations::math::integrate::Integrate;
19    /// let mut int = Integrate::new();
20    /// let mut vec = Vec::new();
21    /// vec.push(&[1.0][..]);
22    /// int.process((vec, 1));
23    /// let mut vec = Vec::new();
24    /// vec.push(&[1.0][..]);
25    /// int.process((vec, 1));
26    /// assert_eq!(int.poll(), &[2.0][..]);
27    /// ```
28    pub fn new() -> Node<T> {
29        let storage = Box::new(Integrate{
30            last: T::default()
31        }) as Box<dyn Any>;
32        Node::new(storage, |data_input, data_container, output| {
33            let integrate: &mut Integrate<T> = data_container.downcast_mut::<Integrate<T>>().unwrap();
34            let (inputs, max_len) = data_input;
35            output.clear();
36            inputs.into_iter().take(1).into_iter().for_each(|data| {
37                data.into_iter().take(max_len).into_iter().for_each(|v| {
38                    let last = integrate.last;
39                    let new_sample = last + *v;
40                    output.push(new_sample);
41                    integrate.last = new_sample;
42                })
43            })
44        })
45    }
46}
47
48#[cfg(test)]
49mod tests {
50    use crate::operations::math::integrate::Integrate;
51    use alloc::vec::Vec;
52
53    #[test]
54    fn test_integrate_constant() {
55        let mut int = Integrate::new();
56
57        let mut input = Vec::new();
58        input.push(&[1.0][..]);
59        int.process((input, 1));
60
61        let mut input = Vec::new();
62        input.push(&[1.0][..]);
63        int.process((input, 1));
64
65        let mut input = Vec::new();
66        input.push(&[1.0][..]);
67        int.process((input, 1));
68        assert_eq!(int.poll(), &[3.0][..]);
69    }
70
71    #[test]
72    fn test_integrate_slope() {
73        let mut int = Integrate::new();
74
75        let mut input = Vec::new();
76        input.push(&[-3.0][..]);
77        int.process((input, 1));
78
79        let mut input = Vec::new();
80        input.push(&[2.0][..]);
81        int.process((input, 1));
82
83        let mut input = Vec::new();
84        input.push(&[1.0][..]);
85        int.process((input, 1));
86        assert_eq!(int.poll(), &[0.0][..]);
87    }
88
89    #[test]
90    fn test_longer_slice() {
91        let mut int = Integrate::new();
92
93        let mut input = Vec::new();
94        input.push(&[-3.0, 3.0, 4.0][..]);
95        int.process((input, 3));
96        assert_eq!(int.poll(), &[-3.0, 0.0, 4.0][..]);
97
98        let mut input = Vec::new();
99        input.push(&[2.0][..]);
100        int.process((input, 1));
101
102        assert_eq!(int.poll(), &[6.0][..]);
103    }
104
105    #[test]
106    fn test_longer_slice_limited() {
107        let mut int = Integrate::new();
108
109        let mut input = Vec::new();
110        input.push(&[3.0, 3.0, 4.0][..]);
111        int.process((input, 2));
112
113        assert_eq!(int.poll(), &[3.0, 6.0][..]);
114    }
115}
116