Advertisement
Dantenerosas

FFT Chris Lomont

May 31st, 2016
56
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.19 KB | None | 0 0
  1. private const int A = 0;
  2.         private const int B = 1;
  3.         public void FFT(double[] data, bool forward)
  4.         {
  5.             var n = data.Length;                                          
  6.             if ((n & (n - 1)) != 0)
  7.                 throw new ArgumentException(
  8.                     "data length " + n + " in FFT is not a power of 2");
  9.             n /= 2;    // кол-во сэмплов                                                            
  10.            
  11.             Reverse(data, n); //перестановка элементов согласнно мод.БПФ                                                      
  12.            
  13.             // преобразование                                
  14.             double sign = forward ? B : -B;
  15.             var mmax = 1;
  16.             while (n > mmax)
  17.             {
  18.                 var istep = 2 * mmax;
  19.                 var theta = sign * Math.PI / mmax;
  20.                 double wr = 1, wi = 0;
  21.                 var wpr = Math.Cos(theta);
  22.                 var wpi = Math.Sin(theta);
  23.                 for (var m = 0; m < istep; m += 2)
  24.                 {
  25.                     for (var k = m; k < 2 * n; k += 2 * istep)
  26.                     {
  27.                         var j = k + istep;
  28.                         var tempr = wr * data[j] - wi * data[j + 1];
  29.                         var tempi = wi * data[j] + wr * data[j + 1];
  30.                         data[j] = data[k] - tempr;
  31.                         data[j + 1] = data[k + 1] - tempi;
  32.                         data[k] = data[k] + tempr;
  33.                         data[k + 1] = data[k + 1] + tempi;
  34.                     }
  35.                     var t = wr;                                                            
  36.                     wr = wr * wpr - wi * wpi;
  37.                     wi = wi * wpr + t * wpi;
  38.                 }
  39.                 mmax = istep;
  40.             }
  41.            
  42.             // маштабирование данных                                                                  
  43.             Scale(data, n, forward);
  44.         }
  45.  
  46.         void Scale(double[] data, int n, bool forward)
  47.         {
  48.             // при прямом                                                                        
  49.             if ((forward) && (A != 1))
  50.             {
  51.                 var scale = Math.Pow(n, (A - 1) / 2.0);
  52.                 for (var i = 0; i < data.Length; ++i)
  53.                     data[i] *= scale;
  54.             }
  55.             // при обратном                                                                        
  56.             if ((!forward) && (A != -1))
  57.             {
  58.                 var scale = Math.Pow(n, -(A + 1) / 2.0);
  59.                 for (var i = 0; i < data.Length; ++i)
  60.                     data[i] *= scale;
  61.             }
  62.         }
  63.  
  64.         static void Reverse(double[] data, int n)
  65.         {
  66.             // битовая перестановка индексов. Взята из 5 упр. в секции                                            
  67.             // 7.2.1.1 в ИП Кнута                            
  68.             int j = 0, k = 0; // Кнут R1: инициализация                                                            
  69.             var top = n / 2;  // это 2^(n-1) Кнута
  70.             // цикл перестановки битов
  71.             while (true)
  72.             {
  73.                 // Кнут R2: swap - swap j+1 и k+2^(n-1), по 2 записи каждая                                      
  74.                 var t = data[j + 2];
  75.                 data[j + 2] = data[k + n];
  76.                 data[k + n] = t;
  77.                 t = data[j + 3];
  78.                 data[j + 3] = data[k + n + 1];
  79.                 data[k + n + 1] = t;
  80.                 if (j > k)
  81.                 { // поменять местами еще две                                                                              
  82.                     // j и k                                                                                  
  83.                     t = data[j];
  84.                     data[j] = data[k];
  85.                     data[k] = t;
  86.                     t = data[j + 1];
  87.                     data[j + 1] = data[k + 1];
  88.                     data[k + 1] = t;
  89.                     // j + top + 1 иk+top + 1                                                                
  90.                     t = data[j + n + 2];
  91.                     data[j + n + 2] = data[k + n + 2];
  92.                     data[k + n + 2] = t;
  93.                     t = data[j + n + 3];
  94.                     data[j + n + 3] = data[k + n + 3];
  95.                     data[k + n + 3] = t;
  96.                 }
  97.                 // Кнут R3: увеличить k                                                                          
  98.                 k += 4;
  99.                 if (k >= n)
  100.                     break;
  101.                 // Кнут R4: увеличить j                                                                          
  102.                 var h = top;
  103.                 while (j >= h)
  104.                 {
  105.                     j -= h;
  106.                     h /= 2;
  107.                 }
  108.                 j += h;
  109.             }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement