Chris@42: Chris@42: Chris@42: Chris@42: Chris@42:
Chris@42:Chris@42: Next: More DFTs of Real Data, Previous: One-Dimensional DFTs of Real Data, Up: Tutorial [Contents][Index]
Chris@42:Multi-dimensional DFTs of real data use the following planner routines: Chris@42:
Chris@42:fftw_plan fftw_plan_dft_r2c_2d(int n0, int n1, Chris@42: double *in, fftw_complex *out, Chris@42: unsigned flags); Chris@42: fftw_plan fftw_plan_dft_r2c_3d(int n0, int n1, int n2, Chris@42: double *in, fftw_complex *out, Chris@42: unsigned flags); Chris@42: fftw_plan fftw_plan_dft_r2c(int rank, const int *n, Chris@42: double *in, fftw_complex *out, Chris@42: unsigned flags); Chris@42:
as well as the corresponding c2r routines with the input/output
Chris@42: types swapped.  These routines work similarly to their complex
Chris@42: analogues, except for the fact that here the complex output array is cut
Chris@42: roughly in half and the real array requires padding for in-place
Chris@42: transforms (as in 1d, above).
Chris@42: 
As before, n is the logical size of the array, and the
Chris@42: consequences of this on the the format of the complex arrays deserve
Chris@42: careful attention.
Chris@42: 
Chris@42: Suppose that the real data has dimensions n0 × n1 × n2 × … × nd-1 (in row-major order).
Chris@42: Then, after an r2c transform, the output is an n0 × n1 × n2 × … × (nd-1/2 + 1) array of
Chris@42: fftw_complex values in row-major order, corresponding to slightly
Chris@42: over half of the output of the corresponding complex DFT.  (The division
Chris@42: is rounded down.)  The ordering of the data is otherwise exactly the
Chris@42: same as in the complex-DFT case.
Chris@42: 
For out-of-place transforms, this is the end of the story: the real Chris@42: data is stored as a row-major array of size n0 × n1 × n2 × … × nd-1 and the complex Chris@42: data is stored as a row-major array of size n0 × n1 × n2 × … × (nd-1/2 + 1). Chris@42:
Chris@42:For in-place transforms, however, extra padding of the real-data array
Chris@42: is necessary because the complex array is larger than the real array,
Chris@42: and the two arrays share the same memory locations.  Thus, for
Chris@42: in-place transforms, the final dimension of the real-data array must
Chris@42: be padded with extra values to accommodate the size of the complex
Chris@42: data—two values if the last dimension is even and one if it is odd.
Chris@42: 
Chris@42: That is, the last dimension of the real data must physically contain
Chris@42: 2 * (nd-1/2+1)double values (exactly enough to hold the complex data).
Chris@42: This physical array size does not, however, change the logical
Chris@42: array size—only
Chris@42: nd-1values are actually stored in the last dimension, and
Chris@42: nd-1is the last dimension passed to the plan-creation routine.
Chris@42: 
For example, consider the transform of a two-dimensional real array of
Chris@42: size n0 by n1.  The output of the r2c transform is a
Chris@42: two-dimensional complex array of size n0 by n1/2+1, where
Chris@42: the y dimension has been cut nearly in half because of
Chris@42: redundancies in the output.  Because fftw_complex is twice the
Chris@42: size of double, the output array is slightly bigger than the
Chris@42: input array.  Thus, if we want to compute the transform in place, we
Chris@42: must pad the input array so that it is of size n0 by
Chris@42: 2*(n1/2+1).  If n1 is even, then there are two padding
Chris@42: elements at the end of each row (which need not be initialized, as they
Chris@42: are only used for output).
Chris@42: 
The following illustration depicts the input and output arrays just
Chris@42: described, for both the out-of-place and in-place transforms (with the
Chris@42: arrows indicating consecutive memory locations):
Chris@42:  Chris@42:
Chris@42: 
These transforms are unnormalized, so an r2c followed by a c2r Chris@42: transform (or vice versa) will result in the original data scaled by Chris@42: the number of real data elements—that is, the product of the Chris@42: (logical) dimensions of the real data. Chris@42: Chris@42:
Chris@42: Chris@42:(Because the last dimension is treated specially, if it is equal to
Chris@42: 1 the transform is not equivalent to a lower-dimensional
Chris@42: r2c/c2r transform.  In that case, the last complex dimension also has
Chris@42: size 1 (=1/2+1), and no advantage is gained over the
Chris@42: complex transforms.)
Chris@42: 
Chris@42: Next: More DFTs of Real Data, Previous: One-Dimensional DFTs of Real Data, Up: Tutorial [Contents][Index]
Chris@42: