123

function dis=Hamming_dis(x,y)
    dis=rem(x+y,2);
    dis=dis*[1;1];
end
%Viterbi算法译码器

function decoder_output=viterbi_hard(y,L)   %y是编码加噪声后的序列,L是信息序列长度
    global G;
    G=[1,1,1;
        1,0,1];
    n=size(G,1);    %G的行数
    K=size(G,2);    %G的列数    
    number_of_states=2^(K-1);   %状态数
    nextstate=zeros(number_of_states,2);    %状态转移矩阵,当前状态j,输入t
    output=zeros(number_of_states,2);       %输出矩阵当前状态j,输入t,十进制
    for j=0:number_of_states-1
        for t=0:1
            [next_state,memory_contents]=next_state_fun(j,t,K);     %由当前状态数j ,输入信息码 t,寄存器长度K
                                                                    %找到下一个状态数next_state, 更新寄存器内容memory_contents
            branch_output=rem(memory_contents*G',2);    % branch_output 分支的输出,1*2维矩阵
            nextstate(j+1,t+1)=next_state;  %nextstate状态转移表,当前状态j,输入t,  2^(K-1)*2维矩阵
            output(j+1,t+1)=bin2deci(branch_output);    %output 输出矩阵,2^(K-1)*2维矩阵
        end
    end 
%------------------------------------------------ %各状态的度量
    metric_of_states=zeros(1,number_of_states);               
    %metricmetric_of_states_c=zeros(number_of_states,2);    %各状态两个输入的度量
    length_seq=length(y)/n;     %信息符号数,1 symbal=n bits
    decoder_output=zeros(1,length_seq-K+1);     %信息码,减去最后补(K-1)个0 
    channel_output_matrix=reshape(y,n,length_seq);      %将解调输出的比特按符号排列 n*length_seq维矩阵,二进制
    survivor_state=zeros(number_of_states, length_seq+1);        %留存路径 
    input_of_state=zeros(number_of_states, length_seq+1, 2);      %汇聚到各状态的分支对应的输入                     
    count=zeros(1, number_of_states);   %count只能为1 或2 ,记录是某输入时刻 第几次进入这个状态
    metric_of_states_c=zeros(number_of_states,2);   %对两次进入同一状态的距离记录

    for i=1:length_seq-K+1      %时间线
        
        for j=0:number_of_states-1   %遍历状态
            for t=0:1   %遍历输入
                binary_output=deci2bin(output(j+1,t+1),n);   %理想输出 binary_output 1*2维度矩阵
                branch_metric=Hamming_dis(channel_output_matrix(:,i)',binary_output); %计算分支度量
                count(nextstate(j+1,t+1)+1)=count(nextstate(j+1,t+1)+1)+1; %count为1,2 ,第几次进入状态
                metric_of_states_c(nextstate(j+1,t+1)+1,count(nextstate(j+1,t+1)+1))=metric_of_states(j+1)+branch_metric;   %计算累积度量(加)      
                input_of_state(nextstate(j+1,t+1)+1,:,count(nextstate(j+1,t+1)+1))=survivor_state(j+1,:);         %该分支所在路径的对应的输入
                input_of_state(nextstate(j+1,t+1)+1,i,count(nextstate(j+1,t+1)+1))=t;
            end
        end
%----------------比较汇聚到同一状态的两条路径,选取距离较小的-----------------
        for j=0:number_of_states-1
            if metric_of_states_c(j+1,1)>=metric_of_states_c(j+1,2)
                metric_of_states(j+1)=metric_of_states_c(j+1,2);
                survivor_state(j+1,:)=input_of_state(j+1,:,2);
            else
                metric_of_states(j+1)=metric_of_states_c(j+1,1);
                survivor_state(j+1,:)=input_of_state(j+1,:,1);
            end
        end
        count=zeros(1,number_of_states); 
%--------------------------截短输出------------------------------------ 
        if i>L
        [min_metric,location]=min(metric_of_states);
        decoder_output(i-L)=survivor_state(location,i-L);
        end
    end
%---------------------最后L个比特译码输出--------------------------------
[min_metric,location]=min(metric_of_states);
decoder_output(length_seq-K+1-L+1:length_seq-K+1)=survivor_state(location,length_seq-K+1-L+1:length_seq-K+1);
%在最后译码结果出来后,将原始信号和译码输出的还原信号进行比较,计算误比特率。
end

%十进制转化为n位的二进制数组
function y1=deci2bin(x,n)
    y1=zeros(1,n);
    i=1;
    while x>=0&&i<=n
        y1(i)=rem(x,2);
        x=(x-y1(i))/2;
        i=i+1;
    end
    y1=y1(n:-1:1);
end

%二进制转化为十进制数字
function y=bin2deci(x)
    n=length(x);
    y=(n-1:-1:0);
    y=2.^y;
    y=x*y';
end


function dis=Hamming_dis(x,y)
    dis=rem(x+y,2);
    dis=dis*[1;1];
end


%求下一个viterbi状态的函数
%当前十进制状态码 j
%当前输入信息码 t
%寄存器限制长度 K
%下个状态码 next_state,
%寄存器内容 memory_contents
function [next_state,memory_contents]=next_state_fun(j,t,K)     %当前状态码 j,当前输入信息码 t,寄存器限制长度 K
    a=deci2bin(j,K-1);      %将j转化为K-1位二进制状态码
    binary_state_1=deci2bin(j,K-1);     %当前状态码
    binary_input=deci2bin(t,1);     %当前输入
    next_state_binary=[binary_input,binary_state_1(1:(K-2))];       %组合成新的状态码
    next_state=bin2deci(next_state_binary);     %新的十进制状态码
    memory_contents=[binary_input,binary_state_1];      %当前寄存器内容
end
function out=conv_enc(msg)
    g1=[1,1,1];
g2=[1,0,1];                                     
%两个连接矢量
m1=conv(msg,g1);                               
%卷积
m2=conv(msg,g2);                               
%卷积
    L1=length(m1);
    for i=1:L1
        out(2*i-1)=rem(m1([i]),2);                     
%奇数位置的点
        out(2*i)=rem(m2([i]),2);                       
%偶数位置的点
    end
end
%将奇数偶数位置的数据交错才能获得整个序列
原文地址:https://www.cnblogs.com/ustcfanli/p/10123811.html