1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
//! RustFFT is a high-performance FFT library written in pure Rust.
//!
//! This is an experimental release of RustFFT that enables AVX acceleration. It currently requires a nightly compiler,
//! mainly for the `min_specialization` feature. The eventual plan is to release this experimental version as version 5.0 of RustFFT,
//! but that will not happen until it compiles on stable Rust.
//!
//! ### Usage
//!
//! The recommended way to use RustFFT is to create a [`FftPlanner`](crate::FftPlanner) instance and then call its
//! [`plan_fft`](crate::FftPlanner::plan_fft) method. This method will automatically choose which FFT algorithms are best
//! for a given size and initialize the required buffers and precomputed data.
//!
//! ```
//! // Perform a forward FFT of size 1234
//! use rustfft::{FftPlanner, num_complex::Complex};
//!
//! let mut planner = FftPlanner::new(false);
//! let fft = planner.plan_fft(1234);
//!
//! let mut buffer = vec![Complex{ re: 0.0f32, im: 0.0f32 }; 1234];
//! fft.process_inplace(&mut buffer);
//! ```
//! The planner returns trait objects of the [`Fft`](crate::Fft) trait, allowing for FFT sizes that aren't known
//! until runtime.
//!
//! RustFFT also exposes individual FFT algorithms. For example, if you know beforehand that you need a power-of-two FFT, you can
//! avoid the overhead of the planner and trait object by directly creating instances of the [`Radix4`](crate::algorithm::Radix4) algorithm:
//!
//! ```
//! // Computes a forward FFT of size 4096
//! use rustfft::{Fft, num_complex::Complex, algorithm::Radix4};
//!
//! let fft = Radix4::new(4096, false);
//!
//! let mut buffer = vec![Complex{ re: 0.0f32, im: 0.0f32 }; 4096];
//! fft.process_inplace(&mut buffer);
//! ```
//!
//! For the vast majority of situations, simply using the [`FftPlanner`](crate::FftPlanner) will be enough, but
//! advanced users may have better insight than the planner into which algorithms are best for a specific size. See the
//! [`algorithm`](crate::algorithm) module for a complete list of scalar (non-AVX) algorithms implemented by RustFFT. As noted below,
//! bypassing the planner will prevent any use of AVX instructions.
//!
//! ### AVX Acceleration
//!
//! RustFFT includes algorithms designed to take advantage of the AVX instruction set. To use AVX,
//! simply plan a FFT through the [`FftPlanner`](crate::FftPlanner) on a machine which supports the `avx` and `fma` features.
//! Benchmarking shows that while using AVX, RustFFT computes FFTs at equal or faster speeds than [FFTW](http://www.fftw.org/)!
//!
//! If your machine doesn't support AVX, the [`FftPlanner`](crate::FftPlanner) will fall back to scalar algorithms. If you'd rather just not compute
//! a FFT at all if AVX isn't available, you can instead create an instance of the [`FftPlannerAvx`](crate::FftPlannerAvx) struct and plan through that.
//!
//! For the time being, individual AVX algorithms can't be constructed outside of the planner. This may change eventually.
//!
//! ### AVX Performance Tips
//!
//! The performance of any given FFT size is heavily dependent on that size's [prime factorization](https://en.wikipedia.org/wiki/Prime_number#Unique_factorization).
//! It's common in FFT libraries (including RustFFT's scalar implementation) for powers of two to be the fastest, but that's not the case for RustFFT's AVX implementation.
//! RustFFT's AVX implementation is fastest when computing any size of the form `2^n * 3^m` -- which includes powers of two, but isn't restricted to them.
//!
//! Any FFT where all prime factors are 11 or smaller (For example, 10164 = `2*2*3*7*11*11`) can be computed very quickly.
//!
//! All other FFT sizes, such as prime numbers, and composite numbers where the largest prime factor is greater than 11, will be noticeably slower.
//! For example, 1201 (prime number) takes 3x longer to compute than 1200 = `2*2*2*2*3*5*5`.
//! However, they will still be computed in O(nlogn) time, they still benefit from AVX acceleration,
//! and according to benchmarks we've run, are still faster than the same size computed by FFTW.
//!
//! ### Normalization
//!
//! RustFFT does not normalize outputs. Callers must manually normalize the results by scaling each element by
//! `1/len().sqrt()`. Multiple normalization steps can be merged into one via pairwise multiplication, so when
//! doing a forward FFT followed by an inverse callers can normalize once by scaling each element by `1/len()`
//!
//! ### Output Order
//!
//! Elements in the output are ordered by ascending frequency, with the first element corresponding to frequency 0.
pub use num_complex;
pub use num_traits;
/// Individual FFT algorithms
use Complex;
use Zero;
pub use crateFftPlanner;
pub use crateFFTnum;
/// A trait that allows FFT algorithms to report their expected input/output size
/// A trait that allows FFT algorithms to report whether they compute forward FFTs or inverse FFTs
/// Trait for algorithms that compute FFTs.
///
/// This trait has two main methods:
/// - [`process_inplace(buffer)`](crate::Fft::process_inplace) computes a FFT using `buffer` as input and store the result back into `buffer`.
/// - [`process(input, output)`](crate::Fft::process) computes a FFT using `input` as input and store the result into `output`.
///
/// Both methods may need to allocate additional scratch space. If you'd like re-use that allocation across multiple FFT computations, call
/// `process_inplace_with_scratch` or `process_with_scratch`, respectively.
// Algorithms implemented to use AVX instructions. Only compiled on x86_64.
// When we're not on avx, keep a stub implementation around that just does nothing
pub use FftPlannerAvx;