#### 4.4.1 Advanced Complex DFTs

         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 plans multidimensional complex DFTs, and is exactly the same as `fftw_plan_dft` except for the new parameters `howmany`, {`i`,`o`}`nembed`, {`i`,`o`}`stride`, and {`i`,`o`}`dist`.

`howmany` is the number of transforms to compute, where the `k`-th transform is of the arrays starting at `in+k*idist` and `out+k*odist`. The resulting plans 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). The two `nembed` parameters (which should be arrays of length `rank`) indicate the sizes of the input and output array dimensions, respectively, where the transform is of a subarray of size `n`. (Each dimension of `n` should be `<=` the corresponding dimension of the `nembed` arrays.) That is, the input and output arrays are stored in row-major order with size given by `nembed` (not counting the strides and howmany multiplicities). 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.

So, for example, to transform a sequence of contiguous arrays, stored one after another, one would use a `stride` of 1 and a `dist` of N, where N is the product of the dimensions. In another example, to transform an array of contiguous “vectors” of length M, one would use a `howmany` of M, a `stride` of M, and a `dist` of 1.