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.
		
		
		
		
		
			
		
			
				
					
					
						
							118 lines
						
					
					
						
							2.5 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							118 lines
						
					
					
						
							2.5 KiB
						
					
					
				| //  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) - .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; | |
| }
 |