1.算法仿真效果
matlab2022a仿真结果如下:
2.算法涉及理论知识概要
LDPC码是麻省理工学院Robert Gallager于1963年在博士论文中提出的一种具有稀疏校验矩阵的分组纠错码。几乎适用于所有的信道,因此成为编码界近年来的研究热点。它的性能逼近香农极限,且描述和实现简单,易于进行理论分析和研究,译码简单且可实行并行操作,适合硬件实现。
LDPC仿真系统图LDPC 码的奇偶校验矩阵H是一个稀疏矩阵,相对于行与列的长度,校验矩阵每行、列中非零元素的数目(我们习惯称作行重、列重)非常小,这也是LDPC码之所以称为低密度码的原因。由于校验矩阵H的稀疏性以及构造时所使用的不同规则,使得不同LDPC码的编码二分图(Taner图)具有不同的闭合环路分布。而二分图中闭合环路是影响LDPC码性能的重要因素,它使得LDPC码在类似可信度传播(Belief ProPagation)算法的一类迭代译码算法下,表现出完全不同的译码性能。
当H的行重和列重保持不变或尽可能的保持均匀时,我们称这样的LDPC码为正则LDPC码,反之如果列、行重变化差异较大时,称为非正则的LDPC码。研究结果表明正确设计的非正则LDPC码的性能要优于正则LDPC。根据校验矩阵H中的元素是属于GF(2)还是GF(q)(q=2p),我们还可以将LDPC码分为二元域或多元域的LDPC码。研究表明多元域LDPC码的性能要比二元域的好。
在LDPC编码中,会用到一个叫做H矩阵的校验矩阵(Parity Check Matrix),比如,我们来看一个简单的H矩阵:
LDPC译码分为硬判决译码和软判决译码。
硬判决译码又称代数译码,主要代表是比特翻转(BF)译码算法,它的实现比较简单,但是译码性能很差。硬判决译码的基本假设是当校验方程不成立时,说明此时必定有比特位发生了错误,而所有可能发生错误的比特中不满足检验方程个数最多的比特发生错误的概率最大。在每次迭代时翻转发生错误概率最大的比特并用更新之后的码字重新进行译码。
软判决译码是一种基于概率论的译码算法,通常需要与迭代译码进行结合,才能体现成译码性能的优势,基本算法是置信传播(BP)译码算法,它的实现比代数译码方法的复杂度高很多,但译码性能非常好。
为了解决BP译码算法实现困难问题,在学术界牵起了优化算法的浪潮,对数域置信传播译码(LLR BP)算法、最小和(Min-Sum)译码算法、Normalized Min-Sum译码算法、Offset Min-Sum译码算法等相继涌现。
在迭代译码的过程中,信息调度方式分为两种:泛滥式调度和分层式调度。泛滥式调度的特点在于每一次译码迭代过程中,首先计算从变量节点到校验节点的所有软信息,然后计算从校验节点到变量节点的所有软信息。分层调度的特点是在计算每层软信息时,更新此次迭代中的相关的节点信息,用于下一层的软信息计算。
最小和译码(MS,Min-Sum)算法是以LLR BP算法译码为基础,对校验节点信息更新的表达式进行的简化,其余步骤均与LLR BP译码算法一致。
比较LLR BP译码算法和Min-Sum译码算法的校验节点信息更新过程,可以看到他们的主要区别在于LLR BP译码算法中的tanh(.)运算和加法运算在Min-Sum译码算法中被最小值和运算符号进行替换,MS译码简化了LLR BP译码算法,降低了译码算法的复杂度。
bp:
BP 译码算法的核心思想在于利用从信道中接收到的信息在变量节点和校验节点之间进行迭代运算,从而获得最大的编码增益。在LDPC 码的校验矩阵H 中,将参与校验方程m 的信息位的集合记为M (n )S {n :H mn =1};同样,将信息位n 所参与的校验方程的集合记为N (m )S {m :H mn =1}。M (n )\n 表示在集合M (n )中除去信息位n ,N (m )\m 表示在集合N (m )中除去校验方程m 。B P 译码算法中包含两个交替执行的部分,与LDPC 码的校验矩阵H 中非零元素H mn 相关的数值q x:
ms:
3.MATLAB核心程序
n = 3;
m = 6;
p = 200;
N = m*p;
M = n*p;
EsN0 = 0.25:0.5:1.25;
R = n/m;
k = R*log2(2);
EbN0 = EsN0/k;
Max_iter = 10;
H1 = func_dys(n,m,p);
% H2 = func_dys(n,m,2*p);
NUMS = [400,300,100,100,80,50,20];
%%
%开始循环,进行误码率仿真
for i=1:length(EsN0)
i
Bit_err(i) = 0; %设置误码率参数
Num_err = 0; %蒙特卡洛模拟次数
Numbers = 0; %误码率累加器
%信道参数
Hsd = 1;
Hsr = 1;
Hrd = 1;
while Num_err <= NUMS(i)
fprintf('Eb/N0 = %f\n', EsN0(i));
Num_err
N0 = 2*10^(-EbN0(i)/10);
Trans_data = round(rand(N-M,1)); %产生需要发送的随机数
[ldpc_code,newH] = func_Enc(Trans_data,H1); %LDPC编码
u = [ldpc_code;Trans_data]; %LDPC编码
Trans_BPSK = 2*u-1; %BPSK
%S->D
%S->D
NTrans_BPSK = Hsd*Trans_BPSK+sqrt(N0/2)*randn(size(Trans_BPSK));
%接收端
[vhatsd,nb_itersd,successsd] = func_Dec(NTrans_BPSK,newH,N0,Max_iter);
[nberr,rat] = biterr(vhatsd(M+1:N)',Trans_data);
%LDPC译码
Num_err = Num_err+nberr;
Numbers = Numbers+1;
end
Bit_err(i) = Num_err/(N*Numbers);
end
figure;
semilogy(EsN0,Bit_err,'o-');
xlabel('Es/N0(dB)');
ylabel('BER');
grid on;
save dat.mat EsN0 Bit_err