% querry_H.m
% Instruction:
% The H matrix is of size 512 x 1024.
% It has 8 1's in each row and 4 1's in each column.
% This program tells you:
%	(1) the row indexes where the 8 1's locate when you provide a row number.
%	(2) the col indexes where the 4 1's locate when you provide a col number.
%	(3) the pattern of 1's in the H matrix.
%
% Warning: Both row are col are counted from '1' !!
%
% (c) Guoyong Shi, 03/10/05, University of Washington

function querry_H

r = 4; c = 8;		% code (r,c)
N = 128;				% size of the identity matrix
L = N*c;				% block length
C = N*r;				% number of parity checks

S = [2     7    29    36    43    51    79   122;  
     4    14    45    49    53    58    72    86;  
     5     8    28    90    98   106   111   116;  
     10    13    16    23    33    35    56    89];
  
% Create the H matrix

H = zeros(r*N, c*N);
% fill in 1's
for i = 1:r
   for j = 1:c
      H(((i-1)*N+1):(i*N), ((j-1)*N+1):(j*N)) = circ_shift(N, S(i,j));
   end
end

% Create another matrix of the same size of H for blocking
B = zeros(size(H));
B(1,1:L) = 1;			% 1st horizontal line
B(1:C,1) = 1;			% 1st vertical line
for i = 1:r
   B(i*N, 1:L) = 1;	% horizontal lines
end
for j = 1:c
   B(1:C,j*N) = 1;	% vertical lines
end

% messages
row_msg = sprintf('row [1,%d] = ', C);
col_msg = sprintf('col [1,%d] = ', L);

% for row indexes and col indexes
row_index = zeros(1,r);
col_index = zeros(1,c);


while 1
   Ans = input('querry: [R]ow/[C]ol/[P]attern/[Q]uit: ', 's');
   if Ans == 'Q' | Ans == 'q'  break; 
   elseif Ans == 'P' | Ans == 'p'		% display the H matrix pattern
      clf;
      spy(H);  hold on;
      spy(B, 'r');
      title('Pattern of the H matrix');
   elseif Ans == 'R' | Ans == 'r'
      row = input(row_msg);
      while row < 1 | row > C
         fprintf('-- Row number out of range.\n');
         row = input(row_msg);
      end
      % Print the col indexes.      
      r1 = floor((row-1)/N)+1;		% get the block row no.
      k1 = rem(row-1,N)+1;			% row within block
      for i = 1:c
         h = rem(S(r1,i)+k1-1, N) + 1;
         col_index(i) = (i-1)*N + h;
      end
      fprintf('\nColumn indexes for row [%d] are \n', row);
      for i = 1:c
         fprintf('%6d', col_index(i));
      end
      fprintf('\n\n');
   elseif Ans == 'C' | Ans == 'c'
      col = input(col_msg);
      while col < 1 | col > L
         fprintf('-- Column number out of range.\n');
         col = input(col_msg);
      end
      % Print the row indexes.      
      c1 = floor((col-1)/N) + 1;		% get the block col no.
      k1 = rem(col-1,N) + 1;			% col within block
      for i = 1:r
         v = mod(k1-S(i,c1)-1, N) + 1;
         row_index(i) = (i-1)*N + v;
      end
      fprintf('\nRow indexes for col [%d] are \n', col);
      for i = 1:r
         fprintf('%6d', row_index(i));
      end
      fprintf('\n\n');
   end
end


%----------------------------

function X = circ_shift(size, pos)
% shifts right the identity matrix of size <size> to position <pos>.
% Returns the shifted matrix to X.

X = wshift('2D', eye(size), [pos 0]);  % shift along row
