啁啾是否具有恒定幅度的频率响应?

信息处理 fft Python 自由度 频率响应 唧唧喳喳
2022-02-20 01:08:59

PG。223 人声称如此,但我通过 DFT 得出的结果不同:

教科书错了吗?


我尝试的解释:(代码

  1. DFT vs DTFT:“频率响应”是通过后者计算的。尽管如此,DFT 应该类似于采样的 DTFT。

  2. DFT 时域周期性,而 DTFT 假定是非周期性的,或“无限重复”并具有无限补零。

为了解决每一个问题,我在下面尝试了更大N的和零填充。零填充似乎可以纠正相位(如果展开,则为二次),并且更多的样本倾向于使幅度不断增长的频率向右变平。

我认为,在 limitN -> inf中,幅度尖峰的宽度为零(如在 Gibbs 中) - 但这在“大 N 长填充”情况下似乎是矛盾的,在这种情况下,幅度的重要部分会随着振荡而衰减。此外,左峰似乎与 成比例N,表现得更像是极限中的脉冲,不会像吉布斯现象那样产生零能量。


更新:事实证明幅度不会尖峰,而是呈指数衰减,这与预期的水平线相去甚远 -而且,相位是线性的:


注意:有关更多信息,请参阅已接受答案下方的评论。

3个回答

这本书没有错,但它确实以笨拙的方式介绍了 LFM 的概念,并且可能会产生误导。本书介绍了 LFM 频谱的解析表达式,这是一个近似值。它还与绘图视图一起使用,并且很可能会展开相位角,这通常是查看您期望的相位所必需的。

通常,当您介绍 LFM 时,您会显示调制脉冲本身以及时域中的相位进展。时域中的解析表达式是您观察线性频率以及 LFM 的二次相位性质所需要的全部内容。在频域中这样做只会带来更多的混乱。时域 LFM 脉冲及其相位的示例如下所示。

在此处输入图像描述

在推导 LFM 脉冲的傅里叶变换表达式时,您确实在脉冲带宽上产生了 1 的幅度。这在直觉上是令人满意的,因为您在带宽上的每个频率都有相同的贡献。

然而,如果他们期望一个恒定的频率响应,那么当人们去绘制这个图时,确实会发生混淆。对于任何实际的 LFM 频谱图,即使脉冲宽度非常长,也应该预期会出现您已经识别的涟漪效应。相位的二次性质仍然在 DFT 中得到体现。上方的 LFM 脉冲频谱如下所示。

在此处输入图像描述

我没有尝试过您的代码,但可能您只需要放大适当的区域并打开各个阶段即可查看您想要的内容。提供了生成绘图的 MATLAB 代码,以帮助您将其转换为 python。

%% LFM - Time and Frequency Domain

% Sampling
Fs = 50e6;

% Pulse parameters
tau = 50e-6;
bandWidth = 10e6;
alpha = bandWidth/tau;

% Define waveform
t = 0:1/Fs:tau - 1/Fs;
fmcwPulse = exp(1i*pi*alpha.*t.^2); % Complex transmitted LFM waveform

% Plot
figure;
subplot(2, 1, 1);
plot(real(fmcwPulse));
xlabel("Samples");
title("LFM Pulse - Real Part");

subplot(2, 1, 2);
plot(unwrap(angle(fmcwPulse)));
xlabel("Samples");
title("LFM Phase");

figure;
subplot(2, 1, 1);
plot(abs(fftshift(fft(fmcwPulse))));
title("LFM Spectrum Magnitude");

subplot(2, 1, 2);
plot(unwrap(angle(fftshift(fft(fmcwPulse)))));
title("LFM Spectrum Phase");

更新

修改上面的代码,使τ=1 s,它相对较长,产生的光谱更接近人们在分析时预期的理想平坦光谱。光谱如下图所示。

在此处输入图像描述

“为什么我的 DFT 响应不同?”的简短回答 是你有一个非常小的时间带宽积的啁啾。持续时间更长或扫过更大频率范围的啁啾声变得更接近理想啁啾声。

在此处输入图像描述

(来自https://en.wikipedia.org/wiki/Chirp_spectrum,尽管该页面总体上也有些混乱)

矩形的形状。频率函数与采样频率无关fs(假设您的采样速度比奈奎斯特频率足够快),与添加额外的零填充无关。

我同意原书通过将图形绘制为直线而不是矩形而令人困惑。@Envidia 的帖子已经说明了更大的时间带宽乘积将如何使频率响应接近理想的 rect 函数,对于非无限离散信号,吉布振铃是不可避免的。

回复:谜题“为什么频率 10 的正弦波比频率 1->2 啁啾移动得慢?”

我只是想包括这个,因为我犯了同样的错误,并且看到新的信号处理学生也这样做。大多数信号处理文本大多包含带有连续变量的数学公式,因此很容易认为cos(2 * pi * f * t)用 Python 或 MATLAB 编写意味着您的角相位是2πft因此频率是变量f,无论代码变量tf持有什么。

虽然看起来像做f = linspace(1, 2); cos(2 * pi * f * t)意味着余弦是“从 1 到 2 的扫描频率”,但瞬时频率cos(ϕ(t)) 是的导数ϕ,ϕ˙(t)(如上所述)。

因此,仅当您从 0 开始时间并且具有f = linspace(1, 2). 这将获得您期望的相位图(余弦的参数)和余弦本身:

在此处输入图像描述

如果你有类似的东西t = linspace(1, 2, n),扫描相同频率范围的相位不再只是2 * pi * f * t

从扫f1(t)f2(t), 你会想要创建函数f(t)作为一条线从f1(t)f2(t). 然后使用的值t您正在考虑并求解斜率截距这可确保相位的斜率与您尝试扫描的频率相匹配。

这是一个差异示例,使用略有不同的数字(如果您尝试“将频率从 1 扫描到 2”,但您查看的时间从 1 开始而不是 0 并持续 1 秒)。左边是阶段,右边是cos(phase)查看它们摆动速度的图。红色的错误方式是做 t = linspace(1, 2); f = linspace(1, 2); phase_wrong = 2 * pi * f * t通过与 2 的恒定斜率相位相比,它肯定在任何地方都有 2 的频率,您可以看到这种方法的斜率比 2 更陡,因此它不是从 1 到 2 扫描频率。

在此处输入图像描述

(情节代码:)

import matplotlib.pyplot as plt
from numpy import pi, cos, linspace

n = 500
t = linspace(0, 2, n)
f = linspace(1, 2, n)

fig, axes = plt.subplots(1, 2)

ax = axes[0]
ax.plot(t, 2 * pi * 1 * t, c="b", label="freq=1")
ax.plot(t, 2 * pi * 2 * t, c="cyan", label="freq=2")
ax.plot(t, 2 * pi * f * t, c="red", label="sweep 1->2")

ax.set_title(r"$\phi(t)$")
ax.legend()

ax = axes[1]
ax.plot(t, cos(2 * pi * 1 * t), c="b", label="freq=1")
ax.plot(t, cos(2 * pi * 2 * t), c="cyan", label="freq=2")
ax.plot(t, cos(2 * pi * f * t), c="red", label="sweep 1->2")

ax.set_title(r"$\cos(\phi(t))$")
ax.legend()


fig, axes = plt.subplots(1, 2)
t = linspace(1, 2, n)
phi_right = pi * (t ** 2 - 1)

f = linspace(1, 2, n)
phi_wrong = 2 * pi * f * t

# Compare to a constant freq (straight phase line)
const_freq = 2

ax = axes[0]
ax.plot(t, 2 * pi * const_freq * t, c="b", label=f"{const_freq = }")
# Make it start at same spot as constant freq phase line
offset1 = phi_right[0] - 2 * pi * const_freq * t[0]
ax.plot(t, phi_right - offset1, c="cyan", label="correct: f sweeps 1 -> 2")
offset2 = phi_wrong[0] - 2 * pi * const_freq * t[0]
ax.plot(t, phi_wrong - offset2, c="red", label="wrong way (2 pi f t)")
ax.set_title(r"$\phi(t)$")
ax.legend()

ax = axes[1]
ax.plot(t, cos(2 * pi * const_freq * t), c="b", label=f"{const_freq = }")
ax.plot(t, cos(phi_right), c="cyan", label="correct: f sweeps 1 -> 2")
ax.plot(t, cos(phi_wrong), c="red", label="wrong way (2 pi f t)")
ax.legend()
ax.set_title(r"$\cos(\phi(t))$")

(@OverLordGoldDragon 还指出了他的更多真实代码示例,这可能比仅数学公式更有用:https ://overlordgolddragon.github.io/test-signals/#signal-general-forms-derivations )

教科书是错误的,或者根据解释非常具有误导性。频率响应是平方的,或者,在扫描频率上是恒定的假设一个可以扩大规模的理想啁啾系统f任意持续时间t(无限带宽);,那么幅度是一个无限宽度的平方 - 这恰好与普通的“常数”相同。

以下是一些相关的描述;感谢 Envidia 的有益讨论 - 请参阅他对复杂啁啾图的回答。


  • 相位 (啁啾):二次。必须小心“阶段”的含义;瞬时,即完整的输入,ϕ(t)cos(ϕ(t)). 瞬时频率cos(t2)不是t, 但t/2; 这里

  • 相位 (频率响应)抛物线,半抛物线对称于尖峰并与尖峰相邻fmax/2. 那么教科书有错吗?对于任何物理的有限啁啾系统,的 - 但本书再次假设一个具有无限频率扫描的理想系统,因此“峰值”位于无穷远处,使相位成为真正的抛物线。

  • 幅度 (啁啾):对于复杂的啁啾,它是单位/峰值幅度,对于任何具有共享inst的复杂信号。阶段 (sin2+cos2)。对于真正的啁啾,它是腹肌。幅度值。

  • 幅度 (频率响应):为什么会出现涟漪?因为f扫描分数频率,当给定频率持续时间不够长时,这些频率表示为附近频率和更高频率的组合(对于啁啾,每个仅持续一个样本)。

    • 对称性:真实 -> 甚至关于 DC;复杂 -> 不对称,没有负频率。

我主要使用这段代码来可视化各种场景。作为一个谜题(对读者来说;我已经理解了)为了理解最重要的要点,我提出以下观点:从 1 扫描到 2 的频率如何具有f=10在同一时期?如果相反怎么办t是从 11.9 到 12.0?

不要看 Wiki,尤其是这段代码,因为它们都回答了这个问题(大部分)。