📄 viterbi_decoder.m
字号:
function [decoder_output,survivor_state,cumulated_metric]=viterbi_decoder(G,k,channel_output)
% Viterbi译码
% G为生成多项式系数矩阵
% k为输入位数
% channel_output为信道输出码序列
n=size(G,1);
% 如果矩阵G的列数不是k的整数倍则报错
if rem(size(G,2),k)~=0
error('Size of G and k do not agree')
end
% 如果信道输出码序列的列数不是n的整数倍则报错
if rem(size(channel_output,2),n)~=0
error('Channel out not of the right size')
end
L=size(G,2)/k; % L为约束长度
number_of_states=2^((L-1)*k); % 状态数
% 建立状态转移表,得到存储编码器进入16个状态时各支路对应的输出值及出发状态
for j=0:number_of_states-1 % 遍历所有状态
for l=0:2^k-1 % 每种状态下遍历所有可能的输入情况
[next_state,memory_contents]=nxt_stat(j,l,L,k); % 得出下一状态并存储相应位的码字
input(j+1,next_state+1)=l; % 存储输入
branch_output=rem(memory_contents*G',2); % 得出各分支路径输出
nextstate(j+1,l+1)=next_state; % 存储各状态
output(j+1,l+1)=bin2deci(branch_output); % 将输出转为十进制并存储
end
end
state_metric=zeros(number_of_states,2); % 状态汉明距矩阵
depth_of_trellis=length(channel_output)/n; % trellis格图深度
channel_output_matrix=reshape(channel_output,n,depth_of_trellis); % 信道输出矩阵
survivor_state=zeros(number_of_states,depth_of_trellis+1); % 幸存状态矩阵
% body decoder
% 循环得出前(depth_of_tellis-L+1)段到达各状态的幸存路径
for i=1:depth_of_trellis-L+1
flag=zeros(1,number_of_states); % 初始化标志矩阵
if i<=L % 如果输入长度不大于约束长度(所有状态未全部遍历),状态间隔为2^((L-i)*k)
step=2^((L-i)*k);
else % 当所有状态全部遍历后,状态间隔为1
step=1;
end
for j=0:step:number_of_states-1
for l=0:2^k-1
branch_metric=0;
binary_output=deci2bin(output(j+1,l+1),n); % 将输出转换为二进制
for ll=1:n
branch_metric=branch_metric+metric(channel_output_matrix(ll,i),binary_output(ll)); % 通过计算信道输出与各状态输出间的汉明距得出各支路的汉明距
end
% 比较到达下一状态的前一状态汉明距与对应各支路汉明距的和,取最小者作为该状态的幸存路径,并存储新的状态汉明距;
% 如果标志位为0则直接取进入该状态的路径作为幸存路径,并存储相应状态汉明距
if((state_metric(nextstate(j+1,l+1)+1,2)>state_metric(j+1,1)+branch_metric)|flag(nextstate(j+1,l+1)+1)==0)
state_metric(nextstate(j+1,l+1)+1,2)=state_metric(j+1,1)+branch_metric; % 更新状态汉明距
survivor_state(nextstate(j+1,l+1)+1,i+1)=j; % 更新幸存路径的状态节点
flag(nextstate(j+1,l+1)+1)=1; % 相应标志位置1
end
end
end
state_metric=state_metric(:,2:-1:1); % 状态汉明距矩阵前后两列互换
end
% tailer decoder
% 循环得出后(L-1)段到达最终状态(全零)的最佳路径,方法与上面相同
for i=depth_of_trellis-L+2:depth_of_trellis
flag=zeros(1,number_of_states);
last_stop=number_of_states/(2^((i-depth_of_trellis+L-2)*k));
for j=0:last_stop-1
branch_metric=0;
binary_output=deci2bin(output(j+1,1),n);
for ll=1:n
branch_metric=branch_metric+metric(channel_output_matrix(ll,i),binary_output(ll));
end
if((state_metric(nextstate(j+1,1)+1,2)>state_metric(j+1,1)+branch_metric)|flag(nextstate(j+1,1)+1)==0)
state_metric(nextstate(j+1,1)+1,2)=state_metric(j+1,1)+branch_metric;
survivor_state(nextstate(j+1,1)+1,i+1)=j;
flag(nextstate(j+1,1)+1)=1;
end
end
state_metric=state_metric(:,2:-1:1);
end
state_sequence=zeros(1,depth_of_trellis+1);
state_sequence(1,depth_of_trellis)=survivor_state(1,depth_of_trellis+1); % 确定最佳路径回溯的起点
% 向前回溯寻找最佳路径上的各状态节点
for i=1:depth_of_trellis
state_sequence(1,depth_of_trellis-i+1)=survivor_state((state_sequence(1,depth_of_trellis+2-i)+1),depth_of_trellis-i+2);
end
decoder_output_matrix=zeros(k,depth_of_trellis-L+1);
for i=1:depth_of_trellis-L+1 % 根据最佳路径得出译码结果
dec_output_deci=input(state_sequence(1,i)+1,state_sequence(1,i+1)+1);
dec_output_bin=deci2bin(dec_output_deci,k);
decoder_output_matrix(:,i)=dec_output_bin(k:-1:1)';
end
decoder_output=reshape(decoder_output_matrix,1,k*(depth_of_trellis-L+1));
cumulated_metric=state_metric(1,1); % 最佳路径的累积汉明距
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -