Crates.io | easyfft |
lib.rs | easyfft |
version | 0.4.1 |
source | src |
created_at | 2022-09-04 10:41:40.906551 |
updated_at | 2024-02-07 18:12:36.851234 |
description | A library crate providing an easy FFT API for arrays and slices |
homepage | |
repository | https://github.com/WalterSmuts/easyfft |
max_upload_size | |
id | 658237 |
size | 68,044 |
A Rust library crate providing an FFT API for arrays and slices. This crate wraps the rustfft and realfft crates that does the heavy lifting behind the scenes.
real_ifft
.The nightly
dependent features are commented out.
// NOTE: Only required for real arrays
// #![allow(incomplete_features)]
// #![feature(generic_const_exprs)]
use easyfft::prelude::*;
use easyfft::num_complex::Complex;
// Complex arrays
let complex_array = [Complex::new(1.0, 0.0); 100];
let complex_array_dft = complex_array.fft();
let _complex_array_dft_idft = complex_array_dft.ifft();
// Real to complex arrays
let real_array = [1.0; 100];
let _real_array_dft = real_array.fft();
// // Real arrays
// let real_array = [1.0; 100];
// let real_array_dft = real_array.real_fft();
// let _real_array_dft_idft = real_array_dft.real_ifft();
// Complex slices
let complex_slice: &[_] = &[Complex::new(1.0, 0.0); 100];
let complex_slice_dft = complex_slice.fft();
let _complex_slice_dft_idft = complex_slice_dft.ifft();
// Real to complex slices
let real_slice: &[_] = &[1.0; 100];
let _real_slice_dft = real_slice.fft();
// Real slices
let real_slice: &[_] = &[1.0; 100];
let real_slice_dft = real_slice.real_fft();
let _real_slice_dft_idft = real_slice_dft.real_ifft();
// In-place mutation on complex -> complex transforms
let mut complex_slice = [Complex::new(1.0, 0.0); 100];
complex_slice.fft_mut();
complex_slice.ifft_mut();
let mut complex_array = [Complex::new(1.0, 0.0); 100];
complex_array.fft_mut();
complex_array.ifft_mut();
const-realfft
feature requires the nightly
compiler because it depends on
the generic_const_exprs feature.Like rustfft and realfft, easyfft
does NOT rescale output! This is
intentional and done for performance reasons. Many applications do an fft
,
manipulate the data, and do an ifft
before actually analysing the data. The
two normalisation steps (1/len().sqrt()
) can be combined into a single step
1/len()
, halving the number of expensive division instructions.
fallible
featureThe DynRealDft
struct has some associated operations which can panic. This is
because the rust language does not have the ability to encode properties of the
length of slices in the type system. This might become possible in the future
if the rust team manages to extend const generics to fully fledged
dependent types. For now, we're limited to using arrays where we can ensure
these properties. If safety is your primary concern I recommend you take a step
back and consider if you REALLY need to work with slices instead of arrays.
Many applications can get away with knowing the size of their signal at compile
time. You can opt out of these panic-able operations by removing the fallible
feature flag, which is enabled by default.
I generally don't like glob imports because it makes code harder to reason about. Explicit imports means you can easily search for the items and see which packages they come from. I believe there is an exception: Traits. Traits don't allow you to do textual matching to figure out which trait is being used and which package it comes from. Since it's already a bit implicit and convoluted, you may aswell get the benefit of importing all of them in a single short line:
use easyfft::prelude::*;
For this reason, easyfft only exposes Traits via the prelude module.