代码之家  ›  专栏  ›  技术社区  ›  Bubble

特征FFT库

  •  0
  • Bubble  · 技术社区  · 6 年前

    我正在尝试使用FFTW后端的Eigen不支持的FFT库。具体来说,我想做一个二维FFT。这是我的代码:

    void fft2(Eigen::MatrixXf * matIn,Eigen::MatrixXcf * matOut)
    {
        const int nRows = matIn->rows();
        const int nCols = matIn->cols();
    
        Eigen::FFT< float > fft;
    
        for (int k = 0; k < nRows; ++k) {
            Eigen::VectorXcf tmpOut(nRows);
            fft.fwd(tmpOut, matIn->row(k));
            matOut->row(k) = tmpOut;
        }
    
        for (int k = 0; k < nCols; ++k) {
            Eigen::VectorXcf tmpOut(nCols);
            fft.fwd(tmpOut, matOut->col(k));
            matOut->col(k) = tmpOut;
        }
    
    }
    

    我有两个问题:

    • 首先,在某些矩阵上使用此代码时,我遇到了一个分段错误。并非所有矩阵都会发生此错误。我想这与校准错误有关。我以以下方式使用这些函数:

      特征::矩阵xxcf matFFT(mat.rows(),mat。cols()); fft2(&matFloat,&matFFT);

    其中mat可以是任何矩阵。有趣的是,只有当我在第二维度上计算FFT时,代码才会运行,而不是在第一维度上。kissFFT后端不会出现这种情况。

    • 其次,当函数工作时,我得到的结果与Matlab(使用FFTW)不同。例如:

    输入矩阵:

    [2, 1, 2]
    [3, 2, 1]
    [1, 2, 3]
    

    Eigen给出:

    [           (0,5),    (0.5,0.86603),          (0,0.5)]
    [  (-4.3301,-2.5),     (-1,-1.7321), (0.31699,-1.549)]
    [ (-1.5,-0.86603),       (2,3.4641),       (2,3.4641)]
    

    Matlab给出:

       17 +          0i          0.5 +    0.86603i          0.5 -    0.86603i
       -1 +          0i           -1 -     1.7321i            2 -     3.4641i
       -1 +          0i            2 +     3.4641i           -1 +     1.7321i 
    

    只有中央部分是相同的。

    欢迎任何帮助。

    1 回复  |  直到 6 年前
        1
  •  0
  •   chtz    6 年前

    在我的第一个解决方案中,我未能激活EIGEN\u FFTW\u DEFAULT,激活它表明了EIGEN的FFTW支持实现中的一个错误。以下工作:

    #define EIGEN_FFTW_DEFAULT
    #include <iostream>
    #include <unsupported/Eigen/FFT>
    
    int main(int argc, char *argv[])
    {
        Eigen::MatrixXf A(3,3);
        A << 2,1,2,  3,2,1,  1,2,3;
        const int nRows = A.rows();
        const int nCols = A.cols();
    
        std::cout << A << "\n\n";
    
        Eigen::MatrixXcf B(3,3);
    
        Eigen::FFT< float > fft;
    
        for (int k = 0; k < nRows; ++k) {
            Eigen::VectorXcf tmpOut(nRows);
            fft.fwd(tmpOut, A.row(k));
            B.row(k) = tmpOut;
        }
        std::cout << B << "\n\n";
        Eigen::FFT< float > fft2;  // Workaround: Using the same FFT object for a real and a complex FFT seems not to work with FFTW
        for (int k = 0; k < nCols; ++k) {
            Eigen::VectorXcf tmpOut(nCols);
            fft2.fwd(tmpOut, B.col(k));
            B.col(k) = tmpOut;
        }
        std::cout << B << '\n';
    }
    

    我得到以下输出:

    2 1 2
    3 2 1
    1 2 3
    
         (17,0)  (0.5,0.866025) (0.5,-0.866025)
         (-1,0)   (-1,-1.73205)     (2,-3.4641)
         (-1,0)      (2,3.4641)    (-1,1.73205)
    

    这与您的Matlab结果相同。

    N、 B.:FFTW似乎支持2D real->本机复FFT(不使用单个FFT)。这可能更有效。

    fftwf_plan fftwf_plan_dft_r2c_2d(int n0, int n1,               
                                     float *in, fftwf_complex *out, unsigned flags);