具有意外结果的正弦波傅立叶变换
Posted
技术标签:
【中文标题】具有意外结果的正弦波傅立叶变换【英文标题】:Fourier Transform of Sine Waves with Unexpected Results 【发布时间】:2016-03-29 19:44:07 【问题描述】:我正在绘制正弦波(左列)及其各自的频域表示(右列):
第一波(幅度:10;频率:0.5)的 fft 表示有点混乱 第二波(幅度:15;频率:5.0)看起来完全符合预期。 第三波只是第一波和第二波的总结和继承问题第二个频率图在 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"$\frac2 \cdot fft(s)len(s)$")
ax2.set_xlabel('freq')
ax2.set_ylabel('amplitude')
ax2.stem(freqs, amps)
plt.show()
buildData()
【问题讨论】:
【参考方案1】:FFT 例程执行(快速实现)离散傅里叶变换,将时间序列信号分解为由傅里叶“单位根”组成的 N 长度正交基。
当且仅当您输入的信号是傅里叶基函数之一(或其相位旋转版本)时,您将获得 FFT 输出的离散单个值,因为它具有非零内积具有一个且只有一个基组成员(根据定义)。
您的第一个示例在分析窗口内有 1.5 个循环,因此它不能是单位根(傅立叶基函数的一个属性是它们在分析窗口内具有整数循环计数)。因此,存在一个非零“DC 偏移”(分析窗口上的平均值不完全为零),这将始终产生一个“DC”项(对应于 DC 偏移的索引 0 处的非零傅立叶贡献)。因为它是分析窗口内的非整数循环计数,除了来自最接近正弦波频率的主要贡献之外,您还可以从 FFT 中获得其他频率的贡献。正如预期的那样 - 任何本身不是傅立叶基函数的正弦曲线都将具有与多个傅立叶基函数的非零内积(因此在 FFT 输出中有多个频谱贡献)。
您的第三个示例只是其他两个的总和,因此通过傅里叶变换的线性,FFT 的输出只是两个单独信号的 FFT 的总和。这也是预期的:FFT(a+b) = FFT(a) + FFT(b)。
【讨论】:
【参考方案2】:如果频率在 FFT 长度内的整数个周期中是周期性的,则 DFT 或 FFT 只会从正弦曲线产生单点结果(图中的尖峰)。否则,能量将在所有其他 FFT 结果箱中分散(但主要在附近的结果频率箱中)。这不是“搞砸”,而是有限长度 DFT 的正常预期行为。
【讨论】:
谢谢。处理非整数循环的常用窗口方法是什么?尤其是在处理现实世界的数据时.. Hamming/Hanning? @bogus :这是一个很好的问题;而是一个单独的问题,因此应该在此处或 dsp.stackexchange 中作为单独的问题提出,而不是作为评论提出以上是关于具有意外结果的正弦波傅立叶变换的主要内容,如果未能解决你的问题,请参考以下文章