1*bf2c3715SXin Li // To use the simple FFT implementation 2*bf2c3715SXin Li // g++ -o demofft -I.. -Wall -O3 FFT.cpp 3*bf2c3715SXin Li 4*bf2c3715SXin Li // To use the FFTW implementation 5*bf2c3715SXin Li // g++ -o demofft -I.. -DUSE_FFTW -Wall -O3 FFT.cpp -lfftw3 -lfftw3f -lfftw3l 6*bf2c3715SXin Li 7*bf2c3715SXin Li #ifdef USE_FFTW 8*bf2c3715SXin Li #include <fftw3.h> 9*bf2c3715SXin Li #endif 10*bf2c3715SXin Li 11*bf2c3715SXin Li #include <vector> 12*bf2c3715SXin Li #include <complex> 13*bf2c3715SXin Li #include <algorithm> 14*bf2c3715SXin Li #include <iterator> 15*bf2c3715SXin Li #include <iostream> 16*bf2c3715SXin Li #include <Eigen/Core> 17*bf2c3715SXin Li #include <unsupported/Eigen/FFT> 18*bf2c3715SXin Li 19*bf2c3715SXin Li using namespace std; 20*bf2c3715SXin Li using namespace Eigen; 21*bf2c3715SXin Li 22*bf2c3715SXin Li template <typename T> mag2(T a)23*bf2c3715SXin LiT mag2(T a) 24*bf2c3715SXin Li { 25*bf2c3715SXin Li return a*a; 26*bf2c3715SXin Li } 27*bf2c3715SXin Li template <typename T> mag2(std::complex<T> a)28*bf2c3715SXin LiT mag2(std::complex<T> a) 29*bf2c3715SXin Li { 30*bf2c3715SXin Li return norm(a); 31*bf2c3715SXin Li } 32*bf2c3715SXin Li 33*bf2c3715SXin Li template <typename T> mag2(const std::vector<T> & vec)34*bf2c3715SXin LiT mag2(const std::vector<T> & vec) 35*bf2c3715SXin Li { 36*bf2c3715SXin Li T out=0; 37*bf2c3715SXin Li for (size_t k=0;k<vec.size();++k) 38*bf2c3715SXin Li out += mag2(vec[k]); 39*bf2c3715SXin Li return out; 40*bf2c3715SXin Li } 41*bf2c3715SXin Li 42*bf2c3715SXin Li template <typename T> mag2(const std::vector<std::complex<T>> & vec)43*bf2c3715SXin LiT mag2(const std::vector<std::complex<T> > & vec) 44*bf2c3715SXin Li { 45*bf2c3715SXin Li T out=0; 46*bf2c3715SXin Li for (size_t k=0;k<vec.size();++k) 47*bf2c3715SXin Li out += mag2(vec[k]); 48*bf2c3715SXin Li return out; 49*bf2c3715SXin Li } 50*bf2c3715SXin Li 51*bf2c3715SXin Li template <typename T> operator -(const vector<T> & a,const vector<T> & b)52*bf2c3715SXin Livector<T> operator-(const vector<T> & a,const vector<T> & b ) 53*bf2c3715SXin Li { 54*bf2c3715SXin Li vector<T> c(a); 55*bf2c3715SXin Li for (size_t k=0;k<b.size();++k) 56*bf2c3715SXin Li c[k] -= b[k]; 57*bf2c3715SXin Li return c; 58*bf2c3715SXin Li } 59*bf2c3715SXin Li 60*bf2c3715SXin Li template <typename T> RandomFill(std::vector<T> & vec)61*bf2c3715SXin Livoid RandomFill(std::vector<T> & vec) 62*bf2c3715SXin Li { 63*bf2c3715SXin Li for (size_t k=0;k<vec.size();++k) 64*bf2c3715SXin Li vec[k] = T( rand() )/T(RAND_MAX) - T(.5); 65*bf2c3715SXin Li } 66*bf2c3715SXin Li 67*bf2c3715SXin Li template <typename T> RandomFill(std::vector<std::complex<T>> & vec)68*bf2c3715SXin Livoid RandomFill(std::vector<std::complex<T> > & vec) 69*bf2c3715SXin Li { 70*bf2c3715SXin Li for (size_t k=0;k<vec.size();++k) 71*bf2c3715SXin Li vec[k] = std::complex<T> ( T( rand() )/T(RAND_MAX) - T(.5), T( rand() )/T(RAND_MAX) - T(.5)); 72*bf2c3715SXin Li } 73*bf2c3715SXin Li 74*bf2c3715SXin Li template <typename T_time,typename T_freq> fwd_inv(size_t nfft)75*bf2c3715SXin Livoid fwd_inv(size_t nfft) 76*bf2c3715SXin Li { 77*bf2c3715SXin Li typedef typename NumTraits<T_freq>::Real Scalar; 78*bf2c3715SXin Li vector<T_time> timebuf(nfft); 79*bf2c3715SXin Li RandomFill(timebuf); 80*bf2c3715SXin Li 81*bf2c3715SXin Li vector<T_freq> freqbuf; 82*bf2c3715SXin Li static FFT<Scalar> fft; 83*bf2c3715SXin Li fft.fwd(freqbuf,timebuf); 84*bf2c3715SXin Li 85*bf2c3715SXin Li vector<T_time> timebuf2; 86*bf2c3715SXin Li fft.inv(timebuf2,freqbuf); 87*bf2c3715SXin Li 88*bf2c3715SXin Li T_time rmse = mag2(timebuf - timebuf2) / mag2(timebuf); 89*bf2c3715SXin Li cout << "roundtrip rmse: " << rmse << endl; 90*bf2c3715SXin Li } 91*bf2c3715SXin Li 92*bf2c3715SXin Li template <typename T_scalar> two_demos(int nfft)93*bf2c3715SXin Livoid two_demos(int nfft) 94*bf2c3715SXin Li { 95*bf2c3715SXin Li cout << " scalar "; 96*bf2c3715SXin Li fwd_inv<T_scalar,std::complex<T_scalar> >(nfft); 97*bf2c3715SXin Li cout << " complex "; 98*bf2c3715SXin Li fwd_inv<std::complex<T_scalar>,std::complex<T_scalar> >(nfft); 99*bf2c3715SXin Li } 100*bf2c3715SXin Li demo_all_types(int nfft)101*bf2c3715SXin Livoid demo_all_types(int nfft) 102*bf2c3715SXin Li { 103*bf2c3715SXin Li cout << "nfft=" << nfft << endl; 104*bf2c3715SXin Li cout << " float" << endl; 105*bf2c3715SXin Li two_demos<float>(nfft); 106*bf2c3715SXin Li cout << " double" << endl; 107*bf2c3715SXin Li two_demos<double>(nfft); 108*bf2c3715SXin Li cout << " long double" << endl; 109*bf2c3715SXin Li two_demos<long double>(nfft); 110*bf2c3715SXin Li } 111*bf2c3715SXin Li main()112*bf2c3715SXin Liint main() 113*bf2c3715SXin Li { 114*bf2c3715SXin Li demo_all_types( 2*3*4*5*7 ); 115*bf2c3715SXin Li demo_all_types( 2*9*16*25 ); 116*bf2c3715SXin Li demo_all_types( 1024 ); 117*bf2c3715SXin Li return 0; 118*bf2c3715SXin Li } 119