Trait array_math::SliceMath

source ·
pub trait SliceMath<T>: SliceOps<T> {
    // Required methods
    fn recip_assign_all(&mut self)
       where T: Inv<Output = T>;
    fn conj_assign_all(&mut self)
       where T: ComplexFloat;
    fn convolve_direct<Rhs, C>(&self, rhs: &[Rhs]) -> C
       where T: Mul<Rhs> + Copy,
             <T as Mul<Rhs>>::Output: AddAssign + Zero,
             Rhs: Copy,
             C: FromIterator<<T as Mul<Rhs>>::Output>;
    fn convolve_fft<Rhs, C>(&self, rhs: &[Rhs]) -> C
       where T: Float + Copy,
             Rhs: Float + Copy,
             Complex<T>: MulAssign + AddAssign + ComplexFloat<Real = T> + Mul<Complex<Rhs>>,
             <Complex<T> as Mul<Complex<Rhs>>>::Output: ComplexFloat + Into<Complex<<<Complex<T> as Mul<Complex<Rhs>>>::Output as ComplexFloat>::Real>>,
             <<Complex<T> as Mul<Complex<Rhs>>>::Output as ComplexFloat>::Real: Float,
             Complex<Rhs>: MulAssign + AddAssign + ComplexFloat<Real = Rhs>,
             Complex<<<Complex<T> as Mul<Complex<Rhs>>>::Output as ComplexFloat>::Real>: MulAssign + AddAssign + ComplexFloat<Real = <<Complex<T> as Mul<Complex<Rhs>>>::Output as ComplexFloat>::Real>,
             C: FromIterator<<<Complex<T> as Mul<Complex<Rhs>>>::Output as ComplexFloat>::Real>;
    fn fft(&mut self)
       where T: ComplexFloat + MulAssign + AddAssign + From<Complex<<T as ComplexFloat>::Real>>,
             <T as ComplexFloat>::Real: Float;
    fn ifft(&mut self)
       where T: ComplexFloat + MulAssign + AddAssign + From<Complex<<T as ComplexFloat>::Real>>,
             <T as ComplexFloat>::Real: Float;
    fn real_fft(&self, y: &mut [Complex<T>])
       where T: Float,
             Complex<T>: ComplexFloat<Real = T> + MulAssign + AddAssign;
    fn real_ifft(&mut self, x: &[Complex<T>])
       where T: Float,
             Complex<T>: ComplexFloat<Real = T> + MulAssign + AddAssign;
}

Required Methods§

source

fn recip_assign_all(&mut self)
where T: Inv<Output = T>,

source

fn conj_assign_all(&mut self)
where T: ComplexFloat,

source

fn convolve_direct<Rhs, C>(&self, rhs: &[Rhs]) -> C
where T: Mul<Rhs> + Copy, <T as Mul<Rhs>>::Output: AddAssign + Zero, Rhs: Copy, C: FromIterator<<T as Mul<Rhs>>::Output>,

source

fn convolve_fft<Rhs, C>(&self, rhs: &[Rhs]) -> C
where T: Float + Copy, Rhs: Float + Copy, Complex<T>: MulAssign + AddAssign + ComplexFloat<Real = T> + Mul<Complex<Rhs>>, <Complex<T> as Mul<Complex<Rhs>>>::Output: ComplexFloat + Into<Complex<<<Complex<T> as Mul<Complex<Rhs>>>::Output as ComplexFloat>::Real>>, <<Complex<T> as Mul<Complex<Rhs>>>::Output as ComplexFloat>::Real: Float, Complex<Rhs>: MulAssign + AddAssign + ComplexFloat<Real = Rhs>, Complex<<<Complex<T> as Mul<Complex<Rhs>>>::Output as ComplexFloat>::Real>: MulAssign + AddAssign + ComplexFloat<Real = <<Complex<T> as Mul<Complex<Rhs>>>::Output as ComplexFloat>::Real>, C: FromIterator<<<Complex<T> as Mul<Complex<Rhs>>>::Output as ComplexFloat>::Real>,

Performs convolution using FFT.

§Examples

Convolution can be done directly O(n^2) or using FFT O(nlog(n)).

use slice_math::*;
 
let x = [1.0, 0.0, 1.5, 0.0, 0.0, -1.0];
let h = [1.0, 0.6, 0.3];
 
let y_fft: Vec<f64> = x.convolve_fft(&h);
let y_direct: Vec<f64> = x.convolve_direct(&h);
 
let avg_error = y_fft.into_iter()
    .zip(y_direct.into_iter())
    .map(|(y_fft, y_direct)| (y_fft - y_direct).abs())
    .sum::<f64>()/x.len() as f64;
assert!(avg_error < 1.0e-15);
source

fn fft(&mut self)

Performs an iterative, in-place radix-2 FFT algorithm as described in https://en.wikipedia.org/wiki/Cooley%E2%80%93Tukey_FFT_algorithm#Data_reordering,_bit_reversal,_and_in-place_algorithms. If length is not a power of two, it uses the DFT, which is a lot slower.

§Examples
use num::Complex;
use slice_math::*;
 
let x = [1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0]
    .map(|x| <Complex<_> as From<_>>::from(x));
 
let mut y = x;
 
y.as_mut_slice().fft();
y.as_mut_slice().ifft();
 
let avg_error = x.into_iter()
    .zip(y.into_iter())
    .map(|(x, y)| (x - y).norm())
    .sum::<f64>()/x.len() as f64;
assert!(avg_error < 1.0e-16);
source

fn ifft(&mut self)

Performs an iterative, in-place radix-2 IFFT algorithm as described in https://en.wikipedia.org/wiki/Cooley%E2%80%93Tukey_FFT_algorithm#Data_reordering,_bit_reversal,_and_in-place_algorithms. If length is not a power of two, it uses the IDFT, which is a lot slower.

§Examples
use num::Complex;
use slice_math::*;
 
let x = [1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0]
    .map(|x| <Complex<_> as From<_>>::from(x));
 
let mut y = x;
 
y.as_mut_slice().fft();
y.as_mut_slice().ifft();
 
let avg_error = x.into_iter()
    .zip(y.into_iter())
    .map(|(x, y)| (x - y).norm())
    .sum::<f64>()/x.len() as f64;
assert!(avg_error < 1.0e-16);
source

fn real_fft(&self, y: &mut [Complex<T>])
where T: Float, Complex<T>: ComplexFloat<Real = T> + MulAssign + AddAssign,

source

fn real_ifft(&mut self, x: &[Complex<T>])
where T: Float, Complex<T>: ComplexFloat<Real = T> + MulAssign + AddAssign,

Object Safety§

This trait is not object safe.

Implementations on Foreign Types§

source§

impl<T> SliceMath<T> for [T]

source§

fn recip_assign_all(&mut self)
where T: Inv<Output = T>,

source§

fn conj_assign_all(&mut self)
where T: ComplexFloat,

source§

fn convolve_direct<Rhs, C>(&self, rhs: &[Rhs]) -> C
where T: Mul<Rhs> + Copy, <T as Mul<Rhs>>::Output: AddAssign + Zero, Rhs: Copy, C: FromIterator<<T as Mul<Rhs>>::Output>,

source§

fn convolve_fft<Rhs, C>(&self, rhs: &[Rhs]) -> C
where T: Float + Copy, Rhs: Float + Copy, Complex<T>: MulAssign + AddAssign + ComplexFloat<Real = T> + Mul<Complex<Rhs>>, <Complex<T> as Mul<Complex<Rhs>>>::Output: ComplexFloat + Into<Complex<<<Complex<T> as Mul<Complex<Rhs>>>::Output as ComplexFloat>::Real>>, <<Complex<T> as Mul<Complex<Rhs>>>::Output as ComplexFloat>::Real: Float, Complex<Rhs>: MulAssign + AddAssign + ComplexFloat<Real = Rhs>, Complex<<<Complex<T> as Mul<Complex<Rhs>>>::Output as ComplexFloat>::Real>: MulAssign + AddAssign + ComplexFloat<Real = <<Complex<T> as Mul<Complex<Rhs>>>::Output as ComplexFloat>::Real>, C: FromIterator<<<Complex<T> as Mul<Complex<Rhs>>>::Output as ComplexFloat>::Real>,

source§

fn fft(&mut self)

source§

fn ifft(&mut self)

source§

fn real_fft(&self, y: &mut [Complex<T>])
where T: Float, Complex<T>: ComplexFloat<Real = T> + MulAssign + AddAssign,

source§

fn real_ifft(&mut self, x: &[Complex<T>])
where T: Float, Complex<T>: ComplexFloat<Real = T> + MulAssign + AddAssign,

Implementors§