use crate::network::node::Node;
use core::ops;
use alloc::boxed::Box;
use core::any::Any;
pub struct Integrate<T> {
last: T
}
impl<T> Integrate<T>
where T: Copy + ops::Add<Output=T> + Default + 'static
{
pub fn new() -> Node<T> {
let storage = Box::new(Integrate{
last: T::default()
}) as Box<dyn Any>;
Node::new(storage, |data_input, data_container, output| {
let integrate: &mut Integrate<T> = data_container.downcast_mut::<Integrate<T>>().unwrap();
let (inputs, max_len) = data_input;
output.clear();
inputs.into_iter().take(1).into_iter().for_each(|data| {
data.into_iter().take(max_len).into_iter().for_each(|v| {
let last = integrate.last;
let new_sample = last + *v;
output.push(new_sample);
integrate.last = new_sample;
})
})
})
}
}
#[cfg(test)]
mod tests {
use crate::operations::math::integrate::Integrate;
use alloc::vec::Vec;
#[test]
fn test_integrate_constant() {
let mut int = Integrate::new();
let mut input = Vec::new();
input.push(&[1.0][..]);
int.process((input, 1));
let mut input = Vec::new();
input.push(&[1.0][..]);
int.process((input, 1));
let mut input = Vec::new();
input.push(&[1.0][..]);
int.process((input, 1));
assert_eq!(int.poll(), &[3.0][..]);
}
#[test]
fn test_integrate_slope() {
let mut int = Integrate::new();
let mut input = Vec::new();
input.push(&[-3.0][..]);
int.process((input, 1));
let mut input = Vec::new();
input.push(&[2.0][..]);
int.process((input, 1));
let mut input = Vec::new();
input.push(&[1.0][..]);
int.process((input, 1));
assert_eq!(int.poll(), &[0.0][..]);
}
#[test]
fn test_longer_slice() {
let mut int = Integrate::new();
let mut input = Vec::new();
input.push(&[-3.0, 3.0, 4.0][..]);
int.process((input, 3));
assert_eq!(int.poll(), &[-3.0, 0.0, 4.0][..]);
let mut input = Vec::new();
input.push(&[2.0][..]);
int.process((input, 1));
assert_eq!(int.poll(), &[6.0][..]);
}
#[test]
fn test_longer_slice_limited() {
let mut int = Integrate::new();
let mut input = Vec::new();
input.push(&[3.0, 3.0, 4.0][..]);
int.process((input, 2));
assert_eq!(int.poll(), &[3.0, 6.0][..]);
}
}