Viterbi1500030085王涛Word格式.docx
《Viterbi1500030085王涛Word格式.docx》由会员分享,可在线阅读,更多相关《Viterbi1500030085王涛Word格式.docx(7页珍藏版)》请在冰豆网上搜索。
序列依次移入一个两级移位寄存器,编码器每输入一位信息bi,输出端的开关就在c1和c2之间来回切换一次,输出为c1,i和c2,i,其中
c1,i=bi+bi-1+bi-2
c2,i=bi+bi-2
图1-1(2,1,2)卷积码编码器
设寄存器m1、m2的起始状态为全零,则编码器的输入输出时序关系可用图1-2表示。
图1-2(2,1,2)卷积码编码器的输入输出时序
要使最后1位输入同样影响3对输出,并且使编码器回到全零状态,还需使编码器多输出2对信息,为了做到这一点,需要增加2个时钟循环,并且在此期间保持输入为0,这一过程叫做“点亮”编码器。
如果不执行“点亮”操作,最后2位输入信息的纠错能力就会下降。
2、Viterbi译码原理(软判决)
维特比译码是基于最大似然准则的概率译码,它的基本思想是比较接收序列与所有可能的发送序列,从中选择与接收序列汉明距离最小的发送序列作为译码输出。
可能的发送序列与接收序列的汉明距离称为量度。
维特比译码使用网格图描述卷积码,每个可能的发送序列都与网格图中的一条路径相对应,如果在某个节点上发现某条路径已不可能与接收序列具有最小距离,那么就放弃这条路径,这样一直进行到倒数第二级。
由于这种方法较早地丢弃了那些不可能的路径,因而减轻了译码的工作量。
Viterbi译码分硬判决和软判决两种,在结构和译码过程上没有区别,区别在于分支度量的计算方法。
硬判决是指解调器根据其判决门限对接收到的信号波形直接进行判决后输出0或1,换句话说,就是解调器供给译码器作为译码用的每个码元只取0或1两个值,以序列之间的汉明距离作为度量进行译码,适用于二进制对称信道(BSC)。
而软判决的解调器不进行判决,直接输出模拟量,或是将解调器输出波形进行多电平量化(不是简单的0、1两电平量化),然后送往译码器,即编码信道的输出是没有经过判决的“软信息”。
软判决译码器以欧几里德距离作为度量进行译码,软判决译码算法的路径度量采用“软距离”而不是汉明距离,最常采用的是欧几里德距离,也就是接收波形与可能的发送波形之间的几何距离,是一种适合于离散无记忆信道(DMC)的译码方法。
下面利用图解的方法来说明维特比解码的方法和运作过程。
设输入编码器的信息序列为(11011000),则由编码器输出的序列Y=(1101010001011100),编码器的状态转移路线为abcdbdca。
若收到的序列R=(0101011001011100),对照网格图来说明维特比译码的方法。
由于该卷积码的约束长度为3位,因此先选择接收序列的前6位序列R1=(010101),同到达第3时刻可能的8个码序列(即8条路径)进行比较,并计算出码距。
该例中到达第3时刻a点的路径序列是(000000)和(111011),它们与R1的距离分别是3和4;
到达第3时刻b点的路径序列是(000011)和(111000),它们与R1的距离分别是3和4,到达第3时刻c点的路径序列是(001110)和(110110),与R1的距离分别是4和1;
到达第3时刻d点的路径序列是(001101)和(110110),与R1的距离分别是2和3。
上述每个节点都保留码距较小的路径为幸存路径,所以幸存路径码序列是(000000)、(000011)、(110101)和(001101),如图2-3(a)所示。
用与上面类同的方法可以得到第4、5、6、7时刻的幸存路径。
需指出对于某一个节点而言比较两条路径与接收序列的累计码距时,若发生两个码距值相等,则可以任选一路径作为幸存路径,此时不会影响最终的译码结果。
图2-3(b)给出了第5时刻的幸存路径,在码的终了时刻a状态,得到一根幸存路径,如图2-3(c)所示。
由此看到译码器输出是R’=(1101010001011100),即可变换成序列(11011000),恢复了发端原始信息。
比较R’和R序列,可以看到在译码过程中己纠正了在码序列第1和第7位上的差错。
当然,差错出现太频繁,以至超出卷积码的纠错能力,则会发生误纠,这是不希望的。
图2-3(a)
图2-3(b)
图2-3(c)
Viterbi译码的缺点是随着约束长度的增加算法的复杂度增加很快。
约束长度N为7时要比较的路径就有64条,为8时路径变为128条。
(2<
<
(N-1))。
所以Viterbi译码一般应用在约束长度小于10的场合中。
3、实验过程
1.产生数据
int*gen_data(longdata_len)//使用指针函数返回生成的输入数组
srand((unsigned)time(NULL));
//头文件是#include<
stdlib.h>
array=(int*)malloc(data_len*sizeof(int));
//开辟动态数组,为了防止栈溢出
for(t=0;
t<
data_len;
t++)
{
*(array+t)=(int)(rand()/(RAND_MAX/2)>
0.5);
}
2.卷积码编码原理
根据生成子元g[2][K]={{1,1,1,0,1},/*35*/
{1,0,0,1,1}};
/*23*/
然后编码
input_len+m;
t++)
shift_reg[sr_head]=*(unencoded_data+t);
//移位寄存器首指针指向unencoded_data
p=0;
q=0;
for(j=0;
j<
K;
j++){
k=(j+sr_head)%K;
p=p^shift_reg[k]&
g[0][j];
q=q^shift_reg[k]&
g[1][j];
3.高斯白噪声
floatgngauss(floatmean,floatsigma)//使用极坐标方法产生高斯白噪声
doublev1,v2,s,x1;
do
{
v1=2.0*rand()/RAND_MAX-1;
//第一步:
产生两个独立同分布的V(0,1)
v2=2.0*rand()/RAND_MAX-1;
s=v1*v1+v2*v2;
//第二步:
计算s
}while(s>
=1);
//第三步:
若s大于1,则返回第一步
if//否则,计算x1
(!
s)x1=0;
else
x1=v1*sqrt(-2.0*log(s)/s);
//log(s)默认对数的底为e
return(mean+sigma*x1);
4.软判决译码
主要是填充网格,然后选择最优路径:
for(j=0;
number_of_states;
j+=step)
//重复每个可能的卷积编码器的输出组
for(l=0;
l<
n;
l++)
branch_metric=0;
//计算每个通道符号的分支度量,以及所有的信道总和在卷积编码器的输出组信道符号
binary_output[0]=(output[j][l]&
0x00000002)>
>
1;
binary_output[1]=output[j][l]&
0x00000001;
branch_metric=branch_metric+
abs(*(channel_output_matrix+(0*channel_length+t))-7*binary_output[0])
+abs(*(channel_output_matrix+(1*channel_length+t))-7*binary_output[1]);
//选择累加误差最小的
if(accum_err_metric[nextstate[j][l]][1]>
accum_err_metric[j][0]+branch_metric)
accum_err_metric[nextstate[j][l]][1]=accum_err_metric[j][0]+branch_metric;
state_history[nextstate[j][l]][sh_ptr]=j;
}
}//循环l结束
}//j结束,更新网格
四、实验结果
可以观察到,输出译码结果与发送结果完全一致。
五、实验分析
软判决译码具有良好的译码效果,可以获得比硬判决多2~3dB的增益。
并且在信噪比增大情况下,其误码率也在下降。