我正在使用FFTW3来计算c ++中的2D实数FFT。我已阅读手册但有一些问题。从手册:http://www.fftw.org/fftw3_doc/One_002dDimensional-DFTs-of-Real-Data.html#One_002dDimensional-DFTs-of-Real-Data
为了换取这些速度和空间优势,用户牺牲了 FFTW复杂变换的一些简单性。首先, 输入和输出数组具有不同的大小和类型:输入是 n实数,而输出是n / 2 + 1复数( 非冗余输出);这也需要轻微的“填充” 用于就地变换的输入数组。第二,逆变换 (复杂到实际)具有覆盖其输入数组的副作用, 默认情况下。这些不便都不应该造成严重后果 用户的问题,但重要的是要了解它们。
我知道我需要将输入的2D矩阵转换为行级1D向量。但是输出是什么样的? n / 2 + 1数字是什么意思?换句话说,如何重新排序输出以获得2D矩阵?
我需要做些什么来创建这个“填充”?
答案 0 :(得分:2)
如果您的输入已经在普通的C ++ 2D数组中,那么您需要做的就是对它进行类型转换:
double twoDarray[10][10];
double *oneDarrayPointer = (double *)twoDarray;
如果输入为100(如上例所示),则输出数组将为51个复数。这些数字的格式应由您的库描述,但可能是102 doubles
- 51个条目乘以2(实/虚部分)的数组。
编辑:已确认 - fftw_complex
定义为:
typedef double fftw_complex[2];
所以它们只是连续的doubles
对,代表复数的实部和虚部。
如果你不想这样做,你不需要填充任何内容 - 只需分配一个适当大小的输出数组。如果你做需要在适当的位置进行,你的输入缓冲区必须有2个额外的双倍空间与输入大小。假设上面的声明,你需要类似的东西:
double *inPlaceFFTPointer = malloc(sizeof twoDarray + 2*sizeof(double));
memcpy(inPlaceFFTPointer, oneDarrayPointer, sizeof twoDarray);
我不确定您是否需要确保在最后两个条目中有0.0
,但这很容易添加。
答案 1 :(得分:2)
您可以查看FFTW3中的实际变换,这完全符合您的要求。这些不需要填充并且考虑到波数0和表示奈奎斯特频率的波数仅具有实际分量。看看这里:
以及内存中的布局: