使用Matlab fft2和MKL DFTI计算得出的不同结果

使用Matlab fft2和MKL DFTI计算得出的不同结果,matlab,intel-mkl,Matlab,Intel Mkl,我尝试计算二维数据的前向Fourie变换时得到了不同的结果 下面是3x3矩阵的简单测试示例: Matlab,清单: fft2([25.6798, 26.0815, 29.0069; 33.5761 37.123 38.4696; 38.6358 38.0078 37.649]) DFTI_DESCRIPTOR_HANDLE descriptor1; double test[3][3] = {{25.6798, 26.0815, 29.0069},

我尝试计算二维数据的前向Fourie变换时得到了不同的结果

下面是3x3矩阵的简单测试示例: Matlab,清单:

fft2([25.6798, 26.0815, 29.0069; 33.5761 37.123 38.4696; 38.6358 38.0078 37.649])
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);
Matlab结果:

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,清单:

fft2([25.6798, 26.0815, 29.0069; 33.5761 37.123 38.4696; 38.6358 38.0078 37.649])
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情况下的输出存储配置。但是我找不到设置此描述符的正确方法


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

我终于明白了。也许这个解决方案对某些人有用

下面给出了正确的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"
#包括
#定义MKL_Complex16 std::complex//在包含MKL文件之前,应先完成此定义。您将需要它来使用STL函数,例如conj,以及MKL_Complex16数据
#包括“mkl.h”
其次,除了问题中的代码外,还应为这种情况定义DFTI_NOT_in place和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]);
   }
}
DFTI\u描述符\u句柄描述符1;
双重测试[3][3]={{25.6798,26.0815,29.0069},
{33.5761, 37.123, 38.4696},
{38.6358, 38.0078, 37.649}};  
MKL_LONG状态1,l1[2];l1[0]=3;l1[1]=3;
MKL_Complex16 fftu1[3][3];
状态1=DftiCreateDescriptor(&Descriptor 1,DFTI_DOUBLE,DFTI_REAL,2,l1);
状态=DftiSetValue(描述符1,DFTI位置,DFTI未就位);
状态=DftiSetValue(描述符1,DFTI共轭偶数存储,DFTI复数);
MKL_LONG rs[2];rs[0]=0;rs[1]=3;rs[2]=1//描述2D 3x3矩阵
状态=DftiSetValue(描述符1,DFTI输入步长,rs);
MKL_LONG cs[2];cs[0]=0;cs[1]=3;cs[2]=1/*描述输出矩阵。警告只有N1x(N2/2)+1半部分包含正确答案。其余部分应该恢复!!!根据手册,cs[1]=N2/2+1,因此在我们的例子中cs[1]应该是2。但如果cs[1]=2,这将导致答案的结果发生变化。。我希望,这是(使cs[1]=N2}处理移位的正确方法,但我不确定是否存在。需要检查*/
状态=DftiSetValue(描述符1,DFTI输出步长,cs);
状态=DftiCommitDescriptor(描述符1);
状态=DFTICOMPUTERFORWARD(描述符1,测试,fftu1);//转发完成
/*现在,共轭偶数域中的复值数据序列可以按照中所述进行重构https://software.intel.com/en-us/mkl-developer-reference-c-dfti-packed-format*/
对于(尺寸ii=0;ii<3;ii++){
对于(尺寸jj=3/2+1;jj<3;jj++){
fftu1[ii][jj]=std::conj((MKL_复合物16)fftu1[(3-ii)%3][(3-jj)%3]);
}
}
现在,fftu1结果与Matlab计算结果相同,直到小数点后第四位