范围
Matlab 确实包含一个名为 的函数,dvbs2ldpc
用于构造一个奇偶校验矩阵,用于 DVB-S2 标准中的 LDPC 编码阶段。
该标准采用两种不同的传输模式(SHORT 和 NORMAL),具体取决于生成的码字的大小。但是dvbs2ldpc
功能仅适用于 NORMAL 之一。因此,我正在尝试构建一个用于 SHORT 传输模式的函数。
代码说明
您可能会在下面找到函数中的所有相关代码dvbs2ldpcShort.m
,我将在其中为 SHORT 传输模式构建奇偶校验矩阵,以及LDPC.m
在其中执行一些 BER 模拟以检查结果。
您可能会看到与Matlab Communication Toolbox 中出现的dvbs2ldpcShort
非常相似。dvbs2ldpc
我包含的唯一两个区别是更改了代码字的长度和它可能对应的奇偶校验矩阵的累加器位(有关更多信息,请参阅此链接中的附件 B 和 C)。
代码
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
问题
相应的 BER 曲线与 NORMAL 传输模式的曲线完全不同(这些表示 BER 是 SNR 的函数。而我的是 EbNo 的函数,但差异根本不应该很大)。相反,结果似乎出乎意料的好。你能看出我的代码有什么问题吗?
我的代码可能有什么问题?
非常感谢您,祝您周末愉快!