Viterbi算法

function viterbi_dec
% convolution parameters
k = 1; % input length
n = 2; % output length
K = 2; % memory of encode
% generator vector
c1 = [0 1 1];%[1 0 1];
c2 = [1 1 1];

[out] = encoder_conv([1     1     0     1     0     0     0     0],[c1;c2])
% generatet the auxiliary table
[trans,s_tab,code_tab] = genTransTable([c1;c2]);

% rx data
Sr = [0 1 ; 1 0; 1 0; 0 0; 1 1; 1 1; 0 0; 0 0;];%[ 0 1 ; 1 1; 0 0; 0 1; 1 1 ;0 0 ;0 0 ];
block_length = length(Sr(:,1));

% state matrix,don't need to store it,only for debugging
state = zeros(2^K,block_length+1)+1000;
%start from state 0
state(1,1) = 0;
%store the transfer-state for "trace back"
bits  = zeros(2^K,block_length+1);

%decoder
for i = 1:block_length
    rc = Sr(i,:);
    % caculate the metrics
    % the hard decision(Hamming distance) is used , replace these codes for
    % soft decision(Euclidean distance)
    [row,clm] = size(trans);
    metrics = zeros(1,clm);
    for j = 1:clm
        metrics(j) = sum(bitxor(rc',trans(:,j)));
    end
    %add compare select
    for j = 1:2^K
        %every state has two input-branch,choose the one with less errors
        s_0 = state(floor(((s_tab(j*2-1)+1)/2)),i)+metrics(s_tab(j*2-1));
        s_1 = state(floor(((s_tab(j*2)+1)/2)),i)+metrics(s_tab(j*2));
        %recoder the start point of the selected branch for "trace back"
        %selece the branch with less errors
        if s_0<=s_1
            bits(j,i+1) = floor(((s_tab(j*2-1)+1)/2));
            state(j,i+1) = s_0;
        else
            bits(j,i+1) = floor(((s_tab(j*2)+1)/2));
            state(j,i+1) = s_1;
        end
    end
end
% make decision
% select the end state with least errors
last_st = i+1;
decision = 1;
min_dist = state(1,last_st);
for i = 2:2^K
    if min_dist>state(i,last_st)
        min_dist = state(i,last_st);
        decision = i;
    end
end
%trace back
mcode = zeros(1,block_length);
mcode(1) = code_tab(decision);
for i=1:block_length-1
    decision = bits(decision,block_length+1+1-i);
    mcode(i+1) = code_tab(decision);
end
%output decode result
mcode = fliplr(mcode)
% for i= 0:7
%     in = deci2bin(i,3,0)*[1 1 0 1 0 0; 0 1 1 0 1 0; 1 0 1 0 0 1];
% y = encoder_conv([in 0 0 ],[0 1 1; 1 1 1])
% 
% end
end
function [out] = encoder_conv(in,C)
[row,clum] = size(C);
out = zeros(row,length(in));
reg_en = zeros(1,clum);
for i = 1:length(in)
    reg_en = [in(i),reg_en(1:end-1)];
    out(:,i) = mod(C*reg_en',2);
end
end
%generate the table for decoder algorithm
function [tr,s_tr,i_v] = genTransTable(C)
% tr = the output of every state with input 0,1
% s_tr = the transfer-branch(the probable previous-state of every state) 
% i_v = the input value of every state
%For example
% c1 = [1 0 1];
% c2 = [1 1 1];
% tr
% array index    1     2     3     4     5     6     7     8
% input\state:   0/00  1/00  0/10  1/10  0/01  1/01  0/11  1/11
% c1 output      0     1     0     1     1     0     1     0
% c2 output      0     1     1     0     1     0     0     1
% s_tr
% state          00          10          01          11  
% transfer from
% (array index)  1     5     2     6     3     7     4     8
% i_v
% end state       00    10    01    11  
% with input      0     1     0     1

[row,clum] = size(C);
tr = zeros(row,2^clum);
s_tr = zeros(1,2^clum);
i_v  = zeros(1,2^(clum-1));
for i=1:2^clum
    idx = deci2bin(i-1,clum,1);
    tr(:,i) = mod(idx*C',2);
    s_tr(i) = bin2deci([idx(2:end),idx(1)],1)+1;
    if mod(i,2) == 1
        i_v((i+1)/2) = idx(2);
    end
end
end

function [y] = deci2bin(x,bits,mirror)
y = zeros(1,bits);
in = x;
for i=1:bits
    y(i) = rem(in,2);
    in = floor(in/2);
end
if mirror==0
    y = fliplr(y);
end
end

function [y] = bin2deci(x,mirror)
y = 0;
in = x;
if mirror ~= 0
    in = fliplr(in);
end
for i=1:length(in)
    y = y*2+in(i);
end
end
This license applies to everything in the package, except where otherwise noted.

This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. 

Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.

2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.

3. This notice may not be removed or altered from any source distribution.

Visit www.feiyilin.com for more information

Written by Benben Qiao 2008
<[email protected]>
  参考: [1].  http://www.feiyilin.com/viterbi.html

你可能感兴趣的:(Viterbi算法)