本征 FFT 库
Eigen FFT library
我正在尝试使用 FFTW 后端使用 Eigen 不受支持的 FFT 库。具体来说,我想做一个 2D 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;
}
}
我有 2 个问题:
首先,在某些矩阵上使用此代码时出现分段错误。并非所有矩阵都会发生此错误。我想这与对齐错误有关。我按以下方式使用这些功能:
Eigen::MatrixXcf matFFT(mat.rows(),mat.cols());
fft2(&matFloat,&matFFT);
其中 mat 可以是任何矩阵。有趣的是,只有当我在二维上计算 FFT 时,代码才会植入,而不是在第一维上。 kissFFT 后端不会发生这种情况。
- 其次,当函数运行时,我没有得到与 Matlab(使用 FFTW)相同的结果。例如:
输入矩阵:
[2, 1, 2]
[3, 2, 1]
[1, 2, 3]
本征给出:
[ (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
只有中间部分是一样的
欢迎任何帮助。
我未能在我的第一个解决方案中激活 EIGEN_FFTW_DEFAULT,激活它会揭示 Eigen 的 fftw-support 实现中的一个错误。以下作品:
#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->complex FFT(不使用单独的 FFT)。这可能更有效。
fftwf_plan fftwf_plan_dft_r2c_2d(int n0, int n1,
float *in, fftwf_complex *out, unsigned flags);
我正在尝试使用 FFTW 后端使用 Eigen 不受支持的 FFT 库。具体来说,我想做一个 2D 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;
}
}
我有 2 个问题:
首先,在某些矩阵上使用此代码时出现分段错误。并非所有矩阵都会发生此错误。我想这与对齐错误有关。我按以下方式使用这些功能:
Eigen::MatrixXcf matFFT(mat.rows(),mat.cols()); fft2(&matFloat,&matFFT);
其中 mat 可以是任何矩阵。有趣的是,只有当我在二维上计算 FFT 时,代码才会植入,而不是在第一维上。 kissFFT 后端不会发生这种情况。
- 其次,当函数运行时,我没有得到与 Matlab(使用 FFTW)相同的结果。例如:
输入矩阵:
[2, 1, 2]
[3, 2, 1]
[1, 2, 3]
本征给出:
[ (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
只有中间部分是一样的
欢迎任何帮助。
我未能在我的第一个解决方案中激活 EIGEN_FFTW_DEFAULT,激活它会揭示 Eigen 的 fftw-support 实现中的一个错误。以下作品:
#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->complex FFT(不使用单独的 FFT)。这可能更有效。
fftwf_plan fftwf_plan_dft_r2c_2d(int n0, int n1,
float *in, fftwf_complex *out, unsigned flags);