gpt4 book ai didi

c++ - 为什么我不能在 Visual Studio 2013 下使用 FFTW 或 AMPFFT 获得有效的二维 FFT?

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:22:21 26 4
gpt4 key购买 nike

我一直在我的一个项目中使用 2D FFT,但无法使用两个不同的 FFT 库获得正确的结果。起初我以为我用错了它们,但在与 MATLAB 和 Linux GCC 引用实现进行比较后,现在我的编译器 (MSVC 2013 express) 似乎出了什么问题。

我的测试用例如下:256x256 复数到实数 IFFT,单个 bin 为 255(X、Y 符号为 0,255)设置为 10000。

使用 AMPFFT,我得到以下 2D 变换:

Broken AMPFFT example

通过 FFTW,我得到以下 2D 变换:

Broken FFTW example

如您所见,AMPFFT 版本“几乎”是正确的,但其中的每个样本 strip 都有这种奇怪的地方,而 FFTW 版本则到处都是,出去吃午饭。

我获取了两个不同测试版本的输出并将它们与 MATLAB(技术上是 Octave 音阶,它在底层使用 FFTW)进行了比较。我还在带有 GCC 的 Linux 下为 FFTW 运行了相同的测试用例。这是第 127 行那组测试的一部分(行号在技术上并不重要,因为我选择的 bins 所有行都应该相同):

FFT comparisons

在此示例中,octave 和 Linux 实现表示正确的结果并遵循红线(octave 绘制为黑色,Linux 绘制为红色,它与 octave 完全一致)。 MSVC 下的 FFTW 绘制为蓝色,AMP FFT 输出绘制为洋红色。如您所见,AMPFFT 版本看起来又很接近,但其中有这种奇怪的高频纹波,而 MSVC 下的 FFTW 只是一团糟,看起来很奇怪。

在这个阶段,我只能将矛头指向 Visual Studio,但我不知道发生了什么或如何修复它。

这是我的两个测试程序:

FFTW 测试:

//fftwtest.cpp
//2 dimensional complex-to-real inverse FFT test.
//Produces a 256 x 256 real-valued matrix that is loadable by octave/MATLAB
#include <fstream>
#include <iostream>
#include <complex>
#include <fftw3.h>

int main(int argc, char** argv)
{
int FFTSIZE = 256;

std::complex<double>* cpxArray;
std::complex<double>* fftOut;

// cpxArray = new std::complex<double>[FFTSIZE * FFTSIZE];
//fftOut = new double[FFTSIZE * FFTSIZE];
fftOut = (std::complex<double>*)fftw_alloc_complex(FFTSIZE*FFTSIZE);
cpxArray = (std::complex<double>*)fftw_alloc_complex(FFTSIZE * FFTSIZE);

for(int i = 0; i < FFTSIZE * FFTSIZE; i++) cpxArray[i] = 0;
cpxArray[255] = std::complex<double>(10000, 0);
fftw_plan p = fftw_plan_dft_2d(FFTSIZE, FFTSIZE, (fftw_complex*)cpxArray, (fftw_complex*)fftOut, FFTW_BACKWARD, FFTW_DESTROY_INPUT | FFTW_ESTIMATE);
fftw_execute(p);

std::ofstream debugDump("debugdumpFFTW.txt");
for(int j = 0; j < FFTSIZE; j++)
{
for(int i = 0; i < FFTSIZE; i++)
{
debugDump << " " << fftOut[j * FFTSIZE + i].real();
}
debugDump << std::endl;
}
debugDump.close();

}

AMPFFT 测试:

//ampffttest.cpp
//2 dimensional complex-to-real inverse FFT test.
//Produces a 256 x 256 real-valued matrix that is loadable by octave/MATLAB
#include <amp_fft.h>
#include <fstream>
#include <iostream>



int main(int argc, char** argv)
{
int FFTSIZE = 256;

std::complex<float>* cpxArray;
float* fftOut;

cpxArray = new std::complex<float>[FFTSIZE * FFTSIZE];
fftOut = new float[FFTSIZE * FFTSIZE];

for(size_t i = 0; i < FFTSIZE * FFTSIZE; i++) cpxArray[i] = 0;
cpxArray[255] = std::complex<float>(10000, 0);

concurrency::extent<2> e(FFTSIZE, FFTSIZE);
std::cout << "E[0]: " << e[0] << " E[1]: " << e[1] << std::endl;

fft<float, 2> m_fft(e);
concurrency::array<float, 2> outpArray(concurrency::extent<2>(FFTSIZE, FFTSIZE));
concurrency::array<std::complex<float>, 2> inpArray(concurrency::extent<2>(FFTSIZE, FFTSIZE), cpxArray);


m_fft.inverse_transform(inpArray, outpArray);
std::vector<float> outVec = outpArray;

std::copy(outVec.begin(), outVec.end(), fftOut);

std::ofstream debugDump("debugdump.txt");
for(int j = 0; j < FFTSIZE; j++)
{
for(int i = 0; i < FFTSIZE; i++)
{
debugDump << " " << fftOut[j * FFTSIZE + i];
}
debugDump << std::endl;
}
}

这两个都是使用 MSVC 2013 上的库存设置为 win32 控制台应用程序编译的,FFTW 测试也在 Centos 6.4 和 GCC 4.4.7 下运行。两个 FFTW 测试都使用 FFTW 版本 3.3.4,顺便说一下,复杂到真实和复杂到复杂的计划都进行了测试(结果相同)。

是否有人对我可以尝试解决此问题的 Visual Studio 编译器设置有丝毫线索?

最佳答案

查看蓝色的 MSVC FFTW 输出,它似乎是多个正弦相乘。也就是说,有一个周期为 64 左右的正弦波,一个周期为 4 的正弦波,可能还有另一个具有相似频率的正弦波来产生节拍。

这基本上意味着 MSVC 版本至少有两个非零输入。我怀疑原因是类型转换,因为你写了 fftw_complex通过 std::complex<double> 对象类型。

关于c++ - 为什么我不能在 Visual Studio 2013 下使用 FFTW 或 AMPFFT 获得有效的二维 FFT?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24175898/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com