8

FFTとkissfftライブラリを使用して高速相関を計算しようとしていますが、スケーリングは正確である必要があります。どのようなスケーリングが必要ですか(順方向と逆方向)、データをスケーリングするためにどのような値を使用しますか?

4

2 に答える 2

11

最も一般的な3つのFFTスケーリング係数は次のとおりです。

  • 1.0フォワードFFT、1.0/NインバースFFT

  • 1.0 / N順方向FFT、1.0逆方向FFT

  • 両方向に1.0/sqrt(N)、FFTとIFFT

ドキュメントにあいまいさがある可能性がある場合、およびユーザーが目的に応じて「正しい」と期待するスケーリングの場合は、既知の(1.0フロートまたは255整数)振幅の純粋な正弦波をFFT長で正確に周期的に供給するのが最適です。問題のFFT(および/またはIFFT)で、スケーリングが上記のいずれかに一致するかどうかを確認します。おそらく、上記のいずれかと2Xまたはsqrt(2)異なるか、目的のスケーリングが完全に異なります。

たとえば、データ型の環境でkissfftの単体テストを記述します。

于 2011-04-12T00:32:25.063 に答える
6

各周波数応答に1/sqrt(N)を掛けて、全体的なスケーリングを1/Nにします。

擬似コードの場合:

ifft( fft(x)*conj( fft(y) )/N ) == circular_correlation(x,y)

少なくとも、これは浮動小数点型のkisfftには当てはまります。

次のc++サンプルコードの出力は次のようになります。

[1、3i、0 0 ....]とそれ自体の循環相関=(10,0)、(1.19796e-10,3)、(-4.91499e-08,1.11519e-15)、(1.77301e -08、-1.19588e-08)..。

#include <complex>
#include <iostream>
#include "kiss_fft.h"
using namespace std;

int main()
{
    const int nfft=256;
    kiss_fft_cfg fwd = kiss_fft_alloc(nfft,0,NULL,NULL);
    kiss_fft_cfg inv = kiss_fft_alloc(nfft,1,NULL,NULL);

    std::complex<float> x[nfft];
    std::complex<float> fx[nfft];
    memset(x,0,sizeof(x));
    x[0] = 1;
    x[1] = std::complex<float>(0,3);

    kiss_fft(fwd,(kiss_fft_cpx*)x,(kiss_fft_cpx*)fx);
    for (int k=0;k<nfft;++k) {
        fx[k] = fx[k] * conj(fx[k]);
        fx[k] *= 1./nfft;
    }
    kiss_fft(inv,(kiss_fft_cpx*)fx,(kiss_fft_cpx*)x);
    cout << "the circular correlation of [1, 3i, 0 0 ....] with itself = ";
    cout
        << x[0] << ","
        << x[1] << ","
        << x[2] << ","
        << x[3] << " ... " << endl;
    kiss_fft_free(fwd);
    kiss_fft_free(inv);
    return 0;
}
于 2011-04-12T02:57:55.707 に答える