Complex Multi-dimensional Transforms Tutorial
=============================================
FFTW can also compute transforms of any number of dimensions
("rank"). The syntax is similar to that for the one-dimensional
transforms, with `fftw_' replaced by `fftwnd_' (which stands for
"`fftw' in `N' dimensions").
As before, we `#include <fftw.h>' and create a plan for the
transforms, this time of type `fftwnd_plan':
fftwnd_plan fftwnd_create_plan(int rank, const int *n,
fftw_direction dir, int flags);
`rank' is the dimensionality of the array, and can be any
non-negative integer. The next argument, `n', is a pointer to an
integer array of length `rank' containing the (positive) sizes of each
dimension of the array. (Note that the array will be stored in
row-major order. Note:Multi-dimensional Array Format, for information
on row-major order.) The last two parameters are the same as in
`fftw_create_plan'. We now, however, have an additional possible flag,
`FFTW_IN_PLACE', since `fftwnd' supports true in-place transforms.
Multiple flags are combined using a bitwise "or" (`|'). (An "in-place"
transform is one in which the output data overwrite the input data. It
thus requires half as much memory as--and is often faster than--its
opposite, an "out-of-place" transform.)
For two- and three-dimensional transforms, FFTWND provides
alternative routines that accept the sizes of each dimension directly,
rather than indirectly through a rank and an array of sizes. These are
otherwise identical to `fftwnd_create_plan', and are sometimes more
convenient:
fftwnd_plan fftw2d_create_plan(int nx, int ny,
fftw_direction dir, int flags);
fftwnd_plan fftw3d_create_plan(int nx, int ny, int nz,
fftw_direction dir, int flags);
Once the plan has been created, you can use it any number of times
for transforms of the same size. When you do not need a plan anymore,
you can deallocate the plan by calling `fftwnd_destroy_plan(plan)'.
Given a plan, you can compute the transform of an array of data by
calling:
void fftwnd_one(fftwnd_plan plan, fftw_complex *in, fftw_complex *out);
Here, `in' and `out' point to multi-dimensional arrays in row-major
order, of the size specified when the plan was created. In the case of
an in-place transform, the `out' parameter is ignored and the output
data are stored in the `in' array. The results are stored in-order,
unnormalized, with the zero-frequency component in `out[0]'. A forward
followed by a backward transform (or vice-versa) yields the original
data multiplied by the size of the array (i.e. the product of the
dimensions). Note:What FFTWND Really Computes, for a discussion of
what FFTWND computes.
For example, code to perform an in-place FFT of a three-dimensional
array might look like:
#include <fftw.h>
...
{
fftw_complex in[L][M][N];
fftwnd_plan p;
...
p = fftw3d_create_plan(L, M, N, FFTW_FORWARD,
FFTW_MEASURE | FFTW_IN_PLACE);
...
fftwnd_one(p, &in[0][0][0], NULL);
...
fftwnd_destroy_plan(p);
}
Note that `in' is a statically-declared array, which is
automatically in row-major order, but we must take the address of the
first element in order to fit the type expected by `fftwnd_one'.
(Note:Multi-dimensional Array Format.)