繁体   English   中英

正确使用fftw fft

[英]Using fftw fft correctly

我想在项目中使用fftw库中的fft函数,因此创建了以下函数:

void fft(const int size, DCOMPLEX *a, DCOMPLEX *b)
{
    fftw_plan p;
    p = fftw_plan_dft_1d(size, a, b, FFTW_FORWARD, FFTW_ESTIMATE);
    fftw_execute(p); /* repeat as needed */
    fftw_destroy_plan(p);
}

static fftw_complex *in;
static fftw_complex *out;
static fftw_plan p_fft, p_ifft;
void init_fft(const int N)
{
    in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex)*N);
    out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex)*N);
    if(fftw_init_threads() != 0)
    {
        printf("Using %d threads!\n", omp_get_max_threads());
        fftw_plan_with_nthreads(omp_get_max_threads());
    };
    p_fft = fftw_plan_dft_1d(N, in, out, FFTW_FORWARD, FFTW_EXHAUSTIVE);
    p_ifft = fftw_plan_dft_1d(N, in, out, FFTW_BACKWARD, FFTW_EXHAUSTIVE);
    memset(in, 0, N);
    memset(out, 0, N);

}
void fft_pre_plan(const int size, DCOMPLEX *a, DCOMPLEX *b)
{
    memcpy(in, a, size*sizeof(DCOMPLEX));
    fftw_execute(p_ifft); /* repeat as needed */
    memcpy(b, out, size*sizeof(DCOMPLEX));
}

我将结果与b = numpy.fft.fft(a)的结果进行比较,同时调用它们,例如

fft(a.size(), a, b)

要么

init_fft(a.size())//Called once
fftw_pre_plan(a.size(), a, b)//Called for each fft

.size()与数组的长度(伪代码)一起使用。 尽管后一种方法与numpy代码相比提高了2倍,但我从中得到的结果并不正确(即错误的值)。 为什么?
编辑:并且,如果您建议我使用python包装器:使用后一种解决方案(甚至比numpy还要慢)时,它们不会为我提供相同的加速。
比较它们时,我得到以下值作为输出(对于2**14元素的数组和相同的输入):

numpy.fft.fft: [ 0.00095184 -1.54074866e-32j  0.00095267 +6.52776772e-18j
  0.00095349 +2.58018535e-18j ...,  0.00095432 +1.26416719e-16j
  0.00095349 +2.61724648e-16j  0.00095267 +1.21645986e-16j]

fft(): [ 0.00095184 -1.54074866e-32j  0.00095267 -5.98482633e-17j
  0.00095349 -1.27638146e-16j ...,  0.00095432 -9.88543196e-16j
  0.00095349 -9.30058376e-16j  0.00095267 -1.09881551e-15j]

fft_pre_plan(): [ 0.00095184 -1.54074866e-32j  0.00095267 -1.09881551e-15j
  0.00095349 -9.30058376e-16j ...,  0.00095432 -1.79405492e-16j
  0.00095349 -1.27638146e-16j  0.00095267 -5.98482633e-17j]

原因可能是我有舍入错误吗?

对于double精度算术,如FFTW精度基准中所示,许多FFT实现都可以预料到10 -16至10 -15的舍入误差。

注意10 -15比峰值1.0小300dB。 大多数实际信号的动态范围要小得多(例如, 16位CD质量的音频的SNR为〜90dB )。 如果您的应用确实确实需要那么高的精度,则可能需要使用FFT的任意精度实现(这就是FFTW精度测量中的参考实现)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM