2011-09-28 17 views
26

Attualmente sto cercando di scrivere un algoritmo di trasformata di Fourier. Ho iniziato con un semplice algoritmo DFT come descritto nella definizione matematica:Trasformata di Fourier discreta

public class DFT { 
    public static Complex[] Transform(Complex[] input) { 
     int N = input.Length; 

     Complex[] output = new Complex[N]; 

     double arg = -2.0 * Math.PI/(double)N; 
     for (int n = 0; n < N; n++) { 
      output[n] = new Complex(); 
      for (int k = 0; k < N; k++) 
       output[n] += input[k] * Complex.Polar(1, arg * (double)n * (double)k); 
     } 
     return output; 
    } 
} 

Così ho provato questo algoritmo con il seguente codice:

private int samplingFrequency = 120; 
    private int numberValues = 240; 

    private void doCalc(object sender, EventArgs e) { 
     Complex[] input = new Complex[numberValues]; 
     Complex[] output = new Complex[numberValues]; 

     double t = 0; 
     double y = 0; 
     for (int i = 0; i < numberValues; i++) { 
      t = (double)i/(double)samplingFrequency; 
      y = Math.Sin(2 * Math.PI * t); 
      input[i] = new Complex(y, 0); 
     } 

     output = DFT.Transform(input); 

     printFunc(input); 
     printAbs(output); 
    } 

La trasformazione funziona bene, ma solo se numberValues ​​è un multiplo numero della frequenza di campionamento (in questo caso: 120, 240, 360, ...). Quello è il mio risultato per 240 valori:

http://s1.directupload.net/images/110928/n3m8hqg6.jpg

La trasformazione appena finito di lavorare bene.

Se sto cercando di calcolare i valori di 280 ottengo questo risultato:

http://s7.directupload.net/images/110928/qizoiqbt.jpg

perché sto ottenendo un risultato errato se cambio il numero dei miei valori calcolati? Non sono sicuro che il mio problema qui sia un problema con il mio codice o un fraintendimento della definizione matematica della DFT. In ogni caso, qualcuno può aiutarmi con il mio problema? Grazie.

+0

Puoi farmi sapere perché l'input per la tua funzione di trasformazione è un array complesso?Sicuramente se stai convertendo da un'onda sonora standard (dominio del tempo), sarebbe un singolo doppio array? –

+2

Ok, ho capito: la parte immaginaria è impostata su 0, quindi è essenzialmente uguale a se fosse solo un singolo doppio. Tra l'altro nel tuo codice, "Complex.Polar" dovrebbe essere "Complex.FromPolarCoordinates". –

+2

cosa usi per le trame? – GorillaApe

risposta

28

Quello che stai vivendo si chiama Spectral Leakage.

Ciò è causato dal fatto che la matematica sottostante della trasformata di Fourier assume una funzione continua da -infinità a + infinito. Quindi la gamma di campioni che fornisci viene effettivamente ripetuta un numero infinito di volte. Se non si dispone di un numero completo di cicli della forma d'onda nella finestra, le estremità non si allineeranno e si otterrà una discontinuità che si manifesta con la frequenza che spunta verso entrambi i lati.

Il modo normale di gestirlo è Windowing. Tuttavia, questo ha uno svantaggio in quanto fa sì che le ampiezze siano leggermente fuori. Questo è il processo di moltiplicazione dell'intera finestra di campioni che si elaborerà con una funzione che tende verso 0 su entrambe le estremità della finestra, causando l'allineamento delle estremità ma con una certa distorsione di ampiezza perché questo processo riduce la potenza totale del segnale.

Quindi per riepilogare non ci sono errori nel codice e il risultato è come previsto. Gli artefatti possono essere ridotti utilizzando una funzione finestra, tuttavia ciò influirà sulla precisione delle ampiezze. Dovrai indagare e determinare quale soluzione si adatta meglio alle esigenze del tuo progetto.

4

NON si ottiene il risultato errato per una sinusoide non periodica. E non sono solo "artefatti". Il risultato è in realtà il risultato DFT più completo che non si vede con una sinusoide periodica. Questi altri valori diversi da zero contengono informazioni utili che possono essere utilizzate, ad esempio, per interpolare la frequenza di una singola sinusoide non-periodica in apertura.

Una DFT può essere pensata come convoluzione di una finestra rettangolare con la vostra onda sinusoidale. Questo produce (qualcosa di molto vicino a) una funzione Sinc, che ha una estensione infinita, ma sembra essere pari a zero ad ogni frequenza DFT bin diversa dal suo DFT bin centrale per qualsiasi sinusoide centrata esattamente su un DFT bin. Ciò accade solo quando la frequenza è esattamente periodica nell'apertura FFT, non per nessun altro. La funzione Sinc ha molte "gobbe" che sono tutte nascoste nella tua prima trama.

Problemi correlati