Eigen庫自帶快速傅立葉變換(FFT)例項
最近在開發一個專案,用到大量線性變換(矩陣計算)和快速傅立葉變換(FFT)。
利用Eigen實現矩陣計算非常方便,在實現FFT時,藉助了FFTW3庫,但二者由於資料型別不同,需要轉化,影響計算效率。
Eigen+FFTW3的計算需要1.7s,希望進一步提高演算法的計算效率。
預算嘗試Eigen庫自帶的FFT,相關資料如下:
EigenFFT
Eigen/FFT
可以看出,Eigen FFT並不成熟,藉助了kissFFT實現的。
在stackoverflow網站上找到了參考程式碼,
eigen-fft-library
在本地計算機上試跑了程式碼
#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';
}
輸出結果如下:
當註釋掉第一個for迴圈時,輸出結果如下:
由此可以判斷,兩個for迴圈是相關的,一起實現了FFT。
可見,Eigen自帶的FFT效率應該不高。
對了,在試跑上面的程式時,在fft.fwd語句處會報錯,
error C4996: ‘std::copy::_Unchecked_iterators::_Deprecate’: Call to ‘std::copy’ with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ ‘Checked Iterators’
參考這個部落格可解決:
Unchecked_iterators
打算繼續用FFTW2,在與Eigen資料型別轉化方面進行優化,並且採用FFTW3庫自帶的函式
fftwf_plan fftwf_plan_dft_r2c_2d(int n0, int n1,
float *in, fftwf_complex *out, unsigned flags);
進行FFT,避免輸入資料額外補充虛部。