cannam@167: cannam@167: cannam@167: cannam@167: cannam@167: cannam@167: FFTW 3.3.8: Complex One-Dimensional DFTs 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.1 Complex One-Dimensional DFTs

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

Plan: To bother about the best method of accomplishing an accidental result. cannam@167: [Ambrose Bierce, The Enlarged Devil’s Dictionary.] cannam@167: cannam@167:

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

The basic usage of FFTW to compute a one-dimensional DFT of size cannam@167: N is simple, and it typically looks something like this code: cannam@167:

cannam@167:
cannam@167:
#include <fftw3.h>
cannam@167: ...
cannam@167: {
cannam@167:     fftw_complex *in, *out;
cannam@167:     fftw_plan p;
cannam@167:     ...
cannam@167:     in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);
cannam@167:     out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);
cannam@167:     p = fftw_plan_dft_1d(N, in, out, FFTW_FORWARD, FFTW_ESTIMATE);
cannam@167:     ...
cannam@167:     fftw_execute(p); /* repeat as needed */
cannam@167:     ...
cannam@167:     fftw_destroy_plan(p);
cannam@167:     fftw_free(in); fftw_free(out);
cannam@167: }
cannam@167: 
cannam@167: cannam@167:

You must link this code with the fftw3 library. On Unix systems, cannam@167: link with -lfftw3 -lm. cannam@167:

cannam@167:

The example code first allocates the input and output arrays. You can cannam@167: allocate them in any way that you like, but we recommend using cannam@167: fftw_malloc, which behaves like cannam@167: cannam@167: malloc except that it properly aligns the array when SIMD cannam@167: instructions (such as SSE and Altivec) are available (see SIMD alignment and fftw_malloc). [Alternatively, we provide a convenient wrapper function fftw_alloc_complex(N) which has the same effect.] cannam@167: cannam@167: cannam@167:

cannam@167: cannam@167:

The data is an array of type fftw_complex, which is by default a cannam@167: double[2] composed of the real (in[i][0]) and imaginary cannam@167: (in[i][1]) parts of a complex number. cannam@167: cannam@167:

cannam@167:

The next step is to create a plan, which is an object cannam@167: cannam@167: that contains all the data that FFTW needs to compute the FFT. cannam@167: This function creates the plan: cannam@167:

cannam@167:
cannam@167:
fftw_plan fftw_plan_dft_1d(int n, fftw_complex *in, fftw_complex *out,
cannam@167:                            int sign, unsigned flags);
cannam@167: 
cannam@167: cannam@167: cannam@167: cannam@167:

The first argument, n, is the size of the transform you are cannam@167: trying to compute. The size n can be any positive integer, but cannam@167: sizes that are products of small factors are transformed most cannam@167: efficiently (although prime sizes still use an O(n log n) cannam@167: algorithm). cannam@167:

cannam@167:

The next two arguments are pointers to the input and output arrays of cannam@167: the transform. These pointers can be equal, indicating an cannam@167: in-place transform. cannam@167: cannam@167:

cannam@167: cannam@167:

The fourth argument, sign, can be either FFTW_FORWARD cannam@167: (-1) or FFTW_BACKWARD (+1), cannam@167: cannam@167: cannam@167: and indicates the direction of the transform you are interested in; cannam@167: technically, it is the sign of the exponent in the transform. cannam@167:

cannam@167:

The flags argument is usually either FFTW_MEASURE or cannam@167: cannam@167: FFTW_ESTIMATE. FFTW_MEASURE instructs FFTW to run cannam@167: cannam@167: and measure the execution time of several FFTs in order to find the cannam@167: best way to compute the transform of size n. This process takes cannam@167: some time (usually a few seconds), depending on your machine and on cannam@167: the size of the transform. FFTW_ESTIMATE, on the contrary, cannam@167: does not run any computation and just builds a cannam@167: cannam@167: reasonable plan that is probably sub-optimal. In short, if your cannam@167: program performs many transforms of the same size and initialization cannam@167: time is not important, use FFTW_MEASURE; otherwise use the cannam@167: estimate. cannam@167:

cannam@167:

You must create the plan before initializing the input, because cannam@167: FFTW_MEASURE overwrites the in/out arrays. cannam@167: (Technically, FFTW_ESTIMATE does not touch your arrays, but you cannam@167: should always create plans first just to be sure.) cannam@167:

cannam@167:

Once the plan has been created, you can use it as many times as you cannam@167: like for transforms on the specified in/out arrays, cannam@167: computing the actual transforms via fftw_execute(plan): cannam@167:

cannam@167:
void fftw_execute(const fftw_plan plan);
cannam@167: 
cannam@167: cannam@167: cannam@167:

The DFT results are stored in-order in the array out, with the cannam@167: zero-frequency (DC) component in out[0]. cannam@167: cannam@167: If in != out, the transform is out-of-place and the input cannam@167: array in is not modified. Otherwise, the input array is cannam@167: overwritten with the transform. cannam@167:

cannam@167: cannam@167:

If you want to transform a different array of the same size, you cannam@167: can create a new plan with fftw_plan_dft_1d and FFTW cannam@167: automatically reuses the information from the previous plan, if cannam@167: possible. Alternatively, with the “guru” interface you can apply a cannam@167: given plan to a different array, if you are careful. cannam@167: See FFTW Reference. cannam@167:

cannam@167:

When you are done with the plan, you deallocate it by calling cannam@167: fftw_destroy_plan(plan): cannam@167:

cannam@167:
void fftw_destroy_plan(fftw_plan plan);
cannam@167: 
cannam@167: cannam@167:

If you allocate an array with fftw_malloc() you must deallocate cannam@167: it with fftw_free(). Do not use free() or, heaven cannam@167: forbid, delete. cannam@167: cannam@167:

cannam@167:

FFTW computes an unnormalized DFT. Thus, computing a forward cannam@167: followed by a backward transform (or vice versa) results in the original cannam@167: array scaled by n. For the definition of the DFT, see What FFTW Really Computes. cannam@167: cannam@167: cannam@167:

cannam@167: cannam@167:

If you have a C compiler, such as gcc, that supports the cannam@167: C99 standard, and you #include <complex.h> before cannam@167: <fftw3.h>, then fftw_complex is the native cannam@167: double-precision complex type and you can manipulate it with ordinary cannam@167: arithmetic. Otherwise, FFTW defines its own complex type, which is cannam@167: bit-compatible with the C99 complex type. See Complex numbers. cannam@167: (The C++ <complex> template class may also be usable via a cannam@167: typecast.) cannam@167: cannam@167:

cannam@167:

To use single or long-double precision versions of FFTW, replace the cannam@167: fftw_ prefix by fftwf_ or fftwl_ and link with cannam@167: -lfftw3f or -lfftw3l, but use the same cannam@167: <fftw3.h> header file. cannam@167: cannam@167:

cannam@167: cannam@167:

Many more flags exist besides FFTW_MEASURE and cannam@167: FFTW_ESTIMATE. For example, use FFTW_PATIENT if you’re cannam@167: willing to wait even longer for a possibly even faster plan (see FFTW Reference). cannam@167: cannam@167: You can also save plans for future use, as described by Words of Wisdom-Saving Plans. 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: