【信道编码/Channel Coding】卷积码和Viterbi译码及其MATLAB实现

article/2025/10/7 11:55:19

简介:


这是本专栏信道编码/Channel Coding的最后一站,想对信道编码有一个系统性的认识可以看本专栏的 信道编码的整体框架 一文。而在本篇文章中,将介绍卷积码的基本原理和Viterbi译码的过程,以及其MATLAB实现。为什么是最后一站呢,明明还有Turbo码,LDPC码和Polar码,这是因为这是我本科的总结,那些码由于实现起来需要很多细节,有很多研究价值,我希望在我的研究生生涯能够完善。

目录

简介:

一、卷积码的原理

1.1 卷积码的符号表示

1.2 运作原理

二、 举例:(2,1,2)卷积编码器

2.1 状态转移表

2.2 状态转移图

2.3 网格图

三、Viterbi译码

3.1 译码过程(以上述(2,1,2)卷积码为例)(假设用硬判决)

3.2 硬判决和软判决

四、MATLAB实现


一、卷积码的原理


1.1 卷积码的符号表示

和分组码稍有不同,卷积码的符号表示有三个维度,(n,k,L)中,n和k和分组码不同,n是每次输出的码字长度,k是每次输入的信息比特长度,而L就是记忆深度,卷积编码器的图表示如下:

1.2 运作原理

  • 每过一个时间单位,比如从 t=0 到 t=1, k个比特从输入端输入k位的移位寄存器,而每一个移位寄存器里的k个比特输入到这个寄存器之后的一个寄存器。总共有L个k位移位寄存器。
  • 紧接着上面的,有L个k位寄存器意味着有k*L个比特。根据设计的不同,每一个比特对n个模二加运算器有独特的影响。
  • 模二加运算器的输出结果作为输出,所以一次输出n个比特。
  • 移位寄存器初始状态都是0

二、 举例:(2,1,2)卷积编码器


 可以看到,(2,1,2)卷积编码器是一个,每一时刻只有一个输入,但是会输出两位(两个模二加运算器)的卷积编码器,里面的寄存器都是1位的,共有两个寄存器(两个记忆深度)。而模二加运算器的数学表达如下:

y_1=Input\bigoplus D_1\bigoplus D_2

y_2=Input\bigoplus D_2

 假如输入序列为 x=10101,则其规律会是这样:

2.1 状态转移表

我们会发现,寄存器的状态就只有00,01,10,11四种可能,而输入只有0/1两种可能,所以输出一定也是伪随机的,也就是说输入输出的关系只有2x4=8种可能,我们将其列表:

输入当前状态下个状态输出1输出2
0000000
0010011
0100110
0110101
1001011
1011000
1101101
1111110

这就是状态转移表,通过查表可以非常简单的看出不同寄存器状态对应的输入输出之间的关系。这种表结构常用于编程。

2.2 状态转移图

我们只需要稍微改一下,将表转化成图就能得到状态转移图,如下:

 箭头表示从某一状态到每一状态,0/10表示在这个状态下,输入0得到输出10.

2.3 网格图

 网格图也非常直观简单,每行是一种寄存器的状态,所以有四行分别是00,01,10,11,而箭头仍然表示从什么状态到什么状态,0/00仍然表示在这个状态下输入0则输出11。但是不同的是,网格图能体现时刻的变化导致状态的转移路线的变化。

三、Viterbi译码


Viterbi译码实际上并不是非常复杂,其基于最大似然估计思想(ML)。我们先通过一个简单的例子迅速的理解一下Viterbi译码的流程。

3.1 译码过程(以上述(2,1,2)卷积码为例)(假设用硬判决)

  • 将接收到的码两两分组(毕竟编码的时候一个输入对应两个输出)
  • 利用和编码器一样的网格图,此时t=0,从状态00出发,画出输入为0和输入为1的两条路线,。并将输入为0的输出 和 输入为1的输出 分别和 t=0 要翻译的码进行异或(计算汉明距离),得到的值称为路径度量(PM,Path Metric),我们将其作为像路径的重量一样累积起来。注意,这时候应该有两个路径了、
  • t=1,t=2,...的操作和上一步一样,从每个路径在上一时刻的状态出发,比较输入为0输入为1的输出和此时刻要翻译的码,计算汉明距离,再计算路径度量(累积的汉明距离)。所以在t=n时刻,理应有 2^{n+1} 个路径
  • 剪枝(Pruning):由于路径过于多,所以在路径达到某个数量的时候,译码器仅保留路径度量(累积汉明距离)最小的两个路径,然后继续译码。直至译码结束。

举例:

假设接收端接收到信号,并将其量化判决为011100(体现了硬判决,下面会讲)

(1)第一步是把信息两两分组:01 11 00,作为t=0,t=1,t=2时刻的输入

(2)第二步,译码,按照上面所述的流程,t=0时,收到的码为00;此时译码器状态为00,输入为0时输出为00,和收到的码的汉明距离是0,故PM=0;输入为1时输出为11,和收到的码汉明距离是2,故PM=2.

(3)继续译码,从上一步的两条路径出发,会衍生出四条路径

(4)进行剪枝(看系统的设计,不一定是这个时候剪枝),只保留最小PM的两个路径,继续译码

(5)回溯,从PM最短的路径开始回溯,译码为110

【注意】通常接收端会在一帧的信息比特发完末尾加入0 0,这样接收端的译码器就会回归00状态

3.2 硬判决和软判决

大家都注意到了,上面栗子的小标题提示了这是硬判决,那么什么是硬判决什么是软判决呢?

  • 硬判决(Hard Decision)是指在接收端,信号被接收后,先进行种种滤波,均衡等操作,然后直接被判决器判为0或1,根据得到的比特串进行如上面所述的Viterbi译码。注意,这时候我们的PM(路径度量)是以汉明距离为度量。由它的二元特性判断,它比较适合BPSK等二元系统。
  • 软判决(Soft Decision)是指在接收端,信号被接收后,进行完种种滤波,均衡等操作,在采样量化后,先不进行判决(也就是先不把多电平状态的量化信号变成0101的数字信号),而是直接经过软判决Viterbi译码器,这时候译码器会以欧氏距离为PM(路径度量),判断某一电平状态距离欧氏距离最近的符号。软判决通常会比硬判决性能更好,因为软判决减少了因量化器判决导致的量化噪声。

四、MATLAB实现


%%
clear all;clc;close all;
% Generation of Bits stream
nob=100; % The amount of bit
bit_stream=[randi([0 1],nob,1);[0;0]];codeword=zeros(2*(nob+2),1);
D1=0; % Initial state of registers
D2=0;
for i_b=1:1:nob+2y1=mod(bit_stream(i_b)+D1+D2,2);y2=mod(bit_stream(i_b)+D2,2);D2=D1;D1=bit_stream(i_b);codeword(2*i_b-1)=y1;codeword(2*i_b)=y2;
end%%
% Viterbi Decoding
received_codeword=codeword;
state_table=[0 0;0 1;1 0;1 1];  %find(ismember(state_table,[1 1],'row')==1)
Transfer_table={[0 0],[0 0],[1 1],[1 0]; % Output with input 0/1;Next State[1 1],[0 0],[0 0],[1 0];[1 0],[0 1],[0 1],[1 1];[0 1],[0 1],[1 0],[1 1]};
D=[0 0]; % State of registers
branch=cell(8,4); % weight, estimated bit stream, last state
branch{1,1}=0;branch{1,2}=[];branch{1,3}=[0 0];branch{1,4}=1;
for i=2:1:8branch{i,1}=0;branch{i,4}=0;
endfor i_b=1:2:length(received_codeword)code_buffer=received_codeword(i_b:i_b+1,1).';a_b=find([branch{:,4}]==0); % Available Branchesn_b=8-length(a_b);for i_s=1:1:n_bi_a_b1=i_s;i_a_b2=a_b(i_s);weight=branch{i_s,1};  % Accumulated weight of branchest_b_s=branch{i_s,2}; % Estimated Bit streamlast_state=branch{i_s,3}; % Last state of this branchindex=find(ismember(state_table,last_state,'row')==1); % Find the index of Last state% Look up tableweight1=weight+sum(xor(code_buffer,Transfer_table{index,1})); % Hamming Distanceweight2=weight+sum(xor(code_buffer,Transfer_table{index,3}));est_b_s1=[est_b_s,0];est_b_s2=[est_b_s,1];last_state1=Transfer_table{index,2};last_state2=Transfer_table{index,4};% Update the branch listbranch{i_a_b1,1}=weight1;branch{i_a_b1,2}=est_b_s1;branch{i_a_b1,3}=last_state1;branch{i_a_b1,4}=1;branch{i_a_b2,1}=weight2;branch{i_a_b2,2}=est_b_s2;branch{i_a_b2,3}=last_state2;branch{i_a_b2,4}=1;end% Pruningif n_b==4weight_list=[branch{:,1}];[~,i_tmw]=sort(weight_list); % Get the index of the two minimum weightbuf11=branch{i_tmw(1),1};buf12=branch{i_tmw(1),2};buf13=branch{i_tmw(1),3};buf21=branch{i_tmw(2),1};buf22=branch{i_tmw(2),2};buf23=branch{i_tmw(2),3};branch{1,1}=buf11;branch{1,2}=buf12;branch{1,3}=buf13;branch{1,4}=1;branch{2,1}=buf21;branch{2,2}=buf22;branch{2,3}=buf23;branch{2,4}=1;for i=3:1:8branch{i,4}=0;endend
end%%
n_survival_branch=length(find([branch{:,4}]==1));
w_survival_branch=[branch{1:n_survival_branch,1}];
[~,i_weight]=sort(w_survival_branch);
i_minimum_weight=i_weight(1);
estimated_bit_stream=branch{i_minimum_weight,2};
BER=sum(abs(estimated_bit_stream-bit_stream'))/(nob+2)


http://chatgpt.dhexx.cn/article/A4afn8X0.shtml

相关文章

不同卷积方法一览(+部分代码)

关键词 卷积方法:2D / 3D / 1x1 /转置/扩张(Atrous)/空间可分/深度可分/平展/分组/混洗分组/逐点分组卷积 卷积网络:全卷积FCN(Fully Convolutional Network),可变形卷积(Deformab…

卷积代码实现

卷积在pytorch中有两种方式,一种是torch.Conv2d(),一种是torch.nn.functional.conv2d(),这两种形式本质都是使用一个卷积操作,下面举例来说明一下这两种卷积方式 import numpy as np import torch from torch import …

最通俗的语言讲解卷积码、码树图、状态图以及维特比译码

什么是卷积码? 卷积码是由伊利亚斯发明的一种非分组码,它更加倾向于纠错,对于实际的性能优于分组码,运算较为简单。 将卷积码记为(n,k,N),码率定义为k/n n是n个比特 k是k个信息位 N是N个信息段 卷积码编码器 组成&#xff1a…

卷积,卷积神经网络,图卷积神经网络中的“卷积”如何理解?

[] 1. 对卷积最朴素的理解 首先我们在教材上看到的卷积公式是 ∫ f ( τ ) g ( x − τ ) d τ \int f(\tau)g(x-\tau)d\tau ∫f(τ)g(x−τ)dτ。对于这个公式的理解,网上有很多讲解视频,都是用一些具体的例子来帮助我们理解卷积的过程。推荐b站上的视…

实现卷积的几种代码方式

目录 摘要 卷积(convolution) 1、pytorch实现 2、对input展开矩阵相乘 3、对kernel展开以及矩阵相乘 转置卷积 1、API实现 2、对kernel矩阵转置矩阵相乘 总结 摘要 卷积的基本元素有着input size、kernel size、stride、padding、group以及dil…

卷积卷积神经网络

文章目录 一、关于卷积(convolution)的直观感受二、卷积在不同领域的应用三、卷积神经网络(CNN)的诞生四、卷积神经网络(CNN)(1)为什么需要卷积层(2)池化&…

MATLAB (n,k,m)卷积码原理及仿真代码(你值得拥有)

卷积码原理介绍 1.基本概念 首先卷积码是一种纠错码,让我们先从大格局出发,去认识卷积码。如图1所示我是先从通信原理书上了解了卷积码的概念,再结合网上部分资料,勉强搞懂,感觉主要需要掌握卷积码编码器、状态图、网…

通信原理学习笔记4:信道编码、分组码、卷积码、现代信道编码(Turbo码、LDPC码、Polar码)

信道编码 / 前向纠错码FEC 思想是在数据中增加冗余信息,即校验码元 / 监督码元,从而检错、纠错 信道编码的优劣评判 首先,最基本的是要追求低差错率 实现纠错很简单,只要多添加冗余信息就好;但实际中,我…

韩信点兵算法:

韩信点兵问题:韩信点兵不足百人,3人一行排列多一人,7人一行排列少两人,5人一行正好, 输出韩信究竟点了多少兵。 使用 math 类的DivRem 方法进行运算。 static void Main(string[] args){///韩信点兵不足百人&#xff…

韩信点兵

韩信点兵&#xff1a; 韩信带1500名兵士打仗&#xff0c;战死四五百人&#xff0c;站3人一排&#xff0c;多出2人&#xff1b;站5人一排&#xff0c;多出4人&#xff1b;站7人一排&#xff0c;多出6人。韩信马上说出人数&#xff1a;1049。 代码实现&#xff1a; <span styl…

韩信点兵(python)

韩信点兵 全部士兵按每行8人站立&#xff0c;剩余7人 全部士兵按每行7人站立&#xff0c;剩余6人 问题&#xff1a;已知每一营士兵人数在1000~2000之间&#xff0c;如何利用循环判断表示出代码逻辑 for num in range (1000,2000):if num % 87 and num %76 and num%65\and num%5…

经典算法--韩信点兵

韩信点兵是一道古代的数学题&#xff0c;题意&#xff1a;韩信点兵不足百人&#xff0c;三人一排多1人&#xff0c;七人一排少2人&#xff0c;五人一排正好。问韩信带兵多少&#xff1f; /*** 韩信点兵&#xff1a;* 韩信带兵不足百人&#xff0c;3人一排多1人&#xff0c;7人一…

枚举算法:韩信点兵。

韩信点兵。韩信在点兵的时候&#xff0c;为了知道有多少名士兵&#xff0c;同时又能保住军事机密&#xff0c;便让士兵排队报数。 按从1至5报数&#xff0c;最末一个士兵报的数为1。 再按从1至6报数&#xff0c;最末一个士兵报的数为5。 再按1至7报数&#xff0c;最末一个士兵报…

java工作流activity_activity 工作流学习(一)

启动流程实例 什么是流程实例?根据一个流程定义具体的一次执行过程就是一个流程实例,一个流程定义对应多个流程实例(一对多关系) 为了演示:在流程图中指定办理人是谁,现在是写死的,表示只能张三能提交请假申请。后面会讲解如何动态指定。 //根据流程定义的Id启动一个流程实…

工作流:一文让你学会使用flowable工作流

1.请假流程图 下图是 一个请假申请的简单流程图 &#xff08;1&#xff09;申请人通过发起流程进行请假申请&#xff0c;给经理发送一个待审批事项&#xff1b; &#xff08;2&#xff09;经理在待办列表选择事项&#xff0c;进行审批&#xff0c;approved同意或者rejected驳回…

jeesite工作流使用

问题&#xff1a;jeesite工作流如何使用&#xff1f; 背景&#xff1a;公司没人熟悉工作流&#xff0c;现在要上线办公系统&#xff0c;请假&#xff0c;加班&#xff0c;报销&#xff0c;预审批&#xff0c;用印&#xff0c;付款等工作流要写&#xff0c;之前有简单版本&…

工作流的大致开发流程

前段时间公司在做一个oa的项目&#xff0c;用到了flowable工作流&#xff0c;刚开始的时候还在纠结于是用activity还是flowable&#xff0c;后来查了相关资料发现flowable的作者之前就是开发activity的作者&#xff0c;只不过后来自己出去又搞了一套就叫做flowable&#xff0c;…

flowable工作流所有业务概念

1.什么是工作流审批 根据本人的理解&#xff0c;就是审批流程管理。 2.什么是flowable 1.官方解释 官方解释如下&#xff1a; Flowable 项目提供了一套核心的开源业务流程引擎&#xff0c;这些引擎紧凑且高效。它们为开发人员、系统管理员和业务用户提供工作流和业务流程管…

微服务与工作流

本文主要想谈一谈工作流在微服务系统中的使用以及工作流能够为微服务系统带来的好处。 通过查找资料可得&#xff0c;微服务的编排主要分为两种形式&#xff0c;一种是“choreography”&#xff0c;有人将其翻译成微服务的编排&#xff1b;另一种是“orchestration”,有人将其翻…

Camunda工作流引擎入门

文档集合 1、camunda文档&#xff1a;https://docs.camunda.org/get-started/quick-start/ 2、camunda资源下载&#xff1a;https://camunda.com/download/ 3、camunda示例github仓库&#xff1a;https://github.com/camunda/camunda-bpm-examples 4、camunda 代码仓库&…