m2016b
m2016b

Reputation: 544

Reverse process of a matrix expansion on Matlab

My program allows to multiply a given B matrix with a z factor with some characteristics listed below, to give an H matrix. I would like to have a programming idea to do the inverse of what I programmed. That is to say with a given H matrix find the value of the B matrix.

For example with a matrix B = [-1 -1 ; 1 0]

I get with my code a matrix :

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

I would like to have from a code H the value of the matrix B.

To specify the matrix H from the matrix B, it is necessary that:

Each coefficient -1 is replaced by a null matrix of dimension z*z;

Each coefficient 0 is replaced by an identity matrix of dimension z*z;

Each coefficient 1,2,...,z-1 is replaced by a circulating permutation matrix of dimension z*z shifted by 1,2,...,z-1 position to the right.

From a matrix B and the expansion factors z , we construct an extended binary H matrix with n-k rows and n columns.

My code :

clear;
close all;

B = [-1 -1 ; 1 0];
z = 3;

H = zeros(size(B)*z);
Y = eye(z);

for X1 = 1:size(B,1)
    
    for X2 = 1:size(B,2)
        
        X3 = B(X1,X2);
        
        if (X3 > -1)
            X4 = circshift(Y,[0 X3]);
        else
            X4 = zeros(z);
        end
        Y1 = (X1-1)*z+1:X1*z;
        Y2 = (X2-1)*z+1:X2*z;
        H(Y1,Y2) = X4;
    end
end

[M,N] = size(H);

Any suggestions?

Upvotes: 0

Views: 118

Answers (1)

beaker
beaker

Reputation: 16791

Assuming that all of the input matrices are well-formed, you can determine the mapping based on the first row of each block. For example, the block mapping to 1:

0 1 0
0 0 1
1 0 0

has a 1 in column 2 of row 1. Similarly, a one in column 1 maps to 0, and column 3 maps to 2. No ones in the row maps to -1. So we just need to find the column containing the 1 in the first row.

Annoyingly, find returns null when it doesn't find a nonzero value rather than 0 (which is what we would want in this case). We can adjust to this by adding a value to the matrix row that is only 1 when all of the others are 0.

If you have the Image Processing Toolbox, you can use blockproc to handle the looping for you:

B = blockproc(H, [z z], @(A)find([~any(A.data(1,:)) A.data(1,:)])-2);

Otherwise, just loop over the blocks and apply the function to each one.

Upvotes: 2

Related Questions