头文件:
/* * Copyright (c) 2008-2011 Zhang Ming (M. Zhang), [email protected] * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 2 or any later version. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. A copy of the GNU General Public License is available at: * http://www.fsf.org/licensing/licenses */ /***************************************************************************** * fft.h * * Some convenient interface for FFT algorithm. If signal length "N" is power * of 2, then calls FFTR2 class to compute, else calls FFTPF class. * Forward: Xk = fftr2c(xn); Xk = fftc2c(xn); * Inverse: xn = fftc2r(Xk); xn = fftc2c(Xk); * * These routines don't need FFTW lib, but less efficiency than FFTW. * * Zhang Ming, 2010-09, Xi'an Jiaotong University. *****************************************************************************/ #ifndef FFT_H #define FFT_H #include <fftmr.h> #include <fftpf.h> namespace splab { template<typename Type> Vector< complex<Type> > fft( const Vector<Type>& ); template<typename Type> Vector< complex<Type> > fft( const Vector< complex<Type> >& ); template<typename Type> Vector< complex<Type> > ifft( const Vector< complex<Type> >& ); template<typename Type> Vector< complex<Type> > fftr2c( const Vector<Type>& ); template<typename Type> Vector< complex<Type> > fftc2c( const Vector< complex<Type> >& ); template<typename Type> Vector<Type> ifftc2r( const Vector< complex<Type> >& ); template<typename Type> Vector< complex<Type> > ifftc2c( const Vector< complex<Type> >& ); #include <fft-impl.h> } // namespace splab #endif // FFT_H
实现文件:
/* * Copyright (c) 2008-2011 Zhang Ming (M. Zhang), [email protected] * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 2 or any later version. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. A copy of the GNU General Public License is available at: * http://www.fsf.org/licensing/licenses */ /***************************************************************************** * fft-impl.h * * Implementation for FFT and IFFT interface. * * Zhang Ming, 2010-09, Xi'an Jiaotong University. *****************************************************************************/ /** * Forward FFT algorithm. */ template<typename Type> inline Vector< complex<Type> > fft( const Vector<Type> &xn ) { return fftr2c( xn ); } template<typename Type> inline Vector< complex<Type> > fft( const Vector< complex<Type> > &xn ) { return fftc2c( xn ); } /** * Inverse FFT algorithm. */ template<typename Type> inline Vector< complex<Type> > ifft( const Vector< complex<Type> > &Xk ) { return ifftc2c( Xk ); } /** * Real to complex DFT of 1D signal. */ template<typename Type> inline Vector< complex<Type> > fftr2c( const Vector<Type> &xn ) { Vector< complex<Type> > Xk( xn.size() ); if( isPower2(xn.size()) ) { FFTMR<Type> dft; dft.fft( xn, Xk ); } else { FFTPF<Type> dft; dft.fft( xn, Xk ); } return Xk; } /** * Complex to complex DFT of 1D signal. */ template<typename Type> inline Vector< complex<Type> > fftc2c( const Vector< complex<Type> > &xn ) { Vector< complex<Type> > Xk( xn.size() ); if( isPower2(xn.size()) ) { for( int i=0; i<xn.size(); ++i ) Xk[i] = xn[i]; FFTMR<Type> dft; dft.fft( Xk ); } else { FFTPF<Type> dft; dft.fft( xn, Xk ); } return Xk; } /** * Complex to real IDFT of 1D signal. */ template<typename Type> inline Vector<Type> ifftc2r( const Vector< complex<Type> > &Xk ) { Vector<Type> xn( Xk.size() ); if( isPower2(xn.size()) ) { Vector< complex<Type> > tmp( Xk ); FFTMR<Type> dft; dft.ifft( tmp, xn ); } else { FFTPF<Type> dft; dft.ifft( Xk, xn ); } return xn; } /** * Complex to complex IDFT of 1D signal. */ template<typename Type> inline Vector< complex<Type> > ifftc2c( const Vector< complex<Type> > &Xk ) { Vector< complex<Type> > xn( Xk.size() ); if( isPower2(xn.size()) ) { for( int i=0; i<xn.size(); ++i ) xn[i] = Xk[i]; FFTMR<Type> dft; dft.ifft( xn ); } else { FFTPF<Type> dft; dft.ifft( Xk, xn ); } return xn; }
测试代码:
/***************************************************************************** * fft_test.cpp * * FFT test. * * Zhang Ming, 2010-09, Xi'an Jiaotong University. *****************************************************************************/ #include <iostream> #include <cstdlib> #include <vectormath.h> #include <fft.h> using namespace std; using namespace splab; typedef double Type; const int MINLEN = 1; const int MAXLEN = 1000; const int STEP = 10; int main() { Vector< complex<Type> > sn, Rk, Sk, xn; Vector<Type> rn, tn; cout << "forward transform: complex to complex." << endl; cout << "inverse transform: complex to complex." << endl << endl; cout << "signal length" << "\t" << "mean(abs((sn-xn))" << endl; for( int len=MINLEN; len<MAXLEN; len+=STEP ) { sn.resize(len); for( int i=0; i<len; ++i ) sn[i] = complex<Type>( rand()%10, rand()%10 ); Sk = fftc2c( sn ); xn = ifftc2c( Sk ); // Sk = fft( sn ); // xn = ifft( Sk ); cout << " " << len << "\t\t" << " " << sum(abs(sn-xn))/len << endl; } cout << endl << endl; cout << "forward transform: real to complex ." << endl; cout << "inverse transform: complex to real." << endl << endl; cout << "signal length" << "\t" << "mean(abs((rn-tn))" << endl; for( int len=MINLEN; len<MAXLEN; len+=STEP ) { rn.resize(len); for( int i=0; i<len; ++i ) rn[i] = rand()%10; Rk = fftr2c( rn ); tn = ifftc2r( Rk ); // Rk = fft( rn ); // tn = real( ifft(Rk) ); cout << " " << len << "\t\t" << " " << sum(abs(rn-tn))/len << endl; } cout << endl; return 0; }
运行结果:
forward transform: complex to complex. inverse transform: complex to complex. signal length mean(abs((sn-xn)) 1 0 11 2.53071e-016 21 2.04167e-015 31 3.23943e-015 41 2.72403e-015 51 3.16559e-015 61 2.59734e-015 71 8.2923e-015 81 6.68263e-015 91 8.43078e-015 101 1.00071e-014 111 6.01269e-015 121 3.93451e-015 131 1.85043e-014 141 8.70367e-015 151 1.23613e-014 161 6.08565e-015 171 9.52577e-015 181 4.67904e-015 191 1.26907e-014 201 7.17336e-015 211 2.48636e-014 221 1.16938e-014 231 1.68039e-014 241 1.37351e-014 251 2.15957e-014 261 1.34044e-014 271 1.57957e-014 281 5.82583e-014 291 6.69909e-015 301 3.8242e-014 311 7.39088e-014 321 2.20706e-014 331 2.58994e-014 341 2.24836e-014 351 1.86775e-014 361 2.74814e-014 371 9.27838e-015 381 1.14252e-014 391 1.0008e-014 401 5.94498e-014 411 1.53057e-014 421 5.47408e-014 431 7.25253e-014 441 7.87218e-015 451 2.92309e-014 461 5.81937e-014 471 4.23726e-014 481 4.51822e-014 491 1.10778e-013 501 3.52489e-014 511 4.42759e-014 521 1.18393e-013 531 5.78823e-014 541 1.26566e-013 551 3.69879e-014 561 5.15765e-014 571 3.83505e-014 581 3.7811e-014 591 3.06472e-014 601 1.39216e-013 611 2.93462e-014 621 4.50018e-014 631 1.35626e-013 641 1.4146e-013 651 1.36433e-014 661 1.35491e-013 671 2.22196e-014 681 7.82905e-014 691 1.41573e-013 701 1.63199e-013 711 2.18095e-014 721 3.11044e-014 731 4.84485e-014 741 6.47117e-014 751 6.65676e-014 761 1.50277e-013 771 3.72186e-014 781 4.02716e-014 791 3.55064e-014 801 8.17425e-014 811 1.82512e-014 821 1.78106e-013 831 1.43936e-014 841 8.8678e-014 851 8.81647e-014 861 6.26873e-015 871 2.98626e-014 881 1.08503e-013 891 2.44492e-014 901 8.29867e-014 911 1.29968e-013 921 5.25883e-014 931 6.62704e-014 941 4.87279e-014 951 5.11132e-014 961 1.33708e-013 971 1.78372e-013 981 8.49343e-014 991 4.66578e-014 forward transform: real to complex . inverse transform: complex to real. signal length mean(abs((rn-tn)) 1 0 11 1.41301e-016 21 1.11022e-015 31 1.96513e-015 41 1.3419e-015 51 2.13333e-015 61 1.88711e-015 71 5.01281e-015 81 4.06212e-015 91 4.96021e-015 101 6.08343e-015 111 3.27759e-015 121 2.21945e-015 131 1.2793e-014 141 4.77218e-015 151 8.30687e-015 161 3.41983e-015 171 5.91683e-015 181 3.50161e-015 191 8.77976e-015 201 4.62208e-015 211 1.66658e-014 221 7.22645e-015 231 1.01782e-014 241 9.79362e-015 251 1.55712e-014 261 7.40681e-015 271 1.01074e-014 281 3.81723e-014 291 3.8929e-015 301 2.22941e-014 311 4.76995e-014 321 1.36251e-014 331 1.78498e-014 341 1.3842e-014 351 1.16846e-014 361 1.50902e-014 371 4.81715e-015 381 7.45036e-015 391 5.79102e-015 401 3.68331e-014 411 8.45149e-015 421 3.5318e-014 431 4.64351e-014 441 4.5536e-015 451 1.82979e-014 461 4.11746e-014 471 2.67421e-014 481 2.76207e-014 491 7.49936e-014 501 2.24768e-014 511 2.8849e-014 521 7.29438e-014 531 3.92363e-014 541 8.14216e-014 551 2.2449e-014 561 3.26657e-014 571 2.44778e-014 581 2.23165e-014 591 1.95616e-014 601 8.50218e-014 611 1.81843e-014 621 2.89087e-014 631 8.84136e-014 641 9.02308e-014 651 8.84008e-015 661 8.58328e-014 671 1.31807e-014 681 4.8685e-014 691 8.97514e-014 701 1.07318e-013 711 1.35663e-014 721 1.82121e-014 731 2.86341e-014 741 4.07251e-014 751 4.35763e-014 761 9.37088e-014 771 2.29587e-014 781 2.29084e-014 791 1.99687e-014 801 5.27873e-014 811 1.21722e-014 821 1.06546e-013 831 9.23176e-015 841 5.27161e-014 851 5.19815e-014 861 3.93491e-015 871 1.86002e-014 881 7.19074e-014 891 1.38322e-014 901 4.85723e-014 911 8.17142e-014 921 3.32546e-014 931 3.87686e-014 941 3.16691e-014 951 2.93188e-014 961 8.21269e-014 971 1.16589e-013 981 5.44883e-014 991 2.98482e-014 Process returned 0 (0x0) execution time : 0.686 s Press any key to continue.