Examples#
We show the configurations for several standard cases. FFTW analogues are provided if applicable. Here, we use double precision; for single precision one uses precision::f32 in the double-batched FFT library and the prefix fftwf in FFTW.
Single complex-data FFT#
configuration cfg = {1, {1, N, 1}, precision::f64, direction::forward, transform_type::c2c};
Tip
Analogue
int n0 = N;
int sign = FFTW_FORWARD; // -1
auto plan = fftw_plan_dft_1d(n0, in_ptr, out_ptr, sign, flags);
Single real-data FFT#
configuration cfg = {1, {1, N, 1}, precision::f64, direction::forward, transform_type::r2c};
Tip
Analogue
int n0 = N;
auto plan = fftw_plan_dft_r2c_1d(n0, in_ptr, out_ptr, flags);
Single-batched real-data FFT (in-place)#
configuration cfg = {1, {1, N, howmany}, precision::f64, direction::forward, transform_type::r2c};
cfg.set_strides_default(true);
Tip
Analogue
int rank = 1;
int n = N;
int nc = N/2 + 1;
int inembed = 2 * nc;
int idist = inembed;
int onembed = nc;
int odist = onembed;
auto plan = fftw_plan_many_dft_r2c(rank, &n, howmany, in_ptr, &inembed, 1, idist,
out_ptr, &onembed, 1, odist, flags);
Double-batched real-data FFT (in-place)#
configuration cfg = {1, {M, N, howmany}, precision::f64, direction::forward, transform_type::r2c};
cfg.set_strides_default(true);
Tip
Analogue
int rank = 1;
int n = N;
int nc = N/2 + 1;
int inembed = 2 * nc;
int idist = inembed * M;
int onembed = nc;
int odist = onembed * M;
auto plan = fftw_plan_many_dft_r2c(rank, &n, howmany, in_ptr, &inembed, 1, idist,
out_ptr, &onembed, 1, odist, flags);
// Execution needs loop over M-mode
for (int m = 0; m < M; ++m) {
fftw_execute_dft_r2c(plan, in_ptr + m, out_ptr + m);
}
Single 3D complex-data FFT#
configuration cfg = {1, {1, N0, N1, N2, 1}, precision::f64, direction::forward, transform_type::c2c};
Tip
Analogue
// FFTW expects row-major, therefore reverse the order
int n0 = N2;
int n1 = N1;
int n2 = N0;
int sign = FFTW_FORWARD; // -1
auto plan = fftw_plan_dft_3d(n0, n1, n2, in_ptr, out_ptr, flags);