📄 soft_viterbi.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 + -