2010-12-12 31 views
5

Próbuję wykonać niektóre filtrowanie z FFT. Używam r2r_1d plan i nie mam pojęcia jak to zrobić odwrotność przekształcić ...Jak wykonać odwrotną rzeczywistą do rzeczywistej FFT w bibliotece FFTW

void PerformFiltering(double* data, int n) 
    { 
        /* FFT */ 
     double* spectrum = new double[n]; 

     fftw_plan plan; 

     plan = fftw_plan_r2r_1d(n, data, spectrum, FFTW_REDFT00, FFTW_ESTIMATE); 

     fftw_execute(plan); // signal to spectrum 
     fftw_destroy_plan(plan); 


        /* some filtering here */ 


        /* Inverse FFT */ 
     plan = fftw_plan_r2r_1d(n, spectrum, data, FFTW_REDFT00, FFTW_ESTIMATE); 
     fftw_execute(plan); // spectrum to signal (inverse FFT) 
     fftw_destroy_plan(plan); 

} 

robię wszystkie rzeczy, prawda? Jestem zdezorientowany, ponieważ w złożonych DFT FFTW można ustawić kierunek transformacji przez flagę w ten sposób:
p = fftw_plan_dft_1d (N, in, out, FFTW_FORWARD, FFTW_ESTIMATE);
lub
p = fftw_plan_dft_1d (N, in, out, FFTW_BACKWARD, FFTW_ESTIMATE);

Odpowiedz

1

Zrobiłeś to poprawnie. FFTW_REDFT00 oznacza transformację kosinusową, która jest własną odwrotnością. Nie ma więc potrzeby rozróżniania "do przodu" i "do tyłu". Należy jednak uważać na rozmiar tablicy. Jeśli chcesz wykryć częstotliwość 10, a dane zawierają 100 znaczących punktów, to tablica data powinna zawierać punkty danych i ustawić n = 101 zamiast 100. Normalizacja powinna być 2*(n-1). Zobacz poniższy przykład, skompiluj z gcc a.c -lfftw3.

#include <stdio.h> 
#include <math.h> 
#include <fftw3.h> 
#define n 101 /* note the 1 */ 
int main(void) { 
    double in[n], in2[n], out[n]; 
    fftw_plan p, q; 
    int i; 
    p = fftw_plan_r2r_1d(n, in, out, FFTW_REDFT00, FFTW_ESTIMATE); 
    for (i = 0; i < n; i++) in[i] = cos(2*M_PI*10*i/(n - 1)); /* n - 1 instead of n */ 
    fftw_execute(p); 
    q = fftw_plan_r2r_1d(n, out, in2, FFTW_REDFT00, FFTW_ESTIMATE); 
    fftw_execute(q); 
    for (i = 0; i < n; i++) 
    printf("%3d %9.5f %9.5f\n", i, in[i], in2[i]/(2*(n - 1))); /* n - 1 instead of n */ 
    fftw_destroy_plan(p); fftw_destroy_plan(q); fftw_cleanup(); 
    return 0; 
}