use crate::kernel::{Complex, Float};
pub struct NopSolver<T: Float> {
_marker: core::marker::PhantomData<T>,
}
impl<T: Float> Default for NopSolver<T> {
fn default() -> Self {
Self::new()
}
}
impl<T: Float> NopSolver<T> {
#[must_use]
pub fn new() -> Self {
Self {
_marker: core::marker::PhantomData,
}
}
#[must_use]
pub fn name(&self) -> &'static str {
"dft-nop"
}
#[must_use]
pub fn applicable(n: usize) -> bool {
n <= 1
}
#[inline]
pub fn execute(&self, input: &[Complex<T>], output: &mut [Complex<T>]) {
match input.len() {
0 => {}
1 => output[0] = input[0],
_ => panic!("NopSolver only handles size 0 or 1"),
}
}
#[inline]
pub fn execute_inplace(&self, _data: &mut [Complex<T>]) {
}
#[inline]
pub unsafe fn execute_ptr(&self, input: *const Complex<T>, output: *mut Complex<T>, n: usize) {
if n == 1 && input != output as *const _ {
unsafe { *output = *input };
}
}
}
#[inline]
pub fn dft_nop<T: Float>(input: &[Complex<T>], output: &mut [Complex<T>]) {
NopSolver::new().execute(input, output);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_nop_size_0() {
let input: [Complex<f64>; 0] = [];
let mut output: [Complex<f64>; 0] = [];
NopSolver::new().execute(&input, &mut output);
}
#[test]
fn test_nop_size_1() {
let input = [Complex::new(3.0_f64, 4.0)];
let mut output = [Complex::zero()];
NopSolver::new().execute(&input, &mut output);
assert!((output[0].re - 3.0).abs() < 1e-10);
assert!((output[0].im - 4.0).abs() < 1e-10);
}
#[test]
fn test_applicable() {
assert!(NopSolver::<f64>::applicable(0));
assert!(NopSolver::<f64>::applicable(1));
assert!(!NopSolver::<f64>::applicable(2));
assert!(!NopSolver::<f64>::applicable(100));
}
}