d@0: d@0: d@0: Multi-Dimensional DFTs of Real Data - FFTW 3.2.1 d@0: d@0: d@0: d@0: d@0: d@0: d@0: d@0: d@0: d@0: d@0: d@0: d@0: d@0:
d@0:

d@0: d@0: d@0: Next: , d@0: Previous: One-Dimensional DFTs of Real Data, d@0: Up: Tutorial d@0:


d@0:
d@0: d@0:

2.4 Multi-Dimensional DFTs of Real Data

d@0: d@0:

Multi-dimensional DFTs of real data use the following planner routines: d@0: d@0:

     fftw_plan fftw_plan_dft_r2c_2d(int n0, int n1,
d@0:                                     double *in, fftw_complex *out,
d@0:                                     unsigned flags);
d@0:      fftw_plan fftw_plan_dft_r2c_3d(int n0, int n1, int n2,
d@0:                                     double *in, fftw_complex *out,
d@0:                                     unsigned flags);
d@0:      fftw_plan fftw_plan_dft_r2c(int rank, const int *n,
d@0:                                  double *in, fftw_complex *out,
d@0:                                  unsigned flags);
d@0: 
d@0:

d@0: as well as the corresponding c2r routines with the input/output d@0: types swapped. These routines work similarly to their complex d@0: analogues, except for the fact that here the complex output array is cut d@0: roughly in half and the real array requires padding for in-place d@0: transforms (as in 1d, above). d@0: d@0:

As before, n is the logical size of the array, and the d@0: consequences of this on the the format of the complex arrays deserve d@0: careful attention. d@0: Suppose that the real data has dimensions n0 × n1 × n2 × … × nd-1 (in row-major order). d@0: Then, after an r2c transform, the output is an n0 × n1 × n2 × … × (nd-1/2 + 1) array of d@0: fftw_complex values in row-major order, corresponding to slightly d@0: over half of the output of the corresponding complex DFT. (The division d@0: is rounded down.) The ordering of the data is otherwise exactly the d@0: same as in the complex-DFT case. d@0: d@0:

Since the complex data is slightly larger than the real data, some d@0: complications arise for in-place transforms. In this case, the final d@0: dimension of the real data must be padded with extra values to d@0: accommodate the size of the complex data—two values if the last d@0: dimension is even and one if it is odd. d@0: That is, the last dimension of the real data must physically contain d@0: 2 * (nd-1/2+1)double values (exactly enough to hold the complex data). d@0: This physical array size does not, however, change the logical d@0: array size—only d@0: nd-1values are actually stored in the last dimension, and d@0: nd-1is the last dimension passed to the plan-creation routine. d@0: d@0:

For example, consider the transform of a two-dimensional real array of d@0: size n0 by n1. The output of the r2c transform is a d@0: two-dimensional complex array of size n0 by n1/2+1, where d@0: the y dimension has been cut nearly in half because of d@0: redundancies in the output. Because fftw_complex is twice the d@0: size of double, the output array is slightly bigger than the d@0: input array. Thus, if we want to compute the transform in place, we d@0: must pad the input array so that it is of size n0 by d@0: 2*(n1/2+1). If n1 is even, then there are two padding d@0: elements at the end of each row (which need not be initialized, as they d@0: are only used for output). d@0: d@0:

The following illustration depicts the input and output arrays just d@0: described, for both the out-of-place and in-place transforms (with the d@0: arrows indicating consecutive memory locations): d@0: d@0:

rfftwnd.png
d@0: d@0:

These transforms are unnormalized, so an r2c followed by a c2r d@0: transform (or vice versa) will result in the original data scaled by d@0: the number of real data elements—that is, the product of the d@0: (logical) dimensions of the real data. d@0: d@0: (Because the last dimension is treated specially, if it is equal to d@0: 1 the transform is not equivalent to a lower-dimensional d@0: r2c/c2r transform. In that case, the last complex dimension also has d@0: size 1 (=1/2+1), and no advantage is gained over the d@0: complex transforms.) d@0: d@0: d@0: d@0: