5

こんにちはすべて私は組み込みシステム上のいくつかの信号処理アプリケーションの周波数スペクトルを計算するためにfftwCライブラリを使用しています。しかし、私のプロジェクトでは、私はわずかな障害に遭遇しました。

以下は、fftw関数を正しく実装していることを確認するために作成した簡単なプログラムです。基本的に、12個の数列のfftを計算してから、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ドキュメント。いくつかのスケーリングについて言及していますが、私はFFT_FORWARDとFFT_BACKWARDではなく「r2c」と「c2r」変換を使用しています。任意の洞察をいただければ幸いです。

4

3 に答える 3

5

使用する関数の優れたドキュメントを見ると、FFT_FORWARDとFFT_BACKWARDを使用していることがわかり、正確に意図された場所にあります。したがって、以前に見つけたスケーリング情報はここにも適用されます。

于 2011-04-28T12:38:29.377 に答える
2

衒学者として申し訳ありませんが、out_cpxのサイズが正しくありません。サイズを長くする代わりに、サイズ/ 2 +1にする必要があります。これは、実際の信号のFFTがエルミートであるためです。out_cpxをいくつかの乱数(すべて3.14159)に初期化することで、私が言っていることを確認できます。順方向と逆方向の両方を実行してから、out_cpxをsize / 2+1からsizeに出力します。変更はありません。

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

于 2011-05-05T04:17:25.497 に答える
1

r2cとc2rは、基本的に通常のフーリエ変換と同じです。唯一の違いは、入力配列と出力配列の両方が数値の半分を保持する必要があることです。FFTWr2cとc2rのマニュアルの最後の段落を見てください。したがって、正規化係数は、正確には実配列の要素の数、またはsizeあなたの場合は変数(== 12)です。

于 2014-02-25T20:51:05.070 に答える