use std::ops::Deref;
use crate::ring::*;
use crate::seq::*;
pub mod bluestein;
pub mod complex_fft;
pub mod cooley_tuckey;
pub mod factor_fft;
pub mod radix3;
pub trait FFTAlgorithm<R: ?Sized + RingBase> {
fn len(&self) -> usize;
fn root_of_unity<S>(&self, ring: S) -> &R::Element
where
S: RingStore<Type = R> + Copy;
fn unordered_fft_permutation(&self, i: usize) -> usize;
fn unordered_fft_permutation_inv(&self, i: usize) -> usize;
fn fft<V, S>(&self, mut values: V, ring: S)
where
V: SwappableVectorViewMut<R::Element>,
S: RingStore<Type = R> + Copy,
{
self.unordered_fft(&mut values, ring);
permute::permute_inv(&mut values, |i| self.unordered_fft_permutation(i));
}
fn inv_fft<V, S>(&self, mut values: V, ring: S)
where
V: SwappableVectorViewMut<R::Element>,
S: RingStore<Type = R> + Copy,
{
permute::permute(&mut values, |i| self.unordered_fft_permutation(i));
self.unordered_inv_fft(&mut values, ring);
}
fn unordered_fft<V, S>(&self, values: V, ring: S)
where
V: SwappableVectorViewMut<R::Element>,
S: RingStore<Type = R> + Copy;
fn unordered_inv_fft<V, S>(&self, values: V, ring: S)
where
V: SwappableVectorViewMut<R::Element>,
S: RingStore<Type = R> + Copy;
}
impl<T, R> FFTAlgorithm<R> for T
where
R: ?Sized + RingBase,
T: Deref,
T::Target: FFTAlgorithm<R>,
{
fn len(&self) -> usize { self.deref().len() }
fn root_of_unity<S>(&self, ring: S) -> &R::Element
where
S: RingStore<Type = R> + Copy,
{
self.deref().root_of_unity(ring)
}
fn unordered_fft_permutation(&self, i: usize) -> usize { self.deref().unordered_fft_permutation(i) }
fn unordered_fft_permutation_inv(&self, i: usize) -> usize { self.deref().unordered_fft_permutation_inv(i) }
fn fft<V, S>(&self, values: V, ring: S)
where
V: SwappableVectorViewMut<<R as RingBase>::Element>,
S: RingStore<Type = R> + Copy,
{
self.deref().fft(values, ring)
}
fn inv_fft<V, S>(&self, values: V, ring: S)
where
V: SwappableVectorViewMut<<R as RingBase>::Element>,
S: RingStore<Type = R> + Copy,
{
self.deref().inv_fft(values, ring)
}
fn unordered_fft<V, S>(&self, values: V, ring: S)
where
V: SwappableVectorViewMut<<R as RingBase>::Element>,
S: RingStore<Type = R> + Copy,
{
self.deref().unordered_fft(values, ring)
}
fn unordered_inv_fft<V, S>(&self, values: V, ring: S)
where
V: SwappableVectorViewMut<<R as RingBase>::Element>,
S: RingStore<Type = R> + Copy,
{
self.deref().unordered_inv_fft(values, ring)
}
}