我只想知道并理解为什么信号x1
的幅度最高,而信号的幅度x2
最低,如下图所示?
当我运行代码时,我希望看到x1
最低幅度、x2
中等幅度和x3
最高幅度,因为如下面的等式所示,x1
乘以 10x2
等于x1
再加上另一个幅度 10,依此类推。
请澄清这些观点。
我只想知道并理解为什么信号x1
的幅度最高,而信号的幅度x2
最低,如下图所示?
当我运行代码时,我希望看到x1
最低幅度、x2
中等幅度和x3
最高幅度,因为如下面的等式所示,x1
乘以 10x2
等于x1
再加上另一个幅度 10,依此类推。
请澄清这些观点。
该信号x3
包含三个具有相同幅度但不同频率的余弦。因此,理想情况下,频谱应该包含三个幅度相同的狄拉克脉冲。只有当我们对信号进行无限长的观察时,才会出现这种情况。我们有由多个L=8000
样本组成的“窗口”信号。您“切掉”了 8000 个样本,这就像将信号与矩形信号相乘一样。一个矩形的频谱是一个 sinc 脉冲,由一个主瓣和几个较小的旁瓣组成。
因此,您将获得的频谱将x3
是 3 个狄拉克与 sinc 脉冲的卷积。这正是绘制 DTFT 时得到的结果:
DFT 是 DTFT 的采样版本。k
DFT频率定义为
其中N
是 DFT 的长度。这就是您的问题所在:您使用N=8192
和计算 DFT fs=8000
。因此,您不会达到准确的频率f1
, f2
, f3
。最接近“真实”峰值的点将是
f1 = 2.9297 Hz
f2 = 19.5313 Hz
f3 = 49.8047 Hz
因此,您在 DFT 中看到的峰值小于应有的值。
您还可以看到,实际频率与测量频率之间的最大差异(位于 处f2
)导致 DFT 中的最小峰值。频率的舍入误差仍然小于,即随着 DFT 长度的增加而减小。
长话短说:对于周期性信号,您可以调整 DFT 长度以确保 DFT 达到实际频率(正如@gg349 在他的回答中建议的那样)。一般来说,可以让 DFT 长度N
更长,以获得更小的舍入误差并更接近 DTFT。为了获得更好的 DTFT 从而提高频率分辨率,您必须增加数据长度L
。
x1,x2,x3
在 3 个不同的频率上分别有 1,2 和 3 个谐波,并且所有的谐波都具有10
幅度。当您在频域中研究这些信号时,您期望x1,x2,x3
分别呈现 1,2 和 3 个峰值,并且所有峰值都具有相同的幅度。所以x1
有 1 个峰值3Hz
(假设我们在这里谈论时间),并且x3
有 3 个峰值,在频率3,20,50Hz
。
尽管我刚才说过,如果您在不选择特定观察窗口的情况下绘制傅立叶变换的绝对值,您会发现例如x3
3 个频率处的 3 个峰值的高度不同。这可以在您的右上角的图中看到x3
,也可以在@hbaderts 的回答中看到,这并没有真正解决您的问题。发生这种情况是因为您的时间向量t
不是信号周期的倍数,这会导致您获得一个非周期性的信号x3
(或x1,x2
就此而言)(或至少不是您认为的周期性) ,并且您不能再期望上述内容受到尊重,因为更多的频率分量会涂抹这张图片。
由于您正在生成信号而不是从传感器加载它,因此您可以更改观察窗口t
,以便信号在该窗口中是周期性的。在这种情况下,所需的观察窗口是1
第二个(因此每个周期t1,t2,t3
都包含在1s
整数次中)。t=0
然后,您可以在和之间选择多个等距点t=1
,不包括最后一个点,即在 范围内[0,1)
。
唯一要讨论的是采样频率,它必须高于信号最高频率的两倍。在这种情况下,最高频率。是fmax = 50
,因此我们需要在上面进行采样fs=100Hz
以解决所有谐波。0
我们还需要采样频率是自然数,或者和之间的离散点1
不会是等距的,信号也不会是周期性的。
以下是python中的示例,留给您在Matlab中进行调整:
from numpy import arange, cos
from numpy.fft import rfft, rfftfreq
import matplotlib.pyplot as plt
f1, f2, f3 = 3., 20., 50. # in Hz
T1, T2, T3 = 1 / f1, 1 / f2, 1 / f3
T_all = 1
# From Shanon theoreom we must use a sampling freq. larger than this:
f_sample = 2 * max([f1, f2, f3])
# we also need to use an integer sampling frequency, or the
# points will not be equispaced between 0 and 1. We then add +1 to f_sample:
dt = 1 / (f_sample + 1)
t = arange(0, T_all, dt)
# another way of generating the points, without fixing the sampling frequency
# follows. In this case one must check that 1 / dt > f_sample afterwards
# t, dt = linspace(0, T_all, 2000, endpoint=False, retstep=True)
x3 = 1 * cos(2 * pi * f1 * t) + 2 * cos(2 * pi * f2 * t) + 3 * cos(2 * pi * f3 * t)
y = rfft(x3)
freqs = rfftfreq(t.size, d=dt) # in Hz
fig, ax = plt.subplots() # we plot the abs. value of the fft:
# the factor 2/t.size is the normalizing factor between peaks
# of the DFT and original amplitudes in time domain.
ax.plot(freqs, 2 * abs(y) / t.size, 'o')
ax.set_ylim(0, 3.5)
ax.set_xlabel('f [Hz]')
ax.grid()
fig.show()
我们发现离散 DFT 实际上仅在指定频率处显示非零值。通过适当地重新调整结果,我们还恢复了谐波的精确幅度,在本例中选择为1,2,3
。
作为参考,我以上面代码中的最小采样率(即
f_sample+1
Hz)报告原始时间信号。此外,采样频率必须大于 1)f_sample
以避免欠采样,并尊重香农定理;2) 一个整数,在 和 之间具有均匀分布的离散样本0s
,1s
即为了具有周期信号。
注意 t=1 的最后一点是如何丢失的: