ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

大衍数构造准循环LDPC校验矩阵及其误码率仿真

大衍数构造准循环LDPC校验矩阵及其误码率仿真 做LDPC仿真这几年最让我头疼的不是译码算法本身而是怎么拿到一副“好”的校验矩阵。随机构造固然省事但仿真跑出来性能飘忽不定尤其是中短码长下错误平台高得离谱排查半天往往发现是矩阵里藏了太多短环。最近我在复现一个比较有意思的思路——用大衍数来构造稀疏校验矩阵在Matlab里做了完整的误码率仿真把译码迭代次数、码率、码长三个维度都扫了一遍。这套流程跑通之后我感觉它对理解LDPC的结构化构造和BP译码行为都挺有帮助的写出来给正在做信道编码仿真的朋友参考。1. 为什么用大衍数构造稀疏校验矩阵而不是随机生成1.1 校验矩阵质量决定LDPC性能的上限LDPC码的性能很大程度上在编码阶段就已经注定了。虽然名字叫低密度奇偶校验码但光有“稀疏”远远不够校验矩阵的环长分布、行列重分布、最小距离特性共同决定了迭代译码能逼近最大似然译码到什么程度。随机生成一个稀疏矩阵很简单但要保证没有四环、六环尽可能少就不是碰运气能解决的事了。短环对BP译码的伤害是致命的。在迭代过程中短环会让外信息在环路上循环加强形成正反馈导致译码器过早收敛到错误的码字表现出来就是误码率曲线在某个信噪比之后出现平层。四环尤其严重设计时基本要完全避免。这也是为什么工程上很少直接用纯随机矩阵而是倾向于用结构化构造方法比如基于有限几何、PEG算法、或者准循环扩展。1.2 大衍数怎么和准循环LDPC结合大衍数出自古代数理典籍核心表述是“大衍之数五十其用四十有九”。把它落到LDPC构造上我采用的是这样一个思路把矩阵组织成准循环QC-LDPC形式每个子块是单位矩阵的循环移位版本而循环移位的步长由一个确定性序列来生成这个序列的种子和规则就来自大衍数的数理特征。具体落地时我取了两个关键数字50作为循环移位取模的模数空间49作为实际使用的移位索引数量。结合基矩阵的行列数可以设计出确定性的移位指数矩阵每个指数对应一个Z×Z的子块。这样构造出来的H矩阵既保持了结构化特性编码时可以用移位寄存器高效实现又避免了纯随机矩阵中常见的局部密集区域。当然大衍数构造并不是一个严格标准化的算法更像是一类“数论启发式构造”的统称。我在复现的时候核心价值在于把古代数理序列转化为一种确定性的伪随机分布规则使得矩阵的环分布可控、行列重均匀同时在不同码率、码长档位之间保持构造逻辑的一致性。1.3 这种构造方式在Matlab仿真中的实际优势用Matlab做LDPC误码率仿真H矩阵的获取方式会直接影响你后续的工作量。如果你用MATLAB自带的通信工具箱里头有内置的LDPC校验矩阵但那些矩阵大多是针对特定码率和码长设计的想自定义参数对比时局限性很大。自己手写随机构造又要反复检查行列重和四环。我采用大衍数构造的好处在于参数可扩展性强换一组基矩阵规模就能得到不同码长和码率的矩阵行列重分布均匀避免了随机生成时常见的病态矩阵构造过程确定性高文章图表可复现性强不会出现这次仿真和下次仿真结果对不上的尴尬这一点在做参数扫描研究时特别重要——你需要保证唯一变量是迭代次数、码率或者码长而不是矩阵本身的随机差异。2. Matlab仿真链路搭建与核心算法实现2.1 整体仿真框架设计整个仿真链路按照典型的数字通信系统搭建信源产生二进制比特经过LDPC编码BPSK调制送入AWGN信道接收端计算对数似然比LLR送入BP迭代译码器最后统计误码率和误比特率。代码结构上分成四个模块参数配置、矩阵构造、编码映射、译码统计。我用的是对数域置信传播LLR-BP也叫sum-product译码。这比概率域的belief propagation数值更稳定不需要频繁做乘法归一化实现起来也直观。核心公式就两个变量节点向校验节点传递的信息以及校验节点回传给变量节点的信息。前者是简单的求和后者要用到tanh变换或者其近似形式。2.2 大衍数构造H矩阵的代码思路我自定义了一个函数来生成校验矩阵。输入是基矩阵的行数、列数、扩展因子Z输出是稀疏的校验矩阵H。基矩阵中的每个元素如果是非负整数就代表该位置子块的循环移位次数如果填充的是-1代表全零子块。大衍数序列在这里扮演的角色是移位指数的生成器。我先把50和49作为初始种子通过简单的递推运算法则生成一组0到Z-1范围内的整数分布的均匀性由这个递推式的混合特性保证。实际测试下来这样得到的矩阵行重和列重比较规则而且girth普遍能达到6以上对中短码长来说已经够用了。需要说明的是这个生成规则不是我拍脑袋定的而是参考了数论中模运算扩散的思想保证生成的移位指数之间没有明显的线性相关性从而抑制短环的形成。2.3 LLR-BP译码器实现要点译码器是整个仿真的核心也是Matlab实现时最容易拖慢速度的地方。我一开始用三重for循环遍历所有变量节点和校验节点码长1880的矩阵单次译码慢得离谱跑一个信噪比点要几个小时。后来改成向量化操作把信息传递过程按矩阵运算批量处理速度提升了将近两个数量级。具体做法是预先计算出H矩阵中每个非零元素的行列索引把变量节点信息和校验节点信息存储为与H矩阵非零元数量等长的向量每次更新直接在这个向量上做切片运算。校验节点更新时tanh变换部分采用查表近似避免重复计算。另外我加了一个提前终止条件每次迭代结束后检查是否满足所有校验方程若满足则立即跳出循环这在低信噪比段可能不明显但在高信噪比段能省掉大量无效迭代。2.4 仿真参数配置参考做参数对比研究时参数配置直接影响结果的说服力。我采用的配置如下参数项基准配置扫描范围调制方式BPSK固定信道模型AWGN固定译码算法LLR-BP固定迭代次数10[1, 5, 10, 20, 50]码率0.5[0.5, 0.75, 0.9]码长1024[512, 1024, 2048]仿真信噪比范围0-5 dB按需调整每个信噪比点仿真的错误帧数100帧高信噪比时可降低信噪比定义用的是Eb/N0也就是每比特能量与噪声功率谱密度之比。BPSK调制下和Es/N0差一个码率的对数关系换算公式是Es/N0(dB)Eb/N0(dB)10*log10(码率)。很多初学者在这里容易搞混导致噪声方差设置错误整个误码率曲线偏移好几个dB。3. 三种参数维度下的误码率行为分析3.1 迭代次数从欠迭代到收敛饱和迭代次数对误码率的影响是最直接的。我测试了1、5、10、20、50次迭代在码率0.5、码长1024的配置下结论和理论上预测的一致迭代次数太少译码器还没收敛误码率很差迭代次数增多误码率快速下降但超过一定次数后性能提升微乎其微。具体数据上从1次迭代提升到5次迭代在2dB处误码率下降了接近两个数量级从5次提升到10次又下降了一个数量级左右但10次以上几乎重合。这说明对码长1024、码率0.5的规则码来说10次迭代基本已经达到收敛点。需要注意一个工程权衡迭代次数翻倍仿真时间几乎线性增长。所以实际系统设计时不是迭代越多越好而是找到性能与复杂度之间的平衡点。在仿真脚本里我还统计了平均迭代次数会发现高信噪比下由于提前终止条件的存在实际平均迭代次数远小于设置的上限。3.2 码率变化冗余度与编码增益的博弈码率对比我选了三组0.5、0.75、0.9。固定码长1024时码率0.5对应的信息位长度是512码率0.9对应的信息位长度是921。仿真结果非常直观码率越低误码率曲线越靠左也就是编码增益越高。原因不难理解。码率低意味着校验位占比高冗余度大译码器可利用的约束关系更多纠错能力自然更强。但代价是频谱效率下降同样的带宽内能传输的有效信息变少。在信道条件较差或者功率受限的场景下牺牲频谱效率换取可靠性是值得的而在SNR充足的场景下高码率反而更有价值。做对比时有一点必须小心保证对比的是同一个矩阵构造框架下的不同码率而不是不同算法生成的矩阵。否则误码率曲线的差异可能来自矩阵质量的差别而非码率本身的影响。我就是用同一套大衍数基矩阵扩展规则只调整行列数比例保证变量可控。3.3 码长效应逼近Shannon极限的典型趋势码长对比同样很有说服力。我测试了512、1024、2048三档码字长度码率都固定在0.5。仿真曲线显示码长越长性能越好尤其是在高信噪比区域长码的优势更加明显。这背后是香农极限附近有限码长的性能损耗问题。理论上无限的码长才能达到香农极限实际有限码长必然有性能损失码长越短损失越大。LDPC码之所以在长码段表现优异正是因为它逼近香农极限的能力强。码长512时2dB附近的误码率在10的负四次方量级码长2048时同样的误码率信噪比需求下降了约0.5dB。但长码的代价也很现实。编码复杂度随码长增加译码延迟线性增长仿真时间更是大幅攀升。码长2048的仿真耗时大约是512码长的6倍。在做学术研究时如果目标是展示算法性能极限建议用长码如果目标是验证算法可行性中短码长就足够了。3.4 参数对比的交叉设计与公平性控制做三组对比研究时最容易被质疑的一点是公平性。我的做法是研究迭代次数时码率和码长固定研究码率时迭代次数取10次码长固定研究码长时码率和迭代次数固定。每次只变一个变量其他的参数全部锁定。这样出来的曲线差异才能准确归因于该变量所带来的影响。另外每个信噪比点的仿真帧数不能太少。我最初为了赶时间每个点只跑1000帧高信噪比时一个误码都没有误码率直接显示为0曲线断了一截根本没法分析。后来改成固定最少100个错误帧作为停止条件虽然耗时增加但曲线完整度和置信度都上来了。4. 常见问题与排查技巧实录4.1 高信噪比误码率为零的假象这是最容易踩的坑。误码率仿真到高信噪比区域时偶尔会出现某个信噪比点一个错误都没有误码率算出0来。在log坐标轴上0值直接让曲线断开看起来特别突兀。解决方法是设定最小错误帧数阈值比如100帧。先按当前信噪比仿真累计错误帧数不足100帧就继续跑达到阈值才停下来计算误码率。但如果信噪比实在太高错误事件极其罕见可以适当降低阈值比如只要求10个错误帧确保曲线不至于断掉。4.2 校验矩阵出现病态导致编码失败我在用高斯消元求生成矩阵G时偶尔会遇到消元失败的情况通常是因为H矩阵行之间线性相关或者存在全零行。大衍数构造出来的矩阵虽然比较规则但基矩阵设计不当时仍然可能出现这种情况。一个实用的检测办法对H做高斯消元后看秩是否为m如果秩不够说明矩阵有冗余校验方程。这时需要回溯调整基矩阵的填充方式或者增大扩展因子Z。还有个小技巧先用Matlab自带函数检查H矩阵是否满足行列约束再去做编码能省掉很多调试的时间。4.3 译码器数值溢出问题LLR-BP译码在Matlab中容易出现数值警告尤其是校验节点更新涉及tanh运算时如果LLR输入值很大tanh后直接变成1log域运算出现log(0)导致-inf或NaN传播。这种情况在高信噪比时尤其常见因为可靠信息非常大。我的处理方法是给校验节点更新加一个clip操作把LLR值限制在一个合理的范围内比如±30超出边界的就截断。这样几乎不影响性能但能完全杜绝NaN问题。另外变量节点更新时也要注意如果某个变量节点的LLR一直增长到很大同样需要截断。4.4 仿真速度过慢时从哪些角度优化Matlab跑LDPC仿真确实不快但通过优化能把耗时降低一个数量级。我自己的经验按优先级排序向量化所有循环避免对每个变量节点逐一更新预计算索引矩阵减少在迭代过程中重复查找H矩阵非零元位置的开销用提前终止条件减少高信噪比下的无效迭代把误码率统计中的码字比较用矩阵运算完成不要用for循环逐比特比还有一个容易被忽略的点Matlab的tic/toc计时显示的总耗时包含了矩阵构造和图绘制的时间。如果做大量参数扫描建议把矩阵构造放在循环外只对译码部分计时这样性能分析才准确。4.5 误码率与误信率的关系差异标题提到了误码率但在实际研究中误比特率也很常用。我在仿真脚本里同时统计了BER和误帧率。误码率是错误比特占总传输比特的比例误帧率是错误码字占总传输码字的比例。一个码字只要有一个比特错误就算错帧所以误帧率总是高于误码率。两者的差值可以反映错误在码字内的分布特征。如果你需要画误码率和误信率的大小关系图仿真数据应该同时保存这两个统计量。信噪比很低时错误通常遍布整个码字两者的差距相对较小信噪比较高时错误往往集中在少数几个码字里误帧率和误码率的差距会拉大。5. 后续还可以扩展的方向这套基于大衍数构造的LDPC仿真框架跑通之后可以做的事情还有不少。一个自然的延伸是尝试不同的扩展因子Z观察准循环矩阵的girth变化对误码率平台的影响。另一个方向是换成Min-Sum译码和LLR-BP做性能对比看看近似译码的损失到底有多大。如果对构造方法本身感兴趣还可以把大衍数生成规则替换成黄金分割序列或者混沌序列对比不同确定性序列构造出的矩阵性能差异。我在实际跑仿真的过程中最深的体会是LDPC性能研究矩阵构造和译码实现是两条腿走路。如果只纠结于译码算法怎么改而不去关注校验矩阵的素质很多时候是在一个不太好的底子上做无用功。反过来有了结构良好的矩阵即使译码算法相对简单性能也相当能打。这套代码我现在还在持续迭代后面准备把构造模块和译码模块彻底解耦这样换一种矩阵构造方法时译码部分一行都不用改做对比实验就方便多了。
返回列表