www.pudn.com > RS_BCM_255_223_4[1].Matlab.rar > viterbi.m, change:2007-04-17,size:4322b


function viterbi_out= viterbi(symbols) 
%用于BCM-8PSK的Vterbi译码,其中BCM的三个分组内码为(8,1,8)(8,7,2)(8,8,1) 
 
%symbols=[5.2 7.3 0.7 7.2 1.6 2.7 1.2 3.2]; 
for frame=0:(length(symbols)/8-1) 
    mmm=frame*8+1; 
    nnn=frame*8+8; 
    sym= symbols(mmm:nnn); 
%以下为一帧8个符号的译码 
%--------------------------------------------------------------------------     
paths=zeros(4,8);                             %用于记录4条路径的输出 
old_paths=zeros(4,8); %%%%%%%%%%%%%%%%%%%%%%% 
cum_metrics = zeros(4, 2);                    %用于保存累计度量值 
for state=1:4                                 %对于step=1情况 
    switch state 
        case 1 
             [min_metrics,sym_out]=compare(sym(1),0,4);  
             %分别对各状态进入两条平行求分支度量,小的值放在min_metrics中,对应分支的输出值放sym_out中输出 
        case 2 
             [min_metrics,sym_out]=compare(sym(1),2,6);   
        case 3 
             [min_metrics,sym_out]=compare(sym(1),1,5);   
        case 4 
             [min_metrics,sym_out]=compare(sym(1),3,7);        
    end     
    cum_metrics(state,1)=min_metrics;            %对于step=1情况,累积度量值为min_metrics 
    paths(state,1)=sym_out;                      %对于step=1情况,保存sym_out1 
end 
old_paths=paths;%%%%%%%%%%%%%%%%%%%%%%% 
 
for step=2:7                                                    %这里从step=2开始到length(sym)-1=7 
   for state=1:2                                                  %网格图分上下两层,对于上层两状态Ae,Ao,每个状态两组平行共4个分支进入 
       [min_metrics1,sym_out1]=compare(sym(step),0,4);            %第一组平行分支,其输出分别为0和4,分别计算和输入符号的距离 
       temp_metrics1=cum_metrics(state,1)+min_metrics1;             %和第一组对应的前一状态(Ae)的累积度量值相加 
       [min_metrics2,sym_out2]=compare(sym(step),2,6);            %第二组平行分支,其输出分别为2和6,分别计算和输入符号的距离 
       temp_metrics2=cum_metrics((3-state),1)+min_metrics2;           %和第二组对应的前一状态(Ao)的累积度量值相加 
       if (temp_metrics1<=temp_metrics2)                          %比较 
           cum_metrics(state,2)=temp_metrics1;                      %小的值保存 
           paths(state,step)=sym_out1;                            %输出值保存 
       else 
           cum_metrics(state,2)=temp_metrics2; 
           paths(state,:)=old_paths((3-state),:); 
           paths(state,step)=sym_out2; 
       end 
   end        
   for state=3:4                                                  %对下层情况处理算法相同 
       [min_metrics3,sym_out3]=compare(sym(step),1,5);          
       temp_metrics3=cum_metrics(state,1)+min_metrics3; 
       [min_metrics4,sym_out4]=compare(sym(step),3,7); 
       temp_metrics4=cum_metrics((7-state),1)+min_metrics4; 
       if (temp_metrics3<=temp_metrics4) 
           cum_metrics(state,2)=temp_metrics3; 
           paths(state,step)=sym_out3; 
       else 
           cum_metrics(state,2)=temp_metrics4; 
           paths(state,:)=old_paths((7-state),:);%%%%%%%%%%%%%%%%%%%%%%%%这里有错,如果在上面state=3时最优路径从4状态过来,那么 
           paths(state,step)=sym_out4; 
       end 
   end    
   cum_metrics(:,1)=cum_metrics(:,2); 
   old_paths=paths;%%%%%%%%%%%%%%%%%%%%%%% 
end 
 
 
for state=1:4       
    switch state 
        case 1 
             [min_metrics,sym_out]=compare(sym(8),0,4);  %对于step=1情况 
             %分别对各状态进入两条平行求分支度量,小的值放在min_metrics中,对应分支的输出值放sym_out中输出 
        case 2 
             [min_metrics,sym_out]=compare(sym(8),2,6);   
        case 3 
             [min_metrics,sym_out]=compare(sym(8),1,5);   
        case 4 
             [min_metrics,sym_out]=compare(sym(8),3,7);        
    end     
    cum_metrics(state,2)=cum_metrics(state,1)+min_metrics;              %对于step=1情况,累积度量值为min_metrics 
    paths(state,8)=sym_out;                      %对于step=1情况,保存sym_out1 
end 
 
 
min_metrics=1e6; 
for state=1:4 
    if min_metrics>cum_metrics(state,2) 
       min_metrics=cum_metrics(state,2); 
       temp_viterbi_out=paths(state,:); 
       a=state;%%%%%%%%%% 
    end 
end 
%-------------------------------------------------------------------------- 
%以上为一帧8个符号的译码 
   if frame==0 
      viterbi_out= temp_viterbi_out; 
   else 
   viterbi_out=[viterbi_out temp_viterbi_out]; 
   end 
end