【问题标题】:Different results using Matlab fft2 and MKL DftiComputeForward使用 Matlab fft2 和 MKL DftiComputeForward 的不同结果
【发布时间】:2017-05-17 08:08:21
【问题描述】:

尝试计算二维数据的正向傅里叶变换时,我得到了不同的结果。

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

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

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,上市:

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案例中的输出存储配置。但是我找不到设置这个描述符的正确方法。

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

【问题讨论】:

    标签: matlab intel-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 计算的结果相同,直到小数点后第四位。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-04-03
      • 1970-01-01
      • 2011-09-09
      • 2023-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多