我正在尝试使用快速傅立叶变换来提取单个正弦函数的相移。我知道,在纸面上,如果我们将函数的变换表示为 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:进一步的实验表明准确性与每个周期的点数有关,而不是绝对数量。增加每个周期的采样点数可以使相位更加准确,但如果信号频率和采样点数都增加相同的倍数,则精度保持不变。