use crate::Zero;
pub fn zero<T>(size: usize) -> impl Fn(usize) -> Vec<T>
where
T: Clone + Zero,
{
move |_| vec![T::zero(); size]
}
pub fn step<T>(k: T, time: usize) -> impl Fn(usize) -> T
where
T: Clone + Zero,
{
move |t| {
if t < time {
T::zero()
} else {
k.clone()
}
}
}
pub fn step_vec<T>(k: T, time: usize, size: usize) -> impl Fn(usize) -> Vec<T>
where
T: Clone + Zero,
{
move |t| {
if t < time {
vec![T::zero(); size]
} else {
vec![k.clone(); size]
}
}
}
pub fn impulse<T>(k: T, time: usize) -> impl Fn(usize) -> T
where
T: Clone + Zero,
{
move |t| {
if t == time {
k.clone()
} else {
T::zero()
}
}
}
pub fn impulse_vec<T>(k: T, time: usize, size: usize) -> impl Fn(usize) -> Vec<T>
where
T: Clone + Zero,
{
move |t| {
if t == time {
vec![k.clone(); size]
} else {
vec![T::zero(); size]
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use proptest::prelude::*;
proptest! {
#[test]
fn qc_zero_input(s: usize) {
assert_relative_eq!(0., zero(1)(s)[0]);
}
}
proptest! {
#[test]
fn qc_step_single_input(s: f32) {
let f = step(s, 2);
assert_relative_eq!(0., f(1));
assert_relative_eq!(s, f(2));
}
}
proptest! {
#[test]
fn qc_step_input(s: usize) {
let f = step_vec(3., 1, 1);
if s == 0 {
assert_relative_eq!(0., f(s)[0]);
} else {
assert_relative_eq!(3., f(s)[0]);
}
}
}
#[test]
fn step_input_at_zero() {
let f = step_vec(3., 1, 1);
assert_relative_eq!(0., f(0)[0]);
}
proptest! {
#[test]
fn qc_impulse_single_input(i: f32) {
let f = impulse(i, 2);
assert_relative_eq!(0., f(1));
assert_relative_eq!(i, f(2));
}
}
#[test]
fn impulse_input() {
let mut out: Vec<_> = (0..20).map(|t| impulse_vec(10., 15, 1)(t)[0]).collect();
assert_relative_eq!(10., out[15]);
out.remove(15);
assert!(out.iter().all(|&o| o == 0.));
}
}