sac-base 0.0.7

Base crate of the sac-signal and sac-control crates
Documentation
use crate::network::node::Node;
use alloc::boxed::Box;
use core::any::Any;
use alloc::collections::VecDeque;


/// Calculates the max value over n samples given
pub struct Max<T> {
    samples: VecDeque<T>,
}

impl<T> Max<T>
    where T: Copy + Default + 'static + PartialOrd
{
    /// Generate a new max operation
    ///
    /// ## Example
    /// ```rust
    /// use sac_base::operations::math::max::Max;
    /// use sac_base::network::node::Node;
    ///
    /// let mut max = Max::new(3) as Node<f32>;
    /// let mut inputs = Vec::new();
    /// inputs.push(&[1.0, 5.0, 6.0, 2.0, 11.0, 12.0, 3.0][..]);
    /// max.process((inputs, 7));
    /// assert_eq!(max.poll(), &[12.0][..]);
    /// let mut inputs = Vec::new();
    /// inputs.push(&[1.0, 5.0][..]);
    /// max.process((inputs, 2));
    /// assert_eq!(max.poll(), &[5.0][..]);
    /// ```
    pub fn new(over_n: usize) -> Node<T> {
        let mut max = Max {
            samples: VecDeque::with_capacity(over_n),
        };

        for _i in 0..over_n {
            max.samples.push_back(T::default());
        }

        let storage = Box::new(max) as Box<dyn Any>;
        Node::new(storage,  |data_input, data_container, output| {
            let max: &mut Max<T> = data_container.downcast_mut::<Max<T>>().unwrap();
            let (inputs, max_len) = data_input;

            inputs.into_iter().take(1).into_iter().for_each(|data| {
                data.into_iter().take(max_len).into_iter().for_each(|v| {
                    max.samples.pop_front();
                    max.samples.push_back(*v);

                    if let Some(start) = max.samples.get(0) {
                        let mut current_max = *start;

                        for i in 1..max.samples.len() {

                            if let Some(v) = max.samples.get(i) {
                                if *v > current_max {
                                    current_max = *v;
                                }
                            }
                        }

                        output.clear();
                        output.insert(0, current_max);
                    }
                })
            })
        })
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use alloc::vec::Vec;

    #[test]
    fn test_max() {
        let mut max = Max::new(5) as Node<f32>;

        let mut inputs = Vec::new();
        inputs.push(&[1.0][..]);
        max.process((inputs, 1));

        let mut inputs = Vec::new();
        inputs.push(&[5.0][..]);
        max.process((inputs, 1));

        let mut inputs = Vec::new();
        inputs.push(&[6.0][..]);
        max.process((inputs, 1));

        let mut inputs = Vec::new();
        inputs.push(&[2.0][..]);
        max.process((inputs, 1));

        let mut inputs = Vec::new();
        inputs.push(&[11.0][..]);
        max.process((inputs, 1));

        let mut inputs = Vec::new();
        inputs.push(&[12.0][..]);
        max.process((inputs, 1));

        let mut inputs = Vec::new();
        inputs.push(&[3.0][..]);
        max.process((inputs, 1));

        assert_eq!(max.poll(), &[12.0][..]);
    }

    #[test]
    fn test_max_slice() {
        let mut max = Max::new(3) as Node<f32>;

        let mut inputs = Vec::new();
        inputs.push(&[1.0, 5.0, 6.0, 2.0, 11.0, 12.0, 3.0][..]);
        max.process((inputs, 7));
        assert_eq!(max.poll(), &[12.0][..]);

        let mut inputs = Vec::new();
        inputs.push(&[1.0, 5.0][..]);
        max.process((inputs, 2));

        assert_eq!(max.poll(), &[5.0][..]);
    }

    #[test]
    fn test_max_integer() {
        let mut max = Max::new(3) as Node<i16>;

        let mut inputs = Vec::new();
        inputs.push(&[1, 5, -6, 2, -11, 12, 3][..]);
        max.process((inputs, 7));
        assert_eq!(max.poll(), &[12][..]);

        let mut inputs = Vec::new();
        inputs.push(&[1, -5][..]);
        max.process((inputs, 2));

        assert_eq!(max.poll(), &[3][..]);
    }
}