番外 E:Polar 码仿真框架怎么搭
第 19 篇已经把一次 AWGN 仿真的数学链路写完整。本篇不再重复噪声方差推导,而是讨论如何把它组织成可替换、可测试的工程模块。目标是:更换构造方法或译码器时,只改一个接口;出现 BER/BLER 异常时,可以定位到具体阶段。
一个最小仿真系统包含什么
建议把单个传输块拆成以下数据流:
\underline{m} \rightarrow \underline{m}_{\mathrm{enc}} \rightarrow \underline{u} \rightarrow \underline{c} \rightarrow \underline{e} \rightarrow \underline{y}^{\mathrm{tx}} \rightarrow \underline{\lambda}^{\mathrm{tx}} \rightarrow \underline{\lambda} \rightarrow \hat{\underline{u}} \rightarrow \hat{\underline{m}}其中消息向量 \underline{m} 长度为 A,CRC 后序列 \underline{m}_{\mathrm{enc}} 长度为 K,母码字 \underline{c} 长度为 N,率匹配发送序列 \underline{e} 长度为 E。\underline{y}^{\mathrm{tx}} 和 \underline{\lambda}^{\mathrm{tx}} 也按发送索引 j\in[0,E-1] 编号,逆率匹配后的 \underline{\lambda} 才按母码索引 i\in[0,N-1] 编号。
配置对象与不变量
一个实验点至少要保存:
| 配置组 | 字段 |
|---|---|
| 码参数 | N,A,L_{\mathrm{CRC}},K |
| 构造 | 方法名、\rho_{\mathrm{des}}、\boldsymbol{\pi}、\mathcal{A} |
| 率匹配 | E、发送到母码的索引 t_j、puncturing/shortening 标志 |
| 译码 | SC/SCL/CA-SCL、L_{\max}、LLR 饱和值和量化位宽 |
| 信道 | \rho_{\mathrm{sim,dB}}、线性值、噪声方差定义 |
| 随机性 | 全局种子、每个 SNR 点的子种子、块计数 |
| 统计 | 消息向量 BER、消息向量 BLER、CRC 失败、译码耗时 |
配置加载后立即检查不变量:
K=A+L_{\mathrm{CRC}},\qquad 0\le K\le N,\qquad |t|=E还要检查 t_j\in[0,N-1]、\mathcal{A}\subseteq[0,N-1]、|\mathcal{A}|=K 以及 \mathcal{A} 无重复。若这些检查在仿真循环内部才执行,错误配置会浪费大量运行时间。
构造器接口
所有构造器都可以返回同一个结构:
\mathrm{ConstructionResult}=(\boldsymbol{\pi},\mathcal{A},\mathcal{A}^c)对于 BEC/Bhattacharyya,记录 \epsilon 和 Z;对于 DE,记录离散网格;对于 GA,记录 \rho_{\mathrm{des}} 与 \phi 近似;对于 RM/PW,记录行重量或 \beta。调用者只依赖排序序列和集合,不依赖构造内部的数值类型。
构造测试不应只检查集合大小。还要验证排序方向、并列规则和全集补集。例如若排序定义为可靠性降序,则对相邻索引必须满足
\operatorname{score}(\pi_j)\ge\operatorname{score}(\pi_{j+1})并且平分时索引按升序。否则同一配置在不同标准库或不同线程顺序下可能得到不同信息集合。
发送端模块
发送端建议按以下边界拆分:
- 消息生成部分只生成 A 个比特;
- CRC 部分把消息向量扩展为 K;
- 信息位置映射部分按 \mathcal{A} 和输入交织写入 \underline{u};
- Polar 编码部分只负责 \underline{u}\to\underline{c};
- 率匹配部分只负责 \underline{c}\to\underline{e}。
每个模块都应返回长度可检查的对象。尤其是 Polar 编码器不能隐式读取全局信息集合,否则切换构造方法时很容易出现“编码器使用旧集合、译码器使用新集合”的错配。
信道与 LLR 模块
信道模块接收 \underline{e}、噪声方差和随机数引擎,返回长度 E 的观测。LLR 模块再把每个 y^{\mathrm{tx}}_j 转换成 \lambda^{\mathrm{tx}}_j。逆率匹配模块完成
\lambda_i=\sum_{j:t_j=i}\lambda^{\mathrm{tx}}_j并按 puncturing、shortening 规则设置无信息或强先验。这样译码器永远只看到长度 N 的母码 LLR,不需要知道发送长度 E 的细节。
若采用定点 LLR,量化应放在一个明确位置:可以在原始 LLR 后量化,也可以在逆率匹配合并后量化,但两种位置会产生不同结果。实验报告必须记录量化位宽、步长、饱和值和舍入规则。
译码器适配
SC、SCL、CA-SCL 可以共享一个输入结构:
\mathrm{译码输入}=(\underline{\lambda},\mathcal{A}^c,L_{\max},\text{CRC 配置})SC 忽略 L_{\max} 和 CRC;SCL 使用 L_{\max} 进行路径分裂和剪枝;CA-SCL 还要对信息位置按升序提取候选并执行 CRC。统一接口的好处是统计器不需要知道译码器内部如何管理路径。
译码器返回值建议包含:
\mathrm{译码结果}=(\hat{\underline{m}},\text{CRC 是否通过},\text{路径度量},\text{复杂度})其中“CRC 是否通过”只表示校验事件,不替代消息向量是否正确;复杂度可以记录 f/g 调用、路径比较次数或实际耗时。
统计模块
每个块都先比较消息向量:
e_{\mathrm{bit}}=\sum_{k=0}^{A-1}\mathbf{1}\{\hat{m}_k\ne m_k\},\qquad e_{\mathrm{blk}}=\mathbf{1}\{e_{\mathrm{bit}}>0\}累计后得到
\widehat{\mathrm{BER}}=\frac{\sum e_{\mathrm{bit}}}{A\,n_{\mathrm{blk}}},\qquad \widehat{\mathrm{BLER}}=\frac{\sum e_{\mathrm{blk}}}{n_{\mathrm{blk}}}CRC 失败单独累计为 n_{\mathrm{crc-fail}}。若系统实际按 CRC 失败触发重传,还可以额外报告 NACK 率,但要在字段名中写出“检测事件”,不能冒充真实消息向量 BLER。
停止规则与置信区间
一个 SNR 点可以设置最大块数 n_{\max} 和最少错误块数 n_{\mathrm{err,min}}>0。循环在任一条件先满足时停止。若错误块数为 0,应报告观测上界或置信区间,而不是写成“BLER=0”。固定随机种子只能保证重复得到相同样本,不能替代足够大的样本量。
为了比较不同构造方法,建议在同一 SNR 点复用相同的消息向量和噪声序列,但每个译码器都要从未修改的 LLR 副本开始。这样可以降低曲线差异中的随机波动,同时不引入路径状态共享。
结果文件与可追溯性
CSV 或 JSON 结果至少包含:
(\rho_{\mathrm{des}},\rho_{\mathrm{sim,dB}},N,E,A,K, L_{\max},\text{construction},n_{\mathrm{blk}},n_{\mathrm{blk,err}}, n_{\mathrm{crc-fail}},n_{\mathrm{bit,err}})同时保存 \boldsymbol{\pi} 或 \mathcal{A} 的完整列表。只保存曲线坐标而不保存信息集合,后续无法判断性能差异来自构造、率匹配还是译码参数。
一个可执行的目录布局
可以采用如下目录:
polar_sim/
include/
construction.hpp
encoder.hpp
rate_matching.hpp
channel.hpp
decoder.hpp
metrics.hpp
src/
construction_ga.cpp
construction_rm.cpp
construction_pw.cpp
encoder.cpp
rate_matching.cpp
channel_awgn.cpp
decoder_sc.cpp
decoder_scl.cpp
metrics.cpp
tests/
test_construction.cpp
test_rate_matching.cpp
test_crc.cpp
test_roundtrip.cpp
configs/
n64_awgn.json
目录只是组织建议,关键是每个模块拥有单一职责和可独立测试的输入输出。把所有逻辑塞进一个 main.cpp 会让参数复用和错误定位变得困难。
验证顺序
建议按以下顺序验收:
- 无噪声、无率匹配时,SC 应恢复所有测试块;
- 无噪声、加入 puncturing/shortening/repetition 时,逆映射后的 LLR 长度和符号正确;
- 固定 \underline{u} 时,矩阵编码和蝶形编码的 \underline{c} 一致;
- L_{\max}=1 的 SCL 与 SC 输出一致;
- CA-SCL 在人为构造的候选列表上按 CRC 通过且 PM 最小者选择;
- 统计器用手工输入能得到预期 BER、BLER 和 CRC 失败统计。
只有这些基础检查通过后,才值得运行大规模 AWGN 曲线。否则一条平滑曲线可能只是同一个索引错误在所有 SNR 点重复出现。
小结
可扩展仿真框架的核心不是目录名称,而是长度、索引和统计口径在模块边界处都明确。构造器输出 \boldsymbol{\pi} 和 \mathcal{A},编码器处理 N,率匹配处理 E,信道产生发送位置 LLR,逆映射恢复母码 LLR,译码器只关心 \mathcal{A}^c 和路径状态,统计器区分消息向量错误与 CRC 检测事件。下一篇用一份逐项清单收束全系列,帮助读者判断自己是否真的能手推、实现和验收 Polar 链路。
参考
- 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.
- I. Tal and A. Vardy, “List decoding of polar codes,” IEEE Transactions on Information Theory, vol. 61, no. 5, pp. 2213–2226, May 2015, doi: 10.1109/TIT.2015.2410251.
- 3GPP, NR; Multiplexing and channel coding, TS 38.212, V17.9.0, Mar. 2023, §§5.3–5.4.
- 牛凯,《极化码原理与应用》,科学出版社,2021,ISBN 978-7-03-071269-1。