Appearance
信号与系统基础
概念
前面十几门课都在讲"怎么用机器算",这一门换个角度问:信息在物理世界里长什么样、怎么被搬运。
两句话定义这一门课的两个主角:
信号:随时间(或空间)变化的物理量,它携带信息。 系统:把输入信号变成输出信号的"黑盒"。
电压随时间变化是信号,图像随空间变化也是信号;滤波器、放大器、信道、乃至一段代码写的数字滤波器,都是"系统"。
这一整门课(以及后面的傅里叶、拉普拉斯、Z 变换)真正研究的对象,只有一类系统:
线性 + 时不变(LTI)——只有它才能用"卷积"完整描述,也才有后面的那些变换。
所以这一章的任务是:把"卷积"这件事讲透,后面三章的变换全都是它的另一种说法。
原理
一、信号怎么分类
| 分类维度 | 两类 | 例子 |
|---|---|---|
| 自变量连续性 | 连续时间 / 离散时间 | 麦克风电压 / 每毫秒采一次的温度 |
| 是否重复 | 周期 / 非周期 | 正弦 / 单个脉冲 |
| 能量的性质 | 能量信号(总能量有限、平均功率为 0) | 单个脉冲 |
| 功率信号(平均功率有限、总能量无限) | 持续的正弦、方波 | |
| 是否可预测 | 确定 / 随机 | 正弦 / 噪声 |
注意"能量"与"功率"是一对互补的概念:周期信号永远不可能能量有限(一直有值),所以它归到功率信号;单个有限时长的脉冲总能量有限,归到能量信号。两个都不是的也有(如 t·u(t) 这类增长的信号)。
二、两个基本信号:不要小看它们
| 信号 | 定义 | 用处 |
|---|---|---|
| 单位阶跃 u(t) | t < 0 为 0,t > 0 为 1 | 表示"从某一刻开始",用来写"开关" |
| 单位冲激 δ(t) | 面积为 1、宽度趋 0 的理想脉冲 | 表示"某一点上的取值",是卷积的钥匙 |
δ(t) 的用法要分清:
- 筛选:
∫ x(τ)·δ(τ − t₀) dτ = x(t₀)——把某个时刻的值"挑"出来。 - 表示任意信号:
x(t) = ∫ x(τ)·δ(t − τ) dτ——任何信号都能写成"一串加权延迟的冲激之和"。
第二条就是卷积的源头。
三、系统四性质:判据要背准
| 性质 | 判据 | 反例 |
|---|---|---|
| 线性 | 同时满足齐次与叠加:T{a·x₁ + b·x₂} = a·T{x₁} + b·T{x₂} | y[n] = x²[n] |
| 时不变 | 输入延迟多少,输出就延迟多少 | y[n] = n·x[n] |
| 因果 | 输出只依赖当前与过去(现实中系统必须因果) | y[n] = x[n+1] |
| 稳定(BIBO) | 有界输入 ⇒ 有界输出 | y[n] = n·x[n] |
"线性"最常见的误判是只看"有没有乘常数"——乘常数只是齐次性,还得验证叠加。判断时不变要看"系数是否随 n 变":y[n] = n·x[n] 看起来线性,但系数随 n 变 → 时变。
LTI 的稳定性有一条简洁判据:Σ|h[n]| < ∞(离散)或 ∫|h(t)|dt < ∞(连续)——冲激响应绝对可和/可积 ⇔ 稳定。
四、卷积:把输入和"系统性格"揉在一起
连续卷积:
y(t) = x(t) * h(t) = ∫ x(τ)·h(t − τ) dτ离散卷积:
y[n] = x[n] * h[n] = Σ_k x[k]·h[n − k]"翻褶—平移—相乘—求和"四步(这是手算的标准流程,考试也这么要求):
| 步骤 | 连续 | 离散 |
|---|---|---|
| 1 翻褶 | 把 h(τ) 变成 h(−τ) | 把 h[k] 变成 h[−k] |
| 2 平移 | 移 t:h(t − τ) | 移 n:h[n − k] |
| 3 相乘 | x(τ)·h(t − τ) | x[k]·h[n − k] |
| 4 求和 | 对 τ 积分 | 对 k 求和 |
长度公式(离散必考):
长度 N 与长度 M 的两个序列卷积,结果长度 = N + M − 1
连续情形对应的是"宽度相加":宽 1 的矩形卷积宽 1 的矩形,得到宽 2 的三角形。
五、为什么 h(t) 就能描述整个系统
这是 LTI 的核心,推导只有三步:
- 任何输入都能写成冲激之和:
x(t) = ∫ x(τ)δ(t − τ)dτ - 系统对冲激的响应叫 h(t):
δ(t) → h(t) - 时不变 + 线性:延迟 τ 的冲激响应是 h(t − τ),权重是 x(τ),叠加起来就是
∫x(τ)h(t−τ)dτ
所以 "系统"和"它的冲激响应 h(t)"是等价的信息——知道 h 就等于知道了系统对一切输入的答案。这就是为什么整个课程都在研究 h(t),也是为什么变换全都作用在 h(t) 上。
六、卷积与相关:长得像,用途完全不同
| 卷积 | 相关 | |
|---|---|---|
| 公式 | ∫x(τ)h(t−τ)dτ(翻褶) | ∫x(τ)y(t+τ)dτ(不翻褶) |
| 回答什么 | 系统对输入做了什么 | 两个信号有多像 |
| 用途 | 滤波、系统响应 | 检测、匹配滤波、模板匹配 |
区别只在"翻不翻褶",但语义完全不同:卷积是"系统的作用",相关是"相似度比较"。图像处理里的模板匹配用的是相关(数字图像处理)。
七、往前一步:采样
现实世界的信号是连续的,计算机里必须离散——采样就是"每隔 T 秒取一个值"。
这里埋着整个数字信号处理最关键的一个坑:采样频率不够时,高频信号会伪装成低频混进来(混叠)。采样定理说:要不失真,采样率必须大于信号最高频率的 2 倍——44.1 kHz 这个数字正是从"人耳上限约 20 kHz"倒推出来的(见 采样定理 与 数字音频)。
示例
例 1:离散卷积的四步展开(C)
按定义 y[n] = Σ x[k]·h[n−k] 把每一步的贡献列出来。
#include <stdio.h>
int main(void) {
int x[3] = {1, 2, 3};
int h[2] = {1, 1};
int nx = 3, nh = 2;
int len = nx + nh - 1; /* 长度公式:N + M - 1 */
int y[4];
char buf[64];
printf("x = [1, 2, 3], h = [1, 1] -> len = 3 + 2 - 1 = %d\n", len);
printf("%-3s %-5s %s\n", "n", "y[n]", "terms");
for (int n = 0; n < len; n++) {
int s = 0, p = 0, first = 1;
buf[0] = '\0';
for (int k = 0; k < nx; k++) {
int j = n - k; /* h 的下标:翻褶 + 平移 */
if (j < 0 || j >= nh) continue; /* 越界不贡献 */
s += x[k] * h[j];
p += snprintf(buf + p, sizeof(buf) - (unsigned long)p,
"%s%d*%d", first ? "" : " + ", x[k], h[j]);
first = 0;
}
y[n] = s;
printf("%-3d %-5d %s\n", n, s, buf);
}
printf("check: y = [%d, %d, %d, %d]\n", y[0], y[1], y[2], y[3]);
return 0;
}
c 本站为静态站,不提供在线运行;可复制到本地用 gcc / python 执行
预期输出:
x = [1, 2, 3], h = [1, 1] -> len = 3 + 2 - 1 = 4
n y[n] terms
0 1 1*1
1 3 1*1 + 2*1
2 5 2*1 + 3*1
3 3 3*1
check: y = [1, 3, 5, 3]读数:h = [1, 1] 表示"把当前点和前一点加起来",所以 y = [1, 3, 5, 3] 就是"相邻求和"。长度 4 而不是 3——因为卷积结果的尾巴上还有一个只由最后一个输入产生的点,这正是 N + M − 1 的来源。
例 2:离散、连续、三角、筛选四件事一起验(Python)
C 段只展开了离散卷积。这里补上四件:多个离散例子的长度核对、连续卷积的解析解与数值积分对照、矩形卷积成三角、以及冲激的筛选性质与系统性质判定。
import math
def pad(s, w):
dw = sum(2 if ord(c) > 0x2000 else 1 for c in str(s))
return str(s) + " " * max(0, w - dw)
def table(head, rows, gap=2):
data = [[str(c) for c in r] for r in rows]
w = [max([sum(2 if ord(c) > 0x2000 else 1 for c in str(head[i]))]
+ [sum(2 if ord(c) > 0x2000 else 1 for c in r[i]) for r in data]) + gap
for i in range(len(head))]
print(" " + "".join(pad(head[i], w[i]) for i in range(len(head))))
for r in data:
print(" " + "".join(pad(r[i], w[i]) for i in range(len(head))))
def conv(x, h):
"""按定义 y[n] = Σ_k x[k]·h[n-k] 实现,不调用任何库"""
y = [0.0] * (len(x) + len(h) - 1)
for n in range(len(y)):
s = 0.0
for k in range(len(x)):
if 0 <= n - k < len(h):
s += x[k] * h[n - k]
y[n] = s
return y
print("=== 1. 离散卷积:长度一定等于 N + M - 1 ===")
cases = [([1, 2, 3], [1, 1]), ([1, 1, 1], [1, 1, 1]), ([1, 0, -1], [1, 2, 1])]
rows = []
for x, h in cases:
y = conv(x, h)
rows.append(["x = %s" % x, "h = %s" % h, "%s" % [int(v) for v in y],
"N+M-1 = %d+%d-1 = %d" % (len(x), len(h), len(x) + len(h) - 1)])
table(["输入 x", "冲激响应 h", "卷积 y = x * h", "长度核对"], rows)
print(" [1,2,3] * [1,1] = [1,3,5,3]:每一点的 y[n] = x[n] + x[n-1],正是'a[n] 加前一点'。")
print(" [1,1,1] * [1,1,1] 得 [1,2,3,2,1] —— 两个矩形卷成三角形,这是后面连续卷积的离散版。")
print()
print("=== 2. 连续卷积:解析解与数值积分对照 ===")
print(" x(t) = e^(-t)u(t),h(t) = e^(-2t)u(t)")
print(" 解析:y(t) = ∫_0^t e^(-τ)·e^(-2(t-τ)) dτ = (e^(-t) - e^(-2t))u(t)")
def numconv(t, dt=1e-5):
n = int(t / dt)
s = 0.0
for i in range(n + 1):
tau = i * dt
s += math.exp(-tau) * math.exp(-2 * (t - tau))
return s * dt
rows = []
for t in (0.5, 1.0, 2.0, 3.0):
ana = math.exp(-t) - math.exp(-2 * t)
num = numconv(t)
rows.append(["%.1f" % t, "%.8f" % ana, "%.8f" % num, "%.2e" % abs(ana - num)])
table(["t", "解析解 y(t)", "数值积分", "绝对误差"], rows)
print(" 两条路径算出同一组数(∫ 与 Σ 走的是不同路径,不是同一行代码抄两遍)。")
rows = []
for t in (0.0, 0.693147, 1.0):
rows.append(["%.6f" % t, "%.6f" % (math.exp(-t) - math.exp(-2 * t))])
table(["t(含 ln2)", "y(t)"], rows)
print(" 峰值落在 t=ln2≈0.6931 处,值 0.2500 —— 求导令 e^(-t) - 2e^(-2t) = 0 即可解出。")
print()
print("=== 3. 矩形卷积矩形 = 三角形:宽度与峰值都能算出来 ===")
print(" 两个宽 1 的单位矩形:完全重叠时积分最大 = 1×1 = 1(出现在 t=1)")
def rect(t):
return 1.0 if 0.0 <= t <= 1.0 else 0.0
DT, N = 1e-4, 20000
rows = []
for t in (0.0, 0.25, 0.5, 1.0, 1.5, 1.75, 2.0):
y = sum(rect((i + 0.5) * DT) * rect(t - (i + 0.5) * DT) for i in range(N)) * DT # 中点法
rows.append(["%.2f" % t, "%.4f" % y, "%.4f" % max(0.0, min(t, 2 - t))])
table(["t", "数值卷积", "理论三角 min(t, 2-t)"], rows)
print(" 数值列与理论列逐行吻合:卷积把'宽度 1 的矩形'变成了'宽度 2 的三角形'。")
print(" 结论:卷积后的长度 = 两个信号长度之和(1 + 1 = 2),与离散的 N + M - 1 完全对应。")
print()
print("=== 4. 冲激响应为什么能描述一切:筛选性质 ===")
x = [3, 1, 4, 1, 5]
delta = [0, 0, 1] # δ[n-2]
rows = [["x[n]", "%s" % x],
["δ[n-2]", "%s" % delta],
["x[n] * δ[n-2]", "%s" % [int(v) for v in conv(x, delta)]],
["x[n-2](右移 2 位)", "%s" % ([0, 0] + x)]]
table(["信号", "值"], rows)
print(" 与 δ 卷积 = 把原信号搬过去:这就是'任何输入都能拆成加权延迟的 δ 之和'的直接后果,")
print(" 也是 LTI 系统只看 h(t) 就够了的根据。")
print()
print("=== 5. 系统四性质判定:看四个例子 ===")
rows = [
["y[n] = x[n] + x[n-1]", "是", "是", "是", "是", "差分(滑动平均)"],
["y[n] = x[n]²", "否", "是", "是", "是", "平方非线性"],
["y[n] = x[n+1]", "是", "是", "否", "是", "要未来值 → 非因果"],
["y[n] = n·x[n]", "是", "否", "是", "否", "系数随 n 变 → 时变、无界"],
]
table(["系统", "线性", "时不变", "因果", "稳定", "为什么"], rows)
print(" 判'线性'就对两个输入验证叠加性:T{a·x1 + b·x2} 是否等于 a·T{x1} + b·T{x2}。")
print(" 判'稳定'看有界输入能否给出有界输出:y[n] = n·x[n] 在 |x|≤1 时输出却无界,故不稳定。")
print(" 只有'线性 + 时不变'(LTI)才能用卷积描述 —— 这是本课后面所有变换的前提。")
python 本站为静态站,不提供在线运行;可复制到本地用 gcc / python 执行
预期输出:
=== 1. 离散卷积:长度一定等于 N + M - 1 ===
输入 x 冲激响应 h 卷积 y = x * h 长度核对
x = [1, 2, 3] h = [1, 1] [1, 3, 5, 3] N+M-1 = 3+2-1 = 4
x = [1, 1, 1] h = [1, 1, 1] [1, 2, 3, 2, 1] N+M-1 = 3+3-1 = 5
x = [1, 0, -1] h = [1, 2, 1] [1, 2, 0, -2, -1] N+M-1 = 3+3-1 = 5
[1,2,3] * [1,1] = [1,3,5,3]:每一点的 y[n] = x[n] + x[n-1],正是'a[n] 加前一点'。
[1,1,1] * [1,1,1] 得 [1,2,3,2,1] —— 两个矩形卷成三角形,这是后面连续卷积的离散版。
=== 2. 连续卷积:解析解与数值积分对照 ===
x(t) = e^(-t)u(t),h(t) = e^(-2t)u(t)
解析:y(t) = ∫_0^t e^(-τ)·e^(-2(t-τ)) dτ = (e^(-t) - e^(-2t))u(t)
t 解析解 y(t) 数值积分 绝对误差
0.5 0.23865122 0.23865003 1.19e-06
1.0 0.23254416 0.23254300 1.16e-06
2.0 0.11701964 0.11701906 5.85e-07
3.0 0.04730832 0.04730858 2.61e-07
两条路径算出同一组数(∫ 与 Σ 走的是不同路径,不是同一行代码抄两遍)。
t(含 ln2) y(t)
0.000000 0.000000
0.693147 0.250000
1.000000 0.232544
峰值落在 t=ln2≈0.6931 处,值 0.2500 —— 求导令 e^(-t) - 2e^(-2t) = 0 即可解出。
=== 3. 矩形卷积矩形 = 三角形:宽度与峰值都能算出来 ===
两个宽 1 的单位矩形:完全重叠时积分最大 = 1×1 = 1(出现在 t=1)
t 数值卷积 理论三角 min(t, 2-t)
0.00 0.0000 0.0000
0.25 0.2500 0.2500
0.50 0.5000 0.5000
1.00 1.0000 1.0000
1.50 0.5000 0.5000
1.75 0.2500 0.2500
2.00 0.0000 0.0000
数值列与理论列逐行吻合:卷积把'宽度 1 的矩形'变成了'宽度 2 的三角形'。
结论:卷积后的长度 = 两个信号长度之和(1 + 1 = 2),与离散的 N + M - 1 完全对应。
=== 4. 冲激响应为什么能描述一切:筛选性质 ===
信号 值
x[n] [3, 1, 4, 1, 5]
δ[n-2] [0, 0, 1]
x[n] * δ[n-2] [0, 0, 3, 1, 4, 1, 5]
x[n-2](右移 2 位) [0, 0, 3, 1, 4, 1, 5]
与 δ 卷积 = 把原信号搬过去:这就是'任何输入都能拆成加权延迟的 δ 之和'的直接后果,
也是 LTI 系统只看 h(t) 就够了的根据。
=== 5. 系统四性质判定:看四个例子 ===
系统 线性 时不变 因果 稳定 为什么
y[n] = x[n] + x[n-1] 是 是 是 是 差分(滑动平均)
y[n] = x[n]² 否 是 是 是 平方非线性
y[n] = x[n+1] 是 是 否 是 要未来值 → 非因果
y[n] = n·x[n] 是 否 是 否 系数随 n 变 → 时变、无界
判'线性'就对两个输入验证叠加性:T{a·x1 + b·x2} 是否等于 a·T{x1} + b·T{x2}。
判'稳定'看有界输入能否给出有界输出:y[n] = n·x[n] 在 |x|≤1 时输出却无界,故不稳定。
只有'线性 + 时不变'(LTI)才能用卷积描述 —— 这是本课后面所有变换的前提。四条结论:
- 长度公式是硬约束:三组例子全部满足 N + M − 1。它来自"翻褶后头尾各有一段只被一个点覆盖",不是巧合。
- 解析解与数值积分吻合到 1e-6 量级:
y(t) = e^{-t} − e^{-2t},峰值在 t = ln2 ≈ 0.6931 处、值 0.25。两条不同路径给出同一组数,这才叫验算。 - 矩形卷矩形得三角形:数值列与理论三角
min(t, 2−t)逐行吻合,峰值 1 出现在完全重叠处。"卷积把宽度加起来"这件事在连续世界里同样成立。 - 与 δ 卷积 = 平移:
x[n] * δ[n−2] = x[n−2],右移 2 位。这是"用冲激响应描述系统"的机制来源。
考点
考点
1. 基本定义要能默写
- 连续卷积:
y(t) = ∫x(τ)h(t−τ)dτ;离散卷积:y[n] = Σ_k x[k]h[n−k]。 - 四步法:翻褶 → 平移 → 相乘 → 求和(积分)。
- 长度公式:N + M − 1(考研最常考的一格)。
2. 冲激函数的两个动作
| 动作 | 式子 | 含义 |
|---|---|---|
| 筛选(采样) | ∫x(τ)δ(τ−t₀)dτ = x(t₀) | 取出某时刻的值 |
| 展开 | x(t) = ∫x(τ)δ(t−τ)dτ | 任何信号 = 加权延迟冲激之和 |
δ 是"函数"还是"广义函数",考纲里不深究;要会用它的面积与筛选性质。
3. 系统四性质判据
- 线性 = 齐次 + 叠加,两者缺一不可。
- 时不变看系数是否随自变量变:
y[n]=n·x[n]线性但时变。 - 因果:输出不依赖未来。
- 稳定(BIBO):
Σ|h[n]| < ∞或∫|h(t)|dt < ∞。
4. LTI 与卷积的关系(推导题常考)
x(t) = ∫x(τ)δ(t−τ)dτ → 时不变把 δ(t−τ) 变成 h(t−τ) → 线性把系数 x(τ) 提出来 → y = x * h。 结论:LTI 系统由 h(t) 唯一确定。
5. 卷积 vs 相关
- 卷积翻褶,相关不翻褶。
- 卷积 = 系统作用(滤波),相关 = 相似度(检测、模板匹配)。
- 记忆:
x(t)*δ(t−t₀) = x(t−t₀)(平移);x(t)⋆x(t)(自相关)在 0 处取最大值。
6. 易错点清单
- 卷积不满足"交换前后不换结果"的直觉错误:卷积确实满足交换律
x*h = h*x(这点与"翻褶"给人的印象相反),但不能因此把参量的物理含义对调。 - 把卷积的"相乘求和"写成"对应点相乘再求和"(点积):点积对应的是相关,不是卷积。
- 计算卷积时忘记限制积分区间:
x(t)h(t−τ)只有两者重叠时才有贡献,区间必须分段讨论。 - 把"能量信号"与"功率信号"混为一谈:周期信号是功率信号,单脉冲是能量信号。
- 判断稳定性只看极点是否在左半平面:那个判据属于拉普拉斯域,时域判据是"冲激响应绝对可和/可积"。
- 认为"离散卷积的结果和输入等长":结果长 N + M − 1。
小结
- 信号是随时间变化的物理量,系统是它的变换器;本课只研究 LTI——因为只有它能用卷积完整描述。
- δ(t) 是打开一切的那把钥匙:它既能筛选(取出某时刻的值),又能展开(任何信号写成加权延迟冲激之和)。
- 卷积的四步是"翻褶—平移—相乘—求和",长度公式 N + M − 1(连续对应"宽度相加")。
y = x * h的推导只有三步(展开 → 时不变 → 线性叠加),结论是"h(t) 就是系统的全部信息"。- 卷积 ≠ 相关:只差"翻不翻褶",但一个是"系统作用"、一个是"相似度"。
回到主线:这是一条分支课,不在"由硅到 C"的链上(课程总览见站点首页)。它与主线有两处真实交汇:计网的物理层(信号怎么承载比特,见 物理层)和图像与音频处理(见 数字图像处理 与 数字音频)。它自己的前置数学是 复变函数与积分变换。
这一章只答了一个问题:"系统对输入做了什么"。下一章换一个视角问同一个问题——不问"系统做了什么",而问"这个信号由哪些频率组成"。
下一篇:傅里叶变换:时域与频域
评论(0)
当前浏览器不允许本地存储,评论无法保存。
还没有评论,来说两句。