卷积码编码和维特比译码
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
卷积码编码维特比译码实验设计报告
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
#include "Conio.h"
#define N 7
#include "math.h"
#include
#include
#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 { 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 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)); else c=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 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);