我目前正在学习离散傅里叶变换,并使用numpy进行实验以更好地理解它。
我尝试绘制了一个“sin x sin x sin”信号,并获得了一个只有4个非零点的干净FFT。我天真地告诉自己:“好吧,如果我用这些振幅和频率绘制一个“sin + sin + sin + sin”的信号,我应该得到相同的“sin x sin x sin”信号,对吧?”
好吧...不完全是这样
(第一个是“x”信号,第二个是“+”信号)
两者具有相同的振幅/频率,但不是相同的信号,即使我可以看到它们有一些相似之处。
好的,既然我只绘制了FFT的绝对值,我想我失去了一些信息。
然后我为两个信号绘制了实部、虚部和绝对值:
现在,我很困惑。我该怎么办?我从数学角度阅读了关于DFT的文章。我理解复数值来自于单位圆。我甚至不得不学习希尔伯特空间来理解它的工作原理(而且这很痛苦!...我只是浅尝辄止)。我只希望了解这些实部/虚部图是否在数学世界之外具有任何具体意义:
- abs(fft):频率+振幅
- real(fft):?
- imaginary(fft):?
代码:
import numpy as np
import matplotlib.pyplot as plt
N = 512 # Sample count
fs = 128 # Sampling rate
st = 1.0 / fs # Sample time
t = np.arange(N) * st # Time vector
signal1 = \
1 *np.cos(2*np.pi * t) *\
2 *np.cos(2*np.pi * 4*t) *\
0.5 *np.cos(2*np.pi * 0.5*t)
signal2 = \
0.25*np.sin(2*np.pi * 2.5*t) +\
0.25*np.sin(2*np.pi * 3.5*t) +\
0.25*np.sin(2*np.pi * 4.5*t) +\
0.25*np.sin(2*np.pi * 5.5*t)
_, axes = plt.subplots(4, 2)
# Plot signal
axes[0][0].set_title("Signal 1 (multiply)")
axes[0][0].grid()
axes[0][0].plot(t, signal1, 'b-')
axes[0][1].set_title("Signal 2 (add)")
axes[0][1].grid()
axes[0][1].plot(t, signal2, 'r-')
# FFT + bins + normalization
bins = np.fft.fftfreq(N, st)
fft = [i / (N/2) for i in np.fft.fft(signal1)]
fft2 = [i / (N/2) for i in np.fft.fft(signal2)]
# Plot real
axes[1][0].set_title("FFT 1 (real)")
axes[1][0].grid()
axes[1][0].plot(bins[:N/2], np.real(fft[:N/2]), 'b-')
axes[1][1].set_title("FFT 2 (real)")
axes[1][1].grid()
axes[1][1].plot(bins[:N/2], np.real(fft2[:N/2]), 'r-')
# Plot imaginary
axes[2][0].set_title("FFT 1 (imaginary)")
axes[2][0].grid()
axes[2][0].plot(bins[:N/2], np.imag(fft[:N/2]), 'b-')
axes[2][1].set_title("FFT 2 (imaginary)")
axes[2][1].grid()
axes[2][1].plot(bins[:N/2], np.imag(fft2[:N/2]), 'r-')
# Plot abs
axes[3][0].set_title("FFT 1 (abs)")
axes[3][0].grid()
axes[3][0].plot(bins[:N/2], np.abs(fft[:N/2]), 'b-')
axes[3][1].set_title("FFT 2 (abs)")
axes[3][1].grid()
axes[3][1].plot(bins[:N/2], np.abs(fft2[:N/2]), 'r-')
plt.show()