2

I need to transform a parity-check matrix H (that only consists of ones and zeros) from a non-standard to a standard form, this is, express it as:

                                    Hsys = [A | I]

H and Hsys share the same dimension: (n-k,n). I above corresponds to an identity matrix of dimension (n-k).

Gauss-Jordan elimination comes in handy to solve this problem. Matlab has an specific command, rref, for this purpose, however it is no longer valid while working over GF(2) as in our case. Glancing through the Internet I found in Github a potentially suitable solution to overcome this drawback. However it does not always work out.

I also tried doing HH = mod(rref(H),2), which did not work at all, as many of the output elements weren't binary.

Here below you may find three samples of non-standard parity check matrices in which Gauss-Jordan elimination (over GF(2)) can be applied. As there should always be a way to arrange any matrix to be systematic, I would need a method that works out with matrices of any dimension.

These first sample is taken from sid's post in Stackoverflow, not responded yet:

H=[1 0 1 1 0; 
   0 0 1 0 1; 
   1 0 0 1 0; 
   1 0 1 1 1];

H=[1 1 0 1 1 0 0 1 0 0;
   0 1 1 0 1 1 1 0 0 0;
   0 0 0 1 0 0 0 1 1 1;
   1 1 0 0 0 1 1 0 1 0;
   0 0 1 0 0 1 0 1 0 1];

The last one is a matrix of dimension (50x100) and can be found in this link to my Dropbox.

Edit on 21/06/2017

The solution proposed by @Jonas worked out in some cases, but not in most of them, as H matrix seems to be singular. Any other similar way to do this?

Thank you in advance, and best regards.

Community
  • 1
  • 1
ailoher
  • 67
  • 1
  • 13

2 Answers2

1

Here is how I'd do it (using Gauss-Jordan elimination):

H=[1 1 0 1 1 0 0 1 0 0;
   0 1 1 0 1 1 1 0 0 0;
   0 0 0 1 0 0 0 1 1 1;
   1 1 0 0 0 1 1 0 1 0;
   0 0 1 0 0 1 0 1 0 1];


rows = size(H, 1);
cols = size(H, 2);

r = 1;
for c = cols - rows + 1:cols
    if H(r,c) == 0
        % Swap needed
        for r2 = r + 1:rows
            if H(r2,c) ~= 0
                tmp = H(r, :);
                H(r, :) = H(r2, :);
                H(r2, :) = tmp;
            end
        end

        % Ups...
        if H(r,c) == 0
            error('H is singular');
        end
    end

    % Forward substitute
    for r2 = r + 1:rows
        if H(r2, c) == 1
            H(r2, :) = xor(H(r2, :), H(r, :));
        end
    end

    % Back Substitution
    for r2 = 1:r - 1
        if H(r2, c) == 1
            H(r2, :) = xor(H(r2, :), H(r, :));
        end
    end

    % Next row
    r = r + 1;
end

Let me know if this doesn't solve your issue.

Jonas
  • 6,915
  • 8
  • 35
  • 53
  • Hello @Jonas, Your method seems nice, but in most of the cases the output is a singular matrix, and therefore I am not able to continue. Wouldn't be any feasible way to check whether the matrix is singular and repeat the process in that case? You can't calculate the determinant as it is not a square matrix in most of the cases, and although I have seen people recommending using 'rcond(A)' and 'cond(A)', the results are pretty much the same either when matrix is singular or when it is not... – ailoher Jun 17 '17 at 07:57
  • And the longer the matrix is, the less likely is this method to work out... – ailoher Jun 23 '17 at 12:10
  • @MisterTellini this is a simplified version, adding such a thing as column swap could make it even more potent. But it all depends on your desired code structure and original code structure. At the end of the day it might be better to design your code with the desired structure to begin with. – Jonas Jun 23 '17 at 19:40
  • However there is still something I don't understand @Jonas . Coming from a rectangular matrix whose ´gfrank´ equals its number of rows, your method cannot still work out, as it says that matrix is singular... – ailoher Jul 05 '17 at 09:29
1

I went through the same issue and @jonas code also produced mostly singular matrix error. you can try the following code which I found to be helpful when searching for the systematic form of H. Its also include the calculation of G.

% Gauss-Jordan elimination 
swaps=zeros(m,2);
swaps_count=1;

n=size(H, 2);
m=size(H, 1);

j=1;
index=1;
while index<=m
    i=index;
    while (HH(i,j)==0)&(i<m)
        i=i+1;
    end
    if HH(i,j)==1
        temp=HH(i,:);
        HH(i,:)=HH(index,:);
        HH(index,:)=temp;
        for i=1:m
            if (index~=i)&(HH(i,j)==1)
                HH(i,:)=mod(HH(i,:)+HH(index,:),2);
            end
        end
        swaps(swaps_count,:)=[index j];
        swaps_count=swaps_count+1;
        index=index+1;
        j=index;
    else
        j=j+1;
    end
end

for i=1:swaps_count-1
    temp=HH(:,swaps(i,1));
    HH(:,swaps(i,1))=HH(:,swaps(i,2));
    HH(:,swaps(i,2))=temp;
end

G=[(HH(:,m+1:n))' eye(n-m)];

for i=swaps_count-1:-1:1
    temp=G(:,swaps(i,1));
    G(:,swaps(i,1))=G(:,swaps(i,2));
    G(:,swaps(i,2))=temp;
end

disp(sum(sum((mod(H*G',2)))));
DaniDaone
  • 11
  • 1
  • +1 and welcome to StackExchange! However, your code does not work. For example, you're trying to use `m` before even assigning it. Also at the end, you use `H` which was never defined. Perhaps you meant `HH`. Same for the `H` in the assignments of `m` and `n`. It would probably help if you gave a sample input and output! I ran your script for `HH = [0 1 0 0 ; 1 0 1 1; 1 0 1 0 ; 1 1 1 1]` and got `error: HH(_,5): but HH has size 4x4`. – Nike May 30 '22 at 20:18