Chris@82: Chris@82: Chris@82: Chris@82: Chris@82:
Chris@82:Chris@82: Next: One-Dimensional DFTs of Real Data, Previous: Complex One-Dimensional DFTs, Up: Tutorial [Contents][Index]
Chris@82:Multi-dimensional transforms work much the same way as one-dimensional
Chris@82: transforms: you allocate arrays of fftw_complex
(preferably
Chris@82: using fftw_malloc
), create an fftw_plan
, execute it as
Chris@82: many times as you want with fftw_execute(plan)
, and clean up
Chris@82: with fftw_destroy_plan(plan)
(and fftw_free
).
Chris@82:
FFTW provides two routines for creating plans for 2d and 3d transforms, Chris@82: and one routine for creating plans of arbitrary dimensionality. Chris@82: The 2d and 3d routines have the following signature: Chris@82:
fftw_plan fftw_plan_dft_2d(int n0, int n1, Chris@82: fftw_complex *in, fftw_complex *out, Chris@82: int sign, unsigned flags); Chris@82: fftw_plan fftw_plan_dft_3d(int n0, int n1, int n2, Chris@82: fftw_complex *in, fftw_complex *out, Chris@82: int sign, unsigned flags); Chris@82:
These routines create plans for n0
by n1
two-dimensional
Chris@82: (2d) transforms and n0
by n1
by n2
3d transforms,
Chris@82: respectively. All of these transforms operate on contiguous arrays in
Chris@82: the C-standard row-major order, so that the last dimension has the
Chris@82: fastest-varying index in the array. This layout is described further in
Chris@82: Multi-dimensional Array Format.
Chris@82:
FFTW can also compute transforms of higher dimensionality. In order to Chris@82: avoid confusion between the various meanings of the the word Chris@82: “dimension”, we use the term rank Chris@82: Chris@82: to denote the number of independent indices in an array.2 For Chris@82: example, we say that a 2d transform has rank 2, a 3d transform has Chris@82: rank 3, and so on. You can plan transforms of arbitrary rank by Chris@82: means of the following function: Chris@82:
Chris@82:fftw_plan fftw_plan_dft(int rank, const int *n, Chris@82: fftw_complex *in, fftw_complex *out, Chris@82: int sign, unsigned flags); Chris@82:
Here, n
is a pointer to an array n[rank]
denoting an
Chris@82: n[0]
by n[1]
by … by n[rank-1]
transform.
Chris@82: Thus, for example, the call
Chris@82:
fftw_plan_dft_2d(n0, n1, in, out, sign, flags); Chris@82:
is equivalent to the following code fragment: Chris@82:
int n[2]; Chris@82: n[0] = n0; Chris@82: n[1] = n1; Chris@82: fftw_plan_dft(2, n, in, out, sign, flags); Chris@82:
fftw_plan_dft
is not restricted to 2d and 3d transforms,
Chris@82: however, but it can plan transforms of arbitrary rank.
Chris@82:
You may have noticed that all the planner routines described so far
Chris@82: have overlapping functionality. For example, you can plan a 1d or 2d
Chris@82: transform by using fftw_plan_dft
with a rank
of 1
Chris@82: or 2
, or even by calling fftw_plan_dft_3d
with n0
Chris@82: and/or n1
equal to 1
(with no loss in efficiency). This
Chris@82: pattern continues, and FFTW’s planning routines in general form a
Chris@82: “partial order,” sequences of
Chris@82:
Chris@82: interfaces with strictly increasing generality but correspondingly
Chris@82: greater complexity.
Chris@82:
fftw_plan_dft
is the most general complex-DFT routine that we
Chris@82: describe in this tutorial, but there are also the advanced and guru interfaces,
Chris@82:
Chris@82:
Chris@82: which allow one to efficiently combine multiple/strided transforms
Chris@82: into a single FFTW plan, transform a subset of a larger
Chris@82: multi-dimensional array, and/or to handle more general complex-number
Chris@82: formats. For more information, see FFTW Reference.
Chris@82:
The Chris@82: term “rank” is commonly used in the APL, FORTRAN, and Common Lisp Chris@82: traditions, although it is not so common in the C world.
Chris@82:Chris@82: Next: One-Dimensional DFTs of Real Data, Previous: Complex One-Dimensional DFTs, Up: Tutorial [Contents][Index]
Chris@82: