Chris@10: Chris@10: Chris@10: Advanced Complex DFTs - FFTW 3.3.3 Chris@10: Chris@10: Chris@10: Chris@10: Chris@10: Chris@10: Chris@10: Chris@10: Chris@10: Chris@10: Chris@10: Chris@10: Chris@10: Chris@10:
Chris@10: Chris@10:

Chris@10: Next: , Chris@10: Previous: Advanced Interface, Chris@10: Up: Advanced Interface Chris@10:


Chris@10:
Chris@10: Chris@10:

4.4.1 Advanced Complex DFTs

Chris@10: Chris@10:
     fftw_plan fftw_plan_many_dft(int rank, const int *n, int howmany,
Chris@10:                                   fftw_complex *in, const int *inembed,
Chris@10:                                   int istride, int idist,
Chris@10:                                   fftw_complex *out, const int *onembed,
Chris@10:                                   int ostride, int odist,
Chris@10:                                   int sign, unsigned flags);
Chris@10: 
Chris@10:

Chris@10: This routine plans multiple multidimensional complex DFTs, and it Chris@10: extends the fftw_plan_dft routine (see Complex DFTs) to Chris@10: compute howmany transforms, each having rank rank and size Chris@10: n. In addition, the transform data need not be contiguous, but Chris@10: it may be laid out in memory with an arbitrary stride. To account for Chris@10: these possibilities, fftw_plan_many_dft adds the new parameters Chris@10: howmany, {i,o}nembed, Chris@10: {i,o}stride, and Chris@10: {i,o}dist. The FFTW basic interface Chris@10: (see Complex DFTs) provides routines specialized for ranks 1, 2, Chris@10: and 3, but the advanced interface handles only the general-rank Chris@10: case. Chris@10: Chris@10:

howmany is the number of transforms to compute. The resulting Chris@10: plan computes howmany transforms, where the input of the Chris@10: k-th transform is at location in+k*idist (in C pointer Chris@10: arithmetic), and its output is at location out+k*odist. Plans Chris@10: obtained in this way can often be faster than calling FFTW multiple Chris@10: times for the individual transforms. The basic fftw_plan_dft Chris@10: interface corresponds to howmany=1 (in which case the dist Chris@10: parameters are ignored). Chris@10: Chris@10: Chris@10:

Each of the howmany transforms has rank rank and size Chris@10: n, as in the basic interface. In addition, the advanced Chris@10: interface allows the input and output arrays of each transform to be Chris@10: row-major subarrays of larger rank-rank arrays, described by Chris@10: inembed and onembed parameters, respectively. Chris@10: {i,o}nembed must be arrays of length rank, Chris@10: and n should be elementwise less than or equal to Chris@10: {i,o}nembed. Passing NULL for an Chris@10: nembed parameter is equivalent to passing n (i.e. same Chris@10: physical and logical dimensions, as in the basic interface.) Chris@10: Chris@10:

The stride parameters indicate that the j-th element of Chris@10: the input or output arrays is located at j*istride or Chris@10: j*ostride, respectively. (For a multi-dimensional array, Chris@10: j is the ordinary row-major index.) When combined with the Chris@10: k-th transform in a howmany loop, from above, this means Chris@10: that the (j,k)-th element is at j*stride+k*dist. Chris@10: (The basic fftw_plan_dft interface corresponds to a stride of 1.) Chris@10: Chris@10: Chris@10:

For in-place transforms, the input and output stride and Chris@10: dist parameters should be the same; otherwise, the planner may Chris@10: return NULL. Chris@10: Chris@10:

Arrays n, inembed, and onembed are not used after Chris@10: this function returns. You can safely free or reuse them. Chris@10: Chris@10:

Examples: Chris@10: One transform of one 5 by 6 array contiguous in memory: Chris@10:

        int rank = 2;
Chris@10:         int n[] = {5, 6};
Chris@10:         int howmany = 1;
Chris@10:         int idist = odist = 0; /* unused because howmany = 1 */
Chris@10:         int istride = ostride = 1; /* array is contiguous in memory */
Chris@10:         int *inembed = n, *onembed = n;
Chris@10: 
Chris@10:

Transform of three 5 by 6 arrays, each contiguous in memory, Chris@10: stored in memory one after another: Chris@10:

        int rank = 2;
Chris@10:         int n[] = {5, 6};
Chris@10:         int howmany = 3;
Chris@10:         int idist = odist = n[0]*n[1]; /* = 30, the distance in memory
Chris@10:                                           between the first element
Chris@10:                                           of the first array and the
Chris@10:                                           first element of the second array */
Chris@10:         int istride = ostride = 1; /* array is contiguous in memory */
Chris@10:         int *inembed = n, *onembed = n;
Chris@10: 
Chris@10:

Transform each column of a 2d array with 10 rows and 3 columns: Chris@10:

        int rank = 1; /* not 2: we are computing 1d transforms */
Chris@10:         int n[] = {10}; /* 1d transforms of length 10 */
Chris@10:         int howmany = 3;
Chris@10:         int idist = odist = 1;
Chris@10:         int istride = ostride = 3; /* distance between two elements in
Chris@10:                                       the same column */
Chris@10:         int *inembed = n, *onembed = n;
Chris@10: 
Chris@10: Chris@10: Chris@10: