2010-04-28 90 views
6

我在寫一個非常簡單的就地DFT。我使用這裏顯示的公式: http://en.wikipedia.org/wiki/Discrete_Fourier_transform#Definition以及歐拉公式,以避免爲此僅使用複數類。到目前爲止,我有這樣的:簡單的就地離散傅里葉變換(DFT)

private void fft(double[] data) 
     { 
      double[] real = new double[256]; 
      double[] imag = new double[256]; 
      double pi_div_128 = -1 * Math.PI/128; 
      for (int k = 0; k < 256; k++) 
      { 
       for (int n = 0; n < 256; n++) 
       { 
        real[k] += data[k] * Math.Cos(pi_div_128 * k * n); 
        imag[k] += data[k] * Math.Sin(pi_div_128 * k * n); 
       } 
       data[k] = Math.Sqrt(real[k] * real[k] + imag[k] * imag[k]); 
      } 
     } 

但Math.Cos和Math.Sin方面最終會積極和消極的,這樣我加入這些條款乘以數據[K],他們取消了,我只是得到一些猥瑣的小价值。我看到它是如何發生的,但我無法理解我的代碼可能是否代表數學。任何幫助表示讚賞。僅供參考,我不得不寫我自己的,我意識到我可以得到現成的FFT。

+3

這是一個dft,而不是fft。請用dft替換fft,由於最少的編輯字符,我無法做到這一點。 – 2012-10-04 19:30:15

回答

8

我相信您在本節

for (int n = 0; n < 256; n++) 
{ 
    real[k] += data[k] * Math.Cos(pi_div_128 * k * n); 
    imag[k] += data[k] * Math.Sin(pi_div_128 * k * n); 
} 

,就應該替換數據[K]數據[N]有一個錯誤

編輯:

你也破壞你的數據在線:

data[k] = Math.Sqrt(real[k] * real[k] + imag[k] * imag[k]); 

你有t o在其他地方或以後存儲複數的模數。如果模量是你想要的,並且你想將它存儲在數據中[],那麼在計算變換之後,你必須編碼另一個循環。爲了計算每個實數[k]和圖形[k],整個數據[]是必需的。

+0

修復後,它確實解決了真正的小值問題,但結果看起來不像是一個傅里葉變換。它只是一個DC偏移量,然後在0到4之間進行其餘的轉換。 – Adam 2010-04-28 02:37:24

+0

@Adam:我發現了一個問題並編輯了我的答案 – 2010-04-28 13:44:56

+0

+1 Maciel是對的。理解在一個點上的傅立葉變換(real [k] real [k],其中k通常爲'frecuency')不僅與一個點處的原始信號(數據[n])有關, '時間'),但所有的信號 - 和相同的反之亦然。 – leonbloy 2010-05-14 16:44:37

7
private double[] dft(double[] data) 
{ 
    int n = data.Length; 
    int m = n;// I use m = n/2d; 
    double[] real = new double[n]; 
    double[] imag = new double[n]; 
    double[] result = new double[m]; 
    double pi_div = 2.0 * Math.PI/n; 
    for (int w = 0; w < m; w++) 
    { 
     double a = w * pi_div; 
     for (int t = 0; t < n; t++) 
     { 
      real[w] += data[t] * Math.Cos(a * t); 
      imag[w] += data[t] * Math.Sin(a * t); 
     } 
     result[w] = Math.Sqrt(real[w] * real[w] + imag[w] * imag[w])/n; 
    } 
    return result; 
}