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

This routine plans multiple multidimensional complex DFTs, and it
extends the `fftw_plan_dft`

routine (see Complex DFTs) to
compute `howmany`

transforms, each having rank `rank`

and size
`n`

. In addition, the transform data need not be contiguous, but
it may be laid out in memory with an arbitrary stride. To account for
these possibilities, `fftw_plan_many_dft`

adds the new parameters
`howmany`

, {`i`

,`o`

}`nembed`

,
{`i`

,`o`

}`stride`

, and
{`i`

,`o`

}`dist`

. The FFTW basic interface
(see Complex DFTs) provides routines specialized for ranks 1, 2,
and 3, but the advanced interface handles only the general-rank
case.

`howmany`

is the number of transforms to compute. The resulting
plan computes `howmany`

transforms, where the input of the
`k`

-th transform is at location `in+k*idist`

(in C pointer
arithmetic), and its output is at location `out+k*odist`

. Plans
obtained in this way can often be faster than calling FFTW multiple
times for the individual transforms. The basic `fftw_plan_dft`

interface corresponds to `howmany=1`

(in which case the `dist`

parameters are ignored).

Each of the `howmany`

transforms has rank `rank`

and size
`n`

, as in the basic interface. In addition, the advanced
interface allows the input and output arrays of each transform to be
row-major subarrays of larger rank-`rank`

arrays, described by
`inembed`

and `onembed`

parameters, respectively.
{`i`

,`o`

}`nembed`

must be arrays of length `rank`

,
and `n`

should be elementwise less than or equal to
{`i`

,`o`

}`nembed`

. Passing `NULL`

for an
`nembed`

parameter is equivalent to passing `n`

(i.e. same
physical and logical dimensions, as in the basic interface.)

The `stride`

parameters indicate that the `j`

-th element of
the input or output arrays is located at `j*istride`

or
`j*ostride`

, respectively. (For a multi-dimensional array,
`j`

is the ordinary row-major index.) When combined with the
`k`

-th transform in a `howmany`

loop, from above, this means
that the (`j`

,`k`

)-th element is at `j*stride+k*dist`

.
(The basic `fftw_plan_dft`

interface corresponds to a stride of 1.)

For in-place transforms, the input and output `stride`

and
`dist`

parameters should be the same; otherwise, the planner may
return `NULL`

.

Arrays `n`

, `inembed`

, and `onembed`

are not used after
this function returns. You can safely free or reuse them.

**Examples**:
One transform of one 5 by 6 array contiguous in memory:

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

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

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

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

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