⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 soft_viterbi.m

📁 完整的OFDM仿真程序
💻 M
字号:
function    [out_put] = soft_viterbi(channel_output)
%
%   维特比译码,软判决。
%   soft_viterbi实现对卷积码的软判决译码工作。给出一个经过似然比计算的输入序列
%   channel_output、卷积码生成矩阵G、和卷积码编码器输出端口数n0。可以正确获得经过维特比算法硬判
%   决译码后的输出序列output。本程序采用软判决,则要求输入的电平值(即channel_output)是已经量
%   化了的值;   
%   G :卷积编码器的生成矩阵,G=[1 0 1 1 1 0 0 0 1;1 1 1 1 0 1 0 1 1];
%   channel_output:经过传输信道的卷积编码序列。
%   
%   
%   [output] = soft_viterbi(channel_output) 返回经维特比软判决译码器译码后的输出比特序列。
%
%进行初始化工作;
%卷积编码器的生成矩阵G;
G = [1 0 0 0 1 1 1 0 1;1 1 0 1 0 1 1 1 1];
%总的状态数;
num_of_states = 256;
%约束长度L;
L = 9;
%初始化寄存器register_1;
register_1 = zeros(num_of_states,L+1);
%初始化寄存器register_2;
register_2 = zeros(num_of_states,L+1);
%对寄存器register_1、register_2赋值;
for i = 1:num_of_states
    %第2至第L列初始化为状态数的二进制形式;
    register_1(i,1:L+1) = [1,deci2bin(i-1,L-1),-64];
    register_2(i,2:L) = deci2bin(i-1,L-1);
end
%对零状态出发的度量值赋初值0;
register_1(1,L+1) = 0;
%depth_of_trellis:需要译码的次数;
depth_of_trellis = length(channel_output)/2;
%定义存储路径变量的数组,长度为depth_of_trellis;
rout = zeros(num_of_states,depth_of_trellis);
%初始化一个temp,作为暂存变量;
temp = 0;
%对channel_output进行循环译码;
for j = 1:depth_of_trellis
    %对register_2所有状态+输入求其对数似然比之和;
    for i = 1:num_of_states
        %branch_output:对应不同的寄存器值的信道编码后的输出码组;
        branch_output = mod(register_2(i,1:L)*G',2);
        %对似然比进行累加;
        for q = 1:2
            %如果为0,给似然比赋正值;
            if  branch_output(q) == 0
                temp = temp + channel_output((j-1)*2+q);
            %如果为1,给似然比赋负值;
            else
                temp = temp - channel_output((j-1)*2+q);
            end
        end
        %register_2中的度量值来自于register_1中的相应度量值;
        register_2(i,L+1) = register_1(ceil(i/2),L+1) + temp;
        %对临时变量清零;
        temp = 0;
    end
    %对register_1所有状态+输入求其对数似然比之和;
    for i = 1:num_of_states
        %branch_output:对应不同的寄存器值的信道编码后的输出码组;
        branch_output = mod(register_1(i,1:L)*G',2);
        %对似然比进行累加;
        for q = 1:2
            %如果为0,给似然比赋正值;
            if  branch_output(q) == 0
                temp = temp + channel_output((j-1)*2+q);
            %如果为1,给似然比赋负值;
            else
                temp = temp - channel_output((j-1)*2+q);
            end
        end
        %register_1中的度量值来自于register_1中的相应度量值;
        register_1(i,L+1) = register_1(ceil(i/2)+num_of_states/2,L+1) + temp;
        %对临时变量清零;
        temp = 0;
    end
    for i = 1:num_of_states
        %对度量值进行判断,如果register_1中的度量值较小,则将其更改为register_2中的度量值;
        if  register_1(i,L+1) < register_2(i,L+1)
            register_1(i,L+1) = register_2(i,L+1);
            %同时将路径赋值rout中的内容也更新;
            rout(i,j) = register_2(i,1);
        %如果register_1中的度量值较大,则保留;
        else
            %记录相应的register_1中的路径信息;
            rout(i,j) = register_1(i,1);
        end
    end
end

%回溯部分;
current_state = 1;
%对深度为depth_of_trellis的rout中的内容进行回溯;
for j = depth_of_trellis:-1:1
    %out_put记录回溯过程中找出的路径信息;
    out_put(j) = rem((current_state-1),2);
    %如rout(current_state,j)为0,说明下一状态值在所有状态的前半部分;
   if rout(current_state,j) == 0
       %下一状态值为当前状态值的一半;
       current_state = ceil(current_state/2);
   else
       %下一状态值为当前状态值的一半加上128;
       current_state=ceil(current_state/2)+num_of_states/2;
   end
end
%输出结果;
out_put = out_put(1:4984);
    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -