率匹配:打孔、缩短和重复到底改变了什么
Polar 变换通常要求码长为 N=2^n,而实际系统分配给一个控制块的发送资源未必正好容纳 N 个比特。率匹配(rate matching)解决的就是这个长度不一致问题:编码器先生成长度为 N 的母码字,再按照规定的顺序选择、跳过或重复其中的比特,得到真正发送的长度 E 的序列。
率匹配改变的是“哪些码字比特被观测,以及每个比特被观测几次”,并不改变 Polar 译码器使用的母码长。接收端仍然要把信息整理成长度为 N 的 LLR 向量,再交给 SC、SCL 或 CA-SCL 译码器。
先把符号和长度分开
本文使用 0-based 索引。消息向量记为
\underline{m}_0^{A-1}=(m_0,m_1,\ldots,m_{A-1}),其中 A 是消息向量长度。如果消息向量后面附加 L_{\mathrm{CRC}} 个 CRC 比特,那么进入 Polar 编码链路的长度为
K=A+L_{\mathrm{CRC}}.一般 Polar 文章可以把这 K 个比特直接看作信息位。Polar 编码器产生长度为 N 的二元码字
\underline{c}_0^{N-1}=(c_0,c_1,\ldots,c_{N-1}),\qquad c_i\in\{0,1\}.率匹配之后得到长度为 E 的发送序列
\underline{e}_0^{E-1}=(e_0,e_1,\ldots,e_{E-1}).这里必须区分:N 是母码长,E 是本次实际发送的比特数。两者相等时不需要改变长度;E<N 时需要减少发送比特,E>N 时需要重复一部分比特。
率匹配首先是一个索引映射
用 t_j 表示第 j 个发送位置对应母码中的哪个位置:
t_j\in[0,N-1],\qquad j\in[0,E-1].于是发送比特由一条很简单的关系给出:
e_j=c_{t_j}.把所有索引按发送顺序写成
\underline{t}=(t_0,t_1,\ldots,t_{E-1}),就能看出率匹配做了什么。
- 若某个母码位置 i 没有出现在 \underline{t} 中,它没有被发送。
- 若 i 在 \underline{t} 中出现一次,它得到一次信道观测。
- 若 i 出现多次,它对应多次独立观测。
打孔、缩短和重复的差别,最终都会反映在这三种情况上。不过,缩短还额外利用了一个事实:未发送位置的比特值是已知的。
发送位置的 LLR 从哪里来
为了说明接收端为什么要填 0、填强先验或做加法,先固定本文的 BPSK 约定:
x_j^{\mathrm{tx}}=1-2e_j.因此 e_j=0 映射为 +1,e_j=1 映射为 -1。设 AWGN 信道为
y_j^{\mathrm{tx}}=x_j^{\mathrm{tx}}+z_j,\qquad z_j\sim\mathcal{N}(0,\sigma^2).对二元输入 e_j=b,接收值的条件密度为
W(y_j^{\mathrm{tx}}\mid b)=\frac{1}{\sqrt{2\pi\sigma^2}}\exp\left(-\frac{\left(y_j^{\mathrm{tx}}-(1-2b)\right)^2}{2\sigma^2}\right).本文把“支持 0”相对于“支持 1”的对数似然比定义为
\lambda_j^{\mathrm{tx}}=\ln\frac{W(y_j^{\mathrm{tx}}\mid0)}{W(y_j^{\mathrm{tx}}\mid1)}.把 b=0 和 b=1 分别代入条件密度,归一化常数相互抵消,于是
\begin{aligned} \lambda_j^{\mathrm{tx}} &=\frac{\left(y_j^{\mathrm{tx}}+1\right)^2-\left(y_j^{\mathrm{tx}}-1\right)^2}{2\sigma^2}\\ &=\frac{4y_j^{\mathrm{tx}}}{2\sigma^2}\\ &=\frac{2y_j^{\mathrm{tx}}}{\sigma^2}. \end{aligned}所以正 LLR 更支持比特 0,负 LLR 更支持比特 1。后面所有例子都采用这个方向。
逆率匹配的统一推导
接收端已知每个发送位置的 LLR \lambda_j^{\mathrm{tx}},需要把它们还原到母码位置。对固定的母码位置 i,记所有对应的发送位置为
\mathcal{J}_i=\{j\in[0,E-1]:t_j=i\}.如果 j\in\mathcal{J}_i,那么第 j 次观测都在提供关于同一个比特 c_i 的信息。条件独立时,联合似然比等于各次似然比的乘积:
\frac{P\left(\{y_j^{\mathrm{tx}}\}_{j\in\mathcal{J}_i}\mid c_i=0\right)}{P\left(\{y_j^{\mathrm{tx}}\}_{j\in\mathcal{J}_i}\mid c_i=1\right)} =\prod_{j\in\mathcal{J}_i}\frac{P(y_j^{\mathrm{tx}}\mid c_i=0)}{P(y_j^{\mathrm{tx}}\mid c_i=1)}.两边取自然对数,乘积就变成求和:
\lambda_i^{\mathrm{obs}}=\sum_{j\in\mathcal{J}_i}\lambda_j^{\mathrm{tx}}=\sum_{j=0}^{E-1}\mathbf{1}\{t_j=i\}\lambda_j^{\mathrm{tx}}.这就是逆率匹配的核心公式。它同时解释了三种结果:
- \mathcal{J}_i 为空时,求和结果为 0,表示没有关于 c_i 的信道观测;
- \mathcal{J}_i 只有一个元素时,保留那一次观测的 LLR;
- \mathcal{J}_i 有多个元素时,把多次独立观测的 LLR 相加。
注意,0 LLR 不是“判定比特为 0”,而是“0 和 1 目前同样缺少直接证据”。
打孔:没有观测,所以填 0
打孔(puncturing)通常用于 E<N。被打孔的母码位置不发送,接收端也没有关于这些位置的直接观测。
取
N=8,\qquad E=6,\qquad \mathcal{R}_{\mathrm{pun}}=\{0,1\}.规定母码位置 0 和 1 不发送,其余位置按升序发送,因此
\underline{t}=(2,3,4,5,6,7).设母码字为
\underline{c}=(1,0,1,1,0,0,0,0).根据 e_j=c_{t_j},发送序列逐项得到
\begin{aligned} e_0&=c_2=1, &e_1&=c_3=1,\\ e_2&=c_4=0, &e_3&=c_5=0,\\ e_4&=c_6=0, &e_5&=c_7=0. \end{aligned}所以
\underline{e}=(1,1,0,0,0,0).假设信道给出六个发送位置的 LLR:
\underline{\lambda}^{\mathrm{tx}}=(1.2,-0.7,2.1,-1.0,0.8,-0.3).现在逐个母码位置放回:
- c_0 和 c_1 没有对应发送位置,所以 \lambda_0=0、\lambda_1=0;
- c_2 对应发送位置 0,所以 \lambda_2=1.2;
- c_3 对应发送位置 1,所以 \lambda_3=-0.7;
- 依此类推,c_7 对应发送位置 5。
最终得到
\underline{\lambda}^{\mathrm{obs}}=(0,0,1.2,-0.7,2.1,-1.0,0.8,-0.3).这里前两个 0 只表示没有观测。若把它们误写成很大的正数,译码器就会把两个未发送位置当成“强烈支持 0”的位置,收到的先验信息就被人为改变了。
缩短:没有发送,但比特值已知
缩短(shortening)也可以让 E<N,但它和打孔的关键信息不同:缩短位置的码字比特值在发送端和接收端之间预先约定。下面假设缩短位置固定为 0。
取
N=8,\qquad E=6,\qquad \mathcal{R}_{\mathrm{short}}=\{6,7\}.前六个母码位置发送,因此
\underline{t}=(0,1,2,3,4,5).发送端保证 c_6=c_7=0。设母码字仍为
\underline{c}=(1,0,1,1,0,0,0,0).则
\underline{e}=(c_0,c_1,c_2,c_3,c_4,c_5)=(1,0,1,1,0,0).前六个位置仍然接收
\underline{\lambda}^{\mathrm{tx}}=(1.2,-0.7,2.1,-1.0,0.8,-0.3).关键在于 c_6 和 c_7 虽然没有通过信道发送,但它们的值已经知道为 0。接收端可以把这个确定信息表示为一个很大的正 LLR:
\lambda_6=+M,\qquad \lambda_7=+M.于是输入 Polar 译码器的向量是
\underline{\lambda}=(1.2,-0.7,2.1,-1.0,0.8,-0.3,M,M).实际计算不会使用真正的无穷大,而使用译码器允许的有限饱和值,例如 M=50。如果某个缩短位置固定为 1,它的先验方向相反:
\lambda_i=-M.统一写作
\lambda_i^{\mathrm{known}}=M(1-2b_i^{\mathrm{known}}),\qquad b_i^{\mathrm{known}}\in\{0,1\}.因此打孔和缩短虽然都“不发送某些位置”,但译码器的输入不同:打孔位置得到 0 LLR,缩短位置得到代表已知值的强先验。
重复:同一位置得到多次观测
重复(repetition)用于 E>N。取
N=8,\qquad E=10,\qquad \underline{t}=(0,1,2,3,4,5,6,7,0,1).位置 0 和位置 1 各发送两次,其余位置发送一次。仍取
\underline{c}=(1,0,1,1,0,0,0,0).所以发送序列为
\underline{e}=(1,0,1,1,0,0,0,0,1,0).假设十个发送位置的 LLR 为
\underline{\lambda}^{\mathrm{tx}}=(1.1,-0.4,2.0,0.7,-1.2,0.3,0.5,-0.2,0.8,1.4).先处理重复位置:
\lambda_0=\lambda_0^{\mathrm{tx}}+\lambda_8^{\mathrm{tx}}=1.1+0.8=1.9, \lambda_1=\lambda_1^{\mathrm{tx}}+\lambda_9^{\mathrm{tx}}=-0.4+1.4=1.0.其余位置只出现一次,因此直接保留对应值:
\underline{\lambda}^{\mathrm{obs}}=(1.9,1.0,2.0,0.7,-1.2,0.3,0.5,-0.2).为什么一定是相加?设同一个比特产生两次独立观测 y_1,y_2,则
\frac{P(y_1,y_2\mid c_i=0)}{P(y_1,y_2\mid c_i=1)}=\frac{P(y_1\mid c_i=0)}{P(y_1\mid c_i=1)}\cdot\frac{P(y_2\mid c_i=0)}{P(y_2\mid c_i=1)}.取对数后得到
\lambda_i=\lambda_i^{(1)}+\lambda_i^{(2)}.所以不能覆盖第一次观测,也不能先取绝对值再相加。正负号本身就表示两次观测对 0 或 1 的支持方向。
三种方式的本质区别
| 方式 | 长度关系 | 母码索引的特点 | 接收端如何恢复 LLR |
|---|---|---|---|
| 打孔 | E<N | 某些位置没有出现 | 未出现位置填 0 |
| 缩短 | E<N | 某些位置没有出现,但值已知 | 未出现位置填 +M 或 -M |
| 重复 | E>N | 某些位置出现多次 | 对应的 LLR 逐项相加 |
统一公式
\lambda_i^{\mathrm{obs}}=\sum_{j=0}^{E-1}\mathbf{1}\{t_j=i\}\lambda_j^{\mathrm{tx}}已经覆盖了打孔和重复。缩短是在此基础上再加入已知比特的先验;如果某位置没有发送观测但已知为 b_i^{\mathrm{known}},则用 M(1-2b_i^{\mathrm{known}}) 表示这个先验。
母码率和实际发送码率
若 CRC 后输入 Polar 编码器的比特数为 K,母码率为
R_{\mathrm{mother}}=\frac{K}{N}.实际发送 E 个比特时,还可以定义按 CRC 后长度计算的发送码率
R_{\mathrm{enc}}=\frac{K}{E}.如果只关心真正的消息向量,则按 A 计算
R_{\mathrm{msg}}=\frac{A}{E}.例如 A=64、L_{\mathrm{CRC}}=8、K=72、N=128,并打孔到 E=96,则
R_{\mathrm{mother}}=\frac{72}{128}=0.5625,\qquad R_{\mathrm{enc}}=\frac{72}{96}=0.75,\qquad R_{\mathrm{msg}}=\frac{64}{96}\approx0.667.三个码率回答的是不同问题,报告仿真结果时应说明分子采用 K 还是 A。
一段通用的逆率匹配示例
下面的代码只处理接收端:\txToMother[j]\ 给出发送位置 j 对应的母码索引,\txLlr[j]\ 是该位置的信道 LLR。输出长度始终为 N。代码中的索引从 0 开始,与本文公式一致。
如果某个母码位置没有发送观测且 \knownMask[i]\ 为假,它会保持 0,表示打孔;如果 \knownMask[i]\ 为真,则使用 \knownBits[i]\ 提供的已知值设置强先验,表示缩短。相同母码索引出现多次时,循环会保留符号并累加 LLR,表示重复。
#include <cstddef>
#include <stdexcept>
#include <vector>
std::vector<double> inverseRateMatch(
std::size_t N,
const std::vector<std::size_t>& txToMother,
const std::vector<double>& txLlr,
const std::vector<bool>& knownMask,
const std::vector<int>& knownBits,
double M) {
// txToMother[j] 和 txLlr[j] 共同描述发送位置 j,长度就是 E。
// 输出固定为 N 个母码位置的 LLR,不能误返回 E 个元素。
if (N == 0 || txToMother.size() != txLlr.size() ||
knownMask.size() != N || knownBits.size() != N || M <= 0.0) {
throw std::invalid_argument("inconsistent input lengths");
}
std::vector<double> motherLlr(N, 0.0);
// 循环不变量:处理完发送位置 [0,j) 后,
// motherLlr[i] 已累加所有已处理且映射到 i 的观测 LLR。
for (std::size_t j = 0; j < txLlr.size(); ++j) {
const std::size_t i = txToMother[j];
if (i >= N) {
throw std::out_of_range("mother index is outside [0,N-1]");
}
// 已知位置不能同时作为普通信道观测发送,避免先验被覆盖。
if (knownMask[i]) {
throw std::invalid_argument(
"a known position must not also be transmitted");
}
// 若 i 重复出现,LLR 相加正是独立观测的对数似然比合并。
motherLlr[i] += txLlr[j];
}
for (std::size_t i = 0; i < N; ++i) {
if (!knownMask[i]) {
continue; // 未发送且未知:保留 0,表示没有直接观测。
}
if (knownBits[i] != 0 && knownBits[i] != 1) {
throw std::invalid_argument("known bits must be binary");
}
// 已知 0 用正 LLR,已知 1 用负 LLR;M 应与译码器饱和值一致。
motherLlr[i] = M * (1.0 - 2.0 * knownBits[i]);
}
return motherLlr;
}
这段代码没有自行生成 \underline{t},因为索引顺序由具体标准或实验配置决定。调用者必须保证 \txToMother\ 长度为 E,每个索引都落在 [0,N-1],并且发送端、接收端使用同一条索引序列。
实现时最容易错的地方
率匹配的错误大多不是公式不会写,而是长度和索引方向没有对齐。至少要检查:
- N 是母码长,E 是发送长度,逆率匹配输出必须有 N 个元素;
- 发送位置 j 属于 [0,E-1],母码位置 t_j 属于 [0,N-1];
- 打孔位置填 0 LLR,而不是填代表比特 0 的强正 LLR;
- 缩短位置不能同时出现在发送索引中;
- 重复位置必须累加 LLR,不能只保留最后一次观测;
- 固定为 0 的缩短位置使用正先验,固定为 1 的位置使用负先验;
- M 应和译码器允许的 LLR 饱和值匹配;
- 发送端和接收端必须共享完全相同的索引顺序。
本篇小结
率匹配可以统一理解为发送位置 j 到母码位置 t_j 的索引映射。打孔让某些母码位置没有观测,因此对应 LLR 为 0;缩短虽然也不发送这些位置,但它们的值已知,因此要加入强先验;重复让同一个位置获得多次独立观测,所以把 LLR 相加。
母码长 N 由 Polar 变换决定,发送长度 E 由当前资源决定。无论 E<N 还是 E>N,接收端都要恢复长度为 N 的母码 LLR,再交给 Polar 译码器。
参考
- 3GPP, NR; Multiplexing and channel coding, TS 38.212, V17.9.0, Mar. 2023, §§5.3.1–5.4.1.
- E. Arıkan, “Channel polarization: A method for constructing capacity-achieving codes for symmetric binary-input memoryless channels,” IEEE Transactions on Information Theory, vol. 55, no. 7, pp. 3051–3073, Jul. 2009, doi: 10.1109/TIT.2009.2021379.
- D. Trifonov, “Efficient design and decoding of polar codes,” IEEE Transactions on Communications, vol. 60, no. 11, pp. 3221–3227, Nov. 2012, doi: 10.1109/TCOMM.2012.090512.110070.
- 牛凯,《极化码原理与应用》,科学出版社,2021,ISBN 978-7-03-071269-1。