Skip to main content

oxifft/
lib.rs

1//! # OxiFFT
2//!
3//! Pure Rust implementation of FFTW - the Fastest Fourier Transform in the West.
4//!
5//! OxiFFT provides high-performance FFT routines with:
6//! - Complex DFT (forward and inverse)
7//! - Real FFT (R2C/C2R)
8//! - DCT/DST transforms
9//! - Multi-dimensional transforms
10//! - Batch processing
11//! - SIMD optimization
12//! - Threading support
13//! - Wisdom system for plan caching
14//!
15//! ## Quick Start
16//!
17//! ```ignore
18//! use oxifft::{Complex, Direction, Flags, Plan};
19//!
20//! // Create a plan for 256-point forward FFT
21//! let plan = Plan::dft_1d(256, Direction::Forward, Flags::MEASURE)?;
22//!
23//! // Execute the transform
24//! let mut input = vec![Complex::new(1.0, 0.0); 256];
25//! let mut output = vec![Complex::zero(); 256];
26//! plan.execute(&mut input, &mut output);
27//! ```
28
29// Allow pedantic/nursery warnings that are intentional in FFT code:
30#![allow(clippy::similar_names)] // fwd/bwd, real/imag pairs are intentionally similar
31#![allow(clippy::many_single_char_names)] // FFT math uses i, j, k, n, m by convention
32#![allow(clippy::cast_precision_loss)] // FFT size computations use float for math
33#![allow(clippy::cast_sign_loss)] // stride/offset calculations need signed/unsigned
34#![allow(clippy::cast_possible_wrap)] // stride calculations need careful wrapping
35#![allow(clippy::missing_panics_doc)] // many internal functions assert preconditions
36#![allow(clippy::must_use_candidate)] // internal helpers don't need must_use
37#![allow(clippy::missing_const_for_fn)] // const fn often not useful for runtime FFT
38#![allow(clippy::doc_markdown)] // allow flexibility in documentation formatting
39#![allow(clippy::return_self_not_must_use)] // builder patterns are fine
40#![allow(clippy::incompatible_msrv)] // allow using newer features when available
41#![allow(clippy::assign_op_pattern)] // a = a + b is fine for clarity
42#![allow(clippy::needless_range_loop)] // explicit loops are clearer for FFT indices
43#![allow(clippy::wildcard_imports)] // use super::* in submodules is fine
44#![allow(clippy::unused_self)] // trait impls may have unused self
45#![allow(clippy::too_many_arguments)] // FFT plans legitimately need many params
46#![allow(clippy::redundant_closure_for_method_calls)] // allow explicit closures
47#![allow(clippy::ptr_as_ptr)] // casting raw pointers is common in FFT
48#![allow(clippy::fn_to_numeric_cast)] // allow function pointer casts
49#![allow(clippy::suboptimal_flops)] // manual FMA control may be intentional
50#![allow(clippy::manual_is_power_of_two)] // explicit bit ops may be clearer
51#![allow(clippy::if_then_some_else_none)] // explicit if-else for clarity
52#![allow(clippy::imprecise_flops)] // sqrt of squares may be intentional
53#![allow(clippy::not_unsafe_ptr_arg_deref)] // FFT internal ops are safe
54#![allow(clippy::derivable_impls)] // explicit impls may be clearer
55#![allow(clippy::ptr_eq)] // allow ptr == ptr comparisons
56#![allow(clippy::use_self)] // explicit type names may be clearer
57#![allow(clippy::unnecessary_wraps)] // wrapping for API consistency
58#![allow(clippy::too_many_lines)] // FFT functions can be long
59#![allow(clippy::trivially_copy_pass_by_ref)] // consistent API style
60#![allow(clippy::panic_in_result_fn)] // internal asserts for invariants
61#![allow(clippy::match_same_arms)] // clarity in match arms
62#![allow(clippy::suspicious_arithmetic_impl)] // complex arithmetic is intentional
63#![allow(clippy::only_used_in_recursion)] // recursive FFT is intentional
64#![allow(clippy::manual_div_ceil)] // explicit ceiling division
65#![allow(clippy::float_cmp)] // intentional float comparison in tests
66#![allow(clippy::cast_possible_truncation)] // deliberate truncation
67#![allow(clippy::if_not_else)] // explicit negation for clarity
68#![allow(clippy::manual_assert)] // if-panic patterns for clarity
69#![allow(clippy::useless_let_if_seq)] // sequential mutation may be clearer
70#![allow(clippy::ptr_cast_constness)] // pointer const casting common in FFT
71#![allow(clippy::derive_partial_eq_without_eq)] // not all types are Eq
72#![allow(clippy::format_push_string)] // format!() for clarity
73#![allow(clippy::redundant_closure)] // explicit closures may be clearer
74#![allow(clippy::significant_drop_tightening)] // locking patterns are intentional
75#![allow(clippy::explicit_iter_loop)] // for i in iter.iter() for clarity
76#![allow(clippy::unreadable_literal)] // FFT constants may use scientific notation
77#![allow(clippy::missing_errors_doc)] // FFT error handling is self-explanatory
78#![allow(clippy::manual_let_else)] // match patterns are clearer for Option handling
79#![allow(clippy::type_complexity)] // complex return types are needed for FFT APIs
80#![allow(clippy::needless_pass_by_value)] // API consistency for flags/options
81#![allow(clippy::option_if_let_else)] // explicit if-let-else for clarity
82#![allow(clippy::struct_field_names)] // field names matching type is intentional
83#![allow(clippy::duplicate_mod)] // conditional compilation requires this
84#![allow(clippy::suspicious_operation_groupings)] // FFT math has specific operator groupings
85#![allow(clippy::verbose_bit_mask)] // explicit bit masks for clarity
86#![allow(clippy::type_repetition_in_bounds)] // MPI traits need separate bounds
87#![allow(clippy::no_effect_underscore_binding)] // placeholder variables for future use
88#![allow(clippy::manual_clamp)] // explicit bounds checking is clearer
89#![allow(clippy::used_underscore_binding)] // underscore prefix for internal use
90#![cfg_attr(not(feature = "std"), no_std)]
91#![cfg_attr(feature = "portable_simd", feature(portable_simd))]
92
93#[cfg(not(feature = "std"))]
94extern crate alloc;
95
96// Internal prelude for no_std compatibility
97pub(crate) mod prelude;
98
99pub mod api;
100#[cfg(feature = "const-fft")]
101pub mod const_fft;
102pub mod dft;
103#[cfg(any(feature = "gpu", feature = "cuda", feature = "metal"))]
104pub mod gpu;
105pub mod kernel;
106#[cfg(feature = "mpi")]
107pub mod mpi;
108#[cfg(feature = "pruned")]
109pub mod pruned;
110pub mod rdft;
111pub mod reodft;
112pub mod simd;
113#[cfg(feature = "sparse")]
114pub mod sparse;
115#[cfg(feature = "streaming")]
116pub mod streaming;
117pub mod support;
118pub mod threading;
119#[cfg(feature = "wasm")]
120pub mod wasm;
121
122// Advanced FFT transforms
123pub mod autodiff;
124pub mod conv;
125#[cfg(feature = "std")]
126pub mod frft;
127#[cfg(feature = "std")]
128pub mod nufft;
129
130// Re-export commonly used types
131pub use api::{
132    fft, fft2d, fft2d_split, fft3d_split, fft_batch, fft_nd, fft_nd_split, fft_split, ifft, ifft2d,
133    ifft2d_split, ifft3d_split, ifft_batch, ifft_nd, ifft_nd_split, ifft_split, irfft, irfft2d,
134    irfft3d, irfft_batch, irfft_nd, rfft, rfft2d, rfft3d, rfft_batch, rfft_nd, Direction, Flags,
135    GuruPlan, Plan, Plan2D, Plan3D, PlanND, R2rKind, R2rPlan, RealPlan, RealPlan2D, RealPlan3D,
136    RealPlanKind, RealPlanND, SplitPlan, SplitPlan2D, SplitPlan3D, SplitPlanND,
137};
138pub use kernel::{Complex, Float, IoDim, Tensor};
139
140// Re-export F128 when f128-support feature is enabled
141#[cfg(feature = "f128-support")]
142pub use kernel::F128;
143
144// Re-export F16 when f16-support feature is enabled
145#[cfg(feature = "f16-support")]
146pub use kernel::F16;
147
148// Re-export sparse FFT when sparse feature is enabled
149#[cfg(feature = "sparse")]
150pub use sparse::{sparse_fft, sparse_ifft, SparsePlan, SparseResult};
151
152// Re-export pruned FFT when pruned feature is enabled
153#[cfg(feature = "pruned")]
154pub use pruned::{
155    fft_pruned_input, fft_pruned_output, goertzel, goertzel_multi, PrunedPlan, PruningMode,
156};
157
158// Re-export WASM bindings when wasm feature is enabled
159#[cfg(feature = "wasm")]
160pub use wasm::{fft_f32, fft_f64, ifft_f32, ifft_f64, rfft_f64, WasmFft, WasmSimdF32, WasmSimdF64};
161
162// Re-export streaming FFT when streaming feature is enabled
163#[cfg(feature = "streaming")]
164pub use streaming::{
165    blackman, cola_normalization, hamming, hann, istft, kaiser, magnitude_spectrogram,
166    phase_spectrogram, power_spectrogram, rectangular, stft, RingBuffer, StreamingFft,
167    WindowFunction,
168};
169
170// Re-export compile-time FFT when const-fft feature is enabled
171#[cfg(feature = "const-fft")]
172pub use const_fft::{
173    const_cos, const_sin, fft_fixed, fft_fixed_inplace, ifft_fixed, ifft_fixed_inplace,
174    twiddle_factor, ConstFft, ConstFftImpl,
175};
176
177// Re-export GPU FFT when gpu/cuda/metal feature is enabled
178#[cfg(any(feature = "gpu", feature = "cuda", feature = "metal"))]
179pub use gpu::{
180    best_backend, is_gpu_available, query_capabilities, GpuBackend, GpuBuffer, GpuCapabilities,
181    GpuDirection, GpuError, GpuFft, GpuFftEngine, GpuPlan, GpuResult,
182};
183
184// Re-export low-level DFT functions for advanced users
185pub use dft::solvers::{
186    ct::{
187        fft_radix2, fft_radix2_inplace, ifft_radix2, ifft_radix2_inplace, ifft_radix2_normalized,
188    },
189    direct::{dft_direct, idft_direct, idft_direct_normalized},
190    nop::dft_nop,
191};
192
193// Re-export DCT/DST/DHT convenience functions
194pub use rdft::solvers::{dct1, dct2, dct3, dct4, dht, dst1, dst2, dst3, dst4};
195
196// Re-export memory allocation utilities
197pub use api::{
198    alloc_complex, alloc_complex_aligned, alloc_real, alloc_real_aligned, is_aligned,
199    AlignedBuffer, DEFAULT_ALIGNMENT,
200};
201
202// Re-export NUFFT (Non-uniform FFT)
203#[cfg(feature = "std")]
204pub use nufft::{
205    nufft_type1, nufft_type2, nufft_type3, Nufft, NufftError, NufftOptions, NufftResult, NufftType,
206};
207
208// Re-export FrFT (Fractional Fourier Transform)
209#[cfg(feature = "std")]
210pub use frft::{frft, frft_checked, ifrft, ifrft_checked, Frft, FrftError, FrftResult};
211
212// Re-export Convolution functions
213pub use conv::{
214    convolve, convolve_circular, convolve_complex, convolve_complex_mode, convolve_mode,
215    convolve_with_mode, correlate, correlate_complex, correlate_complex_mode, correlate_mode,
216    polynomial_multiply, polynomial_multiply_complex, polynomial_power, ConvMode,
217};
218
219// Re-export Automatic Differentiation
220pub use autodiff::{
221    fft_dual, fft_jacobian, grad_fft, grad_ifft, jvp_fft, vjp_fft, DiffFftPlan, Dual, DualComplex,
222};