(17) 率匹配:打孔、缩短和重复到底改变了什么

率匹配:打孔、缩短和重复到底改变了什么

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 映射为 +1e_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=0b=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}}.

这就是逆率匹配的核心公式。它同时解释了三种结果:

  1. \mathcal{J}_i 为空时,求和结果为 0,表示没有关于 c_i 的信道观测;
  2. \mathcal{J}_i 只有一个元素时,保留那一次观测的 LLR;
  3. \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_0c_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_6c_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=64L_{\mathrm{CRC}}=8K=72N=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],并且发送端、接收端使用同一条索引序列。

实现时最容易错的地方

率匹配的错误大多不是公式不会写,而是长度和索引方向没有对齐。至少要检查:

  1. N 是母码长,E 是发送长度,逆率匹配输出必须有 N 个元素;
  2. 发送位置 j 属于 [0,E-1],母码位置 t_j 属于 [0,N-1]
  3. 打孔位置填 0 LLR,而不是填代表比特 0 的强正 LLR;
  4. 缩短位置不能同时出现在发送索引中;
  5. 重复位置必须累加 LLR,不能只保留最后一次观测;
  6. 固定为 0 的缩短位置使用正先验,固定为 1 的位置使用负先验;
  7. M 应和译码器允许的 LLR 饱和值匹配;
  8. 发送端和接收端必须共享完全相同的索引顺序。

本篇小结

率匹配可以统一理解为发送位置 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。
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇