1.算法仿真效果
matlab2022a仿真結果如下:

2.算法涉及理論知識概要
LDPC碼是麻省理工學院Robert Gallager于1963年在博士論文中提出的一種具有稀疏校驗矩陣的分組糾錯碼。幾乎適用于所有的信道,因此成為編碼界近年來的研究熱點。它的性能逼近香農極限,且描述和實現(xiàn)簡單,易于進行理論分析和研究,譯碼簡單且可實行并行操作,適合硬件實現(xiàn)。
LDPC仿真系統(tǒng)圖LDPC 碼的奇偶校驗矩陣H是一個稀疏矩陣,相對于行與列的長度,校驗矩陣每行、列中非零元素的數(shù)目(我們習慣稱作行重、列重)非常小,這也是LDPC碼之所以稱為低密度碼的原因。由于校驗矩陣H的稀疏性以及構造時所使用的不同規(guī)則,使得不同LDPC碼的編碼二分圖(Taner圖)具有不同的閉合環(huán)路分布。而二分圖中閉合環(huán)路是影響LDPC碼性能的重要因素,它使得LDPC碼在類似可信度傳播(Belief ProPagation)算法的一類迭代譯碼算法下,表現(xiàn)出完全不同的譯碼性能。
當H的行重和列重保持不變或盡可能的保持均勻時,我們稱這樣的LDPC碼為正則LDPC碼,反之如果列、行重變化差異較大時,稱為非正則的LDPC碼。研究結果表明正確設計的非正則LDPC碼的性能要優(yōu)于正則LDPC。根據(jù)校驗矩陣H中的元素是屬于GF(2)還是GF(q)(q=2p),我們還可以將LDPC碼分為二元域或多元域的LDPC碼。研究表明多元域LDPC碼的性能要比二元域的好。
在LDPC編碼中,會用到一個叫做H矩陣的校驗矩陣(Parity Check Matrix),比如,我們來看一個簡單的H矩陣:

LDPC譯碼分為硬判決譯碼和軟判決譯碼。
硬判決譯碼又稱代數(shù)譯碼,主要代表是比特翻轉(BF)譯碼算法,它的實現(xiàn)比較簡單,但是譯碼性能很差。硬判決譯碼的基本假設是當校驗方程不成立時,說明此時必定有比特位發(fā)生了錯誤,而所有可能發(fā)生錯誤的比特中不滿足檢驗方程個數(shù)最多的比特發(fā)生錯誤的概率最大。在每次迭代時翻轉發(fā)生錯誤概率最大的比特并用更新之后的碼字重新進行譯碼。
軟判決譯碼是一種基于概率論的譯碼算法,通常需要與迭代譯碼進行結合,才能體現(xiàn)成譯碼性能的優(yōu)勢,基本算法是置信傳播(BP)譯碼算法,它的實現(xiàn)比代數(shù)譯碼方法的復雜度高很多,但譯碼性能非常好。
為了解決BP譯碼算法實現(xiàn)困難問題,在學術界牽起了優(yōu)化算法的浪潮,對數(shù)域置信傳播譯碼(LLR BP)算法、最小和(Min-Sum)譯碼算法、Normalized Min-Sum譯碼算法、Offset Min-Sum譯碼算法等相繼涌現(xiàn)。
在迭代譯碼的過程中,信息調度方式分為兩種:泛濫式調度和分層式調度。泛濫式調度的特點在于每一次譯碼迭代過程中,首先計算從變量節(jié)點到校驗節(jié)點的所有軟信息,然后計算從校驗節(jié)點到變量節(jié)點的所有軟信息。分層調度的特點是在計算每層軟信息時,更新此次迭代中的相關的節(jié)點信息,用于下一層的軟信息計算。
最小和譯碼(MS,Min-Sum)算法是以LLR BP算法譯碼為基礎,對校驗節(jié)點信息更新的表達式進行的簡化,其余步驟均與LLR BP譯碼算法一致。
比較LLR BP譯碼算法和Min-Sum譯碼算法的校驗節(jié)點信息更新過程,可以看到他們的主要區(qū)別在于LLR BP譯碼算法中的tanh(.)運算和加法運算在Min-Sum譯碼算法中被最小值和運算符號進行替換,MS譯碼簡化了LLR BP譯碼算法,降低了譯碼算法的復雜度。
bp:
BP 譯碼算法的核心思想在于利用從信道中接收到的信息在變量節(jié)點和校驗節(jié)點之間進行迭代運算,從而獲得最大的編碼增益。在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 譯碼算法中包含兩個交替執(zhí)行的部分,與LDPC 碼的校驗矩陣H 中非零元素H mn 相關的數(shù)值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];
%%
%開始循環(huán),進行誤碼率仿真
for i=1:length(EsN0)
i
Bit_err(i) ???= 0; %設置誤碼率參數(shù)
Num_err ??????= 0; %蒙特卡洛模擬次數(shù)
Numbers ??????= 0; %誤碼率累加器
%信道參數(shù)
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)); ??????????%產生需要發(fā)送的隨機數(shù)
[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