注1: 如果校验矩阵H满秩,请参考:根据H在有限域GF(2^m)上求解生成矩阵G
**注2:**如果校验矩阵H不满秩,即存在冗余行。在这种情况下,编码时可以采用H的零空间上的一组基来编码,在译码时可以使用所有行做校验。
冗余行直观上构造了高列重的LDPC码,它们和编码时用到的一组基底是线性相关的,因此这些冗余行可作为校验节点参与译码。在保证校验位数不增加的前提下,给出更多零和约束来抵抗噪声干扰,从而获得译码增益。
除此之外,冗余行会增大译码时延。这是因为在译码时,复杂度高的是校验节点的计算,因此冗余行的数量是影响译码时延的重要因素。
Matlab实现:根据非满秩校验矩阵H在GF(2^m)上求解生成矩阵G
其中,查找表的生成请参考: 根据H在有限域GF(2^m)上求解生成矩阵G
Matlab
function [H_fixed,G_system,H_rank,Px,Py]=H2G(H,q,LUT_dec2exp_GFq,LUT_exp2dec_GFq)
%% initial
[m,n]=size(H);
H_stair=H;
Py = eye(n);
Px = eye(m);
H_rank=0;
column_permutation=0;
%% Row Permutations and Row Gaussian Elimination in GF(q)
for i=1:m
if H_stair(i,i)==0
% Row Permutations
for j=i+1:m
if H_stair(j,i)~=0
break;
else
if j==m
% Column Permutations
for k=i+1:n
if H_stair(i,k)~=0
break;
else
if k==n
H_rank=i-1;
end
end
end
if H_rank~=0
break;
else
column_permutation=1;
H_stair(:,[j,k]) = H_stair(:,[k,j]);
Py(:,[j,k]) = Py(:,[k,j]);
i=j;
end
end
end
end
if H_rank~=0
break;
end
if i ~= j
H_stair([j, i],:) = H_stair([i, j],:);
Px([j, i],:) = Px([i, j],:);
end
end
% Row Normalization
inverse_in_GFq = inverse(H_stair(i,i),q,LUT_dec2exp_GFq,LUT_exp2dec_GFq);
for j=1:n
if H_stair(i, j)~=0
H_stair(i, j) = multiplication(H_stair(i, j),inverse_in_GFq,q,LUT_dec2exp_GFq,LUT_exp2dec_GFq);
end
end
for j=1:m
if Px(i, j)~=0
Px(i, j) = multiplication(Px(i, j),inverse_in_GFq,q,LUT_dec2exp_GFq,LUT_exp2dec_GFq);
end
end
% Row Elimination
for j=1:m
if j~=i && H_stair(j,i)~=0
factor=H_stair(j,i);
for k=1:n
temp=multiplication(H_stair(i, k),factor,q,LUT_dec2exp_GFq,LUT_exp2dec_GFq);
H_stair(j, k) = XOR(H_stair(j, k),temp,q);
end
for k=1:m
temp=multiplication(Px(i, k),factor,q,LUT_dec2exp_GFq,LUT_exp2dec_GFq);
Px(j, k)=XOR(Px(j, k),temp,q);
end
end
end
end
if column_permutation==1
disp("The H is permutated by column.");
end
parity_matrix = H_stair(1:H_rank,H_rank+1:n);
G_system=[parity_matrix',eye(n-H_rank)];
% G=G_fixed*Py';
H_fixed=H*Py;
%% subfunctions
function [inverse_in_GFq] = inverse(x,q,LUT_dec2exp_GFq,LUT_exp2dec_GFq)
if x==0
error("The zero element has no inverse element in GF(q).");
else
exponent=LUT_dec2exp_GFq(x+1);
inverse_exponent=mod(q-1-exponent,q-1);
inverse_in_GFq=LUT_exp2dec_GFq(inverse_exponent+2);
end
end
function [product_in_GFq] = multiplication(x,y,q,LUT_dec2exp_GFq,LUT_exp2dec_GFq)
if x==0 || y==0
product_in_GFq=0;
else
exponent_x=LUT_dec2exp_GFq(x+1);
exponent_y=LUT_dec2exp_GFq(y+1);
product_exponent=mod(exponent_x+exponent_y,q-1);
product_in_GFq=LUT_exp2dec_GFq(product_exponent+2);
end
end
function [XOR_in_GFq] = XOR(x,y,q)
vector_x=dec2vec(x,log2(q));
vector_y=dec2vec(y,log2(q));
vector_sum=mod(vector_x+vector_y,2);
XOR_in_GFq=vec2dec(vector_sum,log2(q));
end
function [binaryVec]=dec2vec(x,m)
binaryStr = dec2bin(x, m);
binaryStrReversed = binaryStr(end:-1:1);
binaryVec = binaryStrReversed - '0';
end
function [decimalVec]=vec2dec(x,m)
decimalVec=0;
for jj =1:m
decimalVec=decimalVec+x(jj)*2^(jj-1);
end
end
end