我正在绘制正弦波(左列)及其各自的频域表示(右列):
第二个频率图在x = 5(频率)处恰好有一个峰值,y = 15(幅度)。
为什么当只有一个频率时,第一个频率图有多个峰值?
import numpy as np
import matplotlib.pyplot as plt
def sine(freq, time_interval, rate, amp=1):
w = 2. * np.pi * freq
t = np.linspace(0, time_interval, time_interval*rate)
y = amp*np.sin(w * t)
return y
def buildData():
secs = 3
Fs = 44100
# frequency, duration, sampling rate, amplitude
y1 = sine(0.5, secs, Fs, 10)
y2 = sine(5, secs, Fs, 15)
y3 = y1 + y2
signals = [y1, y2, y3]
showSignals(signals, Fs, secs)
def showSignals(signals, fs, secs):
nrSigs = len(signals)
fig = plt.figure()
fig.subplots_adjust(hspace=.5)
for i in range(len(signals)):
cols=2
pltIdc = []
for col in range(1,cols+1):
pltIdc.append(i*cols+col)
s = signals[i]
t = np.arange(0, secs, 1.0/fs)
ax1 = plt.subplot(nrSigs, cols, pltIdc[0])
ax1.set_title('signal')
ax1.set_xlabel('time')
ax1.set_ylabel('amplitude')
ax1.plot(t, s)
amps = 2*abs(np.fft.fft(s))/len(s) # scaled power spectrum
amps = amps[0:len(amps)/2] # because of the symmetry
amps = amps[0:50] # only the first 50 frequencies, arbitrarily chosen
# this should be close to the amplitude:
print 'magnitude of amplitudes: ' + str(sum(amps*amps)**0.5)
freqs=np.arange(0, len(amps), 1)/secs
ax2 = plt.subplot(nrSigs, cols, pltIdc[1])
ax2.grid(True)
ax2.set_title(r"$\frac{2 \cdot fft(s)}{len(s)}$")
ax2.set_xlabel('freq')
ax2.set_ylabel('amplitude')
ax2.stem(freqs, amps)
plt.show()
buildData()
答案 0 :(得分:1)
FFT例程执行(快速实现)离散傅里叶变换,将时间序列信号分解为N长度标准正交基,由傅立叶"统一的根组成。
当且仅当您输入的信号是傅立叶基函数之一(或其相位旋转版本)时,您将获得FFT输出的离散单值,因为它将具有非零内积只有一个基础集的成员(根据定义)。
您的第一个示例在分析窗口中有1.5个循环,因此它不能是单位的根(傅里叶基函数的一个属性是它们在分析窗口中具有整数循环计数)。因此,存在非零" DC偏移" (分析窗口的平均值不完全为零),这将始终产生一个" DC" term(索引0处的非零傅里叶贡献对应于DC偏移)。因为它是分析窗口内的非积分循环计数,除了来自最接近正弦波的频率的主导贡献之外,您还可以从FFT外的其他频率获得贡献。这是预期的 - 任何本身不是傅里叶函数的正弦曲线都将具有非零内积和多个傅立叶基函数(因此FFT输出中有多个频谱贡献)。
你的第三个例子只是另外两个例子的总和,因此通过傅里叶变换的线性,FFT的输出只是两个独立信号的FFT的总和。这也是预期的:FFT(a + b)= FFT(a)+ FFT(b)。
答案 1 :(得分:1)
如果频率在FFT长度内的整数个周期内是周期性的,则DFT或FFT将仅从正弦曲线产生单点结果(图中的尖峰)。否则,能量将在所有其他FFT结果区间中扩散(但主要在附近的结果频率区间)。这不是“混乱”,而是有限长度DFT的正常预期行为。