简体   繁体   English

为什么`numpy.fft.irfft`如此不精确?

[英]Why `numpy.fft.irfft` is so imprecise?

I understand that most FFT/IFFT routines have an error floor.我知道大多数 FFT/IFFT 例程都有错误底限。 I was expecting NumPy's FFT to have an error floor in the same orders as FFTW (say 1e-15 ), but the following experiment shows errors in the order of 1e-5 .我期待 NumPy 的 FFT 具有与 FFTW 相同顺序的错误底限(例如1e-15 ),但以下实验显示错误顺序为1e-5

Consider calculating the IDFT of a box.考虑计算一个盒子的 IDFT。 It is well-known that the result is the sinc-like Dirichlet kernel. 众所周知,结果是类 sinc Dirichlet kernel。 But that is not what I get from numpy.fft.irfft .但这不是我从numpy.fft.irfft得到的。 In fact even the first sample that should simply equal the width of the box divided by the number of FFT points is off by an amount around 4e-5 as the following example shows:事实上,即使第一个样本应该简单地等于框的宽度除以 FFT 点的数量,也会偏离大约4e-5的量,如下例所示:

import numpy as np
import matplotlib.pyplot as plt

from scipy.special import diric

N = 40960
K = 513

X = np.ones(K, dtype=np.complex)
x = np.fft.irfft(X, N)

print("x[0] = %g: expected %g - error = %g" % (x[0], (2*K+1)/N, x[0]-(2*K+1)/N))

# expected IDFT of a box is Dirichlet function (see
# https://en.wikipedia.org/wiki/Discrete_Fourier_transform#Some_discrete_Fourier_transform_pairs)

y = diric(2*np.pi*np.arange(N)/N, 2*K+1) * (2*K+1) / N

plt.figure()
plt.plot(x[:1024] - y[:1024])
plt.title('error')

plt.show(block=True)

It looks like the error is of sinusoidal form:看起来错误是正弦形式: 在此处输入图像描述

Has anybody experience same issue?有没有人遇到过同样的问题? Am I misunderstanding something about the NumPy's FFT pack or it is just not accurate?我对 NumPy 的 FFT 包有误解还是它不准确?


Update更新

Here is the equivalent of part of the script in Octave:下面是 Octave 中脚本的一部分:

N = 40960;
K = 513;

X = zeros(1, N);


X(1:K) = 1;
X(N-K:N) = 1;

x = ifft(X);

fprintf("x[0] = %g, expected = %g - error = %g\n", x(1), (2*K+1)/N, x(1)-(2*K+1)/N);

The error on x[0] is practically zero in Octave. x[0]上的误差在 Octave 中几乎为零。 (I did not check other samples because I am not aware of equivalent of diric function in Octave.) (我没有检查其他样本,因为我不知道八度音阶中的diric function 等效项。)

Thanks to MarkDickinson , I realized that my math was wrong.感谢MarkDickinson ,我意识到我的数学是错误的。 The correct comparison would be carried out by:正确的比较将通过以下方式进行:

import numpy as np
import matplotlib.pyplot as plt

from scipy.special import diric

N = 40960
K = 513

X = np.ones(K+1, dtype=np.complex)
x = np.fft.irfft(X, N)

print("x[0] = %g: expected %g - error = %g" % (x[0], (2*K+1)/N, x[0]-(2*K+1)/N))

# expected IDFT of a box is Dirichlet function (see
# https://en.wikipedia.org/wiki/Discrete_Fourier_transform#Some_discrete_Fourier_transform_pairs)

y = diric(2*np.pi*np.arange(N)/N, 2*K+1) * (2*K+1) / N

plt.figure()
plt.plot(x[:1024] - y[:1024])
plt.title('error')

plt.show(block=True)

that shows irfft is accurate.这表明irfft是准确的。 Here is the error plot:这是错误 plot: 在此处输入图像描述

Numpy is correct, my math was incorrect. Numpy 是正确的,我的数学不正确。 I am sorry for posting this misleading question.我很抱歉发布这个误导性问题。 I don't know what is the standard procedure in these cases.我不知道在这些情况下的标准程序是什么。 Should I delete my question or leave it here with this answer?我应该删除我的问题还是留下这个答案? I just don't want it to be undermining NumPy or challanging its accuracy (as this was clearly a false alarm).我只是不希望它破坏 NumPy 或挑战其准确性(因为这显然是一个误报)。

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

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