对于fftw3
,如果对大小为[m x n]的矩阵A执行Reals 2D FFT,则会得到大小为[m x(n / 2 + 1)]的复数矩阵B。如果我们只有B,如何确定A的形状,即A的行和列?
对于一维FFT问题,我知道在fft
上以奇数大小执行vector
会导致复数向量以实数结尾,即vector_fft[-1].imag() == 0
。这可能是确定原始vector
大小的关键。
但是,对于2D FFT,问题似乎更加复杂,对于2D FFT编码阵列没有这种明显的功能。我阅读了fftw3
的手册,但仍然对fftw
如何压缩结果矩阵中的共轭数据感到困惑。
#include <iostream>
#include <Eigen/Eigen>
#include <fftw3.h>
#include <complex>
#define EIGEN_DEFAULT_TO_ROW_MAJOR
using namespace Eigen;
using Cmpl = std::complex<double>;
using Matd = Matrix<double, Dynamic, Dynamic, RowMajor>;
using Vecd = Matrix<double, 1, Dynamic, RowMajor>;
using Veccd = Matrix< Cmpl, 1, Dynamic, RowMajor>;
using Matcd = Matrix< Cmpl, Dynamic, Dynamic, RowMajor>;
Veccd fft_1d_r2c(const Vecd& in) {
Veccd out(in.size() / 2 + 1);
auto plan = fftw_plan_dft_r2c_1d(in.size(),
(double*)in.data(), (fftw_complex*)out.data(), FFTW_ESTIMATE);
fftw_execute(plan);
fftw_destroy_plan(plan);
return out;
}
Veccd fft_1d_c2c(const Veccd& in) {
Veccd out(in.size());
auto plan = fftw_plan_dft_1d(in.size(),
(fftw_complex*)in.data(), (fftw_complex*)out.data(),
FFTW_FORWARD, FFTW_ESTIMATE);
fftw_execute(plan);
fftw_destroy_plan(plan);
return out;
}
Matcd fft_2d_r2c(const Matd& in) {
Matcd out(in.rows(), in.cols() / 2 + 1);
auto plan = fftw_plan_dft_r2c_2d(in.rows(), in.cols(),
(double*)in.data(), (fftw_complex*)out.data(), FFTW_ESTIMATE);
fftw_execute(plan);
fftw_destroy_plan(plan);
return out;
}
Matcd fft_2d_c2c(const Matcd& in) {
Matcd out(in.rows(), in.cols());
auto plan = fftw_plan_dft_2d(in.rows(), in.cols(),
(fftw_complex*)in.data(), (fftw_complex*)out.data(),
FFTW_FORWARD, FFTW_ESTIMATE);
fftw_execute(plan);
fftw_destroy_plan(plan);
return out;
}
void test_1d(const int size) {
Vecd vec{size};
vec.setRandom();
Veccd vec_fft = fft_1d_c2c(vec.cast<Cmpl>());
Veccd vec_rfft = fft_1d_r2c(vec);
std::cout << "Original Vector: \n" << vec << std::endl << std::endl
<< "fftw_r2c of vec: \n" << vec_rfft << std::endl << std::endl;
}
void test_2d(const int rows, const int cols) {
Matd mat{rows, cols};
mat.setRandom();
Matcd mat_rfft = fft_2d_r2c(mat);
Matcd mat_fft = fft_2d_c2c(mat.cast<Cmpl>());
std::cout << "Original Matrix: \n" << mat << std::endl << std::endl
<< "fftw_r2c of mat: \n" << mat_rfft << std::endl << std::endl;
std::cout << "fftw_c2c of mat: \n" << mat_fft << std::endl;
}
int main(int argc, char* argv[]) {
std::cout << "For 1D fft problems" << std::endl;
test_1d(9);
test_1d(10);
std::cout << "For 2D fft problems" << std::endl;
test_2d(6, 5);
test_2d(6, 4);
return 0;
}
对于fftw_r2c
返回的矩阵,如何确定原始矩阵的形状?