我正在尝试使用快速傅里叶变换来提取单个正弦函数的相位移。我知道在纸上,如果我们将函数的变换表示为T,则有以下关系:
然而,我发现虽然我能够准确捕捉余弦波的频率,但除非我以极高的速率进行采样,否则相位是不准确的。例如:
import numpy as np
import pylab as pl
num_t = 100000
t = np.linspace(0,1,num_t)
dt = 1.0/num_t
w = 2.0*np.pi*30.0
phase = np.pi/2.0
amp = np.fft.rfft(np.cos(w*t+phase))
freqs = np.fft.rfftfreq(t.shape[-1],dt)
print (np.arctan2(amp.imag,amp.real))[30]
pl.subplot(211)
pl.plot(freqs[:60],np.sqrt(amp.real**2+amp.imag**2)[:60])
pl.subplot(212)
pl.plot(freqs[:60],(np.arctan2(amp.imag,amp.real))[:60])
pl.show()
使用num = 100000个点,我得到了1.57173880459的相位。
使用num = 10000个点,我得到了1.58022110476的相位。
使用num = 1000个点,我得到了1.6650441064的相位。
出了什么问题?即使有1000个点,每个周期有33个点,这应该足以解决。也许有一种方法可以增加计算频率点的数量吗?是否有任何方法可以在“低”点数下完成此操作?
编辑:通过进一步实验,似乎我需要每个周期约1000个点才能准确提取相位。为什么?!
编辑2:进一步实验表明,精度与每个周期的点数有关,而不是绝对数字。增加每个周期采样点的数量会使相位更准确,但如果信号频率和采样点数都按相同因素增加,则精度保持不变。