在你的榜样,如果生成的频率轴(对不起,我没有倍频这里,所以Python将不得不这样做 - 我确保它在八度相同):
faxis = (np.arange(0, t.size)/t.size) * fs
你会看到faxis[200]
(Python是0索引的,相当于Octave的201索引)是199.80019980019981。你认为你要求200Hz的相位,但你不是,你要求的是199.8Hz的相位。
(这是因为你的t
载体包括1.0是一个额外的样品稍微降低了频谱间隔!我不认为张贴在他们的评论的链接@Sardar_Usama是正确的,它没有任何关系的事实该正弦曲线并没有结束对一个完整的周期,因为这种方法不完全循环应该工作)
的溶液:零垫1001长sig
矢量到2000个样品。然后,用新的faxis
频率向量,faxis[400]
(八度的第401位的指数)恰好对应于200赫兹:
In [54]: sig_fft = fft.fft(sig, 2000);
In [55]: faxis = np.arange(0, sig_fft.size)/sig_fft.size * fs
In [56]: faxis[400]
Out[56]: 200.0
In [57]: np.angle(sig_fft[400]) * 180/np.pi
Out[57]: -29.950454729683386
但是不行啊,发生了什么?这说的角度是-30°?
好吧,回想一下Euler’s formula说的是sin(x) = (exp(i * x) - exp(-i * x))/2i
。分母中的i
表示即使输入正弦波具有60°相位,由FFT恢复的相位也不会是60°。相反,由于-90°= angle(1/i) = angle(-i)
,FFT仓的相位将为60 - 90
度。所以这实际上是正确的答案!要恢复正弦波的相位,您需要将90°添加到FFT bin的相位。
所以总结一下,你需要解决两件事情:
- 确保你正在寻找正确的频点。对于
N
点FFT(并且没有fftshift
),分箱是[0 : N - 1]/N * fs
。上面,我们只使用了一个N = 2000点FFT来确保表示200 Hz。要知道,虽然你有一个正弦波,但就FFT而言,它有两个复指数,分别为+200和-200 Hz,幅值为1 /(2i)和-1 /(2i) 。分母中的这个虚数值将您期望的相位分别改变-90°和+ 90°。
- 如果你碰巧使用了
cos
,余弦波,为sig
,你就不会碰到这样的数学障碍,因此今后要注意区别正弦和余弦之间!
这 - > https://www.mathworks.com/matlabcentral/answers/1139#answer_1625似乎是一种解决同样的问题! –