维特比译码算法.docx

上传人:b****7 文档编号:9409208 上传时间:2023-02-04 格式:DOCX 页数:7 大小:16.86KB
下载 相关 举报
维特比译码算法.docx_第1页
第1页 / 共7页
维特比译码算法.docx_第2页
第2页 / 共7页
维特比译码算法.docx_第3页
第3页 / 共7页
维特比译码算法.docx_第4页
第4页 / 共7页
维特比译码算法.docx_第5页
第5页 / 共7页
点击查看更多>>
下载资源
资源描述

维特比译码算法.docx

《维特比译码算法.docx》由会员分享,可在线阅读,更多相关《维特比译码算法.docx(7页珍藏版)》请在冰豆网上搜索。

维特比译码算法.docx

维特比译码算法

这周空时码的老师布置了一个编程的作业,有一天晚上突然兴起,熬夜到2点多,把这个程序写完了,虽然这个程序写的不算简单,于我自己毕竟是自己还是挺喜欢的,同学说我这个编程思想可以有点受C++的影响,不过我看了他写的那个,发现他在巧用矩阵方面确实比我强一点。

下面我把程序贴出来,并做一些简单的说明。

%维特比算法

clearall;

closeall;

filename=['tempdata_viterbi_v'];

PAM=[-3-113];

N=10000;%产生序列的长度

%x=[-331-13-1-113-3];%输入x

x_path=ceil(4*rand(1,N));

fori=1:

N

x(i)=PAM(x_path(i));

end

y=zeros(1,length(x)+1);%输出y

path=zeros(length(y),4);%路径存储

L=zeros(length(y),4);%距离存储

d=zeros(1,4);

%SNR_dB=1:

2:

20;

%count=1;%计数器

forSNR_dB=1:

20

%检验输入序列

fori=1:

N

switchx(i)

case-3

case-1

case1

case3

otherwise

error('wronginput.');

end

end

%关于状态转移表(不加入噪声)y(i+1)=0.8*x(i+1)-0.6*x(i)

P=[PAM;PAM;PAM;PAM];

state=(0.8*P'-0.6*P);%生成状态转移表--取原表的转置,便于计算

n=randn(1,length(x));%噪声

sigma=sqrt(5)*10^(-SNR_dB/20);

%经过信道

fori=1:

length(x)

ifi==1

y(i)=0.8*x(i)+sigma*n(i);

else

y(i)=0.8*x(i)-0.6*x(i-1)+sigma*n(i);

end

end

%viterbi

forj=1:

length(y);

ifj==1

d=(y(j)-0.8*PAM).^2;%求下一状态不同电平的距离

L(j,:

)=d;%保存距离

else

forjj=1:

4

d=(y(j)-state(jj,:

)).^2;%求下一状态不同电平的距离

temp_L=L(j-1,:

)+d;

%temp_L=d;

L(j,jj)=min(temp_L);

r=find(temp_L(1:

length(d))==min(temp_L));

iflength(r)==1%min值可能有相同,这个算法应该可以改进,目前默认取第一个相等的min值

path(j,jj)=r;

else

path(i,jj)=r

(1);

end

end

end

end

%找出最佳路径

path_final=ones(1,length(y)-1);

temp_L=L(length(y)-1,:

);

min_L=min(temp_L);

path_final(end)=find(temp_L(1:

length(temp_L))==min_L);

fori=1:

length(path_final)-1

path_final(length(path_final)-i)=path(length(path_final)-i+1,path_final(length(path_final)-i+1));

end

y_final=-3*ones(1,length(path_final));

fori=1:

length(path_final)

j=path_final(i);

y_final(i)=PAM(j);

end

%检验译码输出

fori=1:

N

switchy_final(i)

case-3

case-1

case1

case3

otherwise

error('wrongdecoder.');

end

end

%参数计算

error_pattern(SNR_dB,:

)=y_final-x;%错误图样

errorNumber(SNR_dB)=nnz(error_pattern(SNR_dB,:

))%错误数

FER(SNR_dB)=errorNumber(SNR_dB)/N;%错误率

end

%误码曲线图

snr=1:

SNR_dB;

semilogy(snr,FER);

xlabel('SNR(dB)');

ylabel('FER');

title('viterbi误码曲线图')

gridon;

save(filename)

说明

输入电平PAM=[-3-113]

序列长度N=10000

产生输入序列x

经过信道输出序列y

yi=0.8*xi-0.6*x(i-1)+n,其中是第i时刻输出,xi为第i时刻的输入

当i=0,x0=0,表示寄存器里没有数据

所以在源程序里面,用if语句把传输起始时刻和别的时刻分开计算。

下面列出的是对应得状态转移表:

-3

-1

1

3

-3

-0.6000

-1.8000

-3.0000

-4.2000

-1

1.0000

-0.2000

-1.4000

-2.6000

1

2.6000

1.4000

0.2000

-1.0000

3

4.2000

3.0000

1.8000

0.6000

译码过程中有两个需要存储的数据:

即当前状态的分支度量值和幸存的路径,分别用L和path来存,L中每个状态中存的都是这个状态以前的总的分支度量(随着i的增加不断累加),而path中存的是当前状态下的前一状态的选择出的最佳状态。

由于path中存的是前一状态,所以循环的次数应该为N+1次。

译码过程有三个步骤

1.Add:

即当前状态分支度量+幸存路径

2.Compare:

通过比较每一状态四条支路的度量

3.Selected:

找出度量最小值,即为该状态最佳路径

最后根据path里存的路径,从最后倒推找出最佳路径。

在这个过程中遇到了几个疑问;

1.本科学习通信原理时,里面讲到的维特比译码,它的起始和结尾状态都应该是零状态,这样做的目的也是为了检测序列是否发完,那么在这个维特比里是否也有某种方法来处理。

2.在译码过程中,调试程序的时候发现,如果在序列译码在中间某一状态时,发现该状态有几条分支最小度量相等,那么该如何选择分支。

在这个程序里面,自动默认找到的第一个最小度量。

附:

下面是我的同学写的matlab程序:

clearall

temp=[-3-113];

N=30;

sent1=zeros(1,N+1);

addgain=zeros(1,4);

addgain1=zeros(1,4);

result2=zeros(4,N);

result2(:

1)=[-3-113];

result1=zeros(4,N);

yy0=[-2.4-0.80.82.4];

yy=[-0.6-1.8-3-4.2;1-0.2-1.4-2.6;2.61.40.2-1;4.231.80.6];

SNR_dB=100;

sigma=10^(-SNR_dB/20)*sqrt(5)

%*****************************************

info=ceil(rand(1,N)*4);

sent=temp(info)

sent1(1,2:

end)=sent(1,1:

end);

%*****************************************

%****************************************

fori=1:

N

ii=i+1;

y(i)=sent1(ii)*(0.8)+sent1(i)*(-0.6);

end

y;

noise=randn(1,N)*sigma;

y=y+noise;

%*****************************************

%*****************************************

addgain=(yy0-y

(1)).^2;

%*******************************************

%******************************************

fori=2:

1:

N

forii=1:

4

xx=addgain+(yy(ii,:

)-y(i)).^2;

[minval,minnum]=min(xx);

xxx=minval-addgain(minnum);

addgain1(ii)=addgain(minnum)+xxx;

result1(ii,:

)=result2(minnum,:

);

result1(ii,i)=temp(ii);

end

addgain=addgain1;

result2=result1;

end

[minval,minnum]=min(addgain);

receive=result2(minnum,:

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 医药卫生 > 基础医学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1