Pregunta

Hola, todo estoy usando las bibliotecas FFTW C para calcular el espectro de frecuencia para algunas aplicaciones de procesamiento de señales en sistemas integrados. Sin embargo, en mi proyecto me he encontrado con un ligero obstáculo.

A continuación se muestra un programa simple que escribí para asegurarme de que estoy implementando las funciones FFTW correctamente. Básicamente, quiero calcular la FFT de una secuencia de 12 números, luego hacer el IFFT y obtener la misma secuencia de números nuevamente. Si tiene FFTW3 y GCC instalado, este programa debería funcionar si se compila con:

gcc -g -lfftw3 -lm fftw_test.c -o fftw_test

Actualmente, mi longitud FFT es del mismo tamaño que la matriz de entrada.

#include <stdio.h>
#include <stdlib.h>
#include <sndfile.h>
#include <stdint.h>
#include <math.h>
#include <fftw3.h>

int main(void)
{
double array[] = {0.1, 0.6, 0.1, 0.4, 0.5, 0, 0.8, 0.7, 0.8, 0.6, 0.1,0};
//double array2[] = {1, 6, 1, 4, 5, 0, 8, 7, 8, 6, 1,0};
double *out;
double *err;
int i,size = 12;

fftw_complex *out_cpx;

fftw_plan fft;
fftw_plan ifft;
out_cpx = (fftw_complex*) fftw_malloc(sizeof(fftw_complex)*size);
out = (double *) malloc(size*sizeof(double));
err = (double *) malloc(size*sizeof(double));

fft = fftw_plan_dft_r2c_1d(size, array, out_cpx, FFTW_ESTIMATE);  //Setup fftw plan for fft
ifft = fftw_plan_dft_c2r_1d(size, out_cpx, out, FFTW_ESTIMATE);   //Setup fftw plan for ifft

fftw_execute(fft);
fftw_execute(ifft);

//printf("Input:    \tOutput:    \tError:\n");
printf("Input:    \tOutput:\n");
for(i=0;i<size;i++)
{
err[i] = abs(array[i] - out[i]);    
printf("%f\t%f\n",(array[i]),out[i]);
//printf("%f\t%f\t%f\n",(array[i]),out[i],err[i]);
}

fftw_destroy_plan(fft);
fftw_destroy_plan(ifft);
fftw_free(out_cpx);
free(err);
free(out);
return 0;
}

Que produce la siguiente salida:

Input:      Output:
0.100000    1.200000
0.600000    7.200000
0.100000    1.200000
0.400000    4.800000
0.500000    6.000000
0.000000    0.000000
0.800000    9.600000
0.700000    8.400000
0.800000    9.600000
0.600000    7.200000
0.100000    1.200000
0.000000    0.000000

Obviamente, el IFFT está produciendo algún resultado escalado. En los documentos FFTW encontrados aquí:FFTW documentos sobre el escala. Menciona sobre algo de escala, sin embargo, estoy usando las transformaciones "R2C" y "C2R" en lugar de FFT_FORWARD y FFT_Backward. Cualquier idea sería apreciada.

¿Fue útil?

Solución

Mirando a la gran documentación para las funciones que usa, te verás son Usando fft_forward y fft_backward, y exactamente donde está previsto. Por lo tanto, la información de escala que encontró anteriormente también se aplica aquí.

Otros consejos

Lamento ser pedante, pero su tamaño para OUT_CPX es incorrecto. En lugar de ser de tamaño largo, debe ser de tamaño/2 + 1. Esto se debe a que FFT de una señal real es hermitante. Puede verificar lo que digo inicializando OUT_CPX en algún número aleatorio (todos 3.14159). Ejecute tanto hacia adelante como hacia atrás y luego imprima OUT_CPX desde el tamaño/2 + 1 al tamaño. No habrá cambiado.

http://www.fftw.org/fftw3_doc/real_002ddata-dft-array-format.html#real_002data-dft-array-format

R2C y C2R hacen esencialmente lo mismo que la transformación regular de Fourier. La única diferencia es que tanto la matriz de entrada como de salida debe contener la mitad de los números. Por favor, eche un vistazo al último párrafo del manual de FFTW R2C y C2R. Entonces, el factor de normalización es precisamente el número de elementos de la matriz real o la variable size (== 12) En su caso.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top