use num_traits::{Float, FromPrimitive};
pub mod naive;
#[cfg(feature = "python")]
pub mod py;
fn get_hb_filter_half_remez<T: Float + FromPrimitive>(ntaps: usize) -> Vec<T> {
if ntaps == 8 {
return vec![
T::from(-0.005476842557111799).expect("constant"),
T::from(0.007835118218077888).expect("constant"),
T::from(-0.013294204112335284).expect("constant"),
T::from(0.02139788621711558).expect("constant"),
T::from(-0.03380624136244843).expect("constant"),
T::from(0.054873461629305925).expect("constant"),
T::from(-0.1006411645771518).expect("constant"),
T::from(0.3164568033034065).expect("constant"),
];
}
todo!("Add support for ntaps={}", ntaps);
}
#[allow(dead_code)]
pub fn get_hb_filter<T: Float + FromPrimitive>(ntaps: usize) -> Vec<T> {
assert_eq!((ntaps - 1) % 2, 0);
assert_ne!((ntaps - 1) % 4, 0);
let half_remez = get_hb_filter_half_remez::<T>((ntaps + 1) / 4);
let mut full = vec![];
for ii in 0..half_remez.len() - 1 {
full.push(half_remez[ii]);
full.push(T::zero());
}
full.push(half_remez[half_remez.len() - 1]);
full.push(T::from(0.5).expect("constant"));
for ii in (1..half_remez.len()).rev() {
full.push(half_remez[ii]);
full.push(T::zero());
}
full.push(half_remez[0]);
full
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_hb_flt_properties() {
let flt = get_hb_filter::<f64>(31);
assert_eq!(flt.len(), 31);
assert_eq!(flt[0], -0.005476842557111799);
assert_eq!(flt[2], 0.007835118218077888);
assert_eq!(flt[4], -0.013294204112335284);
assert_eq!(flt[6], 0.02139788621711558);
assert_eq!(flt[8], -0.03380624136244843);
assert_eq!(flt[10], 0.054873461629305925);
assert_eq!(flt[12], -0.1006411645771518);
assert_eq!(flt[14], 0.3164568033034065);
assert_eq!(flt[flt.len() / 2], 0.5);
for ii in 0..(flt.len() / 2 - 1) {
assert_eq!(flt[ii], flt[flt.len() - ii - 1]);
if ii % 2 == 1 {
assert_eq!(flt[ii], 0.0);
}
}
}
}