Matlab确实包含一个名为dvbs2ldpc
的函数,用于构建在DVB-S2标准的LDPC编码阶段使用的奇偶校验矩阵。
此标准使用两种不同的传输模式(SHORT和NORMAL)计数,具体取决于生成的代码字的大小。但是dvbs2ldpc
函数仅适用于NORMAL 1。因此,我试图建立一个在SHORT传输模式下使用的函数。
您可以在函数dvbs2ldpcShort.m
中找到以下所有相关代码,其中我将构建用于SHORT传输模式的奇偶校验矩阵,以及LDPC.m
,其中我执行一些BER模拟以检查结果
您可能会看到dvbs2ldpcShort
与dvbs2ldpc
相似,后者出现在Matlab Communication Toolbox中。我所包含的两个唯一区别是改变了码字的长度和它可能对应的奇偶校验矩阵的累加器位(please see annexes B and C from this link以获取更多信息)。
dvbs2ldpcShort.m
function H = dvbs2ldpcShort(R)
if R = 1/2
Rreal = 4/9; % Actual rate (as k = 7200 and N = 16200)
end
lenCodeWord = 16200; % Length of codeword for DVB-S.2
NB = 360; % Node indices parameter for DVB-S.2.
numInfoBits = lenCodeWord * Rreal;
numParityBits = lenCodeWord - numInfoBits;
[ct1, ct2] = getchecknodetable(R);
ck1 = nodeindices(ct1, numParityBits, NB);
ck2 = nodeindices(ct2, numParityBits, NB);
d = [size(ck1,2) size(ck1,1) size(ck2,2) size(ck2,1) numParityBits-1 2 1 1];
r = [ck1(:); ck2(:); 0; reshape(ones(2,1)*(1:numParityBits-1),[],1)];
S = zeros(length(r),1);
numGroup = length(d)/2;
n = 0;
ncol = 1;
for i = 1:numGroup
p = d(2*i-1)*d(2*i);
S(n+1:n+p) = reshape(ones(d(2*i),1)*(ncol:ncol+d(2*i-1)-1),p,1);
ncol = ncol + d(2*i-1);
n = n + p;
end
% Parity-check matrix (sparse) for DVB-S.2
outputFormat = 'sparse'; % Sparse matrix by default
if nargin == 2
if ~strcmp(varargin{1}, 'sparse') && ~strcmp(varargin{1}, 'indices')
error(message('comm:dvbs2ldpc:InvalidOutputFormat'));
end
outputFormat = varargin{1};
end
if strcmp(outputFormat, 'sparse')
H = logical(sparse(double(r+1), S, 1));
else
H = [double(r+1), double(S)];
end
%--------------------------------------------------------------------------
function ck = nodeindices(ct, M, NB)
% ct: check node table (single group)
% M: number of parity bits
% NB: block size
[N, D] = size(ct);
q = (M/NB);
b = (1:NB);
bq = (b-1).'*q;
ck = zeros(D, NB*N);
for r=1:N
ck(:, NB*(r-1)+1:NB*r) = mod(addcr(bq, ct(r,:)), M)';
end
%--------------------------------------------------------------------------
function A = addcr(c, r)
M = length(c);
N = length(r);
A = zeros(M, N);
for m = 1:M
A(m, :) = r + c(m);
end
%--------------------------------------------------------------------------
function [ct1, ct2] = getchecknodetable(R)
switch R
case 1/2 % There are all cases, but here I only include the R=1/2 one
ct1 = [20 712 2386 6354 4061 1062 5045 5158
21 2543 5748 4822 2348 3089 6328 5876
22 926 5701 269 3693 2438 3190 3507
23 2802 4520 3577 5324 1091 4667 4449
24 5140 2003 1263 4742 6497 1185 6202];
ct2 = [0 4046 6934
1 2855 66
2 6694 212
3 3439 1158
4 3850 4422
5 5924 290
6 1467 4049
7 7820 2242
8 4606 3080
9 4633 7877
10 3884 6868
11 8935 4996
12 3028 764
13 5988 1057
14 7411 3450];
end
LDPC.m
r = 1/2;
k = 7200;
ldpcEnc = comm.LDPCEncoder(dvbs2ldpcShort(r));
psk4Mod = comm.PSKModulator(4, 'BitInput',true);
EsNo = 0.2 : 0.1 : 1.2;
BER = zeros(size(EsNo));
for k = 1 : 1 : length(EsNo)
awgnChan = comm.AWGNChannel(...
'NoiseMethod','Signal to noise ratio (Es/No)','EsNo',EsNo(k));
psk4Demod = comm.PSKDemodulator(4, 'BitOutput',true,...
'DecisionMethod','Approximate log-likelihood ratio', ...
'Variance', 1/(2*10^(awgnChan.EsNo/10)));
ldpcDec = comm.LDPCDecoder(dvbs2ldpcShort(r));
ber = comm.ErrorRate;
for counter = 1:100
data = logical(randi([0 1], k, 1));
encodedData = ldpcEnc(data);
modSignal = psk4Mod(encodedData);
receivedSignal = awgnChan(modSignal);
demodSignal = psk4Demod(receivedSignal);
receivedBits = ldpcDec(demodSignal);
errorStats = ber(data, receivedBits);
end
BER(k) = errorStats(1);
end
The corresponding BER curve does not resemble at all to how it is for NORMAL transmission mode(这些代表了BER作为SNR的函数。我的是EbNo的函数,但差别不应该太大)。相反,结果似乎出乎意料地好。你能看到我的代码有什么问题吗?
我的代码可能有什么问题?
非常感谢,祝你周末愉快!
答案 0 :(得分:0)
感谢有关LDPC代码标识符和有效LDPC速率的注释。
您的示例性能应该更好,因为您使用了更多的冗余:5/9(0.56)的代码字,而在MATLAB示例中,他们使用(1 / 2/3)= 1/3(0.33)的代码字作为冗余。
我还要添加一条注释:在ETSI标准中,它们还使用参数“ q”,它等于“ q =(M / NB);” (M-奇偶校验位数,NB = 360),当n_ldpc = 64800时,但如果n_ldpc = 16200,则应根据ETSI标准中的表使用“ q”。
让我们看看我的解决方案:dvbs2ldpc_custom