function xrec=hamdec3(r);
%HAMDEC3 3-ary HAMMING DECODER
%
% XREC=HAMDEC3(R) decodes a sequence of tribits, that is a sequence
% of 0's 1's and 2's, applying a shortened Hamming(12,9) code.
%
% All the operations are made using a GF(3^1) (Galois Field),
% containing 3 symbols or elements (0,1,2).
%
% The length of every received encoded word R is 9+3 (9 tribits for the
% unencoded word plus 3 tribits for the redundancy. The length of XREC
% will be length(R)*9/12.
%
% When there is no input argument R, an internal R sequence is generated and
% its decoding steps are explained through the algorithm execution.
%
% See also HAMCOD3.
% Author: Roberto Sanz Gil 1998/11/25
% Copyright (c) 1998 by Grupo de Ingeniera Telemtica
% Universidad de Cantabria
if nargin==0,
test=1;
elseif nargin==1,
test=0;
end;
if test,
nwords=10;
x=floor(rand(1,9*nwords)*3); % Words of information to encode
r=hamcod3(x); % Received encoded words
end;
% Length of unencoded word
% n=10 (unshortened code) | n=9 (shortened code)
n=9;
%%%%%%%%%%%%%%
%% P MATRIX %%
%%%%%%%%%%%%%%
Pcompleta=[1 1 1 0 1 1 1 0 1 1;...
1 2 0 1 1 2 0 1 1 2;...
0 0 1 1 1 1 2 2 2 2]';
P=Pcompleta(10-n+1:size(Pcompleta,1),:);
% P is sign changed (-0=0, -1=2, -2=1)
Pcompletaneg=rem(2*Pcompleta,3);
Pneg=rem(2*P,3);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% H MATRIX : %%
%% - Unshortened H matrix (3x13): %%
%% %%
%% [1 1 1 0 1 1 1 0 1 1 | 1 0 0] %%
%% H=|1 2 0 1 1 2 0 1 1 2 | 0 1 0| %%
%% [0 0 1 1 1 1 2 2 2 2 | 0 0 1] %%
%% %%
%% When shortening, any column is removed (first column is chosen) %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
H=[P' eye(3)];
Hneg=[Pneg' eye(3)];
Hcompletaneg=[Pcompletaneg' eye(3)];
%%%%%%%%%%%%%%
%% G MATRIX %%
%%%%%%%%%%%%%%
G=[eye(n) P];
%%%%%%%%%%%%%%%%%%
%% ERROR MATRIX %%%%%%%%%
%% (look-up table) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% 3 first columns are syndrome, and next 12 are the error %%
%% vectors linked to every syndrome. %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
error=[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;...
0 0 1 0 0 0 0 0 0 0 0 0 0 0 2;...
0 0 2 0 0 0 0 0 0 0 0 0 0 0 1;...
0 1 0 0 0 0 0 0 0 0 0 0 0 2 0;...
0 1 1 0 0 1 0 0 0 0 0 0 0 0 0;...
0 1 2 0 0 0 0 0 0 1 0 0 0 0 0;...
0 2 0 0 0 0 0 0 0 0 0 0 0 1 0;...
0 2 1 0 0 0 0 0 0 2 0 0 0 0 0;...
0 2 2 0 0 2 0 0 0 0 0 0 0 0 0;...
1 0 0 0 0 0 0 0 0 0 0 0 2 0 0;...
1 0 1 0 1 0 0 0 0 0 0 0 0 0 0;...
1 0 2 0 0 0 0 0 1 0 0 0 0 0 0;...
1 1 0 0 0 0 0 0 0 0 0 0 0 0 0;...
1 1 1 0 0 0 1 0 0 0 0 0 0 0 0;...
1 1 2 0 0 0 0 0 0 0 1 0 0 0 0;...
1 2 0 1 0 0 0 0 0 0 0 0 0 0 0;...
1 2 1 0 0 0 0 1 0 0 0 0 0 0 0;...
1 2 2 0 0 0 0 0 0 0 0 1 0 0 0;...
2 0 0 0 0 0 0 0 0 0 0 0 1 0 0;...
2 0 1 0 0 0 0 0 2 0 0 0 0 0 0;...
2 0 2 0 2 0 0 0 0 0 0 0 0 0 0;...
2 1 0 2 0 0 0 0 0 0 0 0 0 0 0;...
2 1 1 0 0 0 0 0 0 0 0 2 0 0 0;...
2 1 2 0 0 0 0 2 0 0 0 0 0 0 0;...
2 2 0 0 0 0 0 0 0 0 0 0 0 0 0;...
2 2 1 0 0 0 0 0 0 0 2 0 0 0 0;...
2 2 2 0 0 0 2 0 0 0 0 0 0 0 0];
%%%%%%%%%%%%%%%%%%%%%%%%
%% DECODING ALGORITHM %%
%%%%%%%%%%%%%%%%%%%%%%%%
r=r(:)'; % row vector
nwords=ceil(length(r)/(n+3));
xrec=zeros(1,nwords*n);
for k=1:nwords,
ind=(k-1)*(n+3)+1:k*(n+3);
rtmp=r(ind);
ind2=(k-1)*n+1:k*n;
if test,
disp(['Transmitted word: ' int2str(x(ind2))]);
disp(['Encoded word: ' int2str(rtmp)]);
% Simulated error in the 'pos' position with value 'value':
pos=floor(rand(1)*12)+1;
value=floor(rand(1)*2)+1;
r(pos)=rem(r(pos)+value,3);
disp(['Received word: ' int2str(rtmp)]);
end;
% Calculates the syndrome:
s=rem(rtmp*Hneg',3);
% Error matrix index to locate the error asociated to the syndrome:
filaerr=s*[9 3 1]'+1;
e=error(filaerr,4:15);
% Corrects the received word:
xrec(ind2)=rem(rtmp(1:n)+e(1:n),3);
if test,
disp(['Syndrome: ' int2str(s)]);
disp(['Error vector: ' int2str(e)]);
disp(['Corrected word: ' int2str(xrec(ind2))]);
if isempty(find(x(ind2)-xrec(ind2))),
disp('OK');
else
disp('!!!! ERROR !!!!');
end;
disp('--------------------------');
pause;
end;
end;
if test,
disp(['Number of tribits with errors: ' int2str(length(find(x-xrec))) ' de ' int2str(length(x))]);
end;