Skip to main content

sac_base/operations/math/
add.rs

1use crate::network::node::Node;
2use core::{ops};
3use alloc::boxed::Box;
4use core::any::Any;
5use crate::helper::iter::iter_n_inputs;
6
7/// Operation to add two or more inputs together
8pub struct Add {}
9
10impl Add {
11    /// Generate a new add operation
12    ///
13    /// ## Example
14    /// ```rust
15    /// use sac_base::operations::math::add::Add;
16    /// let mut add = Add::new();
17    /// let mut vec = Vec::new();
18    /// vec.push(&[1.0, 3.0, 4.0][..]);
19    /// vec.push(&[2.0][..]);
20    /// vec.push(&[3.0][..]);
21    /// // Sums up the three given inputs.
22    /// add.process((vec, 3));
23    /// assert_eq!(add.poll(), &[6.0, 3.0, 4.0][..]);
24    /// ```
25    pub fn new<T>() -> Node<T>
26        where T: Copy + ops::Sub<Output=T> + ops::Add<Output=T> + Default
27    {
28        let storage = Box::new(0) as Box<dyn Any>;
29        Node::new(storage,  |data_input, _input, output| {
30            iter_n_inputs(data_input, output, |left: T, right: T| {
31                return left + right;
32            });
33        })
34    }
35}
36
37#[cfg(test)]
38mod tests {
39    use super::*;
40    use alloc::vec::Vec;
41
42    #[test]
43    fn test_add() {
44        let mut inputs = Vec::new();
45        inputs.push(&[1.0][..]);
46        inputs.push(&[2.0][..]);
47
48        let mut add = Add::new();
49        add.process((inputs, 1));
50
51        assert_eq!(&[3.0][..], add.poll());
52    }
53
54    #[test]
55    fn test_multiple() {
56        let mut inputs = Vec::new();
57        inputs.push(&[1.0][..]);
58        inputs.push(&[2.0][..]);
59        inputs.push(&[3.0][..]);
60
61        let mut add = Add::new();
62        add.process((inputs, 1));
63
64        assert_eq!(&[6.0][..], add.poll());
65    }
66
67    #[test]
68    fn test_variable_len() {
69        let mut inputs = Vec::new();
70        inputs.push(&[1.0, 2.0, 3.0][..]);
71        inputs.push(&[2.0, 1.0][..]);
72        inputs.push(&[3.0][..]);
73
74        let mut add = Add::new();
75        add.process((inputs, 3));
76
77        assert_eq!(&[6.0, 3.0, 3.0][..], add.poll());
78    }
79
80
81    #[test]
82    fn test_multiple_runs() {
83        let mut inputs = Vec::new();
84        inputs.push(&[1.0][..]);
85        inputs.push(&[2.0][..]);
86
87        let mut add = Add::new();
88        add.process((inputs, 1));
89
90
91        let mut inputs = Vec::new();
92        inputs.push(&[5.0][..]);
93        inputs.push(&[6.0][..]);
94        add.process((inputs, 1));
95
96        assert_eq!(&[11.0][..], add.poll());
97    }
98
99    #[test]
100    fn test_multiple_single() {
101        let mut inputs = Vec::new();
102        inputs.push(&[1.0][..]);
103
104        let mut add = Add::new();
105        add.process((inputs, 1));
106
107        assert_eq!(&[1.0][..], add.poll());
108    }
109}