FFTW-计算实2D FFT,特殊要求 < >我使用FFTW3计算C++中的2D实际FFT。我读过手册,但有一些问题。从手册中:

FFTW-计算实2D FFT,特殊要求 < >我使用FFTW3计算C++中的2D实际FFT。我读过手册,但有一些问题。从手册中:,c++,fft,fftw,C++,Fft,Fftw,为了换取这些速度和空间优势,用户做出了牺牲 FFTW复杂变换的一些简单性。首先是 输入和输出数组具有不同的大小和类型:输入是 n个实数,而输出为n/2+1个复数( 非冗余输出);这也需要稍微“填充”的 就地转换的输入数组。第二,逆变换 (复杂到真实)具有覆盖其输入数组的副作用, 默认情况下。这些不便都不应构成严重的后果 这对于用户来说是一个问题,但重要的是要意识到这一点 我知道我需要将输入的二维矩阵转换为行顺序的一维向量。但是输出是什么样子的呢?n/2+1数字是什么意思?换句话说,如何对输出重新

为了换取这些速度和空间优势,用户做出了牺牲 FFTW复杂变换的一些简单性。首先是 输入和输出数组具有不同的大小和类型:输入是 n个实数,而输出为n/2+1个复数( 非冗余输出);这也需要稍微“填充”的 就地转换的输入数组。第二,逆变换 (复杂到真实)具有覆盖其输入数组的副作用, 默认情况下。这些不便都不应构成严重的后果 这对于用户来说是一个问题,但重要的是要意识到这一点

  • 我知道我需要将输入的二维矩阵转换为行顺序的一维向量。但是输出是什么样子的呢?n/2+1数字是什么意思?换句话说,如何对输出重新排序以获得2D矩阵

  • 要创建这个“填充”,我具体需要做什么

  • >P>如果输入已经在普通的C++ 2D数组中,你只需键入它:

    double twoDarray[10][10];
    double *oneDarrayPointer = (double *)twoDarray;
    
    如果您的输入是100(就像上面的例子一样),那么您的输出数组将是51个复数。这些数字的格式应该由您的库描述,但可能是102个双精度的数组-51个条目乘以2(实部/虚部)

    编辑:已确认-
    fftw\u复合体
    定义为:

    typedef double fftw_complex[2];
    

    所以它们只是表示复数实部和虚部的连续的双精度对

  • 如果您不想在适当的位置执行此操作,则无需填充任何内容—只需分配一个大小适当的输出数组即可。如果您确实需要在适当的位置执行此操作,那么您的输入缓冲区必须有足够的空间容纳与输入大小相对应的2个额外的双倍。假设有上述声明,您可能需要如下内容:

    double *inPlaceFFTPointer = malloc(sizeof twoDarray + 2*sizeof(double));
    memcpy(inPlaceFFTPointer, oneDarrayPointer, sizeof twoDarray);
    
    我不确定您是否需要确保在最后两个条目中包含
    0.0
    ,但这很容易添加


  • 您可以查看FFTW3中的实-实转换,它完全满足您的要求。这些不需要填充,并考虑到波数0和表示奈奎斯特频率的波数只有一个实分量。请看这里:

    对于内存中的布局:


    Hm。在我使用过的其他一些FFT库中,Nyquist值被压缩到
    X_0
    的虚部(直流偏移量),因为这两个值都是实的。那么就不需要填充了。显然FFTW没有这样做。仅供参考,
    这样的打包[…]不能很好地推广到多维变换。请参阅第二段的详细说明。您可以使用C++ STD::复杂的以及C样式或以上的TypeFFTW@pyCthon是的。我认为它们在记忆中几乎是一样的。“所以它们只是表示复数实部和虚部的连续双精度对。”对,但为什么只有51?为什么不是100?2D FFT输出的矩阵不是和输入的矩阵一样大吗?从你文章中的链接:“在许多实际应用中,[i]中的输入数据是纯实数,在这种情况下,DFT输出满足“厄米”冗余:
    out[i]
    out[n-i]
    的共轭。”所以如果你愿意的话,你只需要有一半的输出就可以产生所有的输出。我有点理解。这有助于我理解视觉对称性:“你可能开始注意到有很多对称性。对于所有真实(相对于想象或复杂)图像,FT是关于原点对称的,因此第一和第三象限是相同的,第二和第四象限是相同的。如果图像是关于x轴对称的(如余弦图像所示)4倍对称结果。”