2010-04-28 15 views
6

Sto scrivendo un DFT sul posto molto semplice. Sto usando la formula mostrata qui: http://en.wikipedia.org/wiki/Discrete_Fourier_transform#Definition insieme alla formula di Eulero per evitare di dover usare una classe di numeri complessi solo per questo. Finora ho questo:Semplice trasformatore discreto di Fourier (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]); 
      } 
     } 

Ma i termini Math.cos e Math.sin finalmente andare sia positivi che negativi, così come sto aggiungendo questi termini moltiplicati con i dati [k], si annullano e io solo ottenere un valore oscenamente piccolo. Vedo come sta accadendo, ma non riesco a dare un senso a come il mio codice stia forse rappresentando male la matematica. Qualsiasi aiuto è apprezzato. Cordiali saluti, devo scrivere il mio, mi rendo conto che posso ottenere dal FFT di scaffale.

+3

È un dft, non fft. Per favore, sostituisci fft con dft, non posso farlo a causa di un minimo di caratteri di modifica. –

risposta

8

Credo che tu abbia un errore in questa sezione

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

Si dovrebbe sostituire i dati [k] con i dati [n]

EDIT:

Siete anche distruggere i vostri dati nella riga:

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

Hai t o memorizza i moduli dei tuoi numeri complessi da qualche altra parte o più tardi. Se il modulo è tutto ciò che si desidera e si desidera archiviarlo nei dati [] È necessario codificare un altro ciclo dopo aver calcolato la trasformazione., L'intero dato [] è necessario per calcolare ogni reale [k] e imag [k].

+0

Dopo aver corretto ciò, risolve il problema del valore veramente piccolo, ma il risultato non assomiglia a una trasformata di Fourier. È solo un offset DC e quindi valori compresi tra 0 e 4 per il resto della trasformazione. – Adam

+0

@Adam: ho trovato un altro problema e ho modificato la mia risposta –

+0

+1 Maciel ha ragione. È concettualmente importante capire che la trasformata di Fourier in un punto (reale [k] reale [k], con k tipicamente una "frequenza") non si riferisce solo al segnale originale in un punto (dati [n] con n typpicaly a 'tempo') ma con tutto il segnale - e lo stesso 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; 
} 
Problemi correlati