Для fftw3
, если вы выполните Reals 2D FFT для матрицы A с размером [m x n], вы получите комплексную матрицу B с размером [m x (n / 2 + 1)]. Если у нас есть только B, как определить форму A, то есть строки и столбцы A?
Для задач 1D БПФ я узнаю, что выполнение fft
на vector
с нечетным размером приводит к сложному вектору, который заканчивается действительным числом, то есть vector_fft[-1].imag() == 0
. И это может быть ключом для определения оригинального vector
размера.
Тем не менее, для 2D FFT проблема кажется более сложной, такой явной особенности для 2D FFT-ed-матрицы нет. Я прочитал руководство по 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
, как определить форму исходной матрицы?