You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
// 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 <StormEigen/Core>
#include <unsupported/StormEigen/FFT>
using namespace std; using namespace StormEigen;
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) - .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) - .5, T( rand() )/T(RAND_MAX) - .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);
long double 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; }
|