【发布时间】:2016-08-23 19:53:02
【问题描述】:
我正在尝试使用 c++ 进行 fftw。我想测试它是否正确。我实现了一个简单的
ifft(fft(shift(data)) - data == 0
测试,完全失败。
testdata 是一个 rect 函数,幅度和相位为 1。用于比较的 matlab 代码与相同的测试完美配合。
基本问题是:我做错了什么?
这里的 matlab 代码(也是使用 fftw...)FFTW dll/.h 是最新的。
data = zeros(1, 64);
halfsize = numel(data)/2;
data(halfsize-10:halfsize+10) = 1;
phase = ones(size(data));
data = data.*exp(phase*sqrt(-1));
Ft = fft(fftshift(data));
在 C++ 中,代码是(不完整的)
std::vector<complex<double>,fftalloc<complex<double> > > data(N);
std::vector<complex<double>,fftalloc<complex<double> > > dataFourier(N);
... create data
int nfft = data.size();
fftw_plan plan = fftw_plan_dft_1d(nfft,fftw_cast(&data[0]),fftw_cast(&dataFourier[0]), FFTW_FORWARD, FFTW_ESTIMATE|FFTW_PRESERVE_INPUT);
fftw_execute(plan);
//fftw_execute_dft( plan, fftw_cast(&data[0]),fftw_cast(&dataFourier[0]));
cout << dataFourier[0] << dataFourier.back() << endl;
第一个复数值与最后一个完全不同
(59.8627,7.57324)(-4.00561,7.33222)
而在 matlab 中它们是相似的。相位也完全不同:
11.3463 +17.6709i 10.8411 +13.7128i
对于更高的 N,这些值是相同的(这里 N = 64)
【问题讨论】:
-
你为什么在时域中使用 fftshift?它将用于频域。我知道这是一个常见的谬误,但这并不意味着它是正确的。 de.mathworks.com/help/matlab/ref/fftshift.html 顺便说一句。 Matlab 内部使用 FFTW 来计算 DFT。
-
我还建议您可能将矩形函数居中 (halfsize-9:halfsize+10),我想补充一点,由于矩形函数的不连续性,它不是一个适合转换的函数通过 DFT。
-
@Ynpos:我使用移位,否则 f 中的相位。域错误。
-
@Ynpos:如果我在 matlab 中使用“data(halfsize-8:halfsize+10) = 1”,则相位是没有倾斜的矩形光栅形状。然而,matlab 中的步骤数仍然是 c++ 中的两倍。一个最重要的。幅度不会因此而改变。他们。在 C++ 中是错误的。
-
你如何判断这里的对错?你能用正确对齐的矩形更新你的结果吗?记住:傅里叶变换需要一个 l² 可积的周期函数。为什么不在测试中从这样的功能开始呢?如果您需要在时域中移动,那么您做错了。
ifft(fft(shift(data)) - data == 0绝不应该为真,除非班次与句点匹配。