0

我正在重新采样一个真实信号,并且由于我可以使用它的 fft rfft,我想使用irfft(signal, new_length). 但我似乎无法让它工作。

这是一个工作代码片段,它使用复数 fft 对长度为 4 的信号进行重新采样:

from numpy.fft import fft,ifft
p=array([1.,2.2,4.,1.])
pk=fft(p)
pnew=ifft(pk,8)*(8./4.)

其中因子(8./4.)从原始长度重新调整为新长度。你可以检查一下pnew[::2]==p

现在,当我尝试对真实傅里叶变换应用相同的策略时,我在原始点得到了错误的结果:

from numpy.fft import rfft,irfft
p=array([1.,2.2,4.,1.])
pk=rfft(p)
pnew=irfft(pk,8)*(8./4.)

我有pnew[::2]=[ 1.45, 1.75, 4.45, 0.55]!=p

有人知道发生了什么吗?我尝试使用 scipy 中的例程,结果相同。文档本身简要讨论了如何执行此操作,请参阅此处,页面底部

4

1 回答 1

1

您喜欢的文档说:

In other words, irfft(rfft(a), len(a)) == a to within numerical accuracy.

如果你这样做,情况并非如此irfft(pk, 8)!除了填充之外,问题在于奇数样本和傅里叶变换的对称性。len(p)请注意,如果是奇数,则根本没有问题。

为了更好地理解,请考虑以下内容:

>>> p = np.array([1.,2.2,4.,1.])
>>> np.fft.fft(p)
array([ 8.2+0.j , -3.0-1.2j,  1.8+0.j , -3.0+1.2j])
>>> np.fft.fftfreq(len(p))
array([ 0.  ,  0.25, -0.5 , -0.25]) # 0.5 only occurs once negative
>>> np.fft.rfft(p)
array([ 8.2+0.j , -3.0-1.2j,  1.8+0.j ])
>>> np.fft.rfftfreq(len(p)) # (not available in numpy 1.6.)
array([ 0.  ,  0.25,  0.5 ]) # 0.5 occurs, here positive, it does not matter

# also consider the odd length FFT
>>> np.fft.fftfreq(len(p)+1)
array([ 0. ,  0.2,  0.4, -0.4, -0.2]) # 0.4 is in there twice.

# And consider that this gives the result you expect:
>>> symmetric_p = np.fft.rfft(p)
>>> symmetric_p[-1] /= 2
>>> np.fft.irfft(symmetric_p, 8)[::2]*(8./4.)
array([ 1. ,  2.2,  4. ,  1. ])

这意味着如果你仔细观察。如果输入样本是偶数,则计算的 FFT 频率不是对称的,而是有一个额外的负频率(实际上也可以是正频率,因为它始终没有相移)。

因为您正在填充(没有真正的原因?)到不同的频率,RFFT 突然为这个频率提供了额外的“空间”。因此,如果您从 FFT 的角度来看它,通常只会在出现负频率时将其添加为正频率(这基本上意味着它会加倍)。如果您查看symmetric_p减半的上方,则此频率会给出带有填充的预期结果(如果没有填充,它将不会给出预期的结果)。

于 2012-12-10T14:03:35.477 回答