Reputation: 544
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
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