[英]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.