213卷积码编码和译码.docx
《213卷积码编码和译码.docx》由会员分享,可在线阅读,更多相关《213卷积码编码和译码.docx(15页珍藏版)》请在冰豆网上搜索。
![213卷积码编码和译码.docx](https://file1.bdocx.com/fileroot1/2023-1/28/529ebe92-a9ec-4fd7-99c6-3cb5e67d5a4f/529ebe92-a9ec-4fd7-99c6-3cb5e67d5a4f1.gif)
213卷积码编码和译码
No.15(2,1,3)卷积码的编码及译码
摘要:
本报告对于(2,1,3)卷积码原理部分的论述主要参照啜刚教材和课件,编程仿真部分绝对原创,
所有的程序都是在Codeblocks8.02环境下用C语言编写的,编译运行都正常。
完成了卷积码的
编码程序,译码程序,因为对于短于3组的卷积码,即2bit或4bit纠错是没有意义的,所以对正确的短序列直接译码,对长序列纠错后译码,都能得到正确的译码结果。
含仿真结果和程序源代码。
如果您不使用Codeblocks运行程序,则可能不支持中文输出显示,但是所有的数码输出都是正确的。
一、卷积码编码原理
卷积码编码器对输入的数据流每次1bit或kbit进行编码,输出nbit编码符号。
但是输出的分支码字的每个码元不仅于此时可输入的k个嘻嘻有关,业余前m个连续式可输入的
信息有关,因此编码器应包含m级寄存器以记录这些信息。
k
通常卷积码表示为(n,k,m).编码率r—
n
当k=1时,卷积码编码器的结构包括一个由m个串接的寄存器构成的移位寄存器(成
为m级移位寄存器、n个连接到指定寄存器的模二加法器以及把模二加法器的输出转化为穿行的转换开关。
本报告所讲的(2,1,3)卷积码是最简单的卷积码。
就是n2,k1,m3的卷积
码。
每次输入1bit输入信息,经过3级移位寄存器,2个连接到指定寄存器的模二加法器,并把加法器输出转化为串行输出。
Encoder
OuTi>iit
编码器如题所示。
二、卷积码编码器程序仿真
C语言编写的仿真程序。
为了简单起见,这里仅仅提供数组长度30bit的仿真程序,当然如果需要可以修改数
组大小。
为了更精练的实现算法,程序输入模块没有提供非法字符处理过程,如果需要也可以增加相应的功能。
进入程序后,先提示输入数据的长度,请用户输入int(整型数)程序默认用户输入
的数据小于30,然后提示输入01数码,读入数码存储与input数组中,然后运算输出卷积码。
经过实验仿真,编码完全正确。
以下是举例:
a.课件上的输入101输出111000的实验
lei
惹和码输岀包
htl
10
ee
rpocessj*ecitpnedQC0x0>executiontime:
7.197
rressanyk^ytocontinue.
b更长的序列测试
'C:
\User2\吕静"'g5ktop\213巻积碍中ni\Debug\21>巻职码亡灼
PyQcesspetupnedQexecutiontine:
22.027
PT^essany](n,k)线性分组码的最卷积码的最大似然
三、卷积码译码原理
由有限状态移位寄存器产生的卷积码实质上是一个有限状态机。
大似然译码就是在所有合法码字中找出一个最接近接收码字的码字。
译码法则是对于给定的接收符号序列R找出最大可能的编码符号序列C。
维特比于1967
年提出的维特比算法能够系统地去除那些不可能具有最大度量的路径排除,从而降低了
最大似然译码的复杂度。
rSO=CIO,51^01,S2-10,S3-11
10
(2,1,3)卷积码的状态图
(2,1,3)卷积码的网格图
卷积码一码通常按最大似然法则一码,对二进制对称信道(BSC,它就等小于最小汉
明距离译码。
在这种译码器中,把接收序列和所有可能发送序列比较,选择一个汉明距离最小的序列盘坐发送序列。
由于信息序列编码序列有着对应关系,这种序列和网
格图的一条路径唯一对应,因此译码就是根据接收序列R在网格图上全力搜索编码器在
编码时经过的路径。
四、卷积码译码器程序仿真
C语言编写的仿真程序。
为了简单起见,这里仅仅提供数组长度2X10bit的仿真程序,当然如果需要可以修
改数组大小。
为了更精练的实现算法,程序输入模块没有提供非法字符处理过程,如果需要也可以增加相应的功能。
进入程序后,先提示输入数据的长度,请用户输入int(整型数)程序默认用户输入
的数据小于30,然后提示输入01数码,读入数码存储与input数组中,然后运算输出卷积码。
经过实验仿真,译码完全正确。
以下是举例:
a.课件上接收码字111000译码101的实验
/
□C\Users厲静\Wsldop\卷积码解础b;呱Debug、巻积码霹国.exe
b.对应上文中的,长序列译码测试结果
叵二CAUw刊叭昌静\Desktop童垠玛虽码IbinlObugR卷积码蔭穗启"
字?
的S组接几砸需请益
刖
01
31
11
11
le
00
01
共有思位错误,译码如
1011001011
&>{eeatiitntime:
22.042s
i*etai*ned.0(0x0>
Press■anyheytocontxnue.
c•译码与编码的区别在于容错性,如果在传输过程中有出错的比特,也应该用Viterbi
decoder在一定的范围内自动纠错,得到正确的发端的编码,并翻译出发端的原码。
本报告中对于比较长的序列(>2)进行纠错。
以课件中的例子进行仿真
R=[10100001110|l]
c=[ii40h00,0140/01]
R是收到的码字,C是发送方发出的正确的码字,R有2bit信息出现错误。
运行程序的到结果。
当用译码器接收正确的序列C时显示以下结果:
iimi祐字;
11
10
阴
31
13
01
共有0位错误,译码如下i
101110
BxecutIontine:
19-700s
Processpcttirned0<0x0)
Pressan^kej/tocontinite.
当接收到的序列错误时
R=[101000011101]
译码结果如下:
eTs\a嵯码冷biri\De袒嬌誓碍启鴉
la
la
|0i
11
ai
共有2位皓误.译码如下;
JppocesEreturned8executiontine:
26.488e
■pessAnykeytocontinue-
如此时把译码结果输入上文中的编码器程序,即可得到发送方发出的正确的码字:
c=[ii,io,oo,oi40,oi]
综上,译码程序能对于正确的较短(<3组)的卷积码序列进行译码,得到正确的译码结果。
对于较长的序列(>2)可以纠错,纠正后,得到正确的卷积码,然后译码得到原码。
程序仿真完全正确。
d.模拟一个元整的传输过程:
发送方输入序列11001010
输入到编码器程序中:
K'CAUsefiVS静2«^0口\6帕051022書号0阳6102班Nol5213巻积码
PpnreKS
Preaaflinykey
i*»titpnf!
dn得到卷积码输出:
若传送到接收端,
tocontinue”
1101011111100010
由于信道的各种干扰,接收码字发生了变化,得到的接收码字:
1111011101101110
共有2bit出现错误,输入到解码器中,纠错解码后得到:
iSSAfi组接”如]的数字:
11
11
01
11
91
16
90
LS
共有2位错误,译码如下:
11091910
Processreturned9<0x0>execiitiontine:
22.791s
Pressanykeytacontinue_
有效地纠错,解码,还原了发送方的信息。
e.进一步大量仿真得到结果:
当错误量比较多,或者比较集中时,有些时候不能有效地纠错,得到的译码结果可能也有1bit是错误的。
具体截图略。
五、编码C源程序清单
#include
#include
/*3
{
shortadd3(shorta,shortb,shortc)位模二加法器*/
shortsum;sum=a+b+c;sum=sum%2;returnsum;
shortadd2(shorta,shortb)
/*2位模二加法器*/
{
shortsum;
sum=a+b;
sum=sum%2;returnsum;
}
intmain()
{
shorta=0,b=0,c=0;
/*三个移位寄存器初始状态为0*/intlength=0;
/*输入长度*/
shortx,y;
/*两个输出寄存器*/
shortinput[30];
/*存储输入数据的数组*/
inti;
printf("需要输入几位数据?
");scanf("%d",&length);
printf("请输入%d位数字:
\n",length);for(i=0;i{
scanf("%1hd",&input[i]);
}
printf("卷积码输出:
\n");
for(i=0;ic=b;
b=a;
a=input[i];
/*移位运算*/x=add3(a,b,c);y=add2(a,c);printf("%d%d\n",x,y);
}return0;
}
六、译码程序清单
#include
#include
intde(codenow)
{
/*短序列不纠错解码器*/intdecode,now,code;now=codenow%100;
code=(codenow-now)/100;
/*分离状态和接收到的码字*/switch(now)
{
case10:
if(code==10)
{
now=01;decode=0;
}else
{
now=11;
decode=1;}break;
case11:
if(code==01){
now=01;decode=0;
}else
now=11;
decode=1;}break;
case01:
if(code==11){
now=00;decode=0;
}else
{
now=10;
decode=1;
}break;
case00:
if(code==00){
now=00;decode=0;
}else
{
now=10;decode=1;
}break;
default:
printf("error!
");
}codenow=decode*100+now;returncodenow;
}
inthanming(intx,inty)
{
/*计算xy两个2bit数的汉明距离*/intx1,x2,y1,y2,sum=0;
/*分解数位*/
x2=x%2;
x1=(x-x2)/10;y2=y%2;
y1=(y-y2)/10;if(x1!
=y1)sum++;
if(x2!
=y2)sum++;
returnsum;}
voidcorrect(intcode[],intlength)
/*长序列纠错解码器*/
{
inti,j,m,error=0;
int*p;
intd00=0,d10=0,d01=0,d11=0;
intdz00=0,dz10=0,dz01=0,dz11=0;
/*时刻1结束时*/
intlu00[10]={0,0};
intlu10[10]={0,1};
intlu01[10]={1,0};
intlu11[10]={1,1};
intlz00[10]={0},lz10[10]={0};
intlz01[10]={0},lz11[10]={0};
d00=hanming(code[0],0)+hanming(code[1],0);
d10=hanming(code[0],0)+hanming(code[1],11);
d01=hanming(code[0],11)+hanming(code[1],10);
d11=hanming(code[0],11)+hanming(code[1],01);
for(i=2;i{
/*00状态路径*/
if((d00+hanming(0,code[i]))<(d01+hanming(11,code[i]))){
for(j=0;j
{
lz00[j]=lu00[j];
}
lz00[i]=0;
dz00=d00+hanming(0,code[i]);
}else
for(j=0;j
{
lz00[j]=lu01[j];
}
lz00[i]=0;
dz00=d01+hanming(11,code[i]);
}/*10状态路径*/
if((d00+hanming(11,code[i]))<(d01+hanming(00,code[i]))){
for(j=0;j
{
lz10[j]=lu00[j];
}lz10[i]=1;dz10=(d00+hanming(11,code[i]));
}else
{
for(j=0;j
{
lz10[j]=lu01[j];
}
lz10[i]=1;
状态路径*/
dz10=d01+hanming(00,code[i]);
/*01
if((d10+hanming(10,code[i]))<(d11+hanming(01,code[i]))){
for(j=0;j
{
lz01[j]=lu10[j];
}lz01[i]=0;
dz01=d10+hanming(10,code[i]);
}else
{
for(j=0;j
{
lz01[j]=lu11[j];
}
lz01[i]=0;
dz01=d11+hanming(01,code[i]);
}/*11状态路径*/
if((d10+hanming(01,code[i]))<(d11+hanming(10,code[i]))){
for(j=0;j
{
lz11[j]=lu10[j];
}lz11[i]=1;
dz11=d10+hanming(01,code[i]);
}else
{
for(j=0;j
{
lz11[j]=lu11[j];
}lz11[i]=1;dz11=d11+hanming(10,code[i]);
/*更新*/
d00=dz00;
d10=dz10;
d01=dz01;
d11=dz11;
for(m=0;m{
lu00[m]=lz00[m];
}
for(m=0;m{
lu10[m]=lz10[m];
}
for(m=0;m{
lu01[m]=lz01[m];
}
for(m=0;mlu11[m]=lz11[m];
}
}
*/
/*最后一步,在四条路径中选择汉明距离最小的一条error=d00;
p=lu00;
if(d01{error=d01;p=lu01;
}
if(d10{error=d10;p=lu10;
}
if(d11{
error=d11;
p=lu11;
}
printf("共有%d位错误,译码如下:
\n",error);for(m=0;m{
printf("%d",*p);
p++;
}
intmain()
{
intcodenow=0;
intnow=0;
/*当前状态*/
intlength=0;
/*输入长度*/
intdecode;
/*输出*/
intcode[20];
/*存储输入数据的数组*/inti;
printf("需要输入几组数据?
");scanf("%d",&length);
printf("请输入%d组接收到的数字:
\n",length);for(i=0;i{
scanf("%2d",&code[i]);
}/*长度大于3的用Viterbidecoder纠错过程如下,*/if(length>2)
{
correct(code,length);
}
/*长度小于3的直接译码*/
else
{
printf("\n卷积码解码结果:
\n");
/*解码过程如下*/
for(i=0;i{
codenow=code[i]*100+now;codenow=de(codenow);now=codenow%100;
decode=(codenow-now)/100;printf("%d",decode);
}
}
return0;
}