extern crate strided; extern crate num; extern crate simple_parallel;
#[cfg(feature = "unstable")]
use std::f64;
#[cfg(feature = "unstable")]
use num::complex::{Complex, Complex64};
#[cfg(feature = "unstable")]
use strided::{MutStride, Stride};
#[cfg(feature = "unstable")]
fn fft(input: Stride<Complex64>, mut output: MutStride<Complex64>) {
assert!(input.len() == output.len() && input.len().count_ones() == 1);
if input.len() == 1 {
output[0] = input[0];
return
}
let (evens, odds) = input.substrides2();
let (mut start, mut end) = output.split_at_mut(input.len() / 2);
if evens.len() >= 2 {
simple_parallel::both((evens, start.reborrow()), (odds, end.reborrow()),
|(in_, out)| fft(in_, out));
} else {
fft(evens, start.reborrow());
fft(odds, end.reborrow());
}
let twiddle = Complex::from_polar(&1.0, &(-2.0 * f64::consts::PI / input.len() as f64));
let mut factor = Complex::new(1., 0.);
for (even, odd) in start.iter_mut().zip(end.iter_mut()) {
let twiddled = factor * *odd;
let e = *even;
*even = e + twiddled;
*odd = e - twiddled;
factor = factor * twiddle;
}
}
#[cfg(feature = "unstable")]
fn main() {
let a = [Complex::new(3., 0.), Complex::new(1., 0.),
Complex::new(2., 0.), Complex::new(-1., 0.)];
let mut b = [Complex::new(0., 0.); 4];
fft(Stride::new(&a), MutStride::new(&mut b));
println!("forward:\n{:?}\n->\n{:?}", a, b);
}
#[cfg(not(feature = "unstable"))]
fn main() {
println!("compile with --features unstable")
}