我有一个二维矩阵,每列对应一个独立信号。我将在每列上执行N 1D fft。在matlab中,将fft应用于2D矩阵就可以了。但是我用fftw将代码移植到c ++。我想知道是否有办法这样做。我通过将列大小设置为1并将行大小设置为4(总行数)来尝试以下代码,但它没有帮助。
#include <iostream>
#include <complex>
#include "fftw3.h"
using namespace std;
int main(int argc, char** argv)
{
complex<double> data[4][2];
data[0][0] = complex<double>(1,1);
data[1][0] = complex<double>(2,1);
data[2][0] = complex<double>(3,1);
data[3][0] = complex<double>(4,1);
data[0][1] = complex<double>(1,1);
data[1][1] = complex<double>(1,2);
data[2][1] = complex<double>(1,3);
data[3][1] = complex<double>(1,4);
cout << "original data ..." << endl;
cout << data[0][0] << '\t' << data[0][1] << endl;
cout << data[1][0] << '\t' << data[1][1] << endl;
cout << data[2][0] << '\t' << data[2][1] << endl;
cout << data[3][0] << '\t' << data[3][1] << endl;
cout << endl << endl;
fftw_plan plan=fftw_plan_dft_2d(4, 1,(fftw_complex*)&data[0][0], (fftw_complex*)&data[0][0], FFTW_FORWARD, FFTW_ESTIMATE);
fftw_execute(plan);
cout << "after fftw ..." << endl;
cout << data[0][0] << '\t' << data[0][1] << endl;
cout << data[1][0] << '\t' << data[1][1] << endl;
cout << data[2][0] << '\t' << data[2][1] << endl;
cout << data[3][0] << '\t' << data[3][1] << endl;
return 0;
}
上面的代码取第一行和第二行并将它们重新整形为2x2矩阵然后执行2D fft。
到目前为止,我想到的唯一方法如下。假设我有NxM(N行,M列),我为M 1D fftw创建M fftw计划。我连续执行M fftw以获得结果。但在实际应用中,矩阵非常大,M是如此之大。这样做是非常低效的。有什么好主意吗?感谢。
答案 0 :(得分:1)
对于现在遇到这个问题的人来说,FFTW 开发人员已经为这个操作实现了例程,这比循环遍历每一列并进行单独的转换要快。您当然不想进行 2D 变换(如问题所示),这在数学上与逐行 1D 变换不同。
您问题的关键在于fftw_plan_many_dft
。 Here is a link to the full documentation.
这是一个示例(从上面的链接修改),说明了您正在寻找的内容。
#include "fftw3.h"
int main() {
fftw_complex *A; // array of data
A = (fftw_complex*) fftw_malloc(sizeof(fftw_complex)*10*3);
// ...
/* 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 = 1;
int odist = 1;
/* distance between two elements in the same column */
int istride = 3;
int ostride = 3;
int *inembed = n, *onembed = n;
/* forward, in-place, 1D transform of each column */
fftw_plan p;
p = fftw_plan_many_dft(rank, n, howmany, A, inembed, istride, idist, A, onembed, ostride, odist, FFTW_FORWARD, FFTW_ESTIMATE);
// ...
/* run transform */
fftw_execute_dft(p, A, A);
// ...
/* we don't want memory leaks */
fftw_destroy_plan(p);
fftw_free(A);
}