use crate::network::node::Node;
use alloc::boxed::Box;
use core::any::Any;
use alloc::vec::Vec;
use alloc::collections::VecDeque;
use core::ops;
use core::default::Default;
pub struct FIR<T> {
fir: Vec<T>,
fir_samples: VecDeque<T>,
}
impl<T> FIR<T>
where T: Copy + Clone + 'static + ops::Div<Output=T> + ops::Mul<Output=T> + ops::Add<Output=T> + ops::Sub<Output=T> + Default
{
pub fn new(fir: Vec<T>) -> Node<T>
{
let fir_len = fir.len();
let mut internal: FIR<T> = FIR {
fir: fir,
fir_samples: VecDeque::with_capacity(fir_len),
};
for _i in 0..fir_len {
internal.fir_samples.push_back(T::default());
}
let storage = Box::new(internal) as Box<dyn Any>;
Node::new(storage, | data_input, data_container, output| {
let fir: &mut FIR<T> = data_container.downcast_mut::<FIR<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 y_0 = FIR::calculate(*v, fir);
output.push(y_0);
})
})
})
}
#[inline(always)]
pub fn calculate(sample: T, data: &mut FIR<T>) -> T {
data.fir_samples.pop_back();
data.fir_samples.push_front(sample);
let mut y_0 = T::default();
for i in 0..data.fir.len() {
let x = *data.fir_samples.get(i).unwrap();
let b = *data.fir.get(i).unwrap();
y_0 = y_0 + b * x;
}
return y_0;
}
}
#[cfg(test)]
mod tests {
use super::*;
use alloc::vec::Vec;
#[test]
fn test_fir_simple() {
let test_vector: Vec<f64> = [0,1,1,1,1,1,1,1,1].iter().map(|v| {return v.clone() as f64}).collect();
let fir: Vec<f64> = [1.0, 1.0].iter().map(|v| v.clone()).collect();
let mut fir = FIR::new(fir);
let mut result = Vec::new();
for val in test_vector.iter() {
let mut input = Vec::new();
let slice_ref = &[*val][..];
input.push(slice_ref);
fir.process((input, 1));
result.push(fir.data.get(0).unwrap().clone());
}
let control_vector: Vec<f64> = [0, 1, 2, 2, 2, 2, 2, 2, 2].iter().map(|v| v.clone() as f64).collect();
assert_eq!(result, control_vector);
}
#[test]
fn test_fir_integrate() {
let mut test_vector: Vec<&[f64]> = Vec::new();
test_vector.push(&[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0][..]);
let fir: Vec<f64> = [1.0, -1.0].iter().map(|v| v.clone()).collect();
let mut fir = FIR::new(fir);
fir.process((test_vector, 9));
let result = Vec::from(fir.poll());
assert_eq!([0.0, 1.0, 1.0 ,1.0 , 1.0, 1.0, 1.0, 1.0, 1.0], result[..]);
}
}