我正在尝试使用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
....
]
我做错了什么?
答案 0 :(得分:1)
你在C实现中没有做错任何事,但是你不能确定你是否正在比较那样。
为什么你可以在C语言中的FFTW和MATLAB中的fft2()
之间获得不同的结果。
version('-fftw')
找到它的详细信息。libmwmfl_fft
)来取消规划器例程并公开简单函数,如fft()
和fft2()
。您无法确定它是否会选择与您的问题相同的计划程序。FFTW_ESTIMATE
,因为它使用FFTW_MEASURE
,FFTW_PATIENT
或FFTW_EXHAUSTIVE
的不太严格的测试程序。 我查看了您在问题中发布的数据的相对误差,有些值为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结果。