sac_base/operations/math/
integrate.rs1use 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 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