fft2(matlab)和fftw(C)的结果不同

时间:2014-06-30 08:31:38

标签: c matlab fftw

我正在尝试使用FFTW3库在C中实现Matlab fft2()函数。

但是,我得到了不同的结果。

考虑下一个矩阵:

Z=[ 
    0.4791    0.4765    0.4791    0.4765    0.4791    0.4765    0.4791    0.4765     
    0.4798    0.4695    0.4798    0.4695    0.4798    0.4695    0.4798    0.4695     
    0.4791    0.4765    0.4791    0.4765    0.4791    0.4765    0.4791    0.4765     
    0.4798    0.4695    0.4798    0.4695    0.4798    0.4695    0.4798    0.4695     
    0.4791    0.4765    0.4791    0.4765    0.4791    0.4765    0.4791    0.4765     
    0.4798    0.4695    0.4798    0.4695    0.4798    0.4695    0.4798    0.4695     
    0.4791    0.4765    0.4791    0.4765    0.4791    0.4765    0.4791    0.4765     
    0.4798    0.4695    0.4798    0.4695    0.4798    0.4695    0.4798    0.4695     
    .... 
] 

使用以下代码:

Z-> Double* 

fftw_complex* fft2; 
fft2 = (fftw_complex *)fftw_malloc(sizeof(fftw_complex)*Samples*(Lines)); 

fftw_plan p1; 

p1 = fftw_plan_dft_r2c_2d(Lines,Samples, Z, fft2, FFTW_ESTIMATE); 
fftw_execute(p1); 

Matlab的结果:

fft2= [ 
 5534,25859596829 + 0,00000000000000i     186,747610745237 - 529,515274347496i
 42,6452471730436 - 321,074636721419i    -21,4495750160608 - 190,407528614266i
-50,3875107145668 - 50,5480303619799i     30,1151029075525 + 378,240946095017i
-196,295569635431 + 228,972218925794i     35,6434356803659 - 5,46216875816971i
 36,2702126322693 - 38,5502177293316i     18,5093049539101 - 33,4608602804025i
     .... 
 ]

我的C代码的结果:

5534.260423 + 0.000000 i           186.731496 + -529.495788 i 
  42.655319 + -321.068356 i        -21.425010 + -190.382717 i 
 -50.277195 + -50.384210 i          29.909846 + 377.823957 i 
 -195.767224 + 228.693862 i         35.241375 + -5.315382 i 
 36.134134 + -38.527643 i           18.406395 + -33.467351 i 
    .... 
] 

我做错了什么?

2 个答案:

答案 0 :(得分:1)

你在C实现中没有做错任何事,但是你不能确定你是否正在比较那样。

为什么你可以在C语言中的FFTW和MATLAB中的fft2()之间获得不同的结果。

  • MATLAB使用自己专门优化的FFTW版本,使用多线程支持和SSE / AVX矢量化指令进行编译。您可以在MATLAB中使用version('-fftw')找到它的详细信息。
  • MATLAB使用它在FFTW之上拥有抽象(libmwmfl_fft)来取消规划器例程并公开简单函数,如fft()fft2()。您无法确定它是否会选择与您的问题相同的计划程序。
  • FFTW使用启发式方法确定用于计算您指定的数据大小和类型的FFT的最佳算法。这些启发式方法可能因同一数据和同一台机器的运行而异,尤其是FFTW_ESTIMATE,因为它使用FFTW_MEASUREFFTW_PATIENTFFTW_EXHAUSTIVE的不太严格的测试程序。
  • 浮点运算不一定是关联的,并且可能导致根据FFTW决定用于计算FFT的算法计算不同的值。根据所选择的算法,浮点舍入误差可能会通过某些计算传播,导致精度较低。

我查看了您在问题中发布的数据的相对误差,有些值为1e^-5,而平均相对误差为0.2341

总的来说,考虑到浮点计算的性质,谁说计算正确的值? C或MATLAB中的FFTW?

答案 1 :(得分:0)

在比较Matlab的fft2与FFTW之前,对于Matlab和FFTW,您应该在给定相同输入的执行之间验证可重现的结果。因为默认的FFTW不会每次为同一输入产生相同的结果。我知道这很令人不安,(可能会对这个答案产生很多负面评论。)差异很小。

我自己用FFTW遇到了这个问题。我使用输出的MD5校验和来验证没有区别。通过更改默认Planner Flags for FFTW,我能够重现相等的校验和(相同的输出)。此问题已涵盖in Q3.8 of the FFTW FAQ

确定性FFTW工作后,对Matlab执行相同操作(因为它只包含FFTW,并提供修改FFTW计划的选项)。

然后比较FFTW和Matlab结果。