通过matlab对比规则LDPC和非规则LDPC的误码率

333 阅读3分钟

1.算法描述

       LDPC码是麻省理工学院Robert Gallager于1963年在博士论文中提出的一种具有稀疏校验矩阵的分组纠错码。几乎适用于所有的信道,因此成为编码界近年来的研究热点。它的性能逼近香农极限,且描述和实现简单,易于进行理论分析和研究,译码简单且可实行并行操作,适合硬件实现。

 

       LDPC 码可以通过校验矩阵 H 来唯一确定,校验矩阵 H 是大小为m*n 的稀疏矩阵,其中m 为校验位长度,n 为 LDPC 码码长,信息位长度为 k =n-m 。LDPC 码可以分为规则 LDPC 码和非规则 LDPC 码两种[3]。规则 LDPC 码的校验矩阵中不仅每一行中非零元素的个数是相同的,而且每一列中非零元素的个数也是相同的,而非规则LDPC码则不受到该条件的限制。下图给出的是一种规则LDPC码的校验矩阵。

 

 除了使用校验矩阵的方式来表示 LDPC 码之外,Tanner 在 1981 年提出的用 Tanner图来描述码字的方法可以形象的表示 LDPC 码的特性[4]。下图中表示的 Tanner 图与上图中的校验矩阵相对应。

 

1.png

 

 Tanner 图显示了 LDPC 码中校验节点和变量节点之间的连接关系。图中的校验节点对应校验矩阵 H 的行,变量节点对应校验矩阵 H 的列。与节点相连的边的数目被称为节点的度,从一个节点开始出发后又回到该节点时所经过的边的数目称之为循环长度,最短的循环长度被称为图的围长。

 

QC-LDPC码:

 

QC-LDPC码的校验矩阵是由全零阵,单位矩阵和循环右移的单位阵的子矩阵构成的。

 

QC-LDPC码校验矩阵的子矩阵具有如下特点:

 

(1) 每个子矩阵是一个方阵;

 

(2) 循环子矩阵的任一行(列)都是上一行(列)向右移动一位得到的,特别的,矩阵的第一行(列)由最后一行(列)循环右移一位得到;

 

(3) 循环矩阵完全可以由其第一行或者第一列决定。

 

根据这样的形式可以写出他的基矩阵,用来表示所构造的校验矩阵。

 

       如果校验矩阵中各行非零元素的个数相同,各列中非零元素的个数也相同,这样的LDPC码称为规则码,与规则码对照,如果校验矩阵的各行中非零元素的个数不同或各列中非零元素个数不同,此时的LDPC码称为非规则的LDPC码。

 

2.仿真效果预览

matlab2022a仿真结果如下:

 

2.png

 

3.MATLAB核心程序 `Times    = 500;%仿真模拟次数,值越大,效果越好,仿真时间越长

R        = 0.5;%设置码率为1/2;

N        = 192;%设置奇偶校验矩阵大小     

M        = N*R;

EbN0     = [0 1 2 3 4 5 6];     %设置Eb/N0;

Max_iter = 100;                 %最大迭代次数

 

H  = func_Hgen(M,N);%产生奇偶校验矩阵

 

figure;

imshow(H,[]);title('奇偶校验均值H直观图');

for i=1:length(EbN0)

    

    

    Bit_err(i)    = 0; %设置误码率参数

    Num_err       = 0; %蒙特卡洛模拟次数

    Numbers       = 0; %误码率累加器

    iter_moy_temp = [];%叠加寄存器

    

    while Num_err <= Times    

        fprintf('Eb/N0 = %f\n', EbN0(i));

        Num_err

        Trans_data       = round(rand(N-M,1));           %产生需要发送的随机数

        [ldpc_code,newH] = func_Enc(Trans_data,H);       %LDPC编码

        u                = [ldpc_code;Trans_data];       %LDPC编码

        Trans_BPSK       = 2*u-1;                        %BPSK

      

        %通过高斯信道

        N0                   = 2*10^(-EbN0(i)/10);

        Rec_BPSK             = Trans_BPSK+sqrt(N0/2)*randn(size(Trans_BPSK));

        %LDPC译码

        [vhat,nb_iter]       = func_Dec(Rec_BPSK,newH,N0,Max_iter);

        iter_moy_temp(end+1) = nb_iter;

        

        [nberr,rat]=biterr(vhat',u);

        Num_err=Num_err+nberr;

        Numbers=Numbers+1;

    end

    Bit_err(i)  = Num_err/(N*Numbers);

end`