往期博文
低密度奇偶校验码LDPC(一)——概述_什么是gallager构造-CSDN博客
低密度奇偶校验码LDPC(二)——LDPC编码方法-CSDN博客
低密度奇偶校验码LDPC(三)——QC-LDPC码概述-CSDN博客
低密度奇偶校验码LDPC(四)——双对角线结构的QC-LDPC编码-CSDN博客
低密度奇偶校验码LDPC(五)——译码算法概述-CSDN博客
低密度奇偶校验码LDPC(六)——SPA和积译码算法-CSDN博客
QC-LDPC的FPGA实现
基于QC-LDPC编码的循环移位网络的FPGA实现_5g ldpc编码 桶形移位寄存器-CSDN博客
一、和积算法基本原理
二、概率域上的和积算法
传递消息定义
概率域的迭代更新公式
三、对数域上的和积算法
预备知识:对数似然比
预备知识:Gallager引理
VN消息初始化
对数域的迭代更新公式![](https://i-blog.csdnimg.cn/blog_migrate/3798a37a0eb38be5234b8c128b4ad0e2.png)
对数域SPA算法总结
四、SPA算法的调度策略
泛洪调度策略![](https://i-blog.csdnimg.cn/blog_migrate/35f69d492d62f7151ce0766eccc0d464.png)
分层调度策略![](https://i-blog.csdnimg.cn/blog_migrate/f4686a6a8c38d2db9bf4503ec864e661.png)
仿真对比![](https://i-blog.csdnimg.cn/blog_migrate/05c9092f20a96a7c4ad91913daa1c4f5.png)
调度策略总结
泛洪SPA译码算法
分层SPA译码算法
五、SPA算法的Matlab实现
泛洪调度(Flooding Schedule Scheme)
function [x_hat, iter_this_time] = Flooding_BP_decoder(llr, H_row_one_absolute_index, H_comlumn_one_relative_index, N, M, vn_degree, cn_degree, max_iter)
VN_array = zeros(max(vn_degree), N);
CN_tanh_tmp = zeros(max(cn_degree), 1);
iter_this_time = max_iter;
for t = 1 : max_iter
%% L(q_ij) Update
sum_VN = sum(VN_array);
for v = 1 : N
for v_neighbor = 1 : vn_degree(v)
VN_array(v_neighbor, v) = sum_VN(v) - VN_array(v_neighbor, v) + llr(v);
end
end
%% L(sigma_ji) Update
for c = 1 : M
product = 1;
for c_neighbor = 1 : cn_degree(c)
CN_tanh_tmp(c_neighbor) = 1 - 2/(1 + exp(VN_array(H_comlumn_one_relative_index(c, c_neighbor), H_row_one_absolute_index(c, c_neighbor))));
product = product * CN_tanh_tmp(c_neighbor);
end
for c_neighbor = 1 : cn_degree(c)
x = product/CN_tanh_tmp(c_neighbor);
x = sign(x) * min(abs(x), 1 - 1e-15);% Numerical Stability.
VN_array(H_comlumn_one_relative_index(c, c_neighbor), H_row_one_absolute_index(c, c_neighbor)) = log((1 + x)/(1 - x));
end
end
%% L(Qi) Update
x_hat = (sum(VN_array)' + llr) < 0;% Belief propagation Decision.
parity_check = zeros(M, 1);
for m = 1 : M
for k = 1 : 1 : cn_degree(m)
parity_check(m) = parity_check(m) + x_hat(H_row_one_absolute_index(m, k));
end
end
if ~sum(mod(parity_check, 2))% early stop, to see whether Hx = 0.
iter_this_time = t;
break;
end
end
分层迭代(Layered Schedule Scheme)
function [x_hat, iter_this_time] = Layered_BP_decoder(llr, H_row_one_absolute_index, H_comlumn_one_relative_index, N, M, vn_degree, cn_degree, max_iter)
VN_array = zeros(max(vn_degree), N);
CN_tanh_tmp = zeros(max(cn_degree), 1);
iter_this_time = max_iter;
for t = 1 : max_iter
for c = 1 : M
product = 1;
for c_neighbor = 1 : cn_degree(c)
Lji = sum(VN_array(:, H_row_one_absolute_index(c, c_neighbor))) + llr(H_row_one_absolute_index(c, c_neighbor)) - VN_array(H_comlumn_one_relative_index(c, c_neighbor), H_row_one_absolute_index(c, c_neighbor));%VN update. However, this simple MATLAB sentence consumes a lot of time.
CN_tanh_tmp(c_neighbor) = 1 - 2/(1 + exp(Lji));
product = product * CN_tanh_tmp(c_neighbor);
end
for c_neighbor = 1 : cn_degree(c)
Lij = product/CN_tanh_tmp(c_neighbor);
Lij = sign(Lij) * min(abs(Lij), 1 - 1e-15);
VN_array(H_comlumn_one_relative_index(c, c_neighbor), H_row_one_absolute_index(c, c_neighbor)) = log((1 + Lij)/(1 - Lij));
end
end
x_hat = (sum(VN_array)' + llr) < 0;
parity_check = zeros(M, 1);
for m = 1 : M
for k = 1 : 1 : cn_degree(m)
parity_check(m) = parity_check(m) + x_hat(H_row_one_absolute_index(m, k));
end
end
if ~sum(mod(parity_check, 2))
iter_this_time = t;
break;
end
end
参考文献
[1] 白宝明 孙韶辉 王加庆. 5G 移动通信中的信道编码[M]. 北京: 电子工业出版社, 2018.
[2] William E. Ryan, Shu Lin. Channel Codes - Classical and Modern[M]. Cambridge University Press, 2009.
[3] Gallager R. Low-density parity-check codes[J]. IRE Transactions on information theory, 1962, 8(1): 21-28.