2010-04-28 12 views
6

Piszę bardzo prosty lokalny DFT. Używam tutaj formuły: http://en.wikipedia.org/wiki/Discrete_Fourier_transform#Definition wraz z formułą Eulera, aby uniknąć konieczności stosowania złożonej klasy liczb właśnie w tym celu. Do tej pory mam to:Prosta lokalna dyskretna transformata Fouriera (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]); 
      } 
     } 

Ale Math.cos i Math.sin terminy ostatecznie przejść zarówno pozytywne jak i negatywne, tak jak ja dodając te warunki mnożona danych [K], oni znoszą się i ja po prostu uzyskaj nieprzyzwoicie małą wartość. Rozumiem, jak to się dzieje, ale nie mogę zrozumieć, w jaki sposób mój kod może źle odzwierciedlać matematykę. Każda pomoc jest doceniana. FYI, muszę napisać własną, zdaję sobie sprawę, że mogę wyjść z półki FFT.

+3

To jest dft, nie fft. Proszę, zamień fft na dft, nie mogę tego zrobić ze względu na min edycję znaków. –

Odpowiedz

8

wierzę masz błąd w tej sekcji

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); 
} 

należy wymienić dane [K] z danymi [n]

EDIT:

Jesteś również niszcząc swoje dane w linii:

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

Masz t o przechowywać moduły swoich liczb zespolonych gdzie indziej lub później. Jeśli moduł jest wszystkim, czego potrzebujesz, i chcesz go zapisać w danych [] Musisz zakodować kolejną pętlę po obliczeniu transformacji., Całe dane [] są niezbędne do obliczenia wszystkich rzeczywistych [k] i imag [k].

+0

Po naprawieniu tego problemu naprawiono problem z naprawdę małą wartością, ale wynik nie przypomina transformacji Fouriera. To tylko przesunięcie DC, a następnie wartości od 0 do 4 dla pozostałej części transformacji. – Adam

+0

@Adam: Znalazłem jeszcze jeden problem i zredagowałem swoją odpowiedź –

+0

+1 Maciel ma rację. Konceptualnie ważne jest zrozumienie, że transformacja Fouriera w jednym punkcie (rzeczywiste [k] prawdziwe [k], z k typowo "frecuency") nie odnosi się tylko do oryginalnego sygnału w jednym punkcie (dane [n] z n typowo "czas"), ale z całym sygnałem - i tym samym viceversa. – leonbloy

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; 
}