FFTW大师界面
FFTW guru interface
我不明白FFTW的大师界面。让我根据手册和这个问题解释一下我认为它是如何工作的 也许有人可以消除我的误解。
fftw_plan fftw_plan_guru64_dft(
int rank, const fftw_iodim64 *dims,
int howmany_rank, const fftw_iodim64 *howmany_dims,
fftw_complex *in, fftw_complex *out,
int sign, unsigned flags);
假设我们要计算交错多维数组的DFT,例如图中的六个2x2数组(每个数组都有不同的颜色)
interleaved dfts
因为 dfts 在垂直方向上的步幅为 3,在水平方向上的步幅为 2,我认为我们需要 rank = 2 和 dims = {(2, 3, 3), (2, 2, 2 )}。起点是一个 3 x 2 子数组,所以我认为 howmany_rank = 2, howmany_dims = {(3, 1, 1), (2, 1, 1)}.
然而,这实际上并不是 FFTW 所做的。我做了一个更小的例子,很容易用手计算,由 4 个大小为 2x1 的 DFT(用颜色表示)组成。每个 dft 的形式为 (+-1, 0),输出为 (+-1, +-1),但这不是 FFTW 的计算结果。
small example
这是我用来计算 DFT 的代码。
#include <stdio.h>
#include <stdlib.h>
#include <complex.h>
#include <math.h>
#include <fftw3.h>
int main()
{
fftw_complex* X = fftw_malloc(8 * sizeof(fftw_complex));
fftw_iodim* sizes = malloc(2 * sizeof(fftw_iodim));
fftw_iodim* startingPoints = malloc(2 * sizeof(fftw_iodim));
sizes[0].n = 2; sizes[0].is = 2; sizes[0].os = 2;
sizes[1].n = 1; sizes[1].is = 2; sizes[1].os = 2;
startingPoints[0].n = 2; startingPoints[0].is = 1; startingPoints[0].os = 1;
startingPoints[1].n = 2; startingPoints[1].is = 1; startingPoints[1].os = 1;
fftw_plan plan = fftw_plan_guru_dft(2, sizes, 2, startingPoints, X, X, FFTW_FORWARD, FFTW_ESTIMATE);
X[0] = 1.0; X[1] = -1.0;
X[2] = 1.0; X[3] = -1.0;
X[4] = 0.0; X[5] = 0.0;
X[6] = 0.0; X[7] = 0.0;
fftw_execute(plan);
printf("\nOutput in row-major order:\n");
for (int i = 0; i < 8; i++) {
printf("%lf + %lfi, ", creal(X[i]), cimag(X[i]));
}
return 0;
}
即使是主轴的步幅也以“单位”为单位,即 double
s 或 fftw_complex
es,而不是行数:https://www.fftw.org/fftw3_doc/Guru-vector-and-transform-sizes.html#Guru-vector-and-transform-sizes
我的猜测是,在长轴中,步幅必须乘以连续行之间的距离,也以单位为单位。所以对于数组,它们的 iodims.is 和 iodims.os 步幅应该是 4*3 == 12.
我不明白FFTW的大师界面。让我根据手册和这个问题解释一下我认为它是如何工作的
fftw_plan fftw_plan_guru64_dft(
int rank, const fftw_iodim64 *dims,
int howmany_rank, const fftw_iodim64 *howmany_dims,
fftw_complex *in, fftw_complex *out,
int sign, unsigned flags);
假设我们要计算交错多维数组的DFT,例如图中的六个2x2数组(每个数组都有不同的颜色)
interleaved dfts
因为 dfts 在垂直方向上的步幅为 3,在水平方向上的步幅为 2,我认为我们需要 rank = 2 和 dims = {(2, 3, 3), (2, 2, 2 )}。起点是一个 3 x 2 子数组,所以我认为 howmany_rank = 2, howmany_dims = {(3, 1, 1), (2, 1, 1)}.
然而,这实际上并不是 FFTW 所做的。我做了一个更小的例子,很容易用手计算,由 4 个大小为 2x1 的 DFT(用颜色表示)组成。每个 dft 的形式为 (+-1, 0),输出为 (+-1, +-1),但这不是 FFTW 的计算结果。
small example
这是我用来计算 DFT 的代码。
#include <stdio.h>
#include <stdlib.h>
#include <complex.h>
#include <math.h>
#include <fftw3.h>
int main()
{
fftw_complex* X = fftw_malloc(8 * sizeof(fftw_complex));
fftw_iodim* sizes = malloc(2 * sizeof(fftw_iodim));
fftw_iodim* startingPoints = malloc(2 * sizeof(fftw_iodim));
sizes[0].n = 2; sizes[0].is = 2; sizes[0].os = 2;
sizes[1].n = 1; sizes[1].is = 2; sizes[1].os = 2;
startingPoints[0].n = 2; startingPoints[0].is = 1; startingPoints[0].os = 1;
startingPoints[1].n = 2; startingPoints[1].is = 1; startingPoints[1].os = 1;
fftw_plan plan = fftw_plan_guru_dft(2, sizes, 2, startingPoints, X, X, FFTW_FORWARD, FFTW_ESTIMATE);
X[0] = 1.0; X[1] = -1.0;
X[2] = 1.0; X[3] = -1.0;
X[4] = 0.0; X[5] = 0.0;
X[6] = 0.0; X[7] = 0.0;
fftw_execute(plan);
printf("\nOutput in row-major order:\n");
for (int i = 0; i < 8; i++) {
printf("%lf + %lfi, ", creal(X[i]), cimag(X[i]));
}
return 0;
}
即使是主轴的步幅也以“单位”为单位,即 double
s 或 fftw_complex
es,而不是行数:https://www.fftw.org/fftw3_doc/Guru-vector-and-transform-sizes.html#Guru-vector-and-transform-sizes
我的猜测是,在长轴中,步幅必须乘以连续行之间的距离,也以单位为单位。所以对于数组,它们的 iodims.is 和 iodims.os 步幅应该是 4*3 == 12.