gusucode.com > wlan工具箱matlab源码程序 > wlan/wlan/+wlan/+internal/ldpcMatrix.m

    function [H, G] = ldpcMatrix(rate, blockLength)
%LDPCMATRIX Parity-check matrix and generator matrix of WLAN LDPC code
%
%   [H, G] = ldpcMatrix(rate, blockLength) returns the parity-check
%   matrix and the generator matrix of the WLAN LDPC code with the
%   specified coding rate and block length.
%
%   rate must be equal to '1/2', '2/3', '3/4', or '5/6'.
%   blockLength must be equal to 648, 1296, or 1944.
%
%   See also ldpcEncodeCore, ldpcDecodeCore.

%   Copyright 2015-2016 The MathWorks, Inc.

%#codegen

% blockLength should 648, 1296, or 1944
blockSize = blockLength/24; % Possible values for blockSize: 27, 54, 81
switch blockLength
    case 648
        switch rate
            case '1/2'
              % Prototype for rate 1/2 and block length 648
              P = [
                0 -1 -1 -1  0  0 -1 -1  0 -1 -1  0  1  0 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
               22  0 -1 -1 17 -1  0  0 12 -1 -1 -1 -1  0  0 -1 -1 -1 -1 -1 -1 -1 -1 -1
                6 -1  0 -1 10 -1 -1 -1 24 -1  0 -1 -1 -1  0  0 -1 -1 -1 -1 -1 -1 -1 -1
                2 -1 -1  0 20 -1 -1 -1 25  0 -1 -1 -1 -1 -1  0  0 -1 -1 -1 -1 -1 -1 -1
               23 -1 -1 -1  3 -1 -1 -1  0 -1  9 11 -1 -1 -1 -1  0  0 -1 -1 -1 -1 -1 -1
               24 -1 23  1 17 -1  3 -1 10 -1 -1 -1 -1 -1 -1 -1 -1  0  0 -1 -1 -1 -1 -1
               25 -1 -1 -1  8 -1 -1 -1  7 18 -1 -1  0 -1 -1 -1 -1 -1  0  0 -1 -1 -1 -1
               13 24 -1 -1  0 -1  8 -1  6 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1  0  0 -1 -1 -1
                7 20 -1 16 22 10 -1 -1 23 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1  0  0 -1 -1
               11 -1 -1 -1 19 -1 -1 -1 13 -1  3 17 -1 -1 -1 -1 -1 -1 -1 -1 -1  0  0 -1
               25 -1  8 -1 23 18 -1 14  9 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1  0  0
                3 -1 -1 -1 16 -1 -1  2 25  5 -1 -1  1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1  0
              ];
            case '2/3'
              % Prototype for rate 2/3 and block length 648
              P = [
               25 26 14 -1 20 -1  2 -1  4 -1 -1  8 -1 16 -1 18  1  0 -1 -1 -1 -1 -1 -1
               10  9 15 11 -1  0 -1  1 -1 -1 18 -1  8 -1 10 -1 -1  0  0 -1 -1 -1 -1 -1
               16  2 20 26 21 -1  6 -1  1 26 -1  7 -1 -1 -1 -1 -1 -1  0  0 -1 -1 -1 -1
               10 13  5  0 -1  3 -1  7 -1 -1 26 -1 -1 13 -1 16 -1 -1 -1  0  0 -1 -1 -1
               23 14 24 -1 12 -1 19 -1 17 -1 -1 -1 20 -1 21 -1  0 -1 -1 -1  0  0 -1 -1
                6 22  9 20 -1 25 -1 17 -1  8 -1 14 -1 18 -1 -1 -1 -1 -1 -1 -1  0  0 -1
               14 23 21 11 20 -1 24 -1 18 -1 19 -1 -1 -1 -1 22 -1 -1 -1 -1 -1 -1  0  0
               17 11 11 20 -1 21 -1 26 -1  3 -1 -1 18 -1 26 -1  1 -1 -1 -1 -1 -1 -1  0
              ];
            case '3/4'
              % Prototype for rate 3/4 and block length 648
              P = [
               16 17 22 24  9  3 14 -1  4  2  7 -1 26 -1  2 -1 21 -1  1  0 -1 -1 -1 -1
               25 12 12  3  3 26  6 21 -1 15 22 -1 15 -1  4 -1 -1 16 -1  0  0 -1 -1 -1
               25 18 26 16 22 23  9 -1  0 -1  4 -1  4 -1  8 23 11 -1 -1 -1  0  0 -1 -1
                9  7  0  1 17 -1 -1  7  3 -1  3 23 -1 16 -1 -1 21 -1  0 -1 -1  0  0 -1
               24  5 26  7  1 -1 -1 15 24 15 -1  8 -1 13 -1 13 -1 11 -1 -1 -1 -1  0  0
                2  2 19 14 24  1 15 19 -1 21 -1  2 -1 24 -1  3 -1  2  1 -1 -1 -1 -1  0
              ];
            otherwise % case '5/6'
              % Prototype for rate 5/6 and block length 648
              P = [
               17 13  8 21  9  3 18 12 10  0  4 15 19  2  5 10 26 19 13 13  1  0 -1 -1
                3 12 11 14 11 25  5 18  0  9  2 26 26 10 24  7 14 20  4  2 -1  0  0 -1
               22 16  4  3 10 21 12  5 21 14 19  5 -1  8  5 18 11  5  5 15  0 -1  0  0
                7  7 14 14  4 16 16 24 24 10  1  7 15  6 10 26  8 18 21 14  1 -1 -1  0
              ];
        end   
    case 1296
        switch rate
            case '1/2'
              % Prototype for rate 1/2 and block length 1296
              P = [
               40 -1 -1 -1 22 -1 49 23 43 -1 -1 -1  1  0 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
               50  1 -1 -1 48 35 -1 -1 13 -1 30 -1 -1  0  0 -1 -1 -1 -1 -1 -1 -1 -1 -1
               39 50 -1 -1  4 -1  2 -1 -1 -1 -1 49 -1 -1  0  0 -1 -1 -1 -1 -1 -1 -1 -1
               33 -1 -1 38 37 -1 -1  4  1 -1 -1 -1 -1 -1 -1  0  0 -1 -1 -1 -1 -1 -1 -1
               45 -1 -1 -1  0 22 -1 -1 20 42 -1 -1 -1 -1 -1 -1  0  0 -1 -1 -1 -1 -1 -1
               51 -1 -1 48 35 -1 -1 -1 44 -1 18 -1 -1 -1 -1 -1 -1  0  0 -1 -1 -1 -1 -1
               47 11 -1 -1 -1 17 -1 -1 51 -1 -1 -1  0 -1 -1 -1 -1 -1  0  0 -1 -1 -1 -1
                5 -1 25 -1  6 -1 45 -1 13 40 -1 -1 -1 -1 -1 -1 -1 -1 -1  0  0 -1 -1 -1
               33 -1 -1 34 24 -1 -1 -1 23 -1 -1 46 -1 -1 -1 -1 -1 -1 -1 -1  0  0 -1 -1
                1 -1 27 -1  1 -1 -1 -1 38 -1 44 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1  0  0 -1
               -1 18 -1 -1 23 -1 -1  8  0 35 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1  0  0
               49 -1 17 -1 30 -1 -1 -1 34 -1 -1 19  1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1  0
              ];
            case '2/3'
              % Prototype for rate 2/3 and block length 1296
              P = [
               39 31 22 43 -1 40  4 -1 11 -1 -1 50 -1 -1 -1  6  1  0 -1 -1 -1 -1 -1 -1
               25 52 41  2  6 -1 14 -1 34 -1 -1 -1 24 -1 37 -1 -1  0  0 -1 -1 -1 -1 -1
               43 31 29  0 21 -1 28 -1 -1  2 -1 -1  7 -1 17 -1 -1 -1  0  0 -1 -1 -1 -1
               20 33 48 -1  4 13 -1 26 -1 -1 22 -1 -1 46 42 -1 -1 -1 -1  0  0 -1 -1 -1
               45  7 18 51 12 25 -1 -1 -1 50 -1 -1  5 -1 -1 -1  0 -1 -1 -1  0  0 -1 -1
               35 40 32 16  5 -1 -1 18 -1 -1 43 51 -1 32 -1 -1 -1 -1 -1 -1 -1  0  0 -1
                9 24 13 22 28 -1 -1 37 -1 -1 25 -1 -1 52 -1 13 -1 -1 -1 -1 -1 -1  0  0
               32 22  4 21 16 -1 -1 -1 27 28 -1 38 -1 -1 -1  8  1 -1 -1 -1 -1 -1 -1  0
              ];
            case '3/4'
              % Prototype for rate 3/4 and block length 1296
              P = [
               39 40 51 41  3 29  8 36 -1 14 -1  6 -1 33 -1 11 -1  4  1  0 -1 -1 -1 -1
               48 21 47  9 48 35 51 -1 38 -1 28 -1 34 -1 50 -1 50 -1 -1  0  0 -1 -1 -1
               30 39 28 42 50 39  5 17 -1  6 -1 18 -1 20 -1 15 -1 40 -1 -1  0  0 -1 -1
               29  0  1 43 36 30 47 -1 49 -1 47 -1  3 -1 35 -1 34 -1  0 -1 -1  0  0 -1
                1 32 11 23 10 44 12  7 -1 48 -1  4 -1  9 -1 17 -1 16 -1 -1 -1 -1  0  0
               13  7 15 47 23 16 47 -1 43 -1 29 -1 52 -1  2 -1 53 -1  1 -1 -1 -1 -1  0
              ];
            otherwise % case '5/6'
              % Prototype for rate 5/6 and block length 1296
              P = [
               48 29 37 52  2 16  6 14 53 31 34  5 18 42 53 31 45 -1 46 52  1  0 -1 -1
               17  4 30  7 43 11 24  6 14 21  6 39 17 40 47  7 15 41 19 -1 -1  0  0 -1
                7  2 51 31 46 23 16 11 53 40 10  7 46 53 33 35 -1 25 35 38  0 -1  0  0
               19 48 41  1 10  7 36 47  5 29 52 52 31 10 26  6  3  2 -1 51  1 -1 -1  0
              ];
        end
    otherwise % case 1944
        switch rate
            case '1/2'
              % Prototype for rate 1/2 and block length 1944
              P = [
               57 -1 -1 -1 50 -1 11 -1 50 -1 79 -1  1  0 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
                3 -1 28 -1  0 -1 -1 -1 55  7 -1 -1 -1  0  0 -1 -1 -1 -1 -1 -1 -1 -1 -1
               30 -1 -1 -1 24 37 -1 -1 56 14 -1 -1 -1 -1  0  0 -1 -1 -1 -1 -1 -1 -1 -1
               62 53 -1 -1 53 -1 -1  3 35 -1 -1 -1 -1 -1 -1  0  0 -1 -1 -1 -1 -1 -1 -1
               40 -1 -1 20 66 -1 -1 22 28 -1 -1 -1 -1 -1 -1 -1  0  0 -1 -1 -1 -1 -1 -1
                0 -1 -1 -1  8 -1 42 -1 50 -1 -1  8 -1 -1 -1 -1 -1  0  0 -1 -1 -1 -1 -1
               69 79 79 -1 -1 -1 56 -1 52 -1 -1 -1  0 -1 -1 -1 -1 -1  0  0 -1 -1 -1 -1
               65 -1 -1 -1 38 57 -1 -1 72 -1 27 -1 -1 -1 -1 -1 -1 -1 -1  0  0 -1 -1 -1
               64 -1 -1 -1 14 52 -1 -1 30 -1 -1 32 -1 -1 -1 -1 -1 -1 -1 -1  0  0 -1 -1
               -1 45 -1 70  0 -1 -1 -1 77  9 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1  0  0 -1
                2 56 -1 57 35 -1 -1 -1 -1 -1 12 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1  0  0
               24 -1 61 -1 60 -1 -1 27 51 -1 -1 16  1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1  0
              ];
            case '2/3'
              % Prototype for rate 2/3 and block length 1944
              P = [
               61 75  4 63 56 -1 -1 -1 -1 -1 -1  8 -1  2 17 25  1  0 -1 -1 -1 -1 -1 -1
               56 74 77 20 -1 -1 -1 64 24  4 67 -1  7 -1 -1 -1 -1  0  0 -1 -1 -1 -1 -1
               28 21 68 10  7 14 65 -1 -1 -1 23 -1 -1 -1 75 -1 -1 -1  0  0 -1 -1 -1 -1
               48 38 43 78 76 -1 -1 -1 -1  5 36 -1 15 72 -1 -1 -1 -1 -1  0  0 -1 -1 -1
               40  2 53 25 -1 52 62 -1 20 -1 -1 44 -1 -1 -1 -1  0 -1 -1 -1  0  0 -1 -1
               69 23 64 10 22 -1 21 -1 -1 -1 -1 -1 68 23 29 -1 -1 -1 -1 -1 -1  0  0 -1
               12  0 68 20 55 61 -1 40 -1 -1 -1 52 -1 -1 -1 44 -1 -1 -1 -1 -1 -1  0  0
               58  8 34 64 78 -1 -1 11 78 24 -1 -1 -1 -1 -1 58  1 -1 -1 -1 -1 -1 -1  0
              ];
            case '3/4'
              % Prototype for rate 3/4 and block length 1944
              P = [
               48 29 28 39  9 61 -1 -1 -1 63 45 80 -1 -1 -1 37 32 22  1  0 -1 -1 -1 -1
                4 49 42 48 11 30 -1 -1 -1 49 17 41 37 15 -1 54 -1 -1 -1  0  0 -1 -1 -1
               35 76 78 51 37 35 21 -1 17 64 -1 -1 -1 59  7 -1 -1 32 -1 -1  0  0 -1 -1
                9 65 44  9 54 56 73 34 42 -1 -1 -1 35 -1 -1 -1 46 39  0 -1 -1  0  0 -1
                3 62  7 80 68 26 -1 80 55 -1 36 -1 26 -1  9 -1 72 -1 -1 -1 -1 -1  0  0
               26 75 33 21 69 59  3 38 -1 -1 -1 35 -1 62 36 26 -1 -1  1 -1 -1 -1 -1  0
              ];
            otherwise % case '5/6'
              % Prototype for rate 5/6 and block length 1944
              P = [
               13 48 80 66  4 74  7 30 76 52 37 60 -1 49 73 31 74 73 23 -1  1  0 -1 -1
               69 63 74 56 64 77 57 65  6 16 51 -1 64 -1 68  9 48 62 54 27 -1  0  0 -1
               51 15  0 80 24 25 42 54 44 71 71  9 67 35 -1 58 -1 29 -1 53  0 -1  0  0
               16 29 36 41 44 56 59 37 50 24 -1 65  4 65 52 -1  4 -1 73 52  1 -1 -1  0
              ];
        end
end

% Expand each number in P into a sub-matrix (blockSize by blockSize)
[numRows, numCols] = size(P);
H = zeros([numRows numCols]*blockSize);
for i = 1:numRows
    for j = 1:numCols
        H(((i-1)*blockSize+1):i*blockSize, ((j-1)*blockSize+1):j*blockSize) = ...
            BuildSubBlock(blockSize, P(i,j));
    end
end

if nargout > 1
    % Calculate the generator matrix
    G = par2gen(H);
end

function M = BuildSubBlock(s, shift)
if shift == -1
    M = zeros(s);
else
    M = eye(s);
    if shift > 0
        shift = shift - 1;
        M(:) = M(:,[end-shift:end 1:(end-shift-1)]);
    end
end


function G = par2gen(H)
[parityCheckLen,blockLength] = size(H);
infolen = blockLength - parityCheckLen;
H1 = H(:,1:infolen);
H2 = H(:,(infolen+1):end);

% Do LU factorization on H2
[PL, PB, rowOrder, invertible] = gf2factorize(H2);
if invertible % Should always be invertible for LDPC codes supported in 802.11
    PB = PB(rowOrder, :);
end

pbits = false(parityCheckLen,infolen);

for i = 1:parityCheckLen
    PL(i,i) = 0;
    PB(i,i) = 0;
end

for i = 1:infolen
    r = gf2solve(PL,H1(:,i),1);                 % Matrix multiply
    pbits(:,i) = gf2solve(PB,r(rowOrder),-1);   % Backward substitution
end

G = [eye(infolen) double(pbits')];


function [A, B, chosen_pivots, invertible] = gf2factorize(X)
% Factorize a square matrix in GF(2).

n = size(X,1);

A = logical(eye(n,n));
B = full(X~=0);
chosen_pivots = zeros(n,1); % Haven't chosen any pivots yet.
invertible = true; % Assume that X is invertible in GF(2).

for col = 1:n
  candidate_rows = B(:,col);
  candidate_rows(chosen_pivots(1:(col-1))) = 0; % Never use a chosen pivot.
  candidate_rows_ind = find(candidate_rows); % Convert into row indices.
  
  if isempty(candidate_rows_ind)
    invertible = false; % X is not invertible in GF(2).
    break;
  else
    pivot = candidate_rows_ind(1);  % Choose the first candidate row as the pivot row.
    chosen_pivots(col) = pivot;     % Record this pivot.
    
    % Find all nonzero elements in the pivot row.
    % They will be xor-ed with the corresponding elements in other
    % candidate rows.
    columnind = find(B(pivot,:));
    
    % Subtract the pivot row from all other candidate_rows.
    % Take advantage of the fact that we are working in GF(2).
    % Just use logical NOT.
    % As we continue in this loop, B will become "psychologically"
    % upper triangular.
    for k = 1:length(columnind)
        for j = 2:length(candidate_rows_ind)
            B(candidate_rows_ind(j), columnind(k)) = not(B(candidate_rows_ind(j), columnind(k)));
        end
    end
    
    % Update the lower triangular matrix A.
    for j = 2:length(candidate_rows_ind)
        A(candidate_rows_ind(j), pivot) = 1;
    end
  end
end


function y = gf2solve(A, y, direction)
if direction == 1
    columnindex = 1; % Start from the first column for forward substitution
else
    columnindex = length(y); % Start from the last column for backward substitution
end

columncounter = 1;
while columncounter < length(y)
    if y(columnindex)
        y(:) = xor(y,A(:,columnindex));
    end
    
    columncounter = columncounter + 1;
    columnindex = columnindex + direction;
end

% Following code is used to generate the mat files for the encoder. The G
% matrix is reshaped into group of 16 bits, which is converted into decimal
% and stored as unsigned integer in ldpcMatrices.mat file.

% rate = '1/2';
% blockLength = 648;
% [~,g] = wlan.internal.ldpcMatrix(rate,blockLength);
% sizeG = size(g);
% outg = g(:,sizeG(1)+1:end).';
% ldpcMatrices.PT_1_2_648 = uint16(bi2de(reshape(outg,[],16)));
% 
% rate = '1/2';
% blockLength = 1296;
% [~,g] = wlan.internal.ldpcMatrix(rate,blockLength);
% sizeG = size(g);
% outg = g(:,sizeG(1)+1:end).';
% ldpcMatrices.PT_1_2_1296 = uint16(bi2de(reshape(outg,[],16)));
% 
% rate = '1/2';
% blockLength = 1944;
% [~,g] = wlan.internal.ldpcMatrix(rate,blockLength);
% sizeG = size(g);
% outg = g(:,sizeG(1)+1:end).';
% ldpcMatrices.PT_1_2_1944 = uint16(bi2de(reshape(outg,[],16)));
% 
% rate = '2/3';
% blockLength = 648;
% [~,g] = wlan.internal.ldpcMatrix(rate,blockLength);
% sizeG = size(g);
% outg = g(:,sizeG(1)+1:end).';
% ldpcMatrices.PT_2_3_648 = uint16(bi2de(reshape(outg,[],16)));
% 
% rate = '2/3';
% blockLength = 1296;
% [~,g] = wlan.internal.ldpcMatrix(rate,blockLength);
% sizeG = size(g);
% outg = g(:,sizeG(1)+1:end).';
% ldpcMatrices.PT_2_3_1296 = uint16(bi2de(reshape(outg,[],16)));
% 
% rate = '2/3';
% blockLength = 1944;
% [~,g] = wlan.internal.ldpcMatrix(rate,blockLength);
% sizeG = size(g);
% outg = g(:,sizeG(1)+1:end).';
% ldpcMatrices.PT_2_3_1944 = uint16(bi2de(reshape(outg,[],16)));
% 
% rate = '3/4';
% blockLength = 648;
% [~,g] = wlan.internal.ldpcMatrix(rate,blockLength);
% sizeG = size(g);
% outg = g(:,sizeG(1)+1:end).';
% ldpcMatrices.PT_3_4_648 = uint16(bi2de(reshape(outg,[],12)));
% 
% rate = '3/4';
% blockLength = 1296;
% [~,g] = wlan.internal.ldpcMatrix(rate,blockLength);
% sizeG = size(g);
% outg = g(:,sizeG(1)+1:end).';
% ldpcMatrices.PT_3_4_1296 = uint16(bi2de(reshape(outg,[],16)));
% 
% rate = '3/4';
% blockLength = 1944;
% [~,g] = wlan.internal.ldpcMatrix(rate,blockLength);
% sizeG = size(g);
% outg = g(:,sizeG(1)+1:end).';
% ldpcMatrices.PT_3_4_1944 = uint16(bi2de(reshape(outg,[],12)));
% 
% rate = '5/6';
% blockLength = 648;
% [~,g] = wlan.internal.ldpcMatrix(rate,blockLength);
% sizeG = size(g);
% outg = g(:,sizeG(1)+1:end).';
% ldpcMatrices.PT_5_6_648 = uint16(bi2de(reshape(outg,[],16)));
% 
% rate = '5/6';
% blockLength = 1296;
% [~,g] = wlan.internal.ldpcMatrix(rate,blockLength);
% sizeG = size(g);
% outg = g(:,sizeG(1)+1:end).';
% ldpcMatrices.PT_5_6_1296 = uint16(bi2de(reshape(outg,[],16)));
% 
% rate = '5/6';
% blockLength = 1944;
% [~,g] = wlan.internal.ldpcMatrix(rate,blockLength);
% sizeG = size(g);
% outg = g(:,sizeG(1)+1:end).';
% ldpcMatrices.PT_5_6_1944 = uint16(bi2de(reshape(outg,[],16)));
% 
% save('ldpcMatrices.mat','-struct', 'ldpcMatrices')