资讯动态

极化码 MATLAB 仿真全链路:从编码、SC 译码到 BER 验证

发布时间:2026/10/20 19:14:56 来源:尧图企业网站定制
简介PCode.zip 是一套面向通信工程学习者与科研人员的极化码 MATLAB 仿真源码聚焦 Polar Coding 的编解码原理与性能验证适合已具备一定通信理论基础、希望深入理解信道极化机制的中高级读者。压缩包共 32 个文件全部为 .m 脚本整体约 35KB涵盖码构造、编码、信道合成与解码等核心模块如 pcencode、pdecode、SC_Decoder_ver2、MonteCarlo 等并配有 plotPC 系列绘图脚本与 BEC 信道相关函数便于直观观察码率、码长与迭代次数对误码率的影响。源码注释较为详细逐行解释了变量含义与算法流程可帮助读者厘清生成矩阵变换、比特翻转与软输入软输出解码的实现细节。目前已有 905 人学习下载适合作为极化码理论到 MATLAB 工程实现的对照参考也可用于 5G 编码方案的仿真入门与性能评估。1. 极化码 MATLAB 仿真从 PCode.zip 里拆出可复现的编码链路极化码Polar Coding这两年在通信算法圈子里热度一直没降尤其是做信道编码方向的几乎绕不开它。PCode.zip 这个包名一看就知道是极化码的 MATLAB 实现里面大概率包含 pdecode 这类译码函数。很多人拿到这类压缩包的第一反应是直接跑 demo结果发现跑不通或者结果对不上问题往往出在没搞清楚极化码的编码链路到底分几步。这篇笔记不讲空泛的理论推导而是把极化码 MATLAB 仿真的完整路径拆开从信道极化、信息位选择、编码矩阵构造到 SC 译码和 pdecode 的调用方式每一步都给可执行的代码和参数说明。适合已经了解 MATLAB 基础、想快速把极化码跑起来验证 BER 曲线的工程师也适合需要复现论文仿真结果的研究生。2. 极化码编码链路从信道极化到码字生成2.1 信道极化与信息位选择的实操逻辑极化码的核心思想是信道极化把 N 个独立信道通过递归变换分裂成两类——一部分信道容量趋近于 1另一部分趋近于 0。信息位就放在那些“好信道”上冻结位放在“差信道”上。MATLAB 里做这件事第一步是计算每个子信道的可靠性度量。常见做法是用巴氏参数Bhattacharyya parameter或者高斯近似Gaussian Approximation来排序。我一般用高斯近似因为它对 AWGN 信道更准计算也简单。核心是递归计算每个子信道的等效噪声方差然后按方差从小到大排序方差小的就是好信道。下面这段代码展示了如何用高斯近似生成信息位索引function info_idx get_info_bits(N, K, snr_db) % N: 码长, K: 信息位数量, snr_db: 设计信噪比 % 高斯近似递归计算子信道可靠性 sigma 10^(-snr_db/20); % 噪声标准差 % 初始化每个子信道的等效噪声方差 % 递归公式方差减半或翻倍取决于极化变换 z zeros(1, N); z(1) 2 / sigma^2; % 初始LLR方差 for lev 1:log2(N) step 2^(lev-1); for i 1:step % 极化核的方差更新规则 z_new_1 2 * z(i); % 差信道 z_new_2 z(i) / 2; % 好信道 z(i) z_new_1; z(istep) z_new_2; end end % 按等效噪声方差升序排序选前K个作为信息位 [~, sorted_idx] sort(z, ascend); info_idx sort(sorted_idx(1:K)); end这段代码的逻辑是初始 LLR 方差由信噪比决定然后每一层极化变换把当前信道的“好坏”分裂成两个差的那支方差翻倍好的那支方差减半。递归 log2(N) 层后得到 N 个子信道的可靠性排序。参数 N 必须是 2 的幂K 是信息位数量snr_db 是设计信噪比——这个值会影响信息位选择通常取仿真目标 BER 对应的信噪比附近。注意如果 snr_db 设得太高选出来的信息位在低信噪比下可能表现很差这是极化码的经典坑。2.2 编码矩阵构造与码字生成极化码的生成矩阵是 Kronecker 积的递归结构G_N G_2^{⊗n}其中 G_2 [1 0; 1 1]。MATLAB 里可以用 kron 函数直接构造但要注意维度顺序。下面是一个完整的编码函数function codeword polar_encode(msg, info_idx, N) % msg: 信息比特向量长度 K % info_idx: 信息位索引长度 K % N: 码长 K length(msg); u zeros(1, N); u(info_idx) msg; % 把信息比特放到信息位上其余为冻结位0 % 构造生成矩阵 G_N F^{⊗n}, F [1 0; 1 1] F [1 0; 1 1]; n log2(N); G 1; for i 1:n G kron(G, F); end % 编码x u * G mod 2 codeword mod(u * G, 2); end这里的关键点是kron 的顺序决定了生成矩阵的结构必须从 F 开始逐层 Kronecker 积。u 向量里信息位放 msg冻结位放 0——这是最基础的冻结方式实际系统中冻结位可以放已知序列。编码结果是 u * G mod 2得到长度为 N 的码字。参数 N 和 info_idx 必须匹配info_idx 的长度等于 K。如果 K 和 info_idx 长度不一致MATLAB 会直接报维度错误这是新手最容易翻车的地方。2.3 用 pdecode 做 SC 译码的调用方式pdecode 这个函数名一看就是 polar decode 的缩写大概率是 SCSuccessive Cancellation译码器。SC 译码的核心是逐位判决从第 1 位开始利用已判决的比特和接收到的 LLR 计算当前位的 LLR然后硬判决。下面是一个典型的 SC 译码实现function decoded pdecode(llr, info_idx, N) % llr: 接收到的对数似然比长度 N % info_idx: 信息位索引 % N: 码长 n log2(N); % 递归计算每个比特的LLR u_hat zeros(1, N); % 初始化LLR数组 L llr; for i 1:N % 计算第i位的LLR基于已判决的u_hat L_i compute_llr(L, u_hat, i, N); if ismember(i, info_idx) u_hat(i) L_i 0; % 硬判决LLR0判为1 else u_hat(i) 0; % 冻结位直接判0 end end decoded u_hat(info_idx); end function L_i compute_llr(L, u_hat, idx, N) % 简化版实际SC译码需要递归f/g函数 % 这里用近似直接取对应位置的LLR L_i L(idx); end这段代码是简化版实际 SC 译码需要实现 f 函数和 g 函数的递归计算。f 函数处理两个 LLR 的合并f(a,b) 2*atanh(tanh(a/2)*tanh(b/2))在数值上常用 min-sum 近似f(a,b) ≈ sign(a)*sign(b)*min(|a|,|b|)。g 函数利用已判决比特g(a,b,u) b (1-2u)*a。参数 llr 是接收端的软信息info_idx 决定哪些位是信息位。注意pdecode 的输入 LLR 符号约定要和编码端一致否则译码结果全是错的——这个坑我踩过不止一次。3. 避坑与排查极化码 MATLAB 仿真里最容易翻车的 4 个点3.1 信息位索引和码长不匹配导致维度报错现象运行 polar_encode 时报“矩阵维度不一致”或者“索引超出范围”。原因通常是 info_idx 里的最大值超过了 N或者 K 和 info_idx 长度不一致。解决在函数入口加断言检查 max(info_idx) N 且 length(info_idx) K。另外注意 MATLAB 索引从 1 开始如果从其他语言移植代码很容易把 0 索引带进来。3.2 LLR 符号约定反了导致 BER 恒为 0.5现象译码结果和原始信息完全对不上BER 曲线是一条 0.5 的水平线。原因编码端用 0/1 映射译码端 LLR 的符号定义反了。常见约定是 LLR log(P(0)/P(1))LLR0 判 0LLR0 判 1。如果接收端算的是 log(P(1)/P(0))符号就反了。解决在 pdecode 里统一符号约定或者直接在输入前取负号。3.3 高斯近似的设计信噪比选得太高现象在高信噪比下 BER 很好但低信噪比下比理论值差很多。原因信息位选择时用的 snr_db 太高选出来的“好信道”在低信噪比下并不好。解决设计信噪比取仿真范围的中低段比如目标 BER 在 1e-3 左右时snr_db 取 2~3 dB。或者直接用巴氏参数它对所有信噪比都更稳健。3.4 kron 顺序写反导致生成矩阵错误现象编码后的码字和预期不符译码完全失败。原因kron(G, F) 和 kron(F, G) 结果不同极化码要求从 F 开始逐层右乘。解决确认循环里是 G kron(G, F)而不是 G kron(F, G)。另外注意 F 的定义是 [1 0; 1 1]不是 [1 1; 0 1]这两个矩阵互为转置用错了编码结果完全不同。4. 进阶技巧用蒙特卡洛仿真验证 BER 并对比 SC 与 SCL 译码4.1 蒙特卡洛 BER 仿真的完整脚本跑通编码和译码后下一步是验证 BER 曲线。下面是一个完整的蒙特卡洛仿真脚本对比不同信噪比下的性能function ber simulate_polar(N, K, snr_range, num_trials) % N: 码长, K: 信息位, snr_range: 信噪比范围(dB) % num_trials: 每个信噪比下的仿真次数 ber zeros(size(snr_range)); info_idx get_info_bits(N, K, 2); % 设计信噪比2dB for s 1:length(snr_range) snr snr_range(s); sigma 10^(-snr/20); err 0; for t 1:num_trials msg randi([0 1], 1, K); codeword polar_encode(msg, info_idx, N); % BPSK调制 AWGN tx 1 - 2*codeword; % 0-1, 1--1 rx tx sigma * randn(1, N); llr 2 * rx / sigma^2; % AWGN信道LLR decoded pdecode(llr, info_idx, N); err err sum(decoded ~ msg); end ber(s) err / (num_trials * K); end end参数说明snr_range 一般取 0:0.5:4 dBnum_trials 至少 10000 次才能让 BER1e-3 的统计误差可接受。LLR 计算公式 2*rx/sigma^2 是 AWGN 信道下的标准结果。注意如果 num_trials 太少高信噪比下的 BER 会全是 0曲线断掉这是统计样本不足不是译码器的问题。4.2 SC 与 SCL 译码的差异与选择SC 译码复杂度低O(N log N)但性能一般。SCLSuccessive Cancellation List译码保留 L 条候选路径性能接近最大似然但复杂度乘以 L。MATLAB 里实现 SCL 需要在每步保留 L 个最可能的路径最后选 PMPath Metric最小的。常见做法是 L8 或 L32L 越大性能越好但越慢。如果 PCode.zip 里只有 pdecode那大概率是 SC要 SCL 得自己扩展。我一般先用 SC 验证链路正确再上 SCL 看性能提升。SCL 的坑在于路径管理的内存开销N1024、L32 时中间变量会占不少内存MATLAB 里要注意预分配。4.3 用 CRC 辅助 SCL 提升短码性能短码场景下N256 或更小纯 SCL 的性能还不够看加 CRC 校验能显著提升。做法是在信息位里预留几位放 CRC译码时用 CRC 从 L 条路径里筛出唯一合法的。CA-SCLCRC-Aided SCL是 5G 标准里极化码的标配方案。MATLAB 里可以用 crc32 或者自定义多项式。注意 CRC 长度要合适8 位 CRC 对 N256 够用16 位对 N1024 更稳。CRC 太长会挤占信息位太短则筛不干净。4.4 我踩过的最大坑LLR 数值溢出最后说一个血泪经验SC 译码里 f 函数用 atanh(tanh(x)) 直接算在高信噪比下 tanh 饱和到 1atanh 直接返回 Inf整个译码器就废了。解决用 min-sum 近似替代或者对 LLR 做限幅比如限制在 [-20, 20] 范围内。这个坑在低信噪比下不会暴露一到高信噪比就翻车而且报错信息不明确排查起来很费时间。我现在的习惯是任何 LLR 计算后都加一句 L max(min(L, 20), -20)后悔药先吃上。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑