├── ldpcencode.m ├── LICENSE ├── Parity_Matrix_Gen.m ├── QCLDPC_PCM_Gen.m ├── MinimumSum.m ├── README.md ├── SumProduct.m ├── LDPC_Main_Program.m └── MALT.m /ldpcencode.m: -------------------------------------------------------------------------------- 1 | %- Coded By, 2 | %Ganeshaanand (Rishi) Balasubramanian 3 | %MASc. Electrical and Computer Engineering 4 | %Dalhousie University 5 | %2018 - 2022 6 | 7 | %------------------------------%----------------------------------%-----------------------------------% 8 | %------------------------------Linear Encoder for LDPC-----------------------% 9 | 10 | 11 | function p=ldpcencode(H,msg) 12 | [m, n] = size(H); 13 | % Find the 'gap' length 14 | 15 | g = m - find(H(:,end),1, 'first'); 16 | % Extracting the submatrices A, B, C, D, E and T 17 | A = H(1:m-g,1:n-m); 18 | B = H(1:m-g,n-m+1:n-m+g); 19 | T = H(1:m-g,n-m+g+1:end); 20 | C = H(m-g+1:end,1:n-m); 21 | D = H(m-g+1:end,n-m+1:n-m+g); 22 | E = H(m-g+1:end,n-m+g+1:end); 23 | 24 | invT = inv(T); 25 | invD = inv(D); 26 | 27 | %From Cu + Dp1 + 0p2 = 0 28 | p1 = mod((-invD * C * msg'), 2); 29 | %p1 = mod((C*msg'), 2); 30 | %From Au + Bp1 + Tp2 = 0 31 | p2 = mod(-invT * (A * (msg') + B * (p1)),2)'; 32 | 33 | p = [p1' p2]; -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Ganeshaanand Balasubramanian 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Parity_Matrix_Gen.m: -------------------------------------------------------------------------------- 1 | %- Coded By, 2 | %Ganeshaanand (Rishi) Balasubramanian 3 | %MASc. Electrical and Computer Engineering 4 | %Dalhousie University 5 | %2018 - 2022 6 | 7 | %------------------------------%----------------------------------%-----------------------------------% 8 | %------------------------------QC LDPC Specific Type Parity Matrix Generator-----------------------% 9 | %This function generates a particular type of LDPC matrix without short 10 | %cycles. 11 | function Ha = Parity_Matrix_Gen(cpm) 12 | 13 | I0 = zeros(cpm, cpm); 14 | I1 = eye(cpm); 15 | 16 | %I0 = circshift(I1, -0); 17 | I22 = circshift(I1, -22); 18 | I28 = circshift(I1, -28); 19 | I2 = circshift(I1, -2); 20 | I16 = circshift(I1, -16); 21 | I19 = circshift(I1, -19); 22 | I30 = circshift(I1, -30); 23 | I4 = circshift(I1, -4); 24 | %I0 = circshift(I1, -0); 25 | I19 = circshift(I1, -19); 26 | I11 = circshift(I1, -11); 27 | I10 = circshift(I1, -10); 28 | I26 = circshift(I1, -26); 29 | I6 = circshift(I1, -6); 30 | I18 = circshift(I1, -18); 31 | 32 | 33 | Ha = [I0 I22 I28 I2 I16 34 | I19 I30 I4 I0 I19 35 | I11 I10 I26 I6 I18 ]; 36 | 37 | 38 | 39 | end -------------------------------------------------------------------------------- /QCLDPC_PCM_Gen.m: -------------------------------------------------------------------------------- 1 | %- Coded By, 2 | %Ganeshaanand (Rishi) Balasubramanian 3 | %MASc. Electrical and Computer Engineering 4 | %Dalhousie University 5 | %2018 - 2022 6 | 7 | %------------------------------%----------------------------------%-----------------------------------% 8 | %------------------------------QC LDPC Parity Matrix Generator-----------------------% 9 | 10 | %{ 11 | The Matrix will be created in this form 12 | 1 a a2 ... ak−1 13 | b ab a2b ... ak−1b 14 | ... ... ... ... ... 15 | bj−1 abj−1 a2bj−1 ... ak−1bj−1 16 | %} 17 | 18 | function [Base, Mat] = QCLDPC_PCM_Gen(j, k, a, b, p) 19 | 20 | Ha = zeros(j, k); 21 | 22 | %Set initial values 23 | Ha(1, 1) = 1; 24 | Ha(1, 2) = a; 25 | Ha(2, 1) = b; 26 | 27 | %Fill up row wise 28 | for ii = 2:size(Ha, 2) 29 | Ha(1, ii) = a ^ (ii-1); 30 | 31 | if (Ha(1, ii) > p) 32 | Ha(1, ii) = rem(Ha(1, ii), p); 33 | else 34 | continue 35 | end 36 | 37 | ii = ii+1; 38 | end 39 | 40 | %Fill up column wise 41 | for jj = 2:size(Ha, 1) 42 | Ha(jj, 1) = b ^ (jj-1); 43 | 44 | if (Ha(jj, 1) > p) 45 | Ha(jj, 1) = rem(Ha(jj, 1), p); 46 | else 47 | continue 48 | end 49 | 50 | jj = jj+1; 51 | end 52 | 53 | %Final Creation 54 | for m = 2 : size(Ha, 1) 55 | for n = 2 : size(Ha, 2) 56 | 57 | Ha(m, n) = Ha(1, n) * Ha(m, 1); 58 | 59 | if (Ha(m, n) > p) 60 | Ha(m, n) = rem(Ha(m, n), p); 61 | else 62 | continue 63 | end 64 | n = n+1; 65 | end 66 | m = m+1; 67 | end 68 | 69 | Base = Ha; 70 | HaC = cell(size(Ha)); 71 | Ha(1, 1) = 0; % Not 1 72 | Data = eye(p); 73 | for k = 1:numel(HaC) 74 | HaC{k} = circshift(Data, -Ha(k), 1); 75 | end 76 | Mat = cell2mat(HaC); 77 | 78 | end -------------------------------------------------------------------------------- /MinimumSum.m: -------------------------------------------------------------------------------- 1 | %- Coded By, 2 | %Ganeshaanand (Rishi) Balasubramanian 3 | %MASc. Electrical and Computer Engineering 4 | %Dalhousie University 5 | %2018 - 2022 6 | 7 | %------------------------------%----------------------------------%-----------------------------------% 8 | %------------------------------MIN SUM DECODER-----------------------% 9 | function vHat = MinimumSum(rx, H, iteration) 10 | 11 | [M, N] = size(H); 12 | 13 | % Prior log-likelihood (simplified). 14 | Lci = -rx; 15 | 16 | % Initialization 17 | Lrji = zeros(M, N); 18 | Pibetaij = zeros(M, N); 19 | 20 | % Asscociate the L(ci) matrix with non-zero elements of H 21 | Lqij = H.*repmat(Lci, M, 1); 22 | 23 | for n = 1:iteration 24 | %fprintf('Iteration : %d\n', n); 25 | 26 | % Get the sign and magnitude of L(qij) 27 | alphaij = sign(Lqij); 28 | betaij = abs(Lqij); 29 | 30 | % ----- Horizontal step ----- 31 | for i = 1:M 32 | 33 | % Find non-zeros in the column 34 | c1 = find(H(i, :)); 35 | 36 | % Get the minimum of betaij 37 | for k = 1:length(c1) 38 | 39 | % Minimum of betaij\c1(k) 40 | minOfbetaij = realmax; 41 | for l = 1:length(c1) 42 | if l ~= k 43 | if betaij(i, c1(l)) < minOfbetaij 44 | minOfbetaij = betaij(i, c1(l)); 45 | end 46 | end 47 | end % for l 48 | 49 | % Multiplication alphaij\c1(k) (use '*' since alphaij are -1/1s) 50 | prodOfalphaij = prod(alphaij(i, c1))*alphaij(i, c1(k)); 51 | 52 | % Update L(rji) 53 | Lrji(i, c1(k)) = prodOfalphaij*minOfbetaij; 54 | 55 | end % for k 56 | 57 | end % for i 58 | 59 | % ------ Vertical step ------ 60 | for j = 1:N 61 | 62 | % Find non-zero in the row 63 | r1 = find(H(:, j)); 64 | 65 | for k = 1:length(r1) 66 | 67 | % Update L(qij) by summation of L(rij)\r1(k) 68 | Lqij(r1(k), j) = Lci(j) + sum(Lrji(r1, j)) - Lrji(r1(k), j); 69 | 70 | end % for k 71 | 72 | % Get L(Qij) 73 | LQi = Lci(j) + sum(Lrji(r1, j)); 74 | 75 | % Decode L(Qi) 76 | if LQi < 0 77 | vHat(j) = 1; 78 | else 79 | vHat(j) = 0; 80 | end 81 | 82 | end % for j 83 | 84 | %If arrived at proper codeword then break 85 | cs = mod(vHat*H',2); 86 | if sum(cs)== 0 87 | break; 88 | end 89 | end % for n 90 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Low Density Parity Check (LDPC) Codes MATLAB-Simulation 2 | 3 | LDPC MATLAB simulation using BPSK + AWGN modulation decoded using Sum Product and Min Sum Algorithm. 4 | 5 | ## Overview 6 | 7 | This repository contains the MATLAB simulation for Low Density Parity Check (LDPC) codes using Binary Phase Shift Keying (BPSK) modulation and Additive White Gaussian Noise (AWGN) channel, decoded using Sum Product Algorithm (SPA) and Min Sum Algorithm (MSA). 8 | 9 | ## Description 10 | 11 | This simulation is part of my Master's Thesis in Electrical and Computer Engineering. The thesis is currently available on [this link](http://hdl.handle.net/10222/81991) from September 2023. Check out the full thesis manuscript. 12 | 13 | ## Simulation 14 | 15 | The MATLAB simulation involves the following steps: 16 | 17 | 1. Creation of Quasi Cyclic LDPC codes using input parameters `j`, `k`, `m`, `a`, and `b`. 18 | 2. Application of MALT form rearrangement function on the generated matrices, which displays graphs of the original and rearranged matrices. 19 | 3. SNR values are specified from 0 to 5 dB, and the number of iterations is set as `N2` with the PCM as [N1, N2]. 20 | 4. For each iteration of SNR and frame, the message bit is encoded, BPSK modulated, passed through AWGN, and then decoded using SPA and MSA decoders in parallel. The Bit Error Rate (BER) for each iteration is accumulated. 21 | 5. Once the loop is complete, the BER for SPA and MSA are plotted against the SNR values in dB. 22 | 23 | ## Performance and Results 24 | 25 | The simulation achieves a BER in the range of 10^-6. The software was tested on a Windows 10 Intel Dual Core i5 - 7200 of 2.5GHz, and simulations were run on all available cores simultaneously using Parallel Pool. LDPC codes of lengths in the range of 100s showed faster preprocessing and overall simulation. However, codes of higher lengths took longer processing times. For instance, codes above a length of 1000s required anywhere from 4 to 8 hours to complete. During the thesis period, the simulation was also run on an Intel Xeon E3 with 3.5GHz, resulting in significantly reduced processing time, from 6 hours to approximately 30 minutes in total. 26 | 27 | The simulation results are displayed in the repository. 28 | 29 | Feel free to explore the MATLAB code and run the simulation using the provided main program for a detailed understanding of LDPC codes and their performance characteristics. 30 | 31 | Please check back on the link provided above for the full thesis manuscript, which will contain a comprehensive discussion of the LDPC simulation and its implications. 32 | 33 | For any inquiries or feedback, you can contact me at [rbga@dal.ca]. 34 | 35 | 36 | ![image](https://user-images.githubusercontent.com/75168756/213565856-6253a0c5-ee36-4f54-ab84-b02fa6483674.png) 37 | -------------------------------------------------------------------------------- /SumProduct.m: -------------------------------------------------------------------------------- 1 | %- Coded By, 2 | %Ganeshaanand (Rishi) Balasubramanian 3 | %MASc. Electrical and Computer Engineering 4 | %Dalhousie University 5 | %2018 - 2022 6 | 7 | %------------------------------%----------------------------------%-----------------------------------% 8 | %------------------------------SUM PRODUCT-----------------------% 9 | function vHat = SumProduct(rx, H, N0, iteration) 10 | 11 | [M, N] = size(H); 12 | 13 | % Prior log-likelihood. 2y/sigma^2 where sigma = sqrt(N0/2) 14 | Lci = (-4*rx/N0); 15 | 16 | % Initialization 17 | Lrji = zeros(M, N); 18 | Pibetaij = zeros(M, N); 19 | 20 | % Asscociate the L(ci) matrix with non-zero elements of H 21 | Lqij = H.*repmat(Lci, M, 1); 22 | 23 | % Get non-zero elements 24 | [r, c] = find(H); 25 | 26 | % Iteration 27 | for n = 1:iteration 28 | 29 | % fprintf('Iteration : %d\n', n); 30 | 31 | % Get the sign and magnitude of L(qij) 32 | alphaij = sign(Lqij); 33 | betaij = abs(Lqij); 34 | 35 | for l = 1:length(r) 36 | Pibetaij(r(l), c(l)) = log((exp(betaij(r(l), c(l))) + 1)/... 37 | (exp(betaij(r(l), c(l))) - 1)); 38 | end 39 | 40 | % ----- Horizontal step ----- 41 | for i = 1:M 42 | 43 | % Find non-zeros in the column 44 | c1 = find(H(i, :)); 45 | 46 | % Get the summation of Pi(betaij)) 47 | for k = 1:length(c1) 48 | 49 | sumOfPibetaij = 0; 50 | prodOfalphaij = 1; 51 | 52 | % Summation of Pi(betaij)\c1(k) 53 | sumOfPibetaij = sum(Pibetaij(i, c1)) - Pibetaij(i, c1(k)); 54 | 55 | % Avoid division by zero/very small number, get Pi(sum(Pi(betaij))) 56 | if sumOfPibetaij < 1e-20 57 | sumOfPibetaij = 1e-10; 58 | end 59 | PiSumOfPibetaij = log((exp(sumOfPibetaij) + 1)/(exp(sumOfPibetaij) - 1)); 60 | 61 | % Multiplication of alphaij\c1(k) (use '*' since alphaij are -1/1s) 62 | prodOfalphaij = prod(alphaij(i, c1))*alphaij(i, c1(k)); 63 | 64 | % Update L(rji) 65 | Lrji(i, c1(k)) = prodOfalphaij*PiSumOfPibetaij; 66 | 67 | end % for k 68 | 69 | end % for i 70 | 71 | % ------ Vertical step ------ 72 | for j = 1:N 73 | 74 | % Find non-zero in the row 75 | r1 = find(H(:, j)); 76 | 77 | for k = 1:length(r1) 78 | 79 | % Update L(qij) by summation of L(rij)\r1(k) 80 | Lqij(r1(k), j) = Lci(j) + sum(Lrji(r1, j)) - Lrji(r1(k), j); 81 | 82 | end % for k 83 | 84 | % Get L(Qi) 85 | LQi = Lci(j) + sum(Lrji(r1, j)); 86 | 87 | % Decode L(Qi) 88 | if LQi < 0 89 | vHat(j) = 1; 90 | else 91 | vHat(j) = 0; 92 | end 93 | 94 | end % for j 95 | 96 | %If arrived at proper codeword then end 97 | cs = mod(vHat*H',2); 98 | if sum(cs)== 0 99 | break; 100 | end 101 | 102 | if vHat==0 103 | rx(rx>=0)=0; 104 | rx(rx<0)=1; 105 | vHat = rx; 106 | end 107 | 108 | end % for n 109 | -------------------------------------------------------------------------------- /LDPC_Main_Program.m: -------------------------------------------------------------------------------- 1 | %Low Density Parity Check Codes (LDPC) MATLAB Simulation 2 | %Binary Phase Shift Keying (BPSK) and Additive White Gaussian Noise Modulation 3 | %(AWGN) 4 | %Encoded by Modified Approximate Lower Triangular (MALT) Pre Processing 5 | %Decoded by Sum Product (SPA) and Minimum Sum (MSA) Algorithms 6 | %- Coded By, 7 | %Ganeshaanand (Rishi) Balasubramanian 8 | %MASc. Electrical and Computer Engineering 9 | %Dalhousie University 10 | %2018 - 2022 11 | 12 | %------------------------------%----------------------------------%-----------------------------------% 13 | %------------------------------MAIN PROGRAM-----------------------% 14 | 15 | clear; clc; 16 | 17 | %Fixes CPM matrix size affecting Parity Matrix Size 18 | %Circular_Permutation_Matrix_Size = 31; 19 | 20 | %Create the LDPC Parity Check Matrix 21 | %Ha = Parity_Matrix_Gen(Circular_Permutation_Matrix_Size); 22 | 23 | %-------The above are used to create specific design PCMs. For generalised, 24 | %uncomment the below and commment the above. 25 | 26 | [matro, Ha] = QCLDPC_PCM_Gen(3, 5, 2, 5, 31); 27 | 28 | %Rearrange PCM to MALT form for Encoding 29 | H = MALT(Ha); 30 | 31 | figure; 32 | 33 | %View of Pre Processed Parity matrix 34 | imagesc(H); 35 | 36 | %Get its size 37 | [N1, N2] = size(H); 38 | 39 | % Setting SNR decibel values for the Sim. You can run it for any values. 40 | EbN0 = 1:1:5; 41 | 42 | %Noise Variance Calculation 43 | N0 = (10.^(EbN0/10)); 44 | 45 | nlen = length(EbN0); 46 | 47 | % Size without parity bits per codeword 48 | k = N2-N1; 49 | 50 | %Total iterations 51 | iter = 10; 52 | 53 | %LDPC Code Rate 54 | rate = k/N2; 55 | 56 | %Create containers to store BER values, one for each decoder. 57 | berate1 = zeros(1, length(EbN0)); 58 | berate2 = zeros(1, length(EbN0)); 59 | 60 | %Parallel Programming Starts 61 | %Main Loop Begins, For every value of SNR 62 | parfor i = 1:length(EbN0) 63 | 64 | %BER per SNR and total bits being transmitted 65 | ber1 = 0; ber2 = 0; nbits=0; 66 | 67 | %For each SNR, loop until 500 errors are accumulated. Change as needed. 68 | while(ber1 < 50) 69 | 70 | %Random data insertion 71 | y = randi([0 1], 1, k); 72 | 73 | %Linear Encoding Parity Bits Generation 74 | e = ldpcencode(H, y); 75 | 76 | %Joining Info and parity to make an encoded code 77 | msg = [y e]; 78 | 79 | %Now BPSK 80 | bpsk = 2 * msg - 1; 81 | 82 | %Now AWGN 83 | tx = bpsk + sqrt(1 / (2 * rate * N0(i))) * randn(1, length(bpsk)); 84 | 85 | %Bits are transmitted, accumulate count 86 | nbits = nbits + k; 87 | 88 | %Decode using SUM PRODCT 89 | vhat1 = SumProduct(tx, H, rate*N0(i), iter); 90 | ber1 = ber1 + sum(y ~= vhat1(1:k)); 91 | 92 | %Decode using MIN SUM 93 | vhat2 = MinimumSum(tx, H, iter); 94 | ber2 = ber2 + sum(y ~= vhat2(1:k)); 95 | 96 | %Live BER Gen, use if needed, just gives an indicator that it runs 97 | fprintf("\n Errors - %d,%d , Bits - %d, BER - %d, %d", ber1,ber2, nbits, ber1/nbits,ber2/nbits); 98 | end 99 | 100 | %Flush and combine values ready to plot 101 | berate1(i) = ber1/nbits; 102 | berate2(i) = ber2/nbits; 103 | 104 | end 105 | 106 | %Plot 107 | semilogy(EbN0, berate1, 'o--', EbN0, berate2, 'o-'); 108 | grid on; 109 | hold off; 110 | 111 | -------------------------------------------------------------------------------- /MALT.m: -------------------------------------------------------------------------------- 1 | %- Coded By, 2 | %Ganeshaanand (Rishi) Balasubramanian 3 | %MASc. Electrical and Computer Engineering 4 | %Dalhousie University 5 | %2018 - 2022 6 | 7 | %------------------------------%----------------------------------%-----------------------------------% 8 | %------------------------------Modified Approximate Lower Triangular (MALT)-----------------------% 9 | 10 | 11 | function ALTF = MALT(H) 12 | AT = ALT(H); %Makes lower tri 13 | imagesc(AT); 14 | ATE = gjetest(AT); %clears bits below lower tri 15 | imagesc(ATE); 16 | A = uD(ATE); %Clears zero rows 17 | imagesc(ATE); 18 | ALTF = A; %Final 19 | imagesc(ATE); 20 | 21 | function AT = ALT(H) 22 | [m, n] = size(H); 23 | 24 | count = sum(H); 25 | count(count==0) = nan; 26 | [~, mincol] = min(count) ; %Find first column with least # of 1s 27 | 28 | temp = H(:,mincol); 29 | H(:,mincol) = []; 30 | H = [H(:, 1:end) temp]; %Move column to end of matrix 31 | 32 | pero = find(H(:,n)==1); 33 | tero = H(pero,:); %move rows with 1s in column to end of matrix. 34 | H(pero,:)=[]; 35 | H = [H(1:end, :); tero]; 36 | 37 | Tc = find(H(:, n), 1, 'first'); %current position of diagonal. 38 | T = Tc-1; %updated diagonal position 39 | p = n-1; %next column 40 | %Begin loop 41 | while T>=1 42 | 43 | count = sum(H(1:T, 1:p)); 44 | count(count==0) = nan; 45 | [~, mincol] = min(count) ; %choose next column with least number if 1s 46 | temp = H(:, mincol); 47 | H(:, mincol) = []; 48 | H = [H(:, 1:p-1) temp H(:, p:end)]; %move column to index p 49 | 50 | [r, ~] = size(find(H(1:T,p)==1)); %number of ones in column p 51 | d = H(T,p); %is 1 present in current diagonal 52 | 53 | switch true 54 | case d==1 && r==1 %if 1 is in current diagonal and number of ones is 1 55 | disp("Noice"); 56 | 57 | case d==1 && r>1 %if 1 is in current diagonal and number of ones is more than 1 58 | col = p; 59 | rowsOnly = 1:T-1; 60 | pa = find(H(1:T-1, col)==1); 61 | ta = H(pa,:); 62 | H(pa,:)=[]; 63 | H=[H(1:end,:); ta]; 64 | 65 | case d==0 && r==1 %if 1 is not in current diagonal and number of ones is 1 66 | col = p; 67 | rowsOnly = 1:T; 68 | pc = find(H(1:T,col)==1); 69 | idxRows = ismember(1:size(H, 1), rowsOnly)'; 70 | idx0 = H(:, col) < 1 & idxRows; 71 | idx1 = H(:, col) > 0 & idxRows; 72 | H = [H(idx0, :); H(idx1, :); H(~idxRows, :); ]; 73 | 74 | case d==0 && r>1 %if 1 is not in current diagonal and number of ones is more than 1 75 | col = p; 76 | ro = find(H(:, col), 1, 'first'); 77 | te = H(ro,:); 78 | H(ro,:)=[]; 79 | H = [H(1:T-1,:); te; H(T:end,:);]; 80 | 81 | col = p; 82 | rowsOnly = 1:T; 83 | pp = find(H(1:T-1, col)==1); 84 | tt = H(pp,:); 85 | H(pp,:)=[]; 86 | H=[H(1:end,:); tt]; 87 | 88 | end 89 | %imagesc(H) 90 | T = find(H(:, p), 1, 'first'); 91 | T = T-1; %updated diagonal position 92 | p = p-1; 93 | end 94 | 95 | AT = H; 96 | end 97 | 98 | function ATE = gjetest(A) 99 | Hi = A; 100 | 101 | [m, n] = size(Hi); 102 | g = m - (find(Hi(:, n), 1, 'first')); %Find gap of Matrix 103 | 104 | dr = m-g+1; %First row of D matrix 105 | dc1 = n-m+1; 106 | rm = m-g; %Row marker 107 | row = m-g; 108 | col = n-m+g+1; 109 | 110 | for a = 1:m-g 111 | 112 | rta = rm + find(Hi(dr:end, n)==1); 113 | 114 | for i = 1:length(rta) 115 | Hi(rta(i), :) = xor(Hi(rta(i), :), Hi(row, :)); %Add all subsequent rows with current row 116 | end 117 | %imagesc(Hi); 118 | row = row-1; %next row 119 | n = n-1; 120 | 121 | end 122 | 123 | ATE = Hi; 124 | end 125 | 126 | function B = uD(H) 127 | [m, n] = size(H); 128 | g = m - (find(H(:, n), 1, 'first')); %Find gap of PCM 129 | Mat = H(1:end, 1:n-m+g); 130 | 131 | dr = m-g+1; %First row of D matrix 132 | dc = n-m+1; %First col of D matrix 133 | zeron = 0; 134 | 135 | for j = dr : m 136 | chk = find(Mat(dr, dc)); 137 | 138 | if (chk == 1) 139 | disp("G"); %Subsequent rows only 140 | 141 | else 142 | colo = find(Mat(dr, 1:end), 1, 'first'); 143 | if (length(colo)>0) 144 | col = Mat(:, colo); %Extract that col 145 | Mat(:, colo) = Mat(:,dc); %Empty that col in Matrix 146 | Mat(:,dc)=col; %Move that column to required position 147 | 148 | else 149 | Mat(dr, :) = []; 150 | zeron = zeron+1; 151 | m=m-1; 152 | continue; 153 | end 154 | 155 | end 156 | 157 | mark = find(Mat(1:end, dc) == 1); %Find all rows with 1 at same column 158 | mark(mark<=dr)=[]; 159 | 160 | for i = 1:length(mark) 161 | Mat(mark(i), :) = xor(Mat(mark(i), :), Mat(dr, :)); %Add all subsequent rows with current row 162 | end 163 | 164 | dr=dr+1; 165 | dc=dc+1; 166 | 167 | 168 | end 169 | 170 | rtm = Mat(:, end-zeron+1 : end); %Identify the redundant columns after Upper Triangular D matrix 171 | Mat(:, end-zeron+1 : end) = []; 172 | Mat = [Mat(:, 1:end-g+zeron) rtm Mat(:, end-g+zeron+1:end)]; %Move Columns 173 | 174 | C=Mat; 175 | [m,n] = size(C); 176 | 177 | B = [C H(1:m, n+1:end)]; 178 | 179 | end 180 | 181 | 182 | end 183 | --------------------------------------------------------------------------------