使用 Eigen FFT 库沿行对特征矩阵进行 1D FFT 会返回不正确的结果

问题描述 投票:0回答:1

在转向 FFTW 库之前,我在 Eigen FFT 库上看到了一些我想实现的示例。由于某种原因,我无法沿着特征矩阵的每一行获得正确的一维 FFT。我正确地得到了每列的一维 FFT,但没有得到行。为了清楚起见,我将非常非常简单的 C++ 代码与 MATLAB 进行比较。

在 MATLAB 中:

Nx=8;
Ny=8;
u = eye(Ny+1,Nx); %very simple choice for now
%take FFT along columns
ucol = fft(u,[],1);
urow = fft(u,[],2);

在 C++ 中:

#include "fftw3.h"
#include<unsupported/Eigen/CXX11/Tensor>

static const int nx=8;
static const int ny=8;

using namespace std;
using namespace Eigen;
int main{
Eigen::FFT<double> fft;
Eigen::MatrixXcd u(ny+1,nx);
u.setIdentity();

//1D FFT along cols
Eigen::MatrixXcd ucol(ny+1,nx);
for (int k=0; k<u.cols(); k++){
     ucol.col(k) = fft.fwd(u.col(k));
}
std::cout<<ucol<<endl; //correct compared to MATLAB: ucol = fft(u,[],1);

//1D FFT along rows 
Eigen::MatrixXcd urow(ny+1,nx);
for (int k=0; k<u.rows(); k++){
     urow.row(k) = fft.fwd(u.row(k));
}
std::cout<<urow<<endl; //**Incorrect** compared to MATLAB: urow = fft(u,[],2);
}

为什么第二个 1D FFT 与 MATLAB 相比不正确?

MATLAB 输出:

ucol =

   1.0000 + 0.0000i   1.0000 + 0.0000i   1.0000 + 0.0000i   1.0000 + 0.0000i   1.0000 + 0.0000i   1.0000 + 0.0000i   1.0000 + 0.0000i   1.0000 + 0.0000i
   1.0000 + 0.0000i   0.7660 - 0.6428i   0.1736 - 0.9848i  -0.5000 - 0.8660i  -0.9397 - 0.3420i  -0.9397 + 0.3420i  -0.5000 + 0.8660i   0.1736 + 0.9848i
   1.0000 + 0.0000i   0.1736 - 0.9848i  -0.9397 - 0.3420i  -0.5000 + 0.8660i   0.7660 + 0.6428i   0.7660 - 0.6428i  -0.5000 - 0.8660i  -0.9397 + 0.3420i
   1.0000 + 0.0000i  -0.5000 - 0.8660i  -0.5000 + 0.8660i   1.0000 + 0.0000i  -0.5000 - 0.8660i  -0.5000 + 0.8660i   1.0000 + 0.0000i  -0.5000 - 0.8660i
   1.0000 + 0.0000i  -0.9397 - 0.3420i   0.7660 + 0.6428i  -0.5000 - 0.8660i   0.1736 + 0.9848i   0.1736 - 0.9848i  -0.5000 + 0.8660i   0.7660 - 0.6428i
   1.0000 + 0.0000i  -0.9397 + 0.3420i   0.7660 - 0.6428i  -0.5000 + 0.8660i   0.1736 - 0.9848i   0.1736 + 0.9848i  -0.5000 - 0.8660i   0.7660 + 0.6428i
   1.0000 + 0.0000i  -0.5000 + 0.8660i  -0.5000 - 0.8660i   1.0000 + 0.0000i  -0.5000 + 0.8660i  -0.5000 - 0.8660i   1.0000 + 0.0000i  -0.5000 + 0.8660i
   1.0000 + 0.0000i   0.1736 + 0.9848i  -0.9397 + 0.3420i  -0.5000 - 0.8660i   0.7660 - 0.6428i   0.7660 + 0.6428i  -0.5000 + 0.8660i  -0.9397 - 0.3420i
   1.0000 + 0.0000i   0.7660 + 0.6428i   0.1736 + 0.9848i  -0.5000 + 0.8660i  -0.9397 + 0.3420i  -0.9397 - 0.3420i  -0.5000 - 0.8660i   0.1736 - 0.9848i


urow =

   1.0000 + 0.0000i   1.0000 + 0.0000i   1.0000 + 0.0000i   1.0000 + 0.0000i   1.0000 + 0.0000i   1.0000 + 0.0000i   1.0000 + 0.0000i   1.0000 + 0.0000i
   1.0000 + 0.0000i   0.7071 - 0.7071i   0.0000 - 1.0000i  -0.7071 - 0.7071i  -1.0000 + 0.0000i  -0.7071 + 0.7071i   0.0000 + 1.0000i   0.7071 + 0.7071i
   1.0000 + 0.0000i   0.0000 - 1.0000i  -1.0000 + 0.0000i   0.0000 + 1.0000i   1.0000 + 0.0000i   0.0000 - 1.0000i  -1.0000 + 0.0000i   0.0000 + 1.0000i
   1.0000 + 0.0000i  -0.7071 - 0.7071i   0.0000 + 1.0000i   0.7071 - 0.7071i  -1.0000 + 0.0000i   0.7071 + 0.7071i   0.0000 - 1.0000i  -0.7071 + 0.7071i
   1.0000 + 0.0000i  -1.0000 + 0.0000i   1.0000 + 0.0000i  -1.0000 + 0.0000i   1.0000 + 0.0000i  -1.0000 + 0.0000i   1.0000 + 0.0000i  -1.0000 + 0.0000i
   1.0000 + 0.0000i  -0.7071 + 0.7071i   0.0000 - 1.0000i   0.7071 + 0.7071i  -1.0000 + 0.0000i   0.7071 - 0.7071i   0.0000 + 1.0000i  -0.7071 - 0.7071i
   1.0000 + 0.0000i   0.0000 + 1.0000i  -1.0000 + 0.0000i   0.0000 - 1.0000i   1.0000 + 0.0000i   0.0000 + 1.0000i  -1.0000 + 0.0000i   0.0000 - 1.0000i
   1.0000 + 0.0000i   0.7071 + 0.7071i   0.0000 + 1.0000i  -0.7071 + 0.7071i  -1.0000 + 0.0000i  -0.7071 - 0.7071i   0.0000 - 1.0000i   0.7071 - 0.7071i
   0.0000 + 0.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i

C++ 输出:

ucol=

(1.000,0.000)   (1.000,0.000)   (1.000,0.000)   (1.000,0.000)   (1.000,0.000)   (1.000,0.000)   (1.000,0.000)   (1.000,0.000)
  (1.000,0.000)  (0.766,-0.643)  (0.174,-0.985) (-0.500,-0.866) (-0.940,-0.342)  (-0.940,0.342)  (-0.500,0.866)   (0.174,0.985)
  (1.000,0.000)  (0.174,-0.985) (-0.940,-0.342)  (-0.500,0.866)   (0.766,0.643)  (0.766,-0.643) (-0.500,-0.866)  (-0.940,0.342)
  (1.000,0.000) (-0.500,-0.866)  (-0.500,0.866)   (1.000,0.000) (-0.500,-0.866)  (-0.500,0.866)   (1.000,0.000) (-0.500,-0.866)
  (1.000,0.000) (-0.940,-0.342)   (0.766,0.643) (-0.500,-0.866)   (0.174,0.985)  (0.174,-0.985)  (-0.500,0.866)  (0.766,-0.643)
 (1.000,-0.000)  (-0.940,0.342)  (0.766,-0.643)  (-0.500,0.866)  (0.174,-0.985)   (0.174,0.985) (-0.500,-0.866)   (0.766,0.643)
 (1.000,-0.000)  (-0.500,0.866) (-0.500,-0.866)  (1.000,-0.000)  (-0.500,0.866) (-0.500,-0.866)  (1.000,-0.000)  (-0.500,0.866)
 (1.000,-0.000)   (0.174,0.985)  (-0.940,0.342) (-0.500,-0.866)  (0.766,-0.643)   (0.766,0.643)  (-0.500,0.866) (-0.940,-0.342)
 (1.000,-0.000)   (0.766,0.643)   (0.174,0.985)  (-0.500,0.866)  (-0.940,0.342) (-0.940,-0.342) (-0.500,-0.866)  (0.174,-0.985)

urow=

(1.000,0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)
 (1.000,0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)
 (1.000,0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)
 (1.000,0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)
 (1.000,0.000) (0.000,-0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)
 (1.000,0.000) (0.000,-0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)
 (1.000,0.000) (0.000,-0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)
 (1.000,0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)
 (0.000,0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)  (0.000,0.000)

为什么 C++ 代码中的

urow
与 MATLAB 输出不匹配?我很确定第二个循环正在迭代
u

的所有行

谢谢

c++ matlab eigen3 fftw
1个回答
0
投票

您对

fft.fwd
的用法不正确。文档显示该函数需要频率向量,然后是时间向量。您仅提供一项输入。

这里是上帝螺栓:https://www.godbolt.org/z/Mecfr487f

这只是代码。

#include <Eigen/Core>
#include<unsupported/Eigen/CXX11/Tensor>
#include <unsupported/Eigen/FFT>
#include <iostream>

static const int nx=8;
static const int ny=8;

using namespace std;
using namespace Eigen;

int main(int argc, char * argv[]){
Eigen::FFT<double> fft;
Eigen::MatrixXcd u(ny+1,nx);
u.setIdentity();

//1D FFT along cols
Eigen::MatrixXcd ucol(ny+1,nx);
Eigen::VectorXcd col(ny+1);
for (int k=0; k<u.cols(); k++){
     // ucol.col(k) = fft.fwd(u.col(k));
     fft.fwd(col, u.col(k));
     ucol.col(k) = col;
}
std::cout<<ucol<<endl;

//1D FFT along rows 
Eigen::MatrixXcd urow(ny+1,nx);
Eigen::VectorXcd row(nx);
for (int k=0; k<u.rows(); k++){
     // urow.row(k) = fft.fwd(u.row(k));
     fft.fwd(row, u.row(k));
     urow.row(k) = row;
}
std::cout<<urow<<endl;
}
© www.soinside.com 2019 - 2024. All rights reserved.