denyhosts/clamav/libclamav_rust/.cargo/vendor/rustdct/src/twiddles.rs

84 lines
2.4 KiB
Rust

use rustfft::num_complex::Complex;
use std::f64;
use crate::DctNum;
#[inline(always)]
pub fn single_twiddle<T: DctNum>(i: usize, fft_len: usize) -> Complex<T> {
let angle_constant = f64::consts::PI * -2f64 / fft_len as f64;
let c = Complex::from_polar(1f64, angle_constant * i as f64);
Complex {
re: T::from_f64(c.re).unwrap(),
im: T::from_f64(c.im).unwrap(),
}
}
// Same as above, but only return the real portion, not the imaginary portion
#[inline(always)]
pub fn single_twiddle_re<T: DctNum>(i: usize, fft_len: usize) -> T {
let angle_constant = f64::consts::PI * -2f64 / fft_len as f64;
let c = (angle_constant * i as f64).cos();
T::from_f64(c).unwrap()
}
// Same as above, but we add 0.5 to 0 before
#[inline(always)]
pub fn single_twiddle_halfoffset<T: DctNum>(i: usize, fft_len: usize) -> Complex<T> {
let angle_constant = f64::consts::PI * -2f64 / fft_len as f64;
let c = Complex::from_polar(1f64, angle_constant * (i as f64 + 0.5f64));
Complex {
re: T::from_f64(c.re).unwrap(),
im: T::from_f64(c.im).unwrap(),
}
}
#[cfg(test)]
mod unit_tests {
use super::*;
use std::f32;
use crate::test_utils::fuzzy_cmp;
#[test]
fn test_single() {
let len = 20;
for i in 0..len {
let single: Complex<f32> = single_twiddle(i, len);
let single_inverse: Complex<f32> = single_twiddle(i, len).conj();
let expected =
Complex::from_polar(1f32, -2f32 * f32::consts::PI * i as f32 / len as f32);
let expected_inverse =
Complex::from_polar(1f32, 2f32 * f32::consts::PI * i as f32 / len as f32);
assert!(
fuzzy_cmp(single.re, expected.re, 0.001f32),
"forwards, i = {}",
i
);
assert!(
fuzzy_cmp(single.im, expected.im, 0.001f32),
"forwards, i = {}",
i
);
assert!(
fuzzy_cmp(single_inverse.re, expected_inverse.re, 0.001f32),
"inverse, i = {}",
i
);
assert!(
fuzzy_cmp(single_inverse.im, expected_inverse.im, 0.001f32),
"inverse, i = {}",
i
);
}
}
}