2017-05-17 156 views
1

我有不同的结果试图计算用于2D数据的Forward Fourie变换。 MATLAB,列表:使用Matlab fft2和MKL的不同结果DftiComputeForward

fft2([25.6798, 26.0815, 29.0069; 33.5761 37.123 38.4696; 38.6358 38.0078 37.649]) 

Matlab的结果:低于3×3矩阵

简单测试例子

ans = 
    1.0e+02 * 
    3.0423 + 0.0000i -0.0528 + 0.0339i -0.0528 - 0.0339i 
    -0.3096 + 0.0444i 0.0112 + 0.0646i -0.0144 + 0.0225i 
    -0.3096 - 0.0444i -0.0144 - 0.0225i 0.0112 - 0.0646i 

MKL,列表:

DFTI_DESCRIPTOR_HANDLE descriptor1; 
double test[3][3] = {{25.6798, 26.0815, 29.0069}, 
         {33.5761, 37.123, 38.4696}, 
         {38.6358, 38.0078, 37.649}}; 
MKL_LONG status1, l1[2]; l1[0] = 3; l1[1] = 3; 
MKL_Complex16 fftu1[3][3]; 

status1 = DftiCreateDescriptor(&descriptor1, DFTI_DOUBLE, DFTI_REAL, 2, l1); 
status = DftiCommitDescriptor(descriptor1); 
status = DftiComputeForward(descriptor1, test, fftu1); 

MKL结果:

4.02248e-315+2.35325e-310i 6.42285e-323+6.95254e-310i 2.35325e-310+2.35325e-310i 
6.95254e-310+6.95254e-310i 2.35308e-310+2.35325e-310i 0+2.35325e-310i 
2.35325e-310+2.35325e-310i 2.35325e-310+2.35325e-310i 7.41098e-323+1.03754e-322i 

我发现问题可能是由MKL情况下的输出存储配置描述符引起的。但是我找不到设置这个描述符的正确方法。

我在做什么错?请给我一些提示。

回答

1

终于我明白了。可能是解决方案对某人有用。

下面提供了正确的C++ MKL清单,并附有说明意见。 首先,下定义应在包括节中使用:

#include <complex> 
#define MKL_Complex16 std::complex<double> //This definition should be done before including MKL files. You will need it to use STL functions, for example conj, with MKL_Complex16 data 
#include "mkl.h" 

其次,DFTI_NOT_INPLACE和DFTI_STORAGE应为这种情况下被定义,除了代码中的问题是:

DFTI_DESCRIPTOR_HANDLE descriptor1; 
double test[3][3] = {{25.6798, 26.0815, 29.0069}, 
         {33.5761, 37.123, 38.4696}, 
         {38.6358, 38.0078, 37.649}}; 
MKL_LONG status1, l1[2]; l1[0] = 3; l1[1] = 3; 
MKL_Complex16 fftu1[3][3]; 
status1 = DftiCreateDescriptor(&descriptor1, DFTI_DOUBLE, DFTI_REAL, 2, l1); 
status = DftiSetValue(descriptor1, DFTI_PLACEMENT, DFTI_NOT_INPLACE); 
status = DftiSetValue(descriptor1, DFTI_CONJUGATE_EVEN_STORAGE, DFTI_COMPLEX_COMPLEX); 
MKL_LONG rs[2]; rs[0] = 0; rs[1] = 3; rs[2] = 1; //describing 2D 3x3 matrix 
status = DftiSetValue(descriptor1, DFTI_INPUT_STRIDES, rs); 
MKL_LONG cs[2]; cs[0] = 0; cs[1] = 3; cs[2] = 1; /*Describing output matrix. Warning! Only N1x(N2/2)+1 half part will contain correct answer. Rest part should be restored!!! According to the manual, cs[1]=N2/2+1, so cs[1] should be 2 in our case. But if cs[1]=2, this leads to results shift in answer.. I hope, this is (making cs[1]=N2} is a correct way to deal with shift, bu i'm not sure there. Need to be checked*/ 
status = DftiSetValue(descriptor1, DFTI_OUTPUT_STRIDES, cs); 
status = DftiCommitDescriptor(descriptor1); 
status = DftiComputeForward(descriptor1, test, fftu1); // Forward Fourie done 
/*Now the complex-valued data sequences in the conjugate-even domain can be reconstructed as described in https://software.intel.com/en-us/mkl-developer-reference-c-dfti-packed-format*/ 
for (size_t ii=0; ii< 3; ii++){ 
    for (size_t jj=3/2+1; jj< 3; jj++){ 
    fftu1[ii][jj] = std::conj((MKL_Complex16)fftu1 [(3-ii)%3] [(3-jj)%3]); 
    } 
} 

现在fftu1的结果与直到小数点后第四位的Matlab计算结果相同。