вычисление FFT и IFFT с FFTW.H в C - PullRequest
5 голосов
/ 28 апреля 2011

Привет всем! Я использую библиотеки fftw C для вычисления частотного спектра для некоторых приложений обработки сигналов во встроенных системах.Однако в моем проекте я столкнулся с небольшим препятствием.

Ниже приведена простая программа, которую я написал, чтобы убедиться, что я правильно выполняю функции fftw.В основном я хочу вычислить БПФ последовательности из 12 чисел, затем сделать ifft и получить ту же последовательность чисел снова.Если у вас установлены fftw3 и gcc, эта программа должна работать, если вы компилируете:

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

В настоящее время длина моего fft равна размеру входного массива.

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

, который производитследующий вывод:

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

Итак, очевидно, что ifft дает некоторый увеличенный результат.В документации fftw, найденной здесь: документы fftw о масштабировании .В нем упоминается о некотором масштабировании, однако я использую преобразования «r2c» и «c2r», а не FFT_FORWARD и FFT_BACKWARD.Любое понимание будет оценено.

Ответы [ 3 ]

5 голосов
/ 28 апреля 2011

Глядя на отличную документацию по функциям, которые вы используете , вы увидите, что использует FFT_FORWARD и FFT_BACKWARD, и именно там, где они предназначены. Следовательно, ранее найденная информация о масштабировании также применима и здесь.

2 голосов
/ 05 мая 2011

Извините за педантизм, но ваш размер для out_cpx неверен. вместо длинного размера он должен быть размером / 2 + 1. Это потому, что БПФ реального сигнала эрмитово. Вы можете проверить, что я говорю, инициализируя out_cpx некоторым случайным числом (все 3.14159). Запустите вперед и назад, а затем распечатайте out_cpx из размера / 2 + 1 в размер. Он не изменился.

http://www.fftw.org/fftw3_doc/Real_002ddata-DFT-Array-Format.html#Real_002ddata-DFT-Array-Format

1 голос
/ 26 февраля 2014

r2c и c2r делают по существу то же самое, что и обычное преобразование Фурье. Единственное отличие состоит в том, что как входной, так и выходной массив должны содержать половину чисел. Пожалуйста, взгляните на последний параграф руководства FFTW r2c и c2r . Таким образом, коэффициент нормализации - это точно число элементов реального массива или переменная size (== 12) в вашем случае.

...