卷积码的维特比译码原理及仿真
- 格式:doc
- 大小:185.50 KB
- 文档页数:8
3/4卷积码编码原理分析与建模仿真一、摘要卷积码是一种性能优越的信道编码。
它的编码器和译码器都比较容易实现,同时它具有较强的纠错能力。
随着纠错编码理论研究的不断深入,卷积码的实际应用越来越广泛。
本文简明地介绍了卷积码的编码原理和Viterbi译码原理。
并在SIMULINK模块设计中,完成了对卷积码的编码和译码以及误比特统计整个过程的模块仿真。
最后,通过在仿真过程中分析了卷积码误比特率与信噪比之间的关系,及卷积码与非卷积码的对比。
经过仿真和实测,并对测试结果作了分析。
关键词:卷积码编码建模 SIMULINK仿真目录一、摘要 ................................................................................................................................................................. - 1 -二、设计目的和意义 ............................................................................................................................................. - 2 -三、设计原理 ......................................................................................................................................................... - 3 -3.1 卷积码基本概念 ...................................................................................................................................... - 3 -3.2 卷积码的结构 .......................................................................................................................................... - 3 -3.3 卷积码的解析表示 .................................................................................................................................. - 4 -3.4 卷积码的译码 .......................................................................................................................................... - 4 -3.4.1 卷积码译码的方式........................................................................................................................ - 4 -3.5.2 卷积码的Viterbi译码 .................................................................................................................. - 5 -四、详细设计步骤 ................................................................................................................................................. - 6 -4.1 卷积码的仿真 .......................................................................................................................................... - 6 -4.1.1 SIMULINK仿真模块的参数设置及意义 ................................................................................. - 6 -五、设计结果及分析 ........................................................................................................................................... - 11 -5.1不同信噪比对卷积码的影响.................................................................................................................. - 11 -5.2卷积码的对比 ........................................................................................................................................ - 12 -六、总结 ............................................................................................................................................................... - 14 -七、体会 ............................................................................................................................................................... - 14 -八、参考文献 ....................................................................................................................................................... - 14 -二、设计目的和意义因为信道中信号不可避免会受到干扰而出错。
编号:《DSP技术与应用》课程论文卷积码的维特比译码的分析与实现论文作者姓名:______ ______作者学号:___ ______所在学院:所学专业:_____ ___导师姓名职称:__ _论文完成时间: _目录摘要: (1)0 前言 (2)1 理论基础 (2)1.1信道理论基础 (2)1.2差错控制技术 (3)1.3纠错编码 (4)1.4线性分组码 (5)2 卷积码编码 (7)2.1 卷积码概要 (7)2.2 卷积码编码器 (8)2.3卷积码的图解表示 (8)2.4 卷积码的解析表示 (11)3 卷积码的译码 (14)3.1 维特比译码 (15)3.2 代数译码 (17)3.3 门限译码 (18)4 维特比译码器实现 (18)4.1 TMS320C54 系列DSP概述 (18)4.2 Viterbi译码器的DSP实现 (19)4.3 实现结果 (21)5 结论 (21)参考文献 (22)II卷积码的维特比译码的分析与实现摘要:针对数据传输过程中的误码问题,本文论述了提高数据传输质量的一些编码及译码的实现问题。
自P.Elias 首次提出卷积码编码以来,这一编码技术至今仍显示出强大的生命力。
在与分组码同样的码率R 和设备复杂性的条件下,无论从理论上还是从实际上均己证明卷积码的性能至少不比分组码差,且实现最佳和准最佳译码也较分组码容易。
目前,卷积码已广泛应用在无线通信标准中,其维特比译码则利用码树的重复性结构,对最大似然译码算法进行了简化。
本文所做的主要工作:首先对信道编码技术进行了研究,根据信道中可能出现的噪声等问题对卷积码编码方法进行了主要阐释。
其次,对卷积码维特比译码器的实现算法进行了研究,完成了译码器的软件设计。
最后,结合实例,采用DSP芯片实现卷积码的维特比译码算法的仿真和运行。
关键词:卷积码维特比译码DSPConvolutional codes and Viterbi decoding analysis andrealizationZhang Yi-Fei(School of Physics and Electronics, Henan University, Henan Kaifeng 475004, China)Abstract:Considering the error bit problem during data transmission,this thesis discussed some codings and decoders,aiming at enhancing transmission performance. From P.Elias first gave the concept of convolutional code, it has show its’ great advantage. Under the same condition and the same rate of block code, the performance of convolutional code is better than block code, and it’s easier to implement the best decoding.Convolutional codes have been widely used in wireless communication standards, the Viterbi decoding using the repetitive structure of the code tree, the maximum likelihood decoding algorithm has been simplified. Major work done in this article: First, the channel coding techniques have been studied, the main interpretation of the convolutional code encoding method according to the channel may be noise and other issues.Secondly, the convolutional code Viterbi decoder algorithm has been studied, the software design of the decoder.Finally, with examples, simulation and operation of the DSP chip convolutional codes, Viterbi decoding algorithm.1Key words:convolutional code Vltebri decoder DSP0 前言随着数据处理、计算机通信、卫星通信以及高速数据通信网的飞速发展,用户对数据传输的可靠性提出了越来越高的要求,因此如何在保证数据传输速率的前提下,提高传输数据的可靠性,就成为一个迫切需要解决的问题。
编号:《DSP技术与应用》课程论文卷积码的维特比译码的分析与实现论文作者姓名:______ ______作者学号:___ ______所在学院:所学专业:_____ ___导师姓名职称:__ _论文完成时间: _目录摘要: (1)0 前言 (2)1 理论基础 (2)1.1信道理论基础 (2)1.2差错控制技术 (3)1.3纠错编码 (4)1.4线性分组码 (5)2 卷积码编码 (7)2.1 卷积码概要 (7)2.2 卷积码编码器 (8)2.3卷积码的图解表示 (8)2.4 卷积码的解析表示 (11)3 卷积码的译码 (14)3.1 维特比译码 (15)3.2 代数译码 (17)3.3 门限译码 (18)4 维特比译码器实现 (18)4.1 TMS320C54 系列DSP概述 (18)4.2 Viterbi译码器的DSP实现 (19)4.3 实现结果 (21)5 结论 (21)参考文献 (22)II卷积码的维特比译码的分析与实现摘要:针对数据传输过程中的误码问题,本文论述了提高数据传输质量的一些编码及译码的实现问题。
自P.Elias 首次提出卷积码编码以来,这一编码技术至今仍显示出强大的生命力。
在与分组码同样的码率R 和设备复杂性的条件下,无论从理论上还是从实际上均己证明卷积码的性能至少不比分组码差,且实现最佳和准最佳译码也较分组码容易。
目前,卷积码已广泛应用在无线通信标准中,其维特比译码则利用码树的重复性结构,对最大似然译码算法进行了简化。
本文所做的主要工作:首先对信道编码技术进行了研究,根据信道中可能出现的噪声等问题对卷积码编码方法进行了主要阐释。
其次,对卷积码维特比译码器的实现算法进行了研究,完成了译码器的软件设计。
最后,结合实例,采用DSP芯片实现卷积码的维特比译码算法的仿真和运行。
关键词:卷积码维特比译码DSPConvolutional codes and Viterbi decoding analysis andrealizationZhang Yi-Fei(School of Physics and Electronics, Henan University, Henan Kaifeng 475004, China) Abstract:Considering the error bit problem during data transmission,this thesis discussed some codings and decoders,aiming at enhancing transmission performance. From P.Elias first gave the concept of convolutional code, it has show its’ great advantage. Under the same condition and the same rate of block code, the performance of convolutional code is better than block code, and it’s easier to implement the best decoding.Convolutional codes have been widely used in wireless communication standards, the Viterbi decoding using the repetitive structure of the code tree, the maximum likelihood decoding algorithm has been simplified. Major work done in this article: First, the channel coding techniques have been studied, the main interpretation of the convolutional code encoding method according to the channel may be noise and other issues.Secondly, the convolutional code Viterbi decoder algorithm has been studied, the software design of the decoder.Finally, with examples, simulation and operation of the DSP chip convolutional codes, Viterbi decoding algorithm.1Key words:convolutional code Vltebri decoder DSP0 前言随着数据处理、计算机通信、卫星通信以及高速数据通信网的飞速发展,用户对数据传输的可靠性提出了越来越高的要求,因此如何在保证数据传输速率的前提下,提高传输数据的可靠性,就成为一个迫切需要解决的问题。
卷积码编码和维特比译码的原理、性能与仿真分析1.引言卷积码的编码器是由一个有k位输入、n位输出,且具有m位移位寄存器构成的有限状态的有记忆系统,通常称它为时序网络。
编码器的整体约束长度为v,是所有k个移位寄存器的长度之和。
具有这样的编码器的卷积码称作[n,k,v]卷积码。
对于一个(n,1,v)编码器,约束长度v等于存储级数m.卷积码是由k个信息比特编码成n(n>k)比特的码组,编码出的n比特码组值不仅与当前码字中的k个信息比特值有关,而且与其前面v个码组中的v*k个信息比特值有关。
卷积码有三种译码方式:序列译码、门限译码和概率译码。
其中,概率译码根据最大似然译码原理在所有可能路径中求取与接收路径最相似的一条路径,具有最佳的纠错性能,维特比译码是概率译码中极重要的一种方式。
序列译码和门限译码则不一定能找出与接收路径最相似的一条路径。
不同于维特比译码,门限译码与序列译码所需的计算量是可变的且对于给定信息分组的最终判决仅仅基于(m+1)个接收分组,而不是基于整个接收序列。
与维特比译码所使用的对数似然量度不同,序列译码所使用的量度为Fano量度。
在接收序列受扰严重的情况下,序列译码的计算量大于维特比译码所需的固定计算量,虽然序列译码要求的平均计算次数通常小于维特比译码。
在采用并行处理的情况下,维特比译码的速度会优于序列译码。
在同样码率和存储级数的条件下,门限译码的性能比维特比译码低大约3dB.维特比译码的数据输出方式有硬判决及软判决两种方式,本文选取生成多项式为561,753的(2,1,8)卷积码对硬判决的性能进行分析,并依据维特比译码的原理以及卷积码的特性,对卷积码编码和维特比译码过程在加性高斯白噪声(AWGN)信道下进行仿真,并且根据仿真结果对维特比译码(硬判决)的结果进行分析。
由于卷积码的生成可以看做一个马尔科夫过程,因此,不同状态间的转移概率对描述这个过程有极关键的作用。
本文则基于MATLAB对不同状态间的转移概率进行求解,从而更准确地分析维特比译码的性能。
第4卷 第6期信息与电子工程Vo1.4,No.6 2006年12月INFORMATION AND ELECTRONIC ENGINEERING Dec.,2006 文章编号:1672-2892 (2006)06-0467-03(2,1,7)卷积编码及其维特比译码算法的软件实现刘少阳,邹永(国防科技大学电子科学与工程学院,湖南长沙 410073)摘要:提出了一种(2,1,7)卷积编码及其维特比(Viterbi)译码的软件实现方案,在Matlab环境中应用软件技术实现了(2,1,7)卷积码的Viterbi译码器功能。
测试证明,该Viterbi译码算法在低信噪比下的误码率仍能达到10-6。
关键词:卷积编码;维特比译码;Matlab中图分类号:TN957.51+3 文献标识码:ASoftware Implementation of (2,1,7) Convolutional Coding andIts Viterbi Decoding AlgorithmLIU Shao-yang,ZOU Yong(School of Electronic Science and Engineering,National University of Defense Technology,Changsha Hunan 410073,China)Abstract: A software scheme of (2,1,7) convolutional coding and Viterbi decoding technology is presented,which implements Viterbi decoder function of (2,1,7) convolutional code in the Matlab.According to the test, the BER(Bit Error Rate)of Viterbi algorithm can still reach 10-6in the lowSNR( Signal-to-Noise Ratio).Key words: convolutional coding;Viterbi decoding;Matlab1 引言卷积码是由Elias于1955年提出的。
卷积译码的维特比算法和实现技术高宇晨; 武永军; 沈保锁<天津大学 电子信息工程学院; 天津 &***-"=摘 要:介绍了卷积编码、解码的原理及适用于卷积码和网格码维特比译码的编程技术,叙述了用德州仪器(>?)>@0&"*A ’B 9 实现维特比算法的过程。
认为此基本方法可用于对任何卷积码进行解码和译码,比如序列译码等。
关键词:卷积码;维特比算法;网格路径;蝶形结构 中图分类号:>3,%%C "%卷积码和分组码文献标识码:D文章编号:%**E $-’’"("**%)*"$***-$*’另外,卷积码的译码也有其优点,例如利用网格图来寻找最大可能的码序列,通过维特比算法 (78)来限制序列检测的数目和简化解码的任务, 以及为每个状态最可能的路径建立一个新的标示 符号等等。
以下对卷积码编、解码的原理进行具体 的讨论。
!"! 编码过程卷积编码的纠错依靠了过去输出的数据值。
每 一编码输出位均是由输入位与进入移位寄存器存 储的前(3$%)位(未编码位)的卷积形成的。
这个过 程如图 % 所示。
即信息位输入多级移位寄存器后, 各级寄存器的输出可以分接在不同的分接点上,分 接点再通过一个布尔(9:/)函数进行运算,便产生 输出位。
! 卷积码是一种位编码和非系统码,而不是如同里德$所罗门(/$0)码的分组码。
一个(1,2,3)卷 积码,在编码后码元不仅与当前段的 2 个码元信 息有关,而且与前面(3$%)段的信息有关,在编码 过程中相互关联码的码元为 1·3 个。
该卷积码编 码后的输出序列 1 较小,延时也较小,适用于串行形 式传输的信号。
卷积码与分组码相比有以下优点:(%)卷积码对数据采用软判决的方式,当差错 率增加时卷积编码系统的增益呈温和恶化状,而分 组码则在差错率超过一个阈值后,增益会快速下掉。
实验二--卷积码编码及译码实验实验二卷积码编码及译码实验一、实验目的通过本实验掌握卷积编码的特性、产生原理及方法,卷积码的译码方法,尤其是维特比译码的原理、过程、特性及其实现方法。
二、实验内容1、观察NRZ基带信号及其卷积编码信号。
2、观察帧同步信号的生成及巴克码的特性。
3、观察卷积编码信号打孔及码速率匹配方法。
4、观察接收端帧同步过程及帧同步信号。
5、观察译码结果并深入理解维特比译码的过程。
6、观察随机差错及突发差错对卷积译码的影响。
三、基本原理1、卷积码编码卷积码是一种纠错编码,它将输入的k个信息比特编成n个比特输出,特别适合以串行形式进行传输,时延小。
卷积码编码器的形式如图17-1所示,它包括:一个由N段组成的输入移位寄存器,每段有k 段,共Nk 个寄存器;一组n 个模2和相加器;一个由n 级组成的输出移位寄存器,对应于每段k 个比特的输入序列,输出n 个比特。
12…k 12…k …12…k12…n 卷积码输出序列信息比特一次移入k 个Nk 级移位寄存器…图17-1 卷积编码器的一般形式由图17-1可以看到,n 个输出比特不仅与当前的k 个输入信息有关,还与前(N -1)k 个信息有关。
通常将N 称为约束长度(有的书中也把约束长度定为nN 或N -1)。
常把卷积码记为:(n 、k 、N ),当k =1时,N -1就是寄存器的个数。
编码效率定义为:/c R k n (17-1)卷积码的表示方法有图解表示法和解析表示法两种:解析法,它可以用数学公式直接表达,包括离散卷积法、生成矩阵法、码生成多项式法;图解表示法,包括树状图、网络图和状态图(最的图形表达形式)三种。
一般情况下,解析表示法比较适合于描述编码过程,而图形法比较适合于描述译码。
(1)图解表示法(2)解析法下面以(2,1,3)卷积编码器为例详细讲述卷积码的产生原理和表示方法。
(2,1,3)卷积码的约束长度为3,编码速率为1/2,编码器的结构如图17-2所示。
一、概述卷积码是一种常用的编码技术,用于提高数字通信系统的可靠性和抗干扰能力。
而编码的解码过程则需要运用编译码技术,以恢复原始数据。
Matlab作为一种强大的工程仿真软件,可以用来对卷积码编译码进行仿真分析,帮助工程师们更好地理解和优化卷积码系统,提高通信系统的性能。
二、卷积码原理1. 卷积码的概念卷积码是一种线性块码,它采用移位寄存器和模2加法器进行编码,通过引入冗余比特来提高信号的可靠性。
卷积码的编码过程可以简单描述为:将输入信息数据与特定的生成多项式进行卷积运算,得到编码后的输出数据。
2. 卷积码的特点卷积码具有较高的编码效率和能够很好地控制码长、纠错能力等特性,因此在实际通信系统中得到广泛应用。
三、编译码原理1. Viterbi算法卷积码的译码过程通常采用Viterbi算法,它是一种最大似然译码算法,通过计算最小距离路径的方式来进行译码。
Viterbi算法能够有效地对卷积码进行解码,提高译码的准确性。
2. 编译码的实现在Matlab中,编译码的实现通常是通过编写一定的程序来模拟Viterbi算法的译码过程。
通过仿真分析,可以评估不同的编码方案对通信系统性能的影响。
四、Matlab仿真环境1. Matlab的特点Matlab作为一种强大的仿真软件,具有丰富的工具和函数库,能够方便地进行数字通信系统设计与仿真分析。
Matlab提供了直观的图形界面和强大的数据处理能力,可用于展示仿真结果和进行数据分析。
2. 使用Matlab进行卷积码编译码仿真在Matlab环境中,可以编写程序来实现卷积码的编码和Viterbi算法的译码过程。
通过调用Matlab中的工具函数和绘图函数,可以直观地展示通信系统的性能指标,并对比不同编码方式的性能差异。
五、仿真实例分析1. 卷积码编码仿真我们可以编写Matlab程序,实现对卷积码的编码过程。
通过模拟不同的编码率和约束长度,可以观察到编码后的效果,并评估编码的性能。
卷积码的维特比译码卷积编码器自身具有网格构造,基于此构造我们给出两种译码算法:Viterbi 译码算法和BCJR 译码算法。
基于某种准那么,这两种算法都是最优的。
1967 年,Viterbi 提出了卷积码的Viterbi 译码算法,后来Omura 证明Viterbi 译码算法等效于在加权图中寻找最优途径问题的一个动态规划〔Dynamic Programming〕解决方案,随后,Forney 证明它实际上是最大似然〔ML,Maximum Likelihood〕译码算法,即译码器选择输出的码字通常使接收序列的条件概率最大化。
BCJR 算法是1974 年提出的,它实际上是最大后验概率〔MAP,Maximum A Posteriori probability〕译码算法。
这两种算法的最优化目的略有不同:在MAP 译码算法中,信息比特错误概率是最小的,而在ML 译码算法中,码字错误概率是最小的,但两种译码算法的性能在本质上是一样的。
由于Viterbi 算法实现更简单,因此在实际应用比较广泛,但在迭代译码应用中,例如逼近Shannon 限的Turbo 码,常使用BCJR 算法。
另外,在迭代译码应用中,还有一种Viterbi 算法的变种:软输出Viterbi 算法〔SOV A,Soft-Output Viterbi Algorithm〕,它是Hagenauer 和Hoeher 在1989 年提出的。
为了理解Viterbi 译码算法,我们需要将编码器状态图按时间展开〔因为状态图不能反映出时间变化情况〕,即在每个时间单元用一个分隔开的状态图来表示。
例如〔3,1,2〕非系统前馈编码器,其生成矩阵为:G(D)=[1+D1+D21+D+D2]〔1〕图1 〔a〕〔3,1,2〕编码器〔b〕网格图〔h=5〕假定信息序列长度为h=5,那么网格图包含有h+m+1=8 个时间单元,用0 到h+m=7 来标识,如图1〔b〕所示。
假设编码器总是从全0 态S0 开始,又回到全0 态,前m=2 个时间单元对应于编码器开始从S0“启程〞,最后m=2 个时间单元对应于向S0“返航〞。
动态规划:卷积码的Viterbi译码算法学院:网研院姓名:xxx 学号:xxx 一、动态规划原理动态规划(dynamic programming)是运筹学的一个分支,是求解决策过程(decision process)最优化的数学方法。
动态规划算法通常用于求解具有某种最优性质的问题。
在这类问题中,可能会有许多可行解,每一个解都对应于一个值,我们希望找到具有最优值的解。
动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。
与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。
若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算了很多次。
如果我们能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算,节省时间。
动态规划程序设计是对解最优化问题的一种途径、一种方法,而不是一种特殊算法。
不象搜索或数值计算那样,具有一个标准的数学表达式和明确清晰的解题方法。
动态规划程序设计往往是针对一种最优化问题,由于各种问题的性质不同,确定最优解的条件也互不相同,因而动态规划的设计方法对不同的问题,有各具特色的解题方法,而不存在一种万能的动态规划算法,可以解决各类最优化问题。
二、卷积码的Viterbi译码算法简介在介绍维特比译码算法之前,首先了解一下卷积码编码,它常常与维特比译码结合使用。
(2,1,3)卷积码编码器是最常见的卷积码编码器,在本次实验中也使用了(2,1,3)卷积码编码器,下面介绍它的原理。
(2,1,3)卷积码是把信源输出的信息序列,以1个码元为一段,通过编码器输出长为2的一段码段。
该码段的值不仅与当前输入码元有关,而且也与其之前的2个输入码元有关。
如下图所示,输出out1是输入、第一个编码器存储的值和第二个编码器存储的值逻辑加操作的结果,输出out2是输入和第二个编码器存储的值逻辑加操作的结果。
卷积码编码维特比译码实验设计报告SUN一、实验目的掌握卷积码编码和维特比译码的基本原理,利用了卷积码的特性, 运用网格图和回溯以得到译码输出。
二、实验原理1.卷积码是由连续输入的信息序列得到连续输出的已编码序列。
其编码器将k个信息码元编为n个码元时,这n个码元不仅与当前段的k个信息有关,而且与前面的(m-1)段信息有关(m为编码的约束长度)。
2.一般地,最小距离d表明了卷积码在连续m段以内的距离特性,该码可以在m个连续码流内纠正(d-1)/2个错误。
卷积码的纠错能力不仅与约束长度有关,还与采用的译码方式有关。
3. 维特比译码算法基本原理是将接收到的信号序列和所有可能的发送信号序列比较,选择其中汉明距离最小的序列认为是当前发送序列。
卷积码的Viterbi 译码是根据接收码字序列寻找编码时通过网格图最佳路径的过程,找到最佳路径即完成了译码过程,并可以纠正接收码字中的错误比特。
4.所谓“最佳”, 是指最大后验条件概率:P( C/ R) = max [ P ( Cj/ R) ] , 一般来说, 信道模型并不使用后验条件概率,因此利用Beyes 公式、根据信道特性出结论:max[ P ( Cj/ R) ]与max[ P ( R/ Cj) ]等价。
考虑到在系统实现中往往采用对数形式的运算,以求降低运算量,并且为求运算值为整数加入了修正因子a1 、a2 。
令M ( R/ Cj) = log[ P ( R/ Cj) ] =Σa1 (log[ P( Rm/ Cmj ) ] + a2) 。
其中, M 是组成序列的码字的个数。
因此寻找最佳路径, 就变成寻找最大M( R/ Cj) , M( R/ Cj) 称为Cj 的分支路径量度,含义为发送Cj 而接收码元为R的似然度。
5.卷积码的viterbi译码是根据接收码字序列寻找编码时通过网格图最佳路径的过程,找到最佳路径即完成了译码过程并可以纠正接收码字中的错误比特。
三、实验代码#include<stdio.h>#include "Conio.h"#define N 7#include "math.h"#include <stdlib.h>#include<time.h>#define randomize() srand((unsigned)time(NULL))encode(unsigned int *symbols, /*编码输出*/unsigned int *data, /*编码输入*/unsigned int nbytes, /*nbytes=n/16,n为实际输入码字的数目*/unsigned int startstate /*定义初始化状态*/)////////////////////////////////////////////////////////////////////////////卷积码编码///////////////////////////////////////////////////////////////////////////////{unsigned int j;unsigned int input,a1=0,a2=0,a3=0,a4=0,a5=0,a6=0;for(j=0;j<nbytes;j++){input=*data;data++;*symbols = input^a1^a2^a3^a6; //c1(171)symbols++;*symbols = input^a2^a3^a5^a6; //c2(133)symbols++;a2=a1;a1=input;}return 0;}int trandistance(int m, int state1, int state2)/*符号m与从state1到state2时输出符号的汉明距离,如果state1无法到state2则输出度量值为100*/{int c;int sym,sym1,sym2;sym1=((state2>>1)&1)^(state2&1)^(state1&1);sym2=((state2>>1)&1)^(state1&1);sym=(sym1<<1) | sym2;if ( ((state1&2)>>1)==(state2&1))c=((m&1)^(sym&1))+(((m>> 1)&1)^((sym >> 1)&1));elsec=10000;return(c);}int traninput(int a,int b) /*状态从a到b时输入卷积码的符号*/{int c;c=((b&2)>>1);return(c);}int tranoutput(int a,int b) /*状态从a到b时卷积码输出的符号*/{int c,s1,s2;s1=(a&1)^((a&2)>>1)^((b&2)>>1);s2=(a&1)^((b&2)>>1);c=(s1<<1)|s2;return(c);}////////////////////////////////////////////////////////////////////////////维特比译码///////////////////////////////////////////////////////////////////////////////void viterbi(int initialstate, /*定义解码器初始状态*/int *viterbiinput, /*解码器输入码字序列*/int *viterbioutput /*解码器输出码字序列*/){struct sta /*定义网格图中每一点为一个结构体,其元素包括*/ {int met; /*转移到此状态累计的度量值*/int value; /*输入符号*/struct sta *last; /*及指向前一个状态的指针*/};struct sta state[4][N];struct sta *g,*head;int i,j,p,q,t,r,u,l;for(i=0;i<4;i++) /* 初始化每个状态的度量值*/for(j=0;j<N;j++)state[i][j].met=0;for(l=0;l<4;l++){state[l][0].met=trandistance(*viterbiinput,initialstate,l);state[l][0].value=traninput(initialstate,l);state[l][0].last=NULL;}viterbiinput++; /*扩展第一步幸存路径*/for(t=1;t<N;t++){for(p=0;p<4;p++){state[p][t].met=state[0][t-1].met+trandistance(*viterbiinput,0,p);state[p][t].value=traninput(0,p);state[p][t].last=&state[0][t-1];for(q=0;q<4;q++){if(state[q][t-1].met+trandistance(*viterbiinput,q,p)<state[p][t].met){state[p][t].met=state[q][t-1].met+trandistance(*viterbiinput,q,p);state[p][t].value=traninput(q,p);state[p][t].last=&state[q][t-1];}}}viterbiinput++;} /*计算出剩余的幸存路径*/r=state[0][N-1].met; /*找出n步后度量值最小的状态准备回溯路由*/g=&state[0][N-1];for(u=N;u>0;u--) /*向前递归的找出最大似然路径*/{*(viterbioutput+(u-1))=g->value;g=g->last;}/* for(u=0;u<8;u++)*(viterbioutput+u)=state[u][2].met; */ /*此行程序可用于检测第n列的度量值*/}void decode(unsigned int *input, int *output,int n){int viterbiinput[100];int j;for(j=0;j<n+2;j++){viterbiinput[j]=(input[j*2]<<1)|input[j*2+1];}viterbi(0,viterbiinput,output);}void main(){unsigned intencodeinput[100],wrong[10]={0,0,0,0,0,0,0,0,0,0},encodeoutput[100];int n=5,i,m,j=0,decodeinput[100],decodeoutput[100];randomize();for(i=0; i<n; i++)encodeinput[i]=rand()%2;encodeinput[n]= encodeinput[n+1]=0;encode(encodeoutput,encodeinput,n+2,0);printf("the input of encoder is :\n"); //信息源输入的信息码(随机产生)for(i=0;i<n; i++)printf("%2d",encodeinput[i]);printf("\n");printf("the output of encoder is :\n"); //编码之后产生的卷积码for(i=0;i<(n+2)*2;i++){printf("%2d",encodeoutput[i]);if(i%20==19)printf("\n");}printf("\n");printf("please input the number of the wrong bit\n"); //信道传输收到干扰而产生的错误码scanf("%d",&m);printf("please input the positions of the wrong bit(0-9)\n");for(i=0;i<m;i++){scanf("%d",&wrong[m]);if(encodeoutput[wrong[m]]==0)encodeoutput[wrong[m]]=1;elseencodeoutput[wrong[m]]=0;}printf("the input of decoder is :\n");for(i=0;i<(n+2)*2;i++){printf("%2d",encodeoutput[i]);if(i%20==19)printf("\n");}printf("\n");decode(encodeoutput,decodeoutput,n+2);printf("the output of decoder is :\n");for(i=0;i<n;i++)printf("%2d",decodeoutput[i]);printf("\n");for(i=0;i<n;i++){if(encodeinput[i]!=decodeoutput[i])j++;}printf("the number of incorrect bit is:%d\n",j);}四、实验总结(1)了解实验原理,分析实验所占数组变量很重要,也是相对考虑较多的;(2)对于读写文件,通过本实验更加熟悉;(3)记录实验程序最佳路径是本实验的难点;。
实验五维特比译码一、实验题目写一个维特比译码器软件,它接受下列输入:1、以八进制形式给出的码的参数,以及2、接收到的比特流。
二、实验目的1、理解和掌握卷积码的概念;2、掌握维特比译码的方法;三、算法设计四、程序分析min_dist(a,b)函数计算两个码字的汉明重量;num_jinzhi(num,jinzhi,wei)函数将十进制的num转换为进制为jinzhi的wei位数;init_state()函数是对state[ ]矩阵进行初始化操作;G矩阵存储码的参数的二进制形式;xinxi[ ]矩阵存储输入比特流;state[ ]矩阵存储如下表的状态;state 1 2 3 4 5 6 7 8 9 10 11 12 13状态点1 当前寄存器的状态输入为输入为时输出编码值寄存器下一状态输入为1输入为1时输出编码值寄存器下一状态输入为时的汉明距离输入为1时的汉明距离四条路径的汉明距离临时存储解码值当前解码值四条路径的汉明距离状态点2状态点3状态点4五、程序代码主函数:display('编码序列:');xinxi=[1 0 1 0 0 1 1 0 1]% in=0;input_g= '75';str_length=length(input_g);%-----------将输入的char型数字转换成二进制数------------------------% for i=1:str_lengthg_dec=base2dec(input_g,8);%将'75'这个8进制数转换成10进制g=num_jinzhi(g_dec,2,3*str_length);%将10进制数转换成2进制endg; %测试gglobal G;for i=1:str_lengthG_yuanshi(i,1:3)=g(3*i-2:3*i);%将得到的二进制数每三个分成一行endG=G_yuanshi';% ------------------------生成查询表格-----------------------------% state=init_state;% ---------------------以下为编码算法------------------------------ % xinxi_bu0=[xinxi 0 0];xinxi_length=length(xinxi_bu0); %这里的长度实际为补0后的长度state_temp=[0 0]; %初始的状态寄存器里面为00for i=1:xinxi_lengthfor j=1:4 %对应四种状态if isequal(state_temp,state{j,1})if xinxi_bu0(i)==0 %若输入为0code(2*i-1:2*i)=state{j,3};%输出码字state_temp=state{j,4}; %下一状态else if xinxi_bu0(i)==1 %若输入为1code(2*i-1:2*i)=state{j,6};%输出码字state_temp=state{j,7}; %下一状态endendbreak;endendenddisplay('信息编码如下:');code%---------------加入错误编码 (这里仅将第三位出错)---------------------- % code(3)=~code(3);display('出错后的编码:');code%---------------------以下为解码算法--------------------------------- % code_length=length(code); %这里的长度实际为补0后的长度state_temp=[0 0]; %初始的状态寄存器里面为00%计算最初始两个码字四条路径的汉明距离state{1,10}=min_dist(state{1,3},[code(1)code(2)])+min_dist(state{1,3},[code(3) code(4)]);%第一条路径的汉明距离state{2,10}=min_dist(state{1,3},[code(1)code(2)])+min_dist(state{1,6},[code(3) code(4)]);%第二条路径的汉明距离state{3,10}=min_dist(state{1,6},[code(1)code(2)])+min_dist(state{2,3},[code(3) code(4)]);%第三条路径的汉明距离state{4,10}=min_dist(state{1,6},[code(1)code(2)])+min_dist(state{2,6},[code(3) code(4)]);%第四条路径的汉明距离state{1,11}=[0 0];%存放第一条路径的前两个码字state{2,11}=[0 1];%存放第二条路径的前两个码字state{3,11}=[1 0];%存放第三条路径的前两个码字state{4,11}=[1 1];%存放第四条路径的前两个码字for i=1:4state{i,12}=state{i,11};end% for i=3:code_length/2;i=3;while i<=code_length/2temp=[code(2*i-1) code(2*i)]; %下一个码字(2位)%------------四种状态分别输入0/1后得到八种状态,每种可能的距离-----------% for j=1:4state{j,8}=min_dist(temp,state{j,3});%输入0的可能最小距离state{j,9}=min_dist(temp,state{j,6});%输入1的可能最小距离end%--------------------------每种状态所对应的下一编码---------------------% if(state{1,8}+state{1,10})<(state{3,8}+state{3,10}) %第一个状态点的路径选取state{1,12}=[state{1,11} 0];%获得下一个解码else state{1,12}=[state{3,11} 0];endif (state{1,9}+state{1,10})<(state{3,9}+state{3,10})%第二个状态点的路径选取state{2,12}=[state{1,11} 1];else state{2,12}=[state{3,11} 1];endif (state{2,8}+state{2,10})<(state{4,8}+state{4,10})%第三个状态点的路径选取state{3,12}=[state{2,11} 0];else state{3,12}=[state{4,11} 0];endif (state{2,9}+state{2,10})<(state{4,9}+state{4,10})%第四个状态点的路径选取state{4,12}=[state{2,11} 1];else state{4,12}=[state{4,11} 1];end%-------------state{:,13}用来临时存放每条路径的汉明重---------------%state{1,13}=min((state{1,8}+state{1,10}),(state{3,8}+state{3,10}));%第一个状态点在取汉明重量较小的那条路径state{2,13}=min((state{1,9}+state{1,10}),(state{3,9}+state{3,10}));%第二个状态点在取汉明重量较小的那条路径state{3,13}=min((state{2,8}+state{2,10}),(state{4,8}+state{4,10}));%第三个状态点在取汉明重量较小的那条路径state{4,13}=min((state{2,9}+state{2,10}),(state{4,9}+state{4,10}));%第四个状态点在取汉明重量较小的那条路径i=i+1;for j=1:4state{j,10}=state{j,13};%更新state{:,10}state{j,11}=state{j,12};%更新state{:,11}endend%-----------------------判断四组码中的最小距---------------------------% dis_temp=[state{1,10} state{2,10} state{3,10} state{4,10}];index=find(min(dis_temp) == dis_temp);if length(index)>1 %有多条最小路径时的处理方式index=index(1);enddecode_length=length(state{index,12});display('解码如下:')decode=state{index,12}(1:decode_length-2) %%去掉最后面的两个0%-------------------测试解码和原码是否完全相同------------------------% for i=1:decode_length-2test(i)=decode(i) - xinxi(i);enddisplay('检测解码是否正确码字如下'); test子函数:%----------------将十进制的 num转换为进制为jinzhi的wei位数--------------%function out=num_jinzhi(num,jinzhi,wei)% yushu=zeros(1,wei);%为了提高计算速度,提前申请输出数据的内存i=1;shang_pre=num;shang_back=num;while shang_back>=jinzhiyushu(i)=mod(shang_pre,jinzhi);%将10进制数变成二进制数i=i+1;shang_back=fix(shang_pre/jinzhi);shang_pre=shang_back;endyushu(i)=shang_back;for i=1:weiout_yushu(i)=yushu(wei-i+1);%将转换后的结果调整高位在前,低位在后endout=out_yushu;function out=init_state()global G;state=cell(4,7); %创建4*7的数组可以存储不同类型的数据state(:)={[0]};state{1,1}=[0 0];%见教材P164 生成初始状态state{2,1}=[1 0];state{3,1}=[0 1];state{4,1}=[1 1];for i=1:4state{i,2}=0;in=0;% % % 输入0temp=[in state{i,1}];state{i,3}=mod(temp*G,2); %输出值state{i,4}=[in state{i,1}(1)];%下一状态% % % 输入1in=1;state{i,5}=1;temp=[in state{i,1}];state{i,6}=mod(temp*G,2); %输出值state{i,7}=[in state{i,1}(1)];%下一状态endout=state;%--------------------------求两个码字的汉明重量------------------------% function out=min_dist(a,b)min_length=length(a);cnt=0;for i=1:min_lengthif a(i)~=b(i);cnt=cnt+1;endendout=cnt;六、程序运行结果。
卷积码的编译原理及仿真摘 要 本课程设计主要解决对一个卷积码序列进行维特比(Viterbi)译码输出,并通过Matlab 软件进行设计与仿真,并进行误码率分析。
实验原理QPSK :QPSK 是英文QuadraturePhaseShiftKeying 的缩略语简称,意为正交相移键控,是一种数字调制方式。
四相相移键控信号简称“QPSK ”。
它分为绝对相移和相对相移两种。
卷积码:又称连环码,是由伊莱亚斯(P.elias)于1955年提出来的一种非分组码。
积码将k 个信息比特编成n 个比特,但k 和n 通常很小,特别适合以串行形式进行传输,时延小。
卷积码是在一个滑动的数据比特序列上进行模2和操作,从而生成一个比特码流。
卷积码和分组码的根本区别在于,它不是把信息序列分组后再进行单独编码,而是由连续输入的信息序列得到连续输出的已编码序列。
卷积码具有误码纠错的能力,首先被引入卫星和太空的通信中。
NASA 标准(2,1,6)卷积码生成多项式为:346134562()1()1g D D D D Dg D D D D D=++++=++++ 其卷积编码器为:输入序列++输出c1输出c2图1.1 K=7,码率为1/2的卷积码编码器维特比译码:采用概率译码的基本思想是:把已接收序列与所有可能的发送序列做比较,选择其中码距最小的一个序列作为发送序列。
如果接收到L 组信息比特,每个符号包括v 个比特。
接收到的Lv 比特序列与2L 条路径进行比较,汉明距离最近的那一条路径被选择为最有可能被传输的路劲。
当L 较大时,使得译码器难以实现。
维特比算法则对上述概率译码做了简化,以至成为了一种实用化的概率算法。
它并不是在网格图上一次比较所有可能的2kL 条路径(序列),而是接收一段,计算和比较一段,选择一段最大似然可能的码段,从而达到整个码序列是一个最大似然值得序列。
下面以图2.1的(2,1,3)卷积码编码器所编出的码为例,来说明维特比解码的方法和运作过程。
维特比(Viterbi)译码是一种用于解码卷积码的算法,常用于通信和数据存储系统。
在MATLAB中实现维特比译码主要涉及以下步骤:定义模型参数:首先,你需要定义卷积码的生成矩阵和转移概率。
初始化路径:为每个可能的起始状态初始化一个路径。
递归计算:对于每个时间步,根据转移概率和接收信号,递归地计算每条路径的概率。
选择最佳路径:在每个时间步,选择具有最大概率的路径作为当前状态。
生成输出:根据最佳路径,生成输出序列。
终止条件:当达到终止状态或达到最大迭代次数时,停止计算。
下面是一个简单的MATLAB代码示例,演示了如何实现维特比译码:matlabfunction [decoded, decoded_path] = viterbi_decoder(received, G, num_states, init_state_prob) % received: 接收信号% G: 生成矩阵% num_states: 状态数% init_state_prob: 初始状态概率num_time_steps = length(received);transition_prob = zeros(num_states, num_states); % 转移概率矩阵% 初始化路径和概率矩阵path = zeros(num_time_steps, num_states);path(:, 1) = init_state_prob;path(:, 1) = path(:, 1) .* ones(size(path(:, 1))); % 设置初始路径prob = zeros(num_time_steps, 1); % 概率矩阵prob(1) = path(1,:) .* log2(init_state_prob); % 初始化概率矩阵% 递归计算for t = 2:num_time_stepsfor i = 1:num_statesfor j = 1:num_statestransition_prob(i,j) = G(:,j) * received(t) .* path(t-1,i); % 计算转移概率endend[~, max_state] = max(prob(t-1) + log2(transition_prob)); % 选择最佳状态path(t,:) = zeros(1, num_states); % 重置路径矩阵path(t, max_state) = 1; % 设置当前路径为最佳状态prob(t) = max_state + log2(prob(t-1) + log2(transition_prob)); % 更新概率矩阵end% 选择最佳路径和生成输出[~, max_time] = max(prob); % 选择具有最大概率的时间步作为终止状态decoded = path(:, max_time); % 生成输出序列end请注意,这只是一个基本的示例,可能需要根据您的具体应用和需求进行调整。
基于维特比算法的卷积码译码实验摘要:本文主要简述了卷积码的编码过程,以及维特比算法译码的主要原理,是将接收到的编码序列与所有可能的发送序列作比较,选出汉明距离最小的一个序列作为译码输出。
本文根据维特比算法译码原理在matlab编写了程序仿真,对(2,1,7)卷积码数据进行加高斯白噪声,对比不同信噪比下的维特比译码误比特率。
关键词:卷积码;维特比;误比特率1引言卷积码是一种非分组码,它在1955年被伊利亚斯提出的卷积码在编码时是把k个比特的信息段编写成n个比特的码组,但是其监督码元不仅与当前编码比特信息有关,还与前面(N-1)个比特有关,N为卷积码的编码约束度,卷积码通常记为(n,k,N)[1]。
根据卷积码的特性,它更适合用于前向纠错,对于许多实际情况下它的效果好于分组码,并且运算简单,它尤其适合用在被高斯白噪声所干扰的传输信道[2]。
本文主要探索的是(2,1,7)卷积码的译码算法。
2卷积码的编码原理卷积码的编码器的主要由移位寄存器、模2加法器组成。
如图1[3]所示,为(2,1,7)卷积码的编码示意图,其卷积码的生成多项式的八进制表示为(133,171),八进制133转化为二进制为1011011,其中1比特的位置即代表那个移位寄存器的值作为模2加法器的输入,即生成多项式133描述的是图1中模2加法器输出Y,与此同理,生成多项式171描述的是模2加法器输出X。
至于生成多项式为什么是133和171,这其中涉及到编码的检错纠错能力问题、编码的复杂程度等因素,本文不深入探索这个。
很显然,共需要6个移位寄存器,和两个模2加法器来完成编码。
初始状态时,编码器的移位寄存器的值为0。
如待编码的信息序列为11,当第一个数据从最左端进去时,输出X的值为1,输出Y的值为1。
移位寄存器最右边的值不要了,然后把剩下的移位寄存器的值往右边移动一位,再把数据1放在移位寄存器的最左边。
然后再输入第二位待编码数据1,同理输出X值为0,输出Y的值为1。
卷积码的维特比译码原理及仿真摘 要 本课程设计主要解决对一个卷积码序列进行维特比(Viterbi)译码输出,并通过Matlab 软件进行设计与仿真,并进行误码率分析。
实验原理QPSK :QPSK 是英文QuadraturePhaseShiftKeying 的缩略语简称,意为正交相移键控,是一种数字调制方式。
四相相移键控信号简称“QPSK ”。
它分为绝对相移和相对相移两种。
卷积码:又称连环码,是由伊莱亚斯(P.elias)于1955年提出来的一种非分组码。
积码将k 个信息比特编成n 个比特,但k 和n 通常很小,特别适合以串行形式进行传输,时延小。
卷积码是在一个滑动的数据比特序列上进行模2和操作,从而生成一个比特码流。
卷积码和分组码的根本区别在于,它不是把信息序列分组后再进行单独编码,而是由连续输入的信息序列得到连续输出的已编码序列。
卷积码具有误码纠错的能力,首先被引入卫星和太空的通信中。
NASA 标准(2,1,6)卷积码生成多项式为: 346134562()1()1g D D D D D g D D D D D=++++=++++其卷积编码器为:图1.1 K=7,码率为1/2的卷积码编码器维特比译码:采用概率译码的基本思想是:把已接收序列与所有可能的发送序列做比较,选择其中码距最小的一个序列作为发送序列。
如果接收到L 组信息比特,每个符号包括v 个比特。
接收到的Lv 比特序列与2L 条路径进行比较,汉明距离最近的那一条路径被选择为最有可能被传输的路劲。
当L 较大时,使得译码器难以实现。
维特比算法则对上述概率译码做了简化,以至成为了一种实用化的概率算法。
它并不是在网格图上一次比较所有可能的2kL 条路径(序列),而是接收一段,计算和比较一段,选择一段最大似然可能的码段,从而达到整个码序列是一个最大似然值得序列。
下面以图2.1的(2,1,3)卷积码编码器所编出的码为例,来说明维特比解码的方法和运作过程。
为了能说明解码过程,这里给出该码的状态图,如图2.2所示。
维特比译码需要利用图来说明移码过程。
根据卷积码画网格的方法,我们可以画出该码的网格图,如图2.3所示。
该图设接收到的序列长度为8,所以画8个时间单位,图中分别标以0至7。
这里设编码器从a 状态开始运作。
该网格图的每一条路径都对应着不同的输入信息序列。
由于所有可能输入信息序列共有2kL 个,因而网格图中所有可能的路径也为2L 条。
这里节点a=00,b=10,c=01,d=11。
b图2.1 (2,1,3)卷积码编码器图2.2 (2,1,3)卷积码状态图设输入编码器的信息序列为(11011000),则由编码器对应输出的序列为Y=(1101010001011100)。
若收到的序列R=(0101011001011100),对照网格图来说明维特比译码的方法。
首先选择接收序列的前6位序列R 1=(010101)同到达第3时刻的可能的8个码序列(即8条路径)进行比较,并计算出码距。
该例中到达第3时刻a 点的路径序列是(000000)和(111011),他们与R 1的距离分别为3和4;到达第3时刻b 点的路径序列是(000011)和(111000),他们与R 1的距离分别为3和4;到达第3时刻c 点的路径序列是(001110)和(110101),他们与R 1的距离分别为4和1;到达第3时刻d 点的路径序列是(001101)和(110110),他们与R 1的距离分别为2和3。
上述每个节点都保留码距较小的路径作为幸存路径,所以幸存路径码序列是(000000)、(000011)、(1101001)和(001101),如图2.4所示。
用于上面类似的方法可以得到第4、5、6、7时刻的幸存路径。
a bc d节点号 01234567图2.3 (2,1,3)卷积码网格图需要指出的是,对于某个节点,如果比较两条路径与接收序列的累计码距值相等时,则可以任意选者一条路径作为幸存路径,此时不会影响最终的译码结果。
在码的终了时刻a 状态,得到一条幸存路径。
如果2.5所示。
由此可看到译码器输出是R ’=(1101010001011100),即可变换成序列(11011000),恢复了发端原始信息。
比较R’和R 序列,可以看到在译码过程中已纠正了在码序列第1和第7位上的差错。
当然如果差错出现太频繁,以致超出卷积码的纠错能力,还是会发生纠误的。
a b c d节点号 0123a b c d节点号1234567 8图2.4 维特比译码第3时刻幸存路径图2.5 第8时刻幸存路径仿真分析本实验用matlab仿真一个简单的OFDM系统中,观察在不同信噪比下的卷积码和Viterbi算法软判决译码的性能,并与没有编码的接收信号的误码率进行比较。
主要调用函数的介绍:1. trellis = poly2trellis(7,[155 117]);产生约束长度为7,一输入两输出的卷积码,比特连接向量分别为:1101101,1001111;2. code = convenc(Signal,trellis);将原始信号进行卷积编码,编码器由上式产生;3.REdata=awgn(TrData,SNR(i),'measured');加性高斯白噪声信道;4. [d m p in] =vitdec(ReSig,trellis,tblen,'cont','soft',1);利用Viterbi 算法译卷积码。
ReSig为poly2trellis函数或istrellis函数定义的格形trellis结构的卷积码。
参数tblen 取正整数,表示记忆(traceback)深度。
参数'cont'代表解码操作模型,假设编码器在全零状态开始。
'soft'表示软判决,参数nsdec做信道量化。
仿真结果:下图显示的是在不同信噪比下,通过卷积编码和维特比译码与未编码的接收端误码率的对比。
在低信噪比时(小于等于7dB时),未编码的误码率要低于编码的误码率。
这是因为在低信噪比的情况下,卷积码的纠错能力范围超过纠错门限后,纠错码就不是纠错了,而是加错了。
当信噪比比较高时,编码的误码率要好于未编码的误码率。
图2卷积编码和原始信号在不同信噪比下的接收端的误码率程序代码:SNR=1:0.5:15; %信噪比取值;单位为db\Ns=10;datalength=256; %每个数据符号中可用子载波error_bit_rata_code=0; %经卷积编码后解调出的数据的误比特率error_bit_rata_nocode=0; %未经卷积编码后解调出的数据的误比特率for i=1:1:29Signal=double(rand(1,datalength*Ns)>0.5);trel = poly2trellis(7,[155 117]);code = convenc(Signal,trel);%进行串并转化Para=reshape(code,datalength,2*Ns);%进行QPSK数据调制,将数据分为两个通道,SigPara为datalength行2Ns列for j=1:Nss1(:,j)=Para(:,2*j-1);%ich为datalength行Ns列s2(:,j)=Para(:,2*j);endkmod=1./sqrt(2);s1=s1.*kmod;s2=s2.*kmod;x=s1+s2.*sqrt(-1); % 产生复信号y=ifft(x); %通过傅立叶反变换,将频域数据转换为时域数据ich2=real(y); %I信道取变换后的实部qch2=imag(y); %Q信道取变换后的虚部ich4=reshape(ich2,1,datalength*Ns);qch4=reshape(qch2,1,datalength*Ns);TrData=ich4+qch4.*sqrt(-1);% 加入高斯白噪声ReData=awgn(TrData,SNR(i),'measured');idata=real(ReData);qdata=imag(ReData);%进行串并转化idata1=reshape(idata,datalength,Ns);qdata1=reshape(qdata,datalength,Ns);Rex=idata1+qdata1.*sqrt(-1);ry=fft(Rex);ReIChan=real(ry);ReQChan=imag(ry);ReIChan=ReIChan/kmod;ReQChan=ReQChan/kmod;for j=1:NsRePara(:,2*j-1)=ReIChan(:,j);RePara(:,2*j)=ReQChan(:,j);endReSig=reshape(RePara,1,datalength*Ns*2);%符号抽样判决ReSig=double(ReSig>0.5);%维特比译码tblen= log2(trel.numInputSymbols)[d m p in] =vitdec(ReSig,trel,tblen,'cont','soft',1);%统计错误比特数,并计算误比特率error_bit_code=sum(abs(d(2:datalength*Ns)-Signal(1:datalength*Ns-1))) ; error_bit_nocode(i)=sum(abs(ReSig-code));error_bit_rata_code1=error_bit_code/length(Signal);error_bit_rata_code(i)=error_bit_rata_code1;error_bit_rata_nocode(i)=error_bit_nocode(i)/2/length(Signal);endfigure(1);plot(SNR,error_bit_rata_nocode,'-ro',SNR,error_bit_rata_code,'-.b');h=legend('没有卷积','卷积',1);grid on;。