kissfft scaling

删除回忆录丶 提交于 2019-11-29 03:12:36

问题


I am looking to compute a fast correlation using FFTs and the kissfft library, and scaling needs to be precise. What scaling is necessary (forward and backwards) and what value do I use to scale my data?


回答1:


The 3 most common FFT scaling factors are:

  • 1.0 forward FFT, 1.0/N inverse FFT

  • 1.0/N forward FFT, 1.0 inverse FFT

  • 1.0/sqrt(N) in both directions, FFT & IFFT

Given any possible ambiguity in the documentation, and for whatever scaling the user expects to be "correct" for their purposes, best to just feed a pure sine wave of known (1.0 float or 255 integer) amplitude and exactly periodic in the FFT length to the FFT (and/or IFFT) in question, and see if the scaling matches one of the above, is maybe different from one of the above by 2X or sqrt(2), or the desired scaling is something completely different.

e.g. Write a unit test for kissfft in your environment for your data types.




回答2:


multiply each frequency response by 1/sqrt(N), for an overall scaling of 1/N

In pseudocode:

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

At least this is true for kisfft with floating point types.

The output of the following c++ example code should be something like

the circular correlation of [1, 3i, 0 0 ....] with itself = (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;
}


来源:https://stackoverflow.com/questions/5628056/kissfft-scaling

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!