Advertisement
Guest User

Fast Fourier Transform

a guest
May 5th, 2011
5,638
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.10 KB | None | 0 0
  1. #include <algorithm>
  2. #include <cstdio>
  3. #include <ctime>
  4. #include <vector>
  5. #include <complex>
  6.  
  7. using namespace std;
  8.  
  9. typedef complex<double> cd;
  10. typedef vector<cd> vcd;
  11.  
  12. vcd fft(const vcd &as) {
  13.   int n = as.size();
  14.   int k = 0; // Длина n в битах
  15.   while ((1 << k) < n) k++;
  16.   vector<int> rev(n);
  17.   rev[0] = 0;
  18.   int high1 = -1;
  19.   for (int i = 1; i < n; i++) {
  20.     if ((i & (i - 1)) == 0) // Проверка на степень двойки. Если i ей является, то i-1 будет состоять из кучи единиц.
  21.       high1++;
  22.     rev[i] = rev[i ^ (1 << high1)]; // Переворачиваем остаток
  23.     rev[i] |= (1 << (k - high1 - 1)); // Добавляем старший бит
  24.   }
  25.  
  26.   vcd roots(n);
  27.   for (int i = 0; i < n; i++) {
  28.     double alpha = 2 * M_PI * i / n;
  29.     roots[i] = cd(cos(alpha), sin(alpha));
  30.   }
  31.  
  32.   vcd cur(n);
  33.   for (int i = 0; i < n; i++)
  34.     cur[i] = as[rev[i]];
  35.  
  36.   for (int len = 1; len < n; len <<= 1) {
  37.     vcd ncur(n);
  38.     int rstep = roots.size() / (len * 2);
  39.     for (int pdest = 0; pdest < n;) {
  40.       int p1 = pdest;
  41.       for (int i = 0; i < len; i++) {
  42.         cd val = roots[i * rstep] * cur[p1 + len];
  43.         ncur[pdest] = cur[p1] + val;
  44.         ncur[pdest + len] = cur[p1] - val;
  45.         pdest++, p1++;
  46.       }
  47.       pdest += len;
  48.     }
  49.     cur.swap(ncur);
  50.   }
  51.   return cur;
  52. }
  53.  
  54. vcd fft_rev(const vcd &as) {
  55.   vcd res = fft(as);
  56.   for (int i = 0; i < (int)res.size(); i++) res[i] /= as.size();
  57.   reverse(res.begin() + 1, res.end());
  58.   return res;
  59. }
  60.  
  61. int main() {
  62.   int n;
  63.   scanf("%d", &n);
  64.   vcd as(n);
  65.   for (int i = 0; i < n; i++) {
  66.     int x;
  67.     scanf("%d", &x);
  68.     as[i] = x;
  69.   }
  70.  
  71.   clock_t stime = clock();
  72.   vcd res = fft(as);
  73.   fprintf(stderr, "%d\n", (int)(clock() - stime));
  74.   for (int i = 0; i < n; i++)
  75.     printf("%.4lf %.4lf\n", res[i].real(), res[i].imag());
  76.  
  77.   stime = clock();
  78.   vcd as2 = fft_rev(res);
  79.   fprintf(stderr, "%d\n", (int)(clock() - stime));
  80.   for (int i = 0; i < n; i++)
  81.     printf("%.4lf %.4lf\n", as2[i].real(), as2[i].imag());
  82.   return 0;
  83. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement