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 IIR<T> {
fir: Vec<T>,
iir: Vec<T>,
fir_samples: VecDeque<T>,
iir_samples: VecDeque<T>,
}
impl<T> IIR<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>, iir: Vec<T>) -> Node<T>
{
let fir_len = fir.len();
let iir_len = iir.len() - 1;
let mut internal: IIR<T> = IIR {
fir: fir,
iir: iir,
fir_samples: VecDeque::with_capacity(fir_len),
iir_samples: VecDeque::with_capacity(iir_len),
};
for _i in 0..fir_len {
internal.fir_samples.push_back(T::default());
}
for _i in 0..iir_len {
internal.iir_samples.push_back(T::default());
}
let storage = Box::new(internal) as Box<dyn Any>;
Node::new(storage, | data_input, data_container, output| {
let iir: &mut IIR<T> = data_container.downcast_mut::<IIR<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 = IIR::calculate(*v, iir);
output.push(y_0);
})
})
})
}
#[inline(always)]
pub fn calculate(sample: T, data: &mut IIR<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;
}
for i in 1..data.iir.len() {
let y = *data.iir_samples.get(i - 1).unwrap();
let a = *data.iir.get(i).unwrap();
y_0 = y_0 - a * y;
}
data.iir_samples.pop_back();
data.iir_samples.push_front(y_0);
return y_0;
}
}
#[cfg(test)]
mod tests {
use super::*;
use alloc::vec::Vec;
use assert_approx_eq::assert_approx_eq;
#[test]
fn test_iir_actual() {
let fir = [-0.06, 0.4].iter().map(|v| v.clone() as f64).collect();
let iir = [1.0, -1.6, 0.78].iter().map(|v| v.clone() as f64).collect();
let mut iir = IIR::new(fir, iir);
let mut result = Vec::new();
let mut input = Vec::new();
let slice_ref = &[0.0][..];
input.push(slice_ref);
iir.process((input, 1));
result.push(iir.data.get(0).unwrap().clone());
for _i in 1..100 {
let mut input = Vec::new();
let slice_ref = &[1.0][..];
input.push(slice_ref);
iir.process((input, 1));
result.push(iir.data.get(0).unwrap().clone());
}
let test_vector: Vec<f64> = [ 0. , -0.06 , 0.244 , 0.7772 , 1.3932 ,
1.962904 , 2.3939504 , 2.63925552, 2.69552752, 2.59422473,
2.3882481 , 2.13770167, 1.89748915, 1.70857534, 1.59367901,
1.55719765, 1.58844661, 1.66690041, 1.7680523 , 1.86870136,
1.95084138, 2.00375915, 2.02435836, 2.01604124, 1.98666647,
1.94615418, 1.90424684, 1.86879468, 1.84475896, 1.83395448,
1.83541518, 1.8461798 , 1.86226383, 1.87960189, 1.89479723,
1.9055861 , 1.91099592, 1.91123631, 1.90740128, 1.90107773,
1.89395136, 1.88748156, 1.88268842, 1.88006587, 1.87960841,
1.88092209, 1.88338078, 1.88629001, 1.88902702, 1.89113702,
1.89237815, 1.89271817, 1.89229412, 1.89135041, 1.89017125,
1.88902068, 1.88809951, 1.88752309, 1.88731932, 1.88744291,
1.88779958, 1.88827386, 1.88875451, 1.8891536 , 1.88941724,
1.88952778, 1.889499 , 1.88936673, 1.88917755, 1.88897803,
1.88880636, 1.88868731, 1.88863074, 1.88863308, 1.88868095,
1.88875572, 1.88883801, 1.88891135, 1.88896452, 1.88899237,
1.88899547, 1.88897871, 1.88894946, 1.88891575, 1.88888461,
1.8888611 , 1.88884776, 1.88884476, 1.88885036, 1.88886167,
1.88887538, 1.88888851, 1.88889882, 1.88890508, 1.88890704,
1.8889053 , 1.888901 , 1.88889546, 1.88888995, 1.88888547].iter().map(|v| v.clone() as f64).collect();
for i in 0..100 {
assert_approx_eq!(result[i], test_vector[i]);
}
}
#[test]
fn test_iir_simple() {
let mut test_vector = Vec::new();
test_vector.push(&[0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0][..]);
let fir = [1.0].iter().map(|v| v.clone()).collect();
let iir = [1.0, 1.0].iter().map(|v| v.clone()).collect();
let mut iir = IIR::new(fir, iir);
iir.process((test_vector, 9));
let result = Vec::from(iir.poll());
let control_vector: Vec<f64> = [0, 1, 0, 1, 0, 1, 0, 1, 0].iter().map(|v| v.clone() as f64).collect();
assert_eq!(result, control_vector);
}
}