cannam@167: cannam@167: cannam@167: cannam@167: cannam@167: cannam@167: FFTW 3.3.8: One-Dimensional DFTs of Real Data cannam@167: cannam@167: cannam@167: cannam@167: cannam@167: cannam@167: cannam@167: cannam@167: cannam@167: cannam@167: cannam@167: cannam@167: cannam@167: cannam@167: cannam@167: cannam@167: cannam@167: cannam@167: cannam@167: cannam@167: cannam@167:
cannam@167:

cannam@167: Next: , Previous: , Up: Tutorial   [Contents][Index]

cannam@167:
cannam@167:
cannam@167: cannam@167:

2.3 One-Dimensional DFTs of Real Data

cannam@167: cannam@167:

In many practical applications, the input data in[i] are purely cannam@167: real numbers, in which case the DFT output satisfies the “Hermitian” cannam@167: cannam@167: redundancy: out[i] is the conjugate of out[n-i]. It is cannam@167: possible to take advantage of these circumstances in order to achieve cannam@167: roughly a factor of two improvement in both speed and memory usage. cannam@167:

cannam@167:

In exchange for these speed and space advantages, the user sacrifices cannam@167: some of the simplicity of FFTW’s complex transforms. First of all, the cannam@167: input and output arrays are of different sizes and types: the cannam@167: input is n real numbers, while the output is n/2+1 cannam@167: complex numbers (the non-redundant outputs); this also requires slight cannam@167: “padding” of the input array for cannam@167: cannam@167: in-place transforms. Second, the inverse transform (complex to real) cannam@167: has the side-effect of overwriting its input array, by default. cannam@167: Neither of these inconveniences should pose a serious problem for cannam@167: users, but it is important to be aware of them. cannam@167:

cannam@167:

The routines to perform real-data transforms are almost the same as cannam@167: those for complex transforms: you allocate arrays of double cannam@167: and/or fftw_complex (preferably using fftw_malloc or cannam@167: fftw_alloc_complex), create an fftw_plan, execute it as cannam@167: many times as you want with fftw_execute(plan), and clean up cannam@167: with fftw_destroy_plan(plan) (and fftw_free). The only cannam@167: differences are that the input (or output) is of type double cannam@167: and there are new routines to create the plan. In one dimension: cannam@167:

cannam@167:
cannam@167:
fftw_plan fftw_plan_dft_r2c_1d(int n, double *in, fftw_complex *out,
cannam@167:                                unsigned flags);
cannam@167: fftw_plan fftw_plan_dft_c2r_1d(int n, fftw_complex *in, double *out,
cannam@167:                                unsigned flags);
cannam@167: 
cannam@167: cannam@167: cannam@167: cannam@167:

for the real input to complex-Hermitian output (r2c) and cannam@167: complex-Hermitian input to real output (c2r) transforms. cannam@167: cannam@167: cannam@167: Unlike the complex DFT planner, there is no sign argument. cannam@167: Instead, r2c DFTs are always FFTW_FORWARD and c2r DFTs are cannam@167: always FFTW_BACKWARD. cannam@167: cannam@167: cannam@167: (For single/long-double precision cannam@167: fftwf and fftwl, double should be replaced by cannam@167: float and long double, respectively.) cannam@167: cannam@167:

cannam@167: cannam@167:

Here, n is the “logical” size of the DFT, not necessarily the cannam@167: physical size of the array. In particular, the real (double) cannam@167: array has n elements, while the complex (fftw_complex) cannam@167: array has n/2+1 elements (where the division is rounded down). cannam@167: For an in-place transform, cannam@167: cannam@167: in and out are aliased to the same array, which must be cannam@167: big enough to hold both; so, the real array would actually have cannam@167: 2*(n/2+1) elements, where the elements beyond the first cannam@167: n are unused padding. (Note that this is very different from cannam@167: the concept of “zero-padding” a transform to a larger length, which cannam@167: changes the logical size of the DFT by actually adding new input cannam@167: data.) The kth element of the complex array is exactly the cannam@167: same as the kth element of the corresponding complex DFT. All cannam@167: positive n are supported; products of small factors are most cannam@167: efficient, but an O(n log n) cannam@167: algorithm is used even for prime sizes. cannam@167:

cannam@167:

As noted above, the c2r transform destroys its input array even for cannam@167: out-of-place transforms. This can be prevented, if necessary, by cannam@167: including FFTW_PRESERVE_INPUT in the flags, with cannam@167: unfortunately some sacrifice in performance. cannam@167: cannam@167: cannam@167: This flag is also not currently supported for multi-dimensional real cannam@167: DFTs (next section). cannam@167:

cannam@167:

Readers familiar with DFTs of real data will recall that the 0th (the cannam@167: “DC”) and n/2-th (the “Nyquist” frequency, when n is cannam@167: even) elements of the complex output are purely real. Some cannam@167: implementations therefore store the Nyquist element where the DC cannam@167: imaginary part would go, in order to make the input and output arrays cannam@167: the same size. Such packing, however, does not generalize well to cannam@167: multi-dimensional transforms, and the space savings are miniscule in cannam@167: any case; FFTW does not support it. cannam@167:

cannam@167:

An alternative interface for one-dimensional r2c and c2r DFTs can be cannam@167: found in the ‘r2r’ interface (see The Halfcomplex-format DFT), with “halfcomplex”-format output that is the same size cannam@167: (and type) as the input array. cannam@167: cannam@167: That interface, although it is not very useful for multi-dimensional cannam@167: transforms, may sometimes yield better performance. cannam@167:

cannam@167:
cannam@167:
cannam@167:

cannam@167: Next: , Previous: , Up: Tutorial   [Contents][Index]

cannam@167:
cannam@167: cannam@167: cannam@167: cannam@167: cannam@167: