Trait array_math::ArrayMath
source · pub trait ArrayMath<T, const N: usize>: ArrayOps<T, N> {
Show 49 methods
// Required methods
fn sum(self) -> T
where T: AddAssign + Zero;
fn product(self) -> T
where T: MulAssign + One;
fn variance(self) -> <T as Mul>::Output
where Self: ArrayOps<T, N> + Copy,
u8: Into<T>,
T: Div<Output: Mul<Output: Neg<Output = <T as Mul>::Output>> + Copy> + Mul<Output: AddAssign> + AddAssign + Zero,
[(); { _ }]:;
fn variance16(self) -> <T as Mul>::Output
where Self: ArrayOps<T, N> + Copy,
u16: Into<T>,
T: Div<Output: Mul<Output: Neg<Output = <T as Mul>::Output>> + Copy> + Mul<Output: AddAssign> + AddAssign + Zero,
[(); { _ }]:;
fn variance32(self) -> <T as Mul>::Output
where Self: ArrayOps<T, N> + Copy,
u32: Into<T>,
T: Div<Output: Mul<Output: Neg<Output = <T as Mul>::Output>> + Copy> + Mul<Output: AddAssign> + AddAssign + Zero,
[(); { _ }]:;
fn variance64(self) -> <T as Mul>::Output
where Self: ArrayOps<T, N> + Copy,
u64: Into<T>,
T: Div<Output: Mul<Output: Neg<Output = <T as Mul>::Output>> + Copy> + Mul<Output: AddAssign> + AddAssign + Zero;
fn avg(self) -> <T as Div>::Output
where u8: Into<T>,
T: Div + AddAssign + Zero,
[(); { _ }]:;
fn avg16(self) -> <T as Div>::Output
where u16: Into<T>,
T: Div + AddAssign + Zero,
[(); { _ }]:;
fn avg32(self) -> <T as Div>::Output
where u32: Into<T>,
T: Div + AddAssign + Zero,
[(); { _ }]:;
fn avg64(self) -> <T as Div>::Output
where u64: Into<T>,
T: Div + AddAssign + Zero;
fn geometric_mean(self) -> <T as Pow<<T as Inv>::Output>>::Output
where u8: Into<T>,
T: MulAssign + One + Pow<<T as Inv>::Output> + Inv,
[(); { _ }]:;
fn geometric_mean16(self) -> <T as Pow<<T as Inv>::Output>>::Output
where u16: Into<T>,
T: MulAssign + One + Pow<<T as Inv>::Output> + Inv,
[(); { _ }]:;
fn geometric_mean32(self) -> <T as Pow<<T as Inv>::Output>>::Output
where u32: Into<T>,
T: MulAssign + One + Pow<<T as Inv>::Output> + Inv,
[(); { _ }]:;
fn geometric_mean64(self) -> <T as Pow<<T as Inv>::Output>>::Output
where u64: Into<T>,
T: MulAssign + One + Pow<<T as Inv>::Output> + Inv;
fn mul_dot<Rhs>(self, rhs: [Rhs; N]) -> <T as Mul<Rhs>>::Output
where T: Mul<Rhs, Output: AddAssign + Zero>;
fn magnitude_squared(self) -> <T as Mul<T>>::Output
where T: Mul<T, Output: AddAssign + Zero> + Copy;
fn magnitude(self) -> <T as Mul<T>>::Output
where T: Mul<T, Output: AddAssign + Zero + Float> + Copy;
fn magnitude_inv(self) -> <T as Mul<T>>::Output
where T: Mul<T, Output: AddAssign + Zero + Float> + Copy;
fn normalize(self) -> [<T as Mul<<T as Mul<T>>::Output>>::Output; N]
where T: Mul<T, Output: AddAssign + Zero + Float + Copy> + Mul<<T as Mul<T>>::Output> + Copy;
fn normalize_to<Rhs>(
self,
magnitude: Rhs
) -> [<T as Mul<<<T as Mul<T>>::Output as Mul<Rhs>>::Output>>::Output; N]
where T: Mul<T, Output: AddAssign + Zero + Float + Mul<Rhs, Output: Copy>> + Mul<<<T as Mul<T>>::Output as Mul<Rhs>>::Output> + Copy;
fn normalize_assign(&mut self)
where T: Mul<T, Output: AddAssign + Zero + Float + Copy> + MulAssign<<T as Mul<T>>::Output> + Copy;
fn normalize_assign_to<Rhs>(&mut self, magnitude: Rhs)
where T: Mul<T, Output: AddAssign + Zero + Float + Mul<Rhs, Output: Copy>> + MulAssign<<<T as Mul<T>>::Output as Mul<Rhs>>::Output> + Copy;
fn polynomial<Rhs>(self, rhs: Rhs) -> T
where T: AddAssign + MulAssign<Rhs> + Zero,
Rhs: Copy;
fn convolve_direct<Rhs, const M: usize>(
&self,
rhs: &[Rhs; M]
) -> [<T as Mul<Rhs>>::Output; { _ }]
where T: Mul<Rhs, Output: AddAssign + Zero> + Copy,
Rhs: Copy;
fn convolve_real_fft<Rhs, const M: usize>(
self,
rhs: [Rhs; M]
) -> [<<Complex<T> as Mul<Complex<Rhs>>>::Output as ComplexFloat>::Real; { _ }]
where T: Float,
Rhs: Float,
Complex<T>: MulAssign + AddAssign + ComplexFloat<Real = T> + Mul<Complex<Rhs>, Output: ComplexFloat<Real: Float>>,
Complex<Rhs>: MulAssign + AddAssign + ComplexFloat<Real = Rhs>,
<Complex<T> as Mul<Complex<Rhs>>>::Output: ComplexFloat<Real: Float> + Into<Complex<<<Complex<T> as Mul<Complex<Rhs>>>::Output as ComplexFloat>::Real>>,
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>,
[(); { _ }]:;
fn convolve_fft<Rhs, const M: usize>(
self,
rhs: [Rhs; M]
) -> [<T as Mul<Rhs>>::Output; { _ }]
where T: ComplexFloat<Real: Float> + MulAssign + AddAssign + From<Complex<T::Real>> + Sum + Mul<Rhs>,
Rhs: ComplexFloat<Real: Float> + MulAssign + AddAssign + From<Complex<Rhs::Real>> + Sum,
<T as Mul<Rhs>>::Output: ComplexFloat<Real: Float> + MulAssign + AddAssign + From<Complex<<<T as Mul<Rhs>>::Output as ComplexFloat>::Real>> + Sum,
[(); { _ }]:;
fn recip_all(self) -> [<T as Inv>::Output; N]
where T: Inv;
fn recip_assign_all(&mut self)
where T: Inv<Output = T>;
fn conj_all(self) -> Self
where T: ComplexFloat;
fn conj_assign_all(&mut self)
where T: ComplexFloat;
fn dtft(&self, omega: T::Real) -> T
where T: ComplexFloat<Real: Float> + MulAssign + AddAssign + From<Complex<T::Real>> + Sum;
fn real_dtft(&self, omega: T) -> Complex<T>
where T: Float,
Complex<T>: ComplexFloat<Real = T> + MulAssign + AddAssign;
fn fft(&mut self)
where T: ComplexFloat<Real: Float> + MulAssign + AddAssign + From<Complex<T::Real>> + Sum;
fn ifft(&mut self)
where T: ComplexFloat<Real: Float> + MulAssign + AddAssign + From<Complex<T::Real>> + Sum;
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;
fn chebyshev_polynomial(kind: usize, order: usize) -> Option<[T; N]>
where T: Copy + Add<Output = T> + Sub<Output = T> + Neg<Output = T> + AddAssign + Mul<Output = T> + One + Zero;
fn bartlett_window() -> Self
where T: Float;
fn parzen_window() -> Self
where T: Float;
fn belch_window() -> Self
where T: Float;
fn sine_window() -> Self
where T: Float + FloatConst;
fn power_of_sine_window<A>(alpha: A) -> Self
where T: Float + FloatConst + Pow<A, Output = T>,
A: Copy;
fn hann_window() -> Self
where T: Float + FloatConst;
fn hamming_window() -> Self
where T: Float + FloatConst;
fn blackman_window() -> Self
where T: Float + FloatConst;
fn nuttal_window() -> Self
where T: Float + FloatConst;
fn blackman_nuttal_window() -> Self
where T: Float + FloatConst;
fn blackman_harris_window() -> Self
where T: Float + FloatConst;
fn flat_top_window() -> Self
where T: Float + FloatConst;
}Required Methods§
fn sum(self) -> T
fn product(self) -> T
fn variance(self) -> <T as Mul>::Output
fn variance16(self) -> <T as Mul>::Output
fn variance32(self) -> <T as Mul>::Output
fn variance64(self) -> <T as Mul>::Output
fn avg(self) -> <T as Div>::Output
fn avg16(self) -> <T as Div>::Output
fn avg32(self) -> <T as Div>::Output
fn avg64(self) -> <T as Div>::Output
fn geometric_mean(self) -> <T as Pow<<T as Inv>::Output>>::Output
fn geometric_mean16(self) -> <T as Pow<<T as Inv>::Output>>::Output
fn geometric_mean32(self) -> <T as Pow<<T as Inv>::Output>>::Output
fn geometric_mean64(self) -> <T as Pow<<T as Inv>::Output>>::Output
fn mul_dot<Rhs>(self, rhs: [Rhs; N]) -> <T as Mul<Rhs>>::Output
fn magnitude_squared(self) -> <T as Mul<T>>::Output
fn magnitude(self) -> <T as Mul<T>>::Output
fn magnitude_inv(self) -> <T as Mul<T>>::Output
fn normalize(self) -> [<T as Mul<<T as Mul<T>>::Output>>::Output; N]
fn normalize_to<Rhs>( self, magnitude: Rhs ) -> [<T as Mul<<<T as Mul<T>>::Output as Mul<Rhs>>::Output>>::Output; N]
fn normalize_assign(&mut self)
fn normalize_assign_to<Rhs>(&mut self, magnitude: Rhs)
fn polynomial<Rhs>(self, rhs: Rhs) -> T
sourcefn convolve_direct<Rhs, const M: usize>(
&self,
rhs: &[Rhs; M]
) -> [<T as Mul<Rhs>>::Output; { _ }]
fn convolve_direct<Rhs, const M: usize>( &self, rhs: &[Rhs; M] ) -> [<T as Mul<Rhs>>::Output; { _ }]
Performs direct convolution. This is equivalent to a polynomial multiplication.
§Examples
Convolving a unit impulse yields the impulse response.
#![feature(generic_const_exprs)]
use array_math::*;
let x = [1.0];
let h = [1.0, 0.6, 0.3];
let y = x.convolve_direct(&h);
assert_eq!(y, h);Convolution can be done directly O(n^2) or using FFT O(nlog(n)).
#![feature(generic_arg_infer)]
#![feature(generic_const_exprs)]
use array_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 = x.convolve_real_fft(h);
let y_direct = x.convolve_direct(&h);
let avg_error = y_fft.comap(y_direct, |y_fft: f64, y_direct: f64| (y_fft - y_direct).abs()).avg();
assert!(avg_error < 1.0e-15);sourcefn convolve_real_fft<Rhs, const M: usize>(
self,
rhs: [Rhs; M]
) -> [<<Complex<T> as Mul<Complex<Rhs>>>::Output as ComplexFloat>::Real; { _ }]where
T: Float,
Rhs: Float,
Complex<T>: MulAssign + AddAssign + ComplexFloat<Real = T> + Mul<Complex<Rhs>, Output: ComplexFloat<Real: Float>>,
Complex<Rhs>: MulAssign + AddAssign + ComplexFloat<Real = Rhs>,
<Complex<T> as Mul<Complex<Rhs>>>::Output: ComplexFloat<Real: Float> + Into<Complex<<<Complex<T> as Mul<Complex<Rhs>>>::Output as ComplexFloat>::Real>>,
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>,
[(); { _ }]:,
fn convolve_real_fft<Rhs, const M: usize>(
self,
rhs: [Rhs; M]
) -> [<<Complex<T> as Mul<Complex<Rhs>>>::Output as ComplexFloat>::Real; { _ }]where
T: Float,
Rhs: Float,
Complex<T>: MulAssign + AddAssign + ComplexFloat<Real = T> + Mul<Complex<Rhs>, Output: ComplexFloat<Real: Float>>,
Complex<Rhs>: MulAssign + AddAssign + ComplexFloat<Real = Rhs>,
<Complex<T> as Mul<Complex<Rhs>>>::Output: ComplexFloat<Real: Float> + Into<Complex<<<Complex<T> as Mul<Complex<Rhs>>>::Output as ComplexFloat>::Real>>,
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>,
[(); { _ }]:,
Performs convolution using FFT.
§Examples
Convolution can be done directly O(n^2) or using FFT O(nlog(n)).
#![feature(generic_arg_infer)]
#![feature(generic_const_exprs)]
use array_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 = x.convolve_real_fft(h);
let y_direct = x.convolve_direct(&h);
let avg_error = y_fft.comap(y_direct, |y_fft: f64, y_direct: f64| (y_fft - y_direct).abs()).avg();
assert!(avg_error < 1.0e-15);fn convolve_fft<Rhs, const M: usize>(
self,
rhs: [Rhs; M]
) -> [<T as Mul<Rhs>>::Output; { _ }]where
T: ComplexFloat<Real: Float> + MulAssign + AddAssign + From<Complex<T::Real>> + Sum + Mul<Rhs>,
Rhs: ComplexFloat<Real: Float> + MulAssign + AddAssign + From<Complex<Rhs::Real>> + Sum,
<T as Mul<Rhs>>::Output: ComplexFloat<Real: Float> + MulAssign + AddAssign + From<Complex<<<T as Mul<Rhs>>::Output as ComplexFloat>::Real>> + Sum,
[(); { _ }]:,
fn recip_all(self) -> [<T as Inv>::Output; N]where
T: Inv,
fn recip_assign_all(&mut self)where
T: Inv<Output = T>,
fn conj_all(self) -> Selfwhere
T: ComplexFloat,
fn conj_assign_all(&mut self)where
T: ComplexFloat,
fn dtft(&self, omega: T::Real) -> T
fn real_dtft(&self, omega: T) -> Complex<T>
sourcefn fft(&mut self)
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 N is not a power of two, it uses the DFT, which is a lot slower.
§Examples
#![feature(generic_const_exprs)]
use num::Complex;
use array_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.fft();
y.ifft();
let avg_error = x.comap(y, |x, y| (x - y).norm()).avg();
assert!(avg_error < 1.0e-16);sourcefn ifft(&mut self)
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 N is not a power of two, it uses the IDFT, which is a lot slower.
§Examples
#![feature(generic_const_exprs)]
use num::Complex;
use array_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.fft();
y.ifft();
let avg_error = x.comap(y, |x, y| (x - y).norm()).avg();
assert!(avg_error < 1.0e-16);sourcefn real_fft(&self, y: &mut [Complex<T>; { _ }])
fn real_fft(&self, y: &mut [Complex<T>; { _ }])
Performs the FFT on an array of real floating-point numbers of length N.
The result is an array of complex numbers of length N/2 + 1.
This is truncated because the last half of the values are redundant, since they are a conjugate mirror-image of the first half.
if N is not a power of two, the naive DFT is used instead, which is a lot slower.
§Examples
#![feature(generic_arg_infer)]
#![feature(generic_const_exprs)]
use num::{Complex, Zero};
use array_math::*;
let x = [1.0, 1.0, 0.0, 0.0];
let mut z = [Complex::zero(); _];
x.real_fft(&mut z);
let mut y = [0.0; _];
y.real_ifft(&z);
assert_eq!(x, y);sourcefn real_ifft(&mut self, x: &[Complex<T>; { _ }])
fn real_ifft(&mut self, x: &[Complex<T>; { _ }])
Performs the IFFT on a truncated array of complex floating-point numbers of length N/2 + 1.
The result is an array of real numbers of length N.
if N is not a power of two, the naive IDFT is used instead, which is a lot slower.
§Examples
#![feature(generic_arg_infer)]
#![feature(generic_const_exprs)]
use num::{Complex, Zero};
use array_math::*;
let x = [1.0, 1.0, 0.0, 0.0];
let mut z = [Complex::zero(); _];
x.real_fft(&mut z);
let mut y = [0.0; _];
y.real_ifft(&z);
assert_eq!(x, y);