4.5 信道容量与编码定理
上一节讨论压缩的极限:一个信源最少需要多少比特。本节讨论传输的极限:一条有噪声的信道最多能可靠地传送多少信息。两个问题的结构相似,答案都由互信息给出:压缩的极限是熵(互信息的最大值,即与自身的互信息),传输的极限是输入与输出之间互信息的最大值,称为信道容量(channel capacity)。
信道容量给出的结论在直觉上并不显然。有噪声的信道意味着接收的符号可能与发送的不同,若按直觉推理,误差会随着传输长度累积,可靠传输是不可能的。香农第二定理说明这一直觉有误:只要传输速率低于容量,存在编码方案使错误概率任意小,代价是编码长度增加。这一结论把噪声与可靠分离开来:噪声影响的是速率上限,而不是可行性。
本节按建模 → 定义 → 定理 → 具体信道 → 多用户的顺序展开。4.5.1 节给出信道模型与三种典型信道,4.5.2 节定义容量,4.5.3 节陈述编码定理并给出正反两个方向的证明思路,4.5.4 节计算几个常见信道的容量,4.5.5 节讨论高斯信道与功率约束,4.5.6 节处理并行信道与注水算法,4.5.7 节概述多用户信息论的主要结论。本节与 4.4 节合起来构成信息论的经典主体,两者的结论在工程上分别对应压缩算法与纠错码。
4.5.1 信道模型
离散无记忆信道
离散无记忆信道(discrete memoryless channel,DMC)由输入字母表
信道可以用一个概率转移矩阵表示,矩阵的第
三种典型信道
二元对称信道(binary symmetric channel,BSC):输入输出都是
翻转概率
二元擦除信道(binary erasure channel,BEC):输入为
Z 信道:输入
import numpy as np
def bsc_capacity(p):
"""二元对称信道的容量(比特/次使用)"""
if p == 0 or p == 1:
return 1.0
h = -p * np.log2(p) - (1 - p) * np.log2(1 - p)
return 1 - h
def bec_capacity(eps):
"""二元擦除信道的容量"""
return 1 - eps
print("二元对称信道容量:")
for p in [0.0, 0.01, 0.1, 0.25, 0.5]:
print(f" 翻转概率 {p:.2f}:C = {bsc_capacity(p):.4f} 比特")
print("二元擦除信道容量:")
for eps in [0.0, 0.1, 0.25, 0.5]:
print(f" 擦除概率 {eps:.2f}:C = {bec_capacity(eps):.4f} 比特")
# 相同概率下 BEC 的容量大于 BSC,因为接收端知道哪一次不可靠4.5.2 信道容量的定义
信道容量(channel capacity)定义为输入与输出之间互信息的最大值:
最大化在全部可能的输入分布上进行,单位是比特每次信道使用。这一定义包含三层含义。
为什么是互信息的最大值。互信息度量输出的每个符号平均提供了多少关于输入的信息。若每使用一次信道能获得
为什么容量是信道自身的属性。互信息对输入分布取最大后不再依赖
容量的操作性含义由编码定理给出。定义本身只说互信息的最大值,为什么它等于可靠传输的速率上限,需要由 4.5.3 节的两个方向论证。在此之前,容量只是一个待解释的数学量。
互信息关于输入分布是凹函数(可以证明),因此最大化互信息是凸优化问题(第三章),最优输入分布唯一(在等价类意义下)。这一性质使容量可以在数值上可靠地求解。
4.5.3 信道编码定理
定理的内容
信道编码定理(channel coding theorem,香农第二定理)断言:对任意离散无记忆信道,容量
可达性:对任意速率
逆定理:对任意速率
两条合起来说明容量是可靠传输的精确阈值:低于它可行,高于它不可行,没有中间地带。这一阈值结构是信息论最著名的结论之一,它把通信系统的设计目标明确为逼近容量,而不必纠结于噪声是否会导致失败。
可达性的证明思路
证明分三步。
随机码本。从输入分布
联合典型解码。接收端收到序列
错误概率分析。错误发生在两种情况:真实的码字与
证明中的关键量是
逆定理的证明思路
逆定理使用 Fano 不等式(4.1 节)。设消息
当
4.5.4 几个信道的容量
二元对称信道
由对称性,最优输入分布是均匀分布(在对称信道上均匀输入使输出也均匀,且不偏向任何符号)。此时
其中
翻转概率
二元擦除信道
BEC 的推导更直接。接收端要么收到正确符号(概率
因此
这一结果是容量公式中最简洁的一个,它的含义是:擦除的符号可以完全不用管,剩下的部分仍然携带完整信息。与 BSC 对比,同样的
对称信道
对转移矩阵行互为置换的信道(对称信道),容量有统一公式:
以均匀输入达到。这一公式覆盖了 BSC(
import numpy as np
from scipy import optimize
# 一般 DMC 容量的数值求解:在单纯形上最大化互信息
def channel_capacity(P, n_grid=60):
"""P 为转移矩阵,规模为 |X| x |Y|;在输入分布单纯形上做网格 + 局部优化"""
nx, ny = P.shape
def mutual(px):
py = px @ P
I = 0.0
for x in range(nx):
for y in range(ny):
if px[x] > 0 and P[x, y] > 0:
I += px[x] * P[x, y] * np.log2(P[x, y] / py[y])
return I
# 先用随机搜索找到较好的起点
rng = np.random.default_rng(0)
best = None
for _ in range(200):
px = rng.dirichlet(np.ones(nx))
val = mutual(px)
if best is None or val > best[0]:
best = (val, px)
# 再在最优解附近做细网格
base = best[1]
for scale in [0.2, 0.05, 0.01]:
for _ in range(400):
px = np.clip(base + rng.normal(scale=scale, size=nx), 1e-6, None)
px = px / px.sum()
val = mutual(px)
if val > best[0]:
best = (val, px)
base = px
return best
# 二元对称信道
P_bsc = np.array([[0.9, 0.1], [0.1, 0.9]])
C, px = channel_capacity(P_bsc)
print(f"BSC(p=0.1):数值容量 = {C:.4f},理论值 = {1 + 0.1 * np.log2(0.1) + 0.9 * np.log2(0.9):.4f},最优输入 = {np.round(px, 4)}")
# Z 信道
P_z = np.array([[0.8, 0.2], [0.0, 1.0]])
C_z, px_z = channel_capacity(P_z)
theory_z = np.log2(1 + (1 - 0.2) * 0.2 ** (0.2 / 0.8))
print(f"Z 信道(p=0.2):数值容量 = {C_z:.4f},理论值 = {theory_z:.4f},最优输入 = {np.round(px_z, 4)}")
# Z 信道的最优输入分布偏向可靠的那个符号,与均匀分布不同4.5.5 高斯信道与功率约束
信道模型
高斯信道(Gaussian channel)是最常见的连续信道模型:输入
噪声独立于输入。输入受到功率约束:
容量推导
互信息为
其中
三条件解读与功率-带宽折衷
香农公式的三条推论在实际系统中反复使用。
容量随信噪比对数增长。把功率翻倍只能增加
容量随带宽近似线性增长,但存在上限。当
速率与可靠性的关系由编码决定。容量给出的是速率上限,实际系统的误码率取决于编码方案与码长。工程上常用的做法是选择接近容量的编码(如 LDPC、Turbo 码、极化码)并在链路预算中留出几 dB 的余量。
import numpy as np
def shannon_capacity_db(snr_db):
"""由信噪比(dB)计算高斯信道容量(比特/符号)"""
snr = 10 ** (snr_db / 10)
return 0.5 * np.log2(1 + snr)
print("信噪比与容量(比特/符号):")
for snr_db in [-5, 0, 5, 10, 20, 30]:
print(f" SNR = {snr_db:3d} dB:C = {shannon_capacity_db(snr_db):.4f}")
# 带宽与功率的折衷:固定总功率,比较不同带宽下的每秒容量
P, N0 = 1.0, 0.1
print("\n带宽取不同值时的每秒容量:")
for W in [1, 10, 100, 1000, 10_000]:
C = W * np.log2(1 + P / (N0 * W))
print(f" 带宽 {W:6d} Hz:C = {C:.4f} 比特/秒")
print(f"功率受限极限 P / N0 * log2(e) = {P / N0 * np.log2(np.e):.4f} 比特/秒")
# 带宽增大时容量单调上升但趋于极限值4.5.6 并行信道与注水算法
并行高斯信道
许多实际信道可以分解为若干并行子信道:多载波系统(OFDM)的各个子载波、多天线系统的各个特征模式、多条独立链路。设第
这是第三章讨论的凸优化问题(目标函数关于功率是凹函数,约束是线性),可以用拉格朗日乘子法求解。
注水算法
求导并引入乘子
这个解称为注水算法(water-filling):把功率想象成水,把各子信道的噪声水平
注水结果有两条直观含义。第一,功率与信道质量成正比地分配,而非平均分配,这样做的收益来自对数函数的凹性:把功率从好信道转移到差信道的边际收益更低。第二,当总功率很小或某些子信道极差时,最优策略是放弃这些子信道,把功率集中到可用的部分。这一放弃的策略在工程中对应关断部分载波以降低能耗。
对多个天线构成的 MIMO 信道,通过奇异值分解把信道矩阵分解为若干并行子信道(每个奇异值对应一个子信道),容量同样是注水形式:
其中
import numpy as np
def water_filling(noise, total_power):
"""注水算法:返回各子信道的功率分配"""
noise = np.asarray(noise, dtype=float)
# 二分搜索液面高度 nu,使 sum(max(0, nu - noise)) = total_power
lo, hi = noise.min(), noise.min() + total_power
for _ in range(100):
nu = 0.5 * (lo + hi)
allocated = np.maximum(0.0, nu - noise).sum()
if allocated > total_power:
hi = nu
else:
lo = nu
return np.maximum(0.0, nu - noise)
noise = np.array([0.1, 0.3, 1.0, 3.0, 10.0])
P_total = 5.0
P_alloc = water_filling(noise, P_total)
print(f"噪声水平 = {noise}")
print(f"功率分配 = {np.round(P_alloc, 4)}(总和 = {P_alloc.sum():.4f})")
def capacity_parallel(P_alloc, noise):
return 0.5 * np.sum(np.log2(1 + P_alloc / noise))
print(f"注水策略容量 = {capacity_parallel(P_alloc, noise):.4f} 比特/符号")
print(f"平均分配策略容量 = {capacity_parallel(np.full_like(noise, P_total / len(noise)), noise):.4f} 比特/符号")
# 注水策略优于平均分配;噪声最大的子信道分配为零(被放弃)4.5.7 反馈与多用户情形
反馈
一个有反馈的信道允许发送端获知前面接收到的符号,据此调整后续发送。直觉上这一信息应当提高容量。结论是:对无记忆信道,反馈不增加容量。原因在于反馈不改变
反馈在两种情况下的作用明显。第一,它简化编码设计:有反馈时可以用更简单的方案逼近容量,不需要长块的复杂码。第二,对有记忆信道(如带记忆的衰落信道)反馈可以提高容量,原因是发送端可以据此分配功率(类似注水,但分配依据随时间变化的信道质量)。
多用户信道
多个用户共享信道时,描述目标从单一容量变为容量区域(capacity region):一组可达速率向量的集合。几个经典结论如下。
多址信道(multiple access channel,MAC):多个发送端、一个接收端。对高斯 MAC,两个用户的容量区域由约束
广播信道(broadcast channel):一个发送端、多个接收端。退化广播信道的容量区域由叠加编码(superposition coding)达到,发送端把多个用户的信息分层叠加,信道好的用户解出全部层,信道差的用户只解出基础层。
干扰信道(interference channel)与中继信道(relay channel)的容量一般未知,只有部分情形(如强干扰、退化中继)有精确结果。网络编码(network coding)的结论是中间节点对信息做线性组合而非仅仅转发可以提高多播吞吐量,这一结果与路由直觉相反。
分布式信源编码:两个相关的信源分别编码、联合解码时,Slepian-Wolf 定理说明总速率下界是联合熵
这几个结论的共同结构值得记住:当信息可以共享时(无论共享发生在编码端还是解码端),系统能达到的极限由联合分布的互信息或条件熵给出,而不是由各自独立的边界加和给出。
4.5.8 本节小结
噪声下的传输极限
本节给出传输的理论极限。信道容量定义为输入输出互信息的最大值,它只由信道的转移概率决定,是可操作量:信道编码定理说明任何低于容量的速率都存在使错误概率趋于零的编码,任何高于容量的速率都无法可靠传输。可达性由随机码本与联合典型解码证明,逆定理由数据处理不等式与 Fano 不等式给出。几个常见信道有闭式容量:二元对称信道为
信息论的两条经典主线到此完成:压缩的极限由熵与率失真函数给出,传输的极限由互信息与信道容量给出。接下来把视角转向统计推断:互信息与 KL 散度在假设检验与参数估计中给出误差的下界,而这些下界的具体形式(Chernoff 信息、Hoeffding 界、大偏差率函数)构成了信息论与统计推断的接口。下一节讨论这一部分内容,它与第二章的假设检验、Cramér-Rao 下界直接衔接。
练习题
第 1 题 概念推导
设信道为二元对称信道,翻转概率为
参考答案
计算互信息:设输入分布为
条件熵
因此
最大化:
为什么均匀输入最优:信道的转移矩阵行互为置换(对称性),输出分布对输入的依赖是混合形式:输出分布是所有行按输入分布的加权平均。由于
第 2 题 计算推理
某无线链路带宽为
参考答案
原始容量:
带宽减半、功率不变:带宽变为
容量下降约
目标容量 1.5 倍:需要
换算成分贝为
第 3 题 代码验证
实现注水算法并验证三条性质:功率分配之和等于总功率;噪声最小的子信道得到最多功率;在极端噪声分布下部分子信道分配为零。再用数值方法计算 Z 信道的容量,验证最优输入分布不均匀。
参考答案
import numpy as np
def water_filling(noise, total_power, eps=1e-10):
noise = np.asarray(noise, dtype=float)
lo, hi = 0.0, noise.min() + total_power
for _ in range(200):
nu = 0.5 * (lo + hi)
if np.maximum(0.0, nu - noise).sum() > total_power:
hi = nu
else:
lo = nu
return np.maximum(0.0, 0.5 * (lo + hi) - noise)
def capacity(P, noise):
return 0.5 * np.sum(np.log2(1 + np.maximum(P, 0) / noise))
for noise, P_total in [
(np.array([0.2, 0.5, 1.0]), 3.0),
(np.array([0.1, 0.2, 10.0]), 2.0),
(np.array([1.0, 1.0, 1.0, 1.0]), 4.0),
]:
P = water_filling(noise, P_total)
print(f"噪声 {noise},总功率 {P_total}")
print(f" 分配 {np.round(P, 4)}(和 = {P.sum():.6f})")
print(f" 注水容量 {capacity(P, noise):.4f},平均分配容量 {capacity(np.full_like(noise, P_total / len(noise)), noise):.4f}")
# Z 信道:数值求解最优输入分布
def z_capacity(p, n=2001):
px1 = np.linspace(0, 1, n) # P(X=1)
best = (0.0, 0.0)
for a in px1:
px = np.array([1 - a, a])
P = np.array([[1 - p, p], [0.0, 1.0]])
py = px @ P
I = 0.0
for x in range(2):
for y in range(2):
if px[x] > 0 and P[x, y] > 0:
I += px[x] * P[x, y] * np.log2(P[x, y] / py[y])
if I > best[0]:
best = (I, a)
return best
for p in [0.1, 0.3, 0.5]:
C, a = z_capacity(p)
theory = np.log2(1 + (1 - p) * p ** (p / (1 - p)))
print(f"Z 信道 p = {p}:数值容量 {C:.4f},理论 {theory:.4f},最优 P(X=1) = {a:.3f}")输出验证三点:功率分配之和恒等于总功率;噪声最小的子信道获得最多功率;在噪声差异大的例子中噪声为
第 4 题 综合应用
某团队设计一个卫星下行链路:可用带宽
参考答案
可行性判断:由香农公式计算容量上限:
容量约为
三种改进方向:
其一,提高信噪比。要把容量提高到
其二,增加带宽。带宽从
其三,改用多天线(MIMO)。在富散射环境下,
为什么需要留余量:容量是渐近结论,要求码长趋于无穷。实际系统中码长受延迟限制(通常几千比特),实际可达速率低于容量,差距取决于编码方案。此外链路还有额外损耗:雨衰、指向误差、实现损失(滤波器不理想、量化误差)会占用几 dB 的预算;系统还需要在信噪比波动时保持稳定,因此工作点要留有余量。工程上的做法是把理论容量减去实现损失(约
常见错误
错误 1 · 把容量当作有限码长下可达到的速率
原因:容量是渐近结论,要求码长趋于无穷且码本可以任意复杂。实际系统受延迟、复杂度与硬件限制,码长通常只有几千比特,可达速率低于容量。把两者混同会导致链路预算过于乐观,或在实测速率低于容量时误判实现有缺陷。
解决:区分理论极限与实际工作点。设计时把容量减去实现损失与衰落余量得到目标速率,再按目标速率选择编码方案与码长;评估现有系统时,用接近容量的现代编码(LDPC、极化码)作为参照,量化还有多少提升空间。
错误 2 · 认为反馈能提高无记忆信道的容量
原因:对无记忆信道,反馈不改变互信息的上界
解决:区分容量与可达性。需要论证反馈的收益时,指出它降低的是编码与解码的复杂度,或指出它针对的是有记忆信道(如衰落信道,反馈用于功率与速率自适应),在那里容量确实可以提高。
错误 3 · 对非对称信道沿用均匀输入
原因:对称信道的容量公式
解决:先检查信道的对称性。行互为置换时用闭式公式;不是对称信道时求解
错误 4 · 混淆擦除与错误
原因:擦除的位置对接收端可见,错误的位置不可见。这一差别使二元擦除信道的容量为
解决:按信道的行为特征选择模型。数据包丢失、存储单元失效这类知道哪一部分不可用的场景用擦除模型;符号被替换、位被翻转这类不可见错误用对称信道模型。混合情形(既擦除又出错)分别建模,容量由两者的联合模型给出,不能用单一公式外推。