cannam@127: cannam@127: cannam@127: cannam@127: cannam@127:
cannam@127:cannam@127: Next: Multi-Dimensional DFTs of Real Data, Previous: Complex Multi-Dimensional DFTs, Up: Tutorial [Contents][Index]
cannam@127:In many practical applications, the input data in[i]
are purely
cannam@127: real numbers, in which case the DFT output satisfies the “Hermitian”
cannam@127:
cannam@127: redundancy: out[i]
is the conjugate of out[n-i]
. It is
cannam@127: possible to take advantage of these circumstances in order to achieve
cannam@127: roughly a factor of two improvement in both speed and memory usage.
cannam@127:
In exchange for these speed and space advantages, the user sacrifices
cannam@127: some of the simplicity of FFTW’s complex transforms. First of all, the
cannam@127: input and output arrays are of different sizes and types: the
cannam@127: input is n
real numbers, while the output is n/2+1
cannam@127: complex numbers (the non-redundant outputs); this also requires slight
cannam@127: “padding” of the input array for
cannam@127:
cannam@127: in-place transforms. Second, the inverse transform (complex to real)
cannam@127: has the side-effect of overwriting its input array, by default.
cannam@127: Neither of these inconveniences should pose a serious problem for
cannam@127: users, but it is important to be aware of them.
cannam@127:
The routines to perform real-data transforms are almost the same as
cannam@127: those for complex transforms: you allocate arrays of double
cannam@127: and/or fftw_complex
(preferably using fftw_malloc
or
cannam@127: fftw_alloc_complex
), create an fftw_plan
, execute it as
cannam@127: many times as you want with fftw_execute(plan)
, and clean up
cannam@127: with fftw_destroy_plan(plan)
(and fftw_free
). The only
cannam@127: differences are that the input (or output) is of type double
cannam@127: and there are new routines to create the plan. In one dimension:
cannam@127:
fftw_plan fftw_plan_dft_r2c_1d(int n, double *in, fftw_complex *out, cannam@127: unsigned flags); cannam@127: fftw_plan fftw_plan_dft_c2r_1d(int n, fftw_complex *in, double *out, cannam@127: unsigned flags); cannam@127:
for the real input to complex-Hermitian output (r2c) and
cannam@127: complex-Hermitian input to real output (c2r) transforms.
cannam@127:
cannam@127:
cannam@127: Unlike the complex DFT planner, there is no sign
argument.
cannam@127: Instead, r2c DFTs are always FFTW_FORWARD
and c2r DFTs are
cannam@127: always FFTW_BACKWARD
.
cannam@127:
cannam@127:
cannam@127: (For single/long-double precision
cannam@127: fftwf
and fftwl
, double
should be replaced by
cannam@127: float
and long double
, respectively.)
cannam@127:
cannam@127:
Here, n
is the “logical” size of the DFT, not necessarily the
cannam@127: physical size of the array. In particular, the real (double
)
cannam@127: array has n
elements, while the complex (fftw_complex
)
cannam@127: array has n/2+1
elements (where the division is rounded down).
cannam@127: For an in-place transform,
cannam@127:
cannam@127: in
and out
are aliased to the same array, which must be
cannam@127: big enough to hold both; so, the real array would actually have
cannam@127: 2*(n/2+1)
elements, where the elements beyond the first
cannam@127: n
are unused padding. (Note that this is very different from
cannam@127: the concept of “zero-padding” a transform to a larger length, which
cannam@127: changes the logical size of the DFT by actually adding new input
cannam@127: data.) The kth element of the complex array is exactly the
cannam@127: same as the kth element of the corresponding complex DFT. All
cannam@127: positive n
are supported; products of small factors are most
cannam@127: efficient, but an O(n log n) algorithm is used even for prime sizes.
cannam@127:
As noted above, the c2r transform destroys its input array even for
cannam@127: out-of-place transforms. This can be prevented, if necessary, by
cannam@127: including FFTW_PRESERVE_INPUT
in the flags
, with
cannam@127: unfortunately some sacrifice in performance.
cannam@127:
cannam@127:
cannam@127: This flag is also not currently supported for multi-dimensional real
cannam@127: DFTs (next section).
cannam@127:
Readers familiar with DFTs of real data will recall that the 0th (the
cannam@127: “DC”) and n/2
-th (the “Nyquist” frequency, when n
is
cannam@127: even) elements of the complex output are purely real. Some
cannam@127: implementations therefore store the Nyquist element where the DC
cannam@127: imaginary part would go, in order to make the input and output arrays
cannam@127: the same size. Such packing, however, does not generalize well to
cannam@127: multi-dimensional transforms, and the space savings are miniscule in
cannam@127: any case; FFTW does not support it.
cannam@127:
An alternative interface for one-dimensional r2c and c2r DFTs can be cannam@127: found in the ‘r2r’ interface (see The Halfcomplex-format DFT), with “halfcomplex”-format output that is the same size cannam@127: (and type) as the input array. cannam@127: cannam@127: That interface, although it is not very useful for multi-dimensional cannam@127: transforms, may sometimes yield better performance. cannam@127:
cannam@127:cannam@127: Next: Multi-Dimensional DFTs of Real Data, Previous: Complex Multi-Dimensional DFTs, Up: Tutorial [Contents][Index]
cannam@127: