1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
#![allow(non_camel_case_types)] include!(concat!(env!("OUT_DIR"), "/bindings.rs")); #[cfg(test)] mod tests { use super::*; use libc::{c_float, free, posix_memalign}; use std::{f64, mem::size_of, ptr, slice}; fn impulse_error(n: usize, sign: i32, data: &[f32]) -> f64 { let mut delta_sum: f64 = 0.0; let mut sum: f64 = 0.0; let mut re: f64; let mut im: f64; let mut inner: f64; for i in 0..n { inner = 2.0 * f64::consts::PI * (i as f64) / (n as f64); re = inner.cos(); im = if sign < 0 { -inner.sin() } else { inner.sin() }; sum += re * re + im * im; re = re - (data[2 * i] as f64); im = im - (data[2 * i + 1] as f64); delta_sum += re * re + im * im; } delta_sum.sqrt() / sum.sqrt() } fn test_transform(n: usize, sign: i32) { unsafe { let mut _input = ptr::null_mut(); let mut _output = ptr::null_mut(); match posix_memalign(&mut _input, 32, 2 * n * size_of::<f32>()) { 0 => (), _ => panic!("posix_memalign failed for input array"), } match posix_memalign(&mut _output, 32, 2 * n * size_of::<f32>()) { 0 => (), _ => panic!("posix_memalign failed for output array"), } let input: &mut [c_float] = slice::from_raw_parts_mut(_input as *mut c_float, 2 * n); let output: &mut [c_float] = slice::from_raw_parts_mut(_output as *mut c_float, 2 * n); for i in 0..n { input[2 * i + 0] = 0.0; input[2 * i + 1] = 0.0; } input[2] = 1.0; let p = ffts_init_1d(n, sign); if p.is_null() { panic!("ffts plan unsupported") } ffts_execute(p, _input, _output); println!( " {:3} | {:9} | {:.6E}", sign, n, impulse_error(n, sign, output) ); ffts_free(p); free(_input); free(_output); } } #[test] fn test_ffts_errors() { let mut n: usize = 1; let mut power2: usize = 2; while n <= 18 { test_transform(power2, -1); n += 1; power2 <<= 1; } n = 1; power2 = 2; while n <= 18 { test_transform(power2, 1); n += 1; power2 <<= 1; } } }