离散傅立叶变换可为您提供复指数的系数,这些系数相加在一起可产生原始离散信号。特别是,第k个傅里叶系数可为您提供有关在给定数量的样本上具有k个周期的正弦波振幅的信息。
请注意,由于您的正弦波在1000个样本中没有整数个周期,因此实际上您将无法使用FFT检索原始正弦波。相反,您将得到许多不同正弦曲线的混合体,包括〜.4的恒定分量。
您可以使用以下代码绘制各种分量正弦曲线,并观察它们的和为原始信号:
freqs = np.fft.fftfreq(len(x),.01)threshold = 0.0recomb = np.zeros((len(x),))for i in range(len(fft3)): if abs(fft3[i])/(len(x)) > threshold: recomb += 1/(len(x))*(fft3[i].real*np.cos(freqs[i]*2*np.pi*x)-fft3[i].imag*np.sin(freqs[i]*2*np.pi*x)) plt.plot(x,1/(len(x))*(fft3[i].real*np.cos(freqs[i]*2*np.pi*x)-fft3[i].imag*np.sin(freqs[i]*2*np.pi*x)))plt.show()plt.plot(x,recomb,x,sin3)plt.show()
通过更改
threshold,您还可以选择排除低功率的正弦波,并查看其如何影响最终的重建。
编辑:上面的代码中有一个陷阱,尽管它没有错。它隐藏了DFT对于真实信号的固有对称性,并以其真实幅度的一半绘制了每个正弦曲线两次。此代码性能更高,并以正确的幅度绘制正弦曲线:
freqs = np.fft.fftfreq(len(x),.01)threshold = 0.0recomb = np.zeros((len(x),))middle = len(x)//2 + 1for i in range(middle): if abs(fft3[i])/(len(x)) > threshold: if i == 0: coeff = 2 else: coeff = 1 sinusoid = 1/(len(x)*coeff/2)*(abs(fft3[i])*np.cos(freqs[i]*2*np.pi*x+cmath.phase(fft3[i]))) recomb += sinusoid plt.plot(x,sinusoid)plt.show()plt.plot(x,recomb,x,sin3)plt.show()
在一般情况下,如果您知道信号是由一些正弦波子集组成的,这些子集的频率可能与信号的长度未正确对齐,则可以通过零填充或扩展信号来识别频率。您可以在此处了解更多信息。如果信号是完全任意的,而您只是对查看分量正弦波感兴趣,则无需这样做。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)