123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- // To use the simple FFT implementation
- // g++ -o demofft -I.. -Wall -O3 FFT.cpp
- // To use the FFTW implementation
- // g++ -o demofft -I.. -DUSE_FFTW -Wall -O3 FFT.cpp -lfftw3 -lfftw3f -lfftw3l
- #ifdef USE_FFTW
- #include <fftw3.h>
- #endif
- #include <vector>
- #include <complex>
- #include <algorithm>
- #include <iterator>
- #include <iostream>
- #include <Eigen/Core>
- #include <unsupported/Eigen/FFT>
- using namespace std;
- using namespace Eigen;
- template <typename T>
- T mag2(T a)
- {
- return a*a;
- }
- template <typename T>
- T mag2(std::complex<T> a)
- {
- return norm(a);
- }
- template <typename T>
- T mag2(const std::vector<T> & vec)
- {
- T out=0;
- for (size_t k=0;k<vec.size();++k)
- out += mag2(vec[k]);
- return out;
- }
- template <typename T>
- T mag2(const std::vector<std::complex<T> > & vec)
- {
- T out=0;
- for (size_t k=0;k<vec.size();++k)
- out += mag2(vec[k]);
- return out;
- }
- template <typename T>
- vector<T> operator-(const vector<T> & a,const vector<T> & b )
- {
- vector<T> c(a);
- for (size_t k=0;k<b.size();++k)
- c[k] -= b[k];
- return c;
- }
- template <typename T>
- void RandomFill(std::vector<T> & vec)
- {
- for (size_t k=0;k<vec.size();++k)
- vec[k] = T( rand() )/T(RAND_MAX) - T(.5);
- }
- template <typename T>
- void RandomFill(std::vector<std::complex<T> > & vec)
- {
- for (size_t k=0;k<vec.size();++k)
- vec[k] = std::complex<T> ( T( rand() )/T(RAND_MAX) - T(.5), T( rand() )/T(RAND_MAX) - T(.5));
- }
- template <typename T_time,typename T_freq>
- void fwd_inv(size_t nfft)
- {
- typedef typename NumTraits<T_freq>::Real Scalar;
- vector<T_time> timebuf(nfft);
- RandomFill(timebuf);
- vector<T_freq> freqbuf;
- static FFT<Scalar> fft;
- fft.fwd(freqbuf,timebuf);
- vector<T_time> timebuf2;
- fft.inv(timebuf2,freqbuf);
- T_time rmse = mag2(timebuf - timebuf2) / mag2(timebuf);
- cout << "roundtrip rmse: " << rmse << endl;
- }
- template <typename T_scalar>
- void two_demos(int nfft)
- {
- cout << " scalar ";
- fwd_inv<T_scalar,std::complex<T_scalar> >(nfft);
- cout << " complex ";
- fwd_inv<std::complex<T_scalar>,std::complex<T_scalar> >(nfft);
- }
- void demo_all_types(int nfft)
- {
- cout << "nfft=" << nfft << endl;
- cout << " float" << endl;
- two_demos<float>(nfft);
- cout << " double" << endl;
- two_demos<double>(nfft);
- cout << " long double" << endl;
- two_demos<long double>(nfft);
- }
- int main()
- {
- demo_all_types( 2*3*4*5*7 );
- demo_all_types( 2*9*16*25 );
- demo_all_types( 1024 );
- return 0;
- }
|