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

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