use num_complex::Complex;
use num_traits::{AsPrimitive, Float};
use pxfm::{f_cospi, f_cospif, f_sincospi, f_sincospif, f_sinpi, f_sinpif, f_tanpi, f_tanpif};
pub(crate) trait FftTrigonometry {
fn sincos_pi(self) -> (Self, Self)
where
Self: Sized;
fn cospi(self) -> Self;
#[allow(unused)]
fn sinpi(self) -> Self;
fn tanpi(self) -> Self;
}
impl FftTrigonometry for f32 {
#[inline]
fn sincos_pi(self) -> (Self, Self) {
f_sincospif(self)
}
#[inline]
fn cospi(self) -> Self {
f_cospif(self)
}
#[inline]
fn sinpi(self) -> Self {
f_sinpif(self)
}
#[inline]
fn tanpi(self) -> Self {
f_tanpif(self)
}
}
impl FftTrigonometry for f64 {
#[inline]
fn sincos_pi(self) -> (Self, Self) {
f_sincospi(self)
}
#[inline]
fn cospi(self) -> Self {
f_cospi(self)
}
#[inline]
fn sinpi(self) -> Self {
f_sinpi(self)
}
#[inline]
fn tanpi(self) -> Self {
f_tanpi(self)
}
}
#[inline]
pub(crate) fn compute_twiddle<T: Float + FftTrigonometry + 'static>(
index: usize,
fft_len: usize,
) -> Complex<T>
where
f64: AsPrimitive<T>,
{
let angle = (-2. * index as f64 / fft_len as f64).as_();
let (v_sin, v_cos) = angle.sincos_pi();
Complex {
re: v_cos,
im: v_sin,
}
}