在转向 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
的所有行
谢谢
您对
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;
}