viterbi译码算法实现及其性能仿真
  • 收藏任务 (2)
  • 订阅任务

    • 价格¥200
    • 任务编号:6174
    • 任务分类编程 >> 系统开发
    • 开始时间:2008-04-16 10:32:40
    • 结束时间:2008-04-21 10:32:40
    • 任务状态:任务已圆满结束
    中标稿件:

    中标模式

    单人中标模式,一人独享赏金。

    赏金申明

    本站已经收到客户的汇款,确定此任务总金额的80%可以支付 给被客户选中的会员。

    版权声明

    稿件如果被客户选中,在完成赏金支付后,该作品的全部知识产权自动转移给客户;如果没有被选中,可自行处理。

  • 任务发布者

    用户:jxph117156

    信用:5.0

    发送短消息加为好友

    任务秘书

    用户:猪八戒客服19号

    电话:023-68691132

    给我发邮件

    发送短信息加为好友

当前任务已有:1070人关注 10人报名 10个稿件 3篇交流  备选稿件(0)个  橱窗方式浏览 

稿件编号:1841932号    参加猪八戒礼品游戏之捉迷藏,免费礼品等你拿!
  • 泽一 爱心威客 VIP会员
  • 等 级:猪五戒
  • 信用值:
  • 能力值:
发布者已浏览查看所有交稿 时间:2008/04/16 13:29:39 评论:0票数:79   matlabviterbi译码算法

 

 

%维特比算法

clear all;
close all;

filename=['tempdata_viterbi_v'];
PAM=[-3 -1 1 3];
N=10000;                              %
产生序列的长度

%x=[-3 3 1 -1 3 -1 -1 1 3 -3];     %
输入x
x_path=ceil(4*rand(1,N));
for i=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;                           %
计数器
for SNR_dB=1:20
    %
检验输入序列
    for i=1:N
        switch x(i)
            case -3
            case -1
            case 1
            case 3
            otherwise
                error('wrong input.');
        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);
    %
经过信道

    for i=1:length(x)
        if i==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
    for j=1:length(y);
        if j==1
            d=(y(j)-0.8*PAM).^2;        %
求下一状态不同电平的距离

            L(j,:)=d;                   %
保存距离
        else
            for jj=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));
                if length(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);

    for i=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));
    for i=1:length(path_final)
        j=path_final(i);
        y_final(i)=PAM(j);
    end

    %检验译码输出
    for i=1:N
        switch y_final(i)
            case -3
            case -1
            case 1
            case 3
            otherwise
                error('wrong decoder.');
        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
误码曲线图')
grid on ;
save(filename)

说明

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

序列长度  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

  

译码过程中有两个需要存储的数据:即当前状态的分支度量值和幸存的路径,分别用Lpath来存,L中每个状态中存的都是这个状态以前的总的分支度量(随着i的增加不断累加),而path中存的是当前状态下的前一状态的选择出的最佳状态。由于path中存的是前一状态,所以循环的次数应该为N+1次。

译码过程有三个步骤

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

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

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

 

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

  
稿件编号:1843117号    参加猪八戒礼品游戏之捉迷藏,免费礼品等你拿!
  • jidaoyong VIP会员
  • 等 级:猪五戒
  • 信用值:
  • 能力值:
发布者已浏览查看所有交稿 时间:2008/04/16 19:54:04 评论:0票数:4   报个名,试试刀,q q :6 7 9 5 5 0 2  
稿件编号:1843160号    参加猪八戒礼品游戏之捉迷藏,免费礼品等你拿!
  • zmqhbd VIP会员
  • 等 级:猪六戒
  • 信用值:
  • 能力值:
发布者已浏览查看所有交稿 时间:2008/04/16 20:11:47 评论:0票数:75   

 viterbi译码算法(matlab)

简单,方便,简捷!

clear all
temp=[-3 -1 1 3];   %输入电平
N=30;      %产生序列的长度
sent1=zeros(1,N+1);

addgain=zeros(1,4);
addgain1=zeros(1,4);

result2=zeros(4,N);
result2(:,1)=[-3 -1 1 3];
result1=zeros(4,N);

yy0=[-2.4 -0.8 0.8 2.4];
yy=[-0.6 -1.8 -3 -4.2;1 -0.2 -1.4 -2.6;2.6 1.4 0.2 -1;4.2 3 1.8 0.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);
%*****************************************

%****************************************
for i=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;
%*******************************************

%******************************************
for i=2:1:N
    for ii=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,:)

  
稿件编号:1843174号    
  • zmqhbd VIP会员
  • 等 级:猪六戒
  • 信用值:
  • 能力值:
发布者已浏览查看所有交稿 时间:2008/04/16 20:17:39 评论:0票数:83   

 matlab实现viterbi译码算法


function [decoder_output,survivor_state,cumulated_metric]=viterbi(G,k,channel_output)
%维特比译码函数
%VITERBI 卷积码的维特比解码器
%[decoder_ouput,survivor_state,cumulated_metric]=viterbi(G,k,channel_output)
% G是一个n*Lk矩阵,该矩阵的每一行确
% 定了从移位记错器到第n个输出间的连接,
% 是码速率。
% survivor_state是表示通过网络的最佳路径的矩阵。
% 量度在另一个函数metric(x,y)中给出,而且可根据
% 硬判决和软判决来指定。
% 该算法最小化了量度而不是最大化似然
n=size(G,1); %取出矩阵G的一维大小,即得出输出端口
% 检查大小
if rem(size(G,2),k)~=0 %当G列数不是k的整数倍时
error('Size of G and k do not agree') %发出出错信息
end
if rem(size(channel_output,2),n)~=0 %当输出量元素个数不是输出端口的整数倍时
error('Channel output not of the right size') %发出出错信息
end
L=size(G,2)/k; %得出移位数,即寄存器的个数
% 由于L-1个寄存器的状态即可表示出输出状态,
% 所以总的状态数number_of_states可由前L-1个
% 寄存器的状态组合来确定
number_of_states=2^((L-1)*k);
% 产生状态转移矩阵、输出矩阵和输入矩阵
for j=0:number_of_states-1 %j表示当前寄存器组的状态因为状态是从零
%开始的,所以循环从0到number_of_states-1

for l=0:2^k-1 %l为从k个输入端的信号组成的状态,总的状
%态数为2^k,所以循环从0到2^k-11

% nxt_stat完成从当前的状态和输入的矢量得出下寄存器组的一个状态
[next_state,memory_contents]=nxt_stat(j,l,L,k);
% input数组值是用于记录当前状态到下一个状态所要的输入信号矢量
% input数组的维数: 一维坐标x=j+1指当前状态的值
% 二维坐标y=next_state+1指下一个状态的值
% 由于Matlab中数组的下标是从1开始的,而状态值
% 是从0开始的,所以以上坐标值为:状态值+1
input(j+1,next_state+1)=l;
% branch_output用于记录在状态j下输入l时的输出
branch_output=rem(memory_contents*G',2);
% nextstate数组记录了当前状态j下输入l时的下一个状态
nextstate(j+1,l+1)=next_state;
% output数组记录了当前状态j下输入l时的输出(十进制)
output(j+1,l+1)=bin2deci(branch_output);
end
end
% state_metric数组用于记录译码过程在每状态时的汉明距离
% state_metric大小为number_of_states 2,(:,1)当前
% 状态位置的汉明距离,为确定值,而(:,2)为当前状态加输入
% 得到的下一个状态汉明距离,为临时值
state_metric=zeros(number_of_states,2);
% depth_of_trellis用于记录网格图的深度
depth_of_trellis=length(channel_output)/n;
% 输出矩阵,每一列为一个输出状态
channel_output_matrix=reshape(channel_output,n,depth_of_trellis);
% survivor_state描述译码过程中在网格图中的路径
survivor_state=zeros(number_of_states,depth_of_trellis+1);
%开始无尾信道输出的解码
for i=1:depth_of_trellis-L+1 %i指示网格图的深度
% flag矩阵用于记录网格图中的某一列是否被访问过
flag=zeros(1,number_of_states);
if i<=L
step=2^((L-i)*k); %在网格图的开始处,并不是所有的状态都取
else %用step来说明这个变化
step=1; %状态数从1→2→4→...→number_of_states
end
for j=0:step:number_of_states-1 %j表示寄存器的当前状态
for l=0:2^k-1 %l为当前的输入
branch_metric=0; %用于记录码间距离
% 将当前状态下输入状态l时的输出output转为n位二进制,以便
% 计算码间距离(说明:数组坐标大小变化同上)。
binary_output=deci2bin(output(j+1,l+1),n);
% 计算实际的输出码同网格图中此格某种输出的码间距离
for ll=1:n
branch_metric=branch_metric+metric(channel_output_matrix(ll,i),binary_output(ll));
end
% 选择码间距离较小的那条路径
% 选择方法:
% 当下一个状态没有被访问时就直接赋值,否则,用比它小的将其覆盖
if((state_metric(nextstate(j+1,l+1)+1,2)>state_metric(j+1,1)...
+branch_metric)|flag(nextstate(j+1,l+1)+1)==0)
% 下一个状态的汉明距离(临时值)=当前状态的汉明距离(确定值)+ 码间距离
state_metric(nextstate(j+1,l+1)+1,2)=state_metric(j+1,1)+branch_metric;
% survivor_state数组的一维坐标为下一个状态值,二维坐标为此状态
% 在网格图中的列位置,记录的数值为当前状态,这样就可以从网格图中
% 某位置的某个状态得出其对应上一个列位置的状态,从而能很方便的完
% 成译码过程。
survivor_state(nextstate(j+1,l+1)+1,i+1)=j;
flag(nextstate(j+1,l+1)+1)=1; %指示该状态已被访问过
end
end
end
state_metric=state_metric(:,2:-1:1); %移动state_metric,将临时值移为确定值
end
%开始尾部信道输出解码
for i=depth_of_trellis-L+2:depth_of_trellis
flag=zeros(1,number_of_states);
% 状态数从number_of_states→number_of_states/2→...→2→1
% 程序说明同上,只不过输入矢量只为0
last_stop=number_of_states/(2^((i-depth_of_trellis+L-2)*k));
for j=0:last_stop-1
branch_metric=0;
binary_output=deci2bin(output(j+1,1),n);
for ll=1:n
branch_metric=branch_metric+metric(channel_output_matrix(ll,i),binary_output(ll));
end
if((state_metric(nextstate(j+1,1)+1,2)>state_metric(j+1,1)...
+branch_metric)|flag(nextstate(j+1,1)+1)==0)
state_metric(nextstate(j+1,1)+1,2)=state_metric(j+1,1)+branch_metric;
survivor_state(nextstate(j+1,1)+1,i+1)=j;
flag(nextstate(j+1,1)+1)=1;
end
end
state_metric=state_metric(:,2:-1:1);
end
% 从最佳路径中产生解码
% 译码过程可从数组survivor_state的最后一个位置向前逐级译码
state_sequence=zeros(1,depth_of_trellis+1);
% survivor_state数组的最后的输出状态肯定是“0”
state_sequence(1,depth_of_trellis)=survivor_state(1,depth_of_trellis+1);
% 逐级译码过程
for i=1:depth_of_trellis
state_sequence(1,depth_of_trellis-i+1)=survivor_state((state_sequence(1,depth_of_trellis+2-i)...
+1),depth_of_trellis-i+2);
end
decorder_output_matrix=zeros(k,depth_of_trellis-L+1);
for i=1:depth_of_trellis-L+1
% 根据数组input的定义来得出从当前状态到下一个状态的输入信号矢量
dec_output_deci=input(state_sequence(1,i)+1,state_sequence(1,i+1)+1);
% 转成二进制信号
dec_output_bin=deci2bin(dec_output_deci,k);
% 将一次译码存入译码输出矩阵decoder_output_matrix相应的位置
decoder_output_matrix(:,i)=dec_output_bin(k:-1:1)';
end
% 按照一维序列形式重新组织输出
decoder_output=reshape(decoder_output_matrix,1,k*(depth_of_trellis-L+1));
% state_metric为网格图最后一个列位置中“0”状态位置的汉明距
% 离,这个值就是整个译码过程中的汉明距离。
cumulated_metric=state_metric(1,1);
%卷积码的维特比译码函数

%nxt_stat.m 记录状态函数
% next_state用于记录下一个状态的值
% memory_contents用于记录
function [next_state,memory_contents]=nxt_stat(current_state,input,L,k)
% 将当前状态值(十进制)转成位数为k*(L-1)的二进制
binary_state=deci2bin(current_state,k*(L-1));
% 将输入状态值(十进制)转成位数为k的二进制序列
binary_input=deci2bin(input,k);
% 寄存器组的下一个状态值(二进制)
next_state_binary=[binary_input,binary_state(1:(L-2)*k)];
% 将寄存器组的下一个状态值(二进制)转成十进制
next_state=bin2deci(next_state_binary);
% 用memory_contents来记录各个寄存器在下一个状态下的信息(二进制)
% 以便与生成矩阵相乘得出输出
memory_contents=[binary_input,binary_state];
%nxt_stat.m 记录状态函数

 

 

 

 

 

  
稿件编号:1843227号    
  • zmqhbd VIP会员
  • 等 级:猪六戒
  • 信用值:
  • 能力值:
发布者已浏览查看所有交稿 时间:2008/04/16 20:35:31 评论:0票数:93   

viterbi译码算法(C语言实现)

//---------------------------------------------------------------------------
#include <stdlib.h>
#include <math.h>
#include "class.h"
#pragma hdrstop

//******************************************************************
//名称: MCreatMatrix
//功能: 产生生成距阵
//******************************************************************
__fastcall MCreatMatrix::MCreatMatrix()
{
Buffer=NULL;
Buffer=new Byte[1];
Row=0;
Column=0;
}

__fastcall MCreatMatrix::~MCreatMatrix()
{
if(Buffer!=NULL)
delete Buffer;
}

void MCreatMatrix::Input(int n0,int k0,int m,int *Member)
{
int i,j,k,g;
int NewNum;
Row=k0;
Column=n0*(m+1);
if(Buffer!=NULL)
delete Buffer;
Buffer=new Byte[Row*Column];
for(i=0;i<k0;i++)
{
for(j=0;j<n0;j++)
{
g=Member[i*n0+j];
for(k=0;k<m+1;k++)
{
NewNum=g&0x01;
Buffer[i*Column+j+(m-k)*n0]=(unsigned char )NewNum;
g=g>>1;
}
}
}
}

//******************************************************************
//名称: MTransferState
//功能: 生成状态转移表
//******************************************************************
__fastcall MTransferState::MTransferState()
{
Buffer=NULL;
Buffer=new int[1];
num=1;
zh1=new Byte[1];
zh2=new Byte[1];
in=new int[1];
out=new int[1];
Zh1Num=1;
Zh2Num=1;
InNum=1;
OutNum=1;
}
__fastcall MTransferState::~MTransferState()
{
if(Buffer!=NULL)
delete Buffer;
Row=0;
Column=0;
if(zh1!=NULL)
delete zh1;
if(zh2!=NULL)
delete zh2;
if(in!=NULL)
delete in;
if(out!=NULL)
delete out;
Zh1Num=0;
Zh2Num=0;
InNum=0;
OutNum=0;
}
void MTransferState::Input(int n0,int k0,int m,unsigned char *Matrix)
{
int i,j,k,l,site,num2,d,out2;
for(i=0,Row=1;i<m*k0;i++){//状态表行数
Row=Row*2;
}
for(i=0,num2=1;i<k0;i++){//状态表列数
num2=num2*2;
}
Column=num2*3;
if(num!=Row*Column){ //申请地址
delete Buffer;
Buffer=NULL;
Buffer=new int[num=Row*Column];
}
for(i=0;i<num;i++){
Buffer=1000;
}
if(OutNum!=n0)
{
delete out;
out=new int[n0];
OutNum=n0;
}
if(InNum!=k0)
{
delete in;
in=new int[k0];
InNum=k0;
}
if(Zh1Num!=(k0*m))
{
delete zh1;
zh1=new Byte[k0*m];
Zh1Num=k0*m;
}
if(Zh2Num!=(k0*m))
{
delete zh2;
zh2=new Byte[k0*m];
Zh2Num=k0*m;
}
for(i=0;i<Row;i++){//对每个状态循环
for(k=m*k0-1,j=i;k>=0;k--){//将状态送入状态寄存器
zh1[k]=(unsigned char)(j&1);
j=j>>1;
}
for(d=0;d<num2;d++){ //对各种输入循环
for(k=k0-1,j=d;k>=0;k--){//将输入变为二进制
in[k]=j&1;
j=j>>1;
}
for(k=0;k<n0;k++){//清零
out[k]=0;
}
for(k=0;k<k0;k++){ //对一个输入码字的每bit循环
for(j=0;j<n0;j++){ //对一个输出码字的每bit循环
for(l=m-1;l>=0;l--){ //对一个移存器的每个单元循环
site=k*(m+1)*n0+(l+1)*n0+j;//g(k,n)在基本生成矩阵的位置
out[j]=out[j]+zh1[k*m+l]*Matrix[site];
}
out[j]=out[j]+in[k]*Matrix[k*(m+1)*n0+j];
}
}
for(k=0;k<n0;k++){
out[k]=out[k]%2;
}
for(k=n0-1,out2=0,l=1;k>=0;k--){//将输出转化成十进制
if(out[k]!=0){
out2=out2|l;
}
l=l<<1;
}
for(k=0;k<k0;k++){
for(l=m-1;l>0;l--){ //更新移存器
zh2[k*m+l]=zh1[k*m+l-1];
}
zh2[k*m]=(unsigned char)in[k];
}
for(k=m*k0-1,l=1,site=0;k>=0;k--){//将移存器状态转化成十进制
if(zh2[k]!=0){
site=site|l;
}
l=l<<1;
}
for(k=0;k<num2;k++){
if(Buffer[site*num2*3+k*3+2]==1000){
Buffer[site*num2*3+k*3]=i;
Buffer[site*num2*3+k*3+1]=out2;
Buffer[site*num2*3+k*3+2]=d;
break;
}
}
}
}
out1:

return ;
}


//******************************************************************
//名称: MVitebiDecode
//功能: 通用维特比译码器
//******************************************************************
__fastcall MVitebiDecode::MVitebiDecode()
{
Buffer=new unsigned char[1];
BufBitLen=8;
ByteBuffer=new Byte[1];
ByteBufLen=1;
PathStore=new unsigned char[1];
Measurement=new int[1];
NowStoreLength=0;
NowStoreSite=0;
Old=0;
RemainBit=new Byte[1];
RemainBitLen=0;
State=new int[1];
ByteCodeIn=new Byte[1];
}

__fastcall MVitebiDecode::~MVitebiDecode()
{
if(Buffer!=NULL)
delete Buffer;
if(PathStore!=NULL)
delete PathStore;
if(Measurement!=NULL)
delete Measurement;
if(RemainBit!=NULL)
delete RemainBit;
if(ByteBuffer!=NULL)
delete ByteBuffer;
if(State!=NULL)
delete State;
if(ByteCodeIn!=NULL)
delete ByteCodeIn;
}

void MVitebiDecode::Initial(int n,int k,int m,int *Member)
{
int i;
n0=n;
k0=k;
NowStoreLength=0;
NowStoreSite=0;
Old=0;

CreatMatrix.Input(n,k,m,Member);
TransferState.Input(n,k,m,CreatMatrix.Buffer);
if(State!=NULL)
delete State;
State=new int[(TransferState.Row)*(TransferState.Column)];
memcpy(State,TransferState.Buffer,sizeof(int)*TransferState.Row*TransferState.Column);
// State=TransferState.Buffer;

for(i=0,Row=1;i<m*k0;i++){//状态表行数
Row=Row*2;
}
for(i=0,PathNum=1;i<k0;i++){//状态表列数
PathNum=PathNum*2;
}
BitSite=PathNum/2;
Column=PathNum*3;
PathStoreLength=m*7; //路径存储长度
if(PathStore!=NULL) //申请路径寄存器并清零
{
delete PathStore;
}
PathStore=new Byte[2*PathStoreLength*Row];
memset(PathStore,0,2*PathStoreLength*Row);
if(Measurement!=NULL) //申请比特度量寄存器并清零
{
delete Measurement;
}
Measurement=new int[2*Row];
memset(Measurement,0,sizeof(int)*2*Row);
if(RemainBit!=NULL)
{
delete RemainBit;
}
RemainBit=new Byte[n0-1];
RemainBitLen=0;
if(ByteCodeIn!=NULL)
delete ByteCodeIn;
ByteCodeIn=new Byte[n0];
}

void MVitebiDecode::ByteInput(char *Data,int ByteLength)
{
int i,j,k,b,l,Counter,ByteNum,RemainBitLen1;
Byte CodeMeasurement,m;
int Max,MaxMeasurement,MaxPath,MaxFrontState,POldStartSite,PNewStartSite,MOldStartSite,MNewStartSite;
unsigned char CodeIn,Code;
if(ByteLength==0)
{
if(ByteBuffer!=NULL)
delete ByteBuffer;
ByteBuffer=NULL;
ByteBufLen=0;
return;
}
i=((ByteLength+RemainBitLen-PathStoreLength*n0+NowStoreLength*n0)/n0)*k0;//输出比特长度
RemainBitLen1=(ByteLength+RemainBitLen)%n0;
if(ByteBufLen!=i)
{
if(ByteBuffer!=NULL)
delete ByteBuffer;
ByteBuffer=NULL;
if(i>0){
ByteBufLen=i;
ByteBuffer=new Byte[ByteBufLen];
memset(ByteBuffer,0,ByteBufLen);
}
else{
ByteBufLen=0;
}
}
else{
if(ByteBufLen!=0)
{
memset(ByteBuffer,0,ByteBufLen);
}
}
Counter=0;
for(i=-RemainBitLen;i<ByteLength-RemainBitLen1;i=i+n0)
{
New=(Old+1)%2;
POldStartSite=Old*PathStoreLength*Row;//PathStore[]的起始位置
PNewStartSite=New*PathStoreLength*Row;//PathStore[]的起始位置
MOldStartSite=Old*Row; // Measurement[]的起始位置
MNewStartSite=New*Row; //(此四变量是为了减少下面循环的运算量)
MaxMeasurement=0; //寻找最大比特度量的中间变量(所有状态)
//取编码数据
if(i<0)
{
for(j=0;j<RemainBitLen;j++)
{
ByteCodeIn[j]=RemainBit[j];
}
for(j=RemainBitLen;j<n0;j++)
{
ByteCodeIn[j]=Data[i+j];
}
}
else
{
for(j=0;j<n0;j++)
{
ByteCodeIn[j]=Data[i+j];
}
}
for(j=0;j<Row;j++) //对每个状态进行计算
{
Max=0; //寻找最大比特度量路径(一个状态)的中间变量
for(k=0;k<PathNum;k++)//对进入一个状态的每条路径进行计算比特度量
{
Code=State[j*Column+k*3+1]; //取子码
CodeMeasurement=0;
for(l=0;l<n0;l++)
{
if(ByteCodeIn[l]==((Code>>(n0-1-l))&0x01))
CodeMeasurement=CodeMeasurement+1;
}
if((b=CodeMeasurement+Measurement[MOldStartSite+State[j*Column+k*3]])>Max)//求bit度量最大的前态,输出及其度量
{
Max=b;
MaxPath=k; //最大比特度量路径(一个状态)
}
}
Measurement[MNewStartSite+j]=Max;//更新度量寄存器
if(Max>MaxMeasurement) //Max为最大比特度量(一个状态)
{
MaxMeasurement=Max; //MaxMeasurement为最大比特度量(所有状态)
MaxFrontState=State[j*Column+MaxPath*3]; //最大度量状态的前态(所有状态)
}
memcpy(&PathStore[PNewStartSite+j*PathStoreLength],&PathStore[POldStartSite+State[j*Column+MaxPath*3]*PathStoreLength],PathStoreLength);
PathStore[PNewStartSite+j*PathStoreLength+NowStoreSite]=State[j*Column+MaxPath*3+2];//最大比特度量的译码
} //NowStoreSite为PathStore[new]里进行更新的位置,同时也为PathStore[old]里进行输出的位置
if(MaxMeasurement>150000) //防止bit度量溢出
{
for(j=0;j<Row;j++)
Measurement[MNewStartSite+j]=Measurement[MNewStartSite+j]-100000;
}
if(NowStoreLength==PathStoreLength) //当路径存储器满时,输出结果
{
b=POldStartSite+MaxFrontState*PathStoreLength+NowStoreSite;//在PathStore[Old]里应输出结果的位置
for(j=0,m=BitSite;j<k0;j++)
{
if((PathStore&m)!=0)
ByteBuffer[Counter]=1;
Counter++;
m=m>>1;
}
}
Old=New;
NowStoreSite=(NowStoreSite+1)%PathStoreLength; //更新
if(NowStoreLength<PathStoreLength) //存储记数加一
{
NowStoreLength++;
}
}
//保留剩余数据
RemainBitLen=(ByteLength+RemainBitLen)%n0;
for(i=0;i<RemainBitLen;i++)
{
if((ByteLength-RemainBitLen+i)>=0)
{
RemainBit=Data[ByteLength-RemainBitLen+i];
}
}

}

void MVitebiDecode::Input(char *Data,int BitLength)
{
int i,j,k,b,l,Counter,ByteNum,BitNum,RemainBitLen1;
Byte CodeMeasurement,m;
int Max,MaxMeasurement,MaxPath,MaxFrontState,POldStartSite,PNewStartSite,MOldStartSite,MNewStartSite;
unsigned char CodeIn,Code;
unsigned char Select[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
if(BitLength==0)
{
if(Buffer!=NULL)
delete Buffer;
Buffer=NULL;
BufBitLen=0;
return;
}
i=BitLength/n0;//输出比特长度
RemainBitLen1=(BitLength+RemainBitLen)%n0;
if(BufBitLen!=i)
{
if(Buffer!=NULL)
delete Buffer;
Buffer=NULL;
if(i>0){
BufBitLen=i;
Buffer=new Byte[BufBitLen/8+1];
memset(Buffer,0,BufBitLen/8+1);
}
else{
BufBitLen=0;
}
}
else{
if(BufBitLen!=0)
{
memset(Buffer,0,BufBitLen/8+1);
}
}
Counter=0;
for(i=-RemainBitLen;i<BitLength-RemainBitLen1;i=i+n0)
{
New=(Old+1)%2;
POldStartSite=Old*PathStoreLength*Row;//PathStore[]的起始位置
PNewStartSite=New*PathStoreLength*Row;//PathStore[]的起始位置
MOldStartSite=Old*Row; // Measurement[]的起始位置
MNewStartSite=New*Row; //(此四变量是为了减少下面循环的运算量)
MaxMeasurement=0; //寻找最大比特度量的中间变量(所有状态)
CodeIn=0;
//取编码数据
if(i<0)
{
for(j=0;j<RemainBitLen;j++)
{
if((RemainBit[j])!=0)
{
CodeIn=CodeIn|Select[8-n0+j];
}
}
for(j=RemainBitLen;j<n0;j++)
{
ByteNum=(i+j)/8;
BitNum=(i+j)%8;
if((Data[ByteNum]&Select[BitNum])!=0)
{
CodeIn=CodeIn|Select[8-n0+j];
}
}
}
else
{
for(j=0;j<n0;j++)
{
ByteNum=(i+j)/8;
BitNum=(i+j)%8;
if((Data[ByteNum]&Select[BitNum])!=0)
{
CodeIn=CodeIn|Select[8-n0+j];
}
}
}
for(j=0;j<Row;j++) //对每个状态进行计算
{
Max=0; //寻找最大比特度量路径(一个状态)的中间变量
for(k=0;k<PathNum;k++)//对进入一个状态的每条路径进行计算比特度量
{
Code=State[j*Column+k*3+1]; //取子码
CodeMeasurement=0;
for(l=0;l<n0;l++)
{
CodeMeasurement=CodeMeasurement+((~(Code^CodeIn)>>l)&0x01);
}
if((b=CodeMeasurement+Measurement[MOldStartSite+State[j*Column+k*3]])>Max)//求bit度量最大的前态,输出及其度量
{
Max=b;
MaxPath=k; //最大比特度量路径(一个状态)
}
}
Measurement[MNewStartSite+j]=Max;//更新度量寄存器
if(Max>MaxMeasurement) //Max为最大比特度量(一个状态)
{
MaxMeasurement=Max; //MaxMeasurement为最大比特度量(所有状态)
MaxFrontState=State[j*Column+MaxPath*3]; //最大度量状态的前态(所有状态)
}
memcpy(&PathStore[PNewStartSite+j*PathStoreLength],&PathStore[POldStartSite+State[j*Column+MaxPath*3]*PathStoreLength],PathStoreLength);
PathStore[PNewStartSite+j*PathStoreLength+NowStoreSite]=State[j*Column+MaxPath*3+2];//最大比特度量的译码
} //NowStoreSite为PathStore[new]里进行更新的位置,同时也为PathStore[old]里进行输出的位置
if(MaxMeasurement>150000) //防止bit度量溢出
{
for(j=0;j<Row;j++)
Measurement[MNewStartSite+j]=Measurement[MNewStartSite+j]-100000;
}
if(NowStoreLength==PathStoreLength) //当路径存储器满时,输出结果
{
b=POldStartSite+MaxFrontState*PathStoreLength+NowStoreSite;//在PathStore[Old]里应输出结果的位置
for(j=0,m=BitSite;j<k0;j++)
{
ByteNum=Counter/8;
BitNum=Counter%8;
if((PathStore&m)!=0)
Buffer[ByteNum]=Buffer[ByteNum]|Select[BitNum];
Counter++;
m=m>>1;
}
}
Old=New;
NowStoreSite=(NowStoreSite+1)%PathStoreLength; //更新
if(NowStoreLength<PathStoreLength) //存储记数加一
{
NowStoreLength++;
}
}
//输出剩余数据
for(i=0;i<42;i++)
{

}

}

//**********************************************************************
//名称:MPuncturedDecoder
//功能:卷积码的增信删余译码
//**********************************************************************
MPuncturedDecoder::MPuncturedDecoder()
{
Buffer=new unsigned char[1];
BufferLen=1;
PathStore=new unsigned char[1];
Measurement=new int[1];
NowStoreLength=0;
NowStoreSite=0;
Old=0;
RemainData=new Byte[1];
RemainDataLen=0;
State=new int[1];
ReBuffer=new Byte[1];
ReBufferLen=1;
DivData=new Byte[1];
PunSite=new Byte[1];
CodeIn=new Byte[1];
}

MPuncturedDecoder::~MPuncturedDecoder()
{
if(Buffer!=NULL)
delete Buffer;
if(PathStore!=NULL)
delete PathStore;
if(Measurement!=NULL)
delete Measurement;
if(RemainData!=NULL)
delete RemainData;
if(State!=NULL)
delete State;
if(CodeIn!=NULL)
delete CodeIn;
if(ReBuffer!=NULL)
delete ReBuffer;
if(DivData!=NULL)
delete DivData;
if(PunSite!=NULL)
delete PunSite;
}

void MPuncturedDecoder::Initial(int n,int k,int m,int *Member,Byte *Site)
{
int i;
NowStoreLength=0;
NowStoreSite=0;
Old=0;
SendNum=n;
k0=k;
DivDataLen=2*(n-1);

if(PunSite!=NULL)
delete PunSite;
PunSite=new Byte[DivDataLen];
for(i=0;i<DivDataLen;i=i+2)
{
PunSite=Site[i/2];
PunSite[i+1]=Site[(n-1)+i/2];
}
CreatMatrix.Input(2,1,m,Member);
TransferState.Input(2,1,m,CreatMatrix.Buffer);
if(State!=NULL)
delete State;
State=new int[(TransferState.Row)*(TransferState.Column)];
memcpy(State,TransferState.Buffer,sizeof(int)*TransferState.Row*TransferState.Column);
// State=TransferState.Buffer;

for(i=0,Row=1;i<m;i++){//状态表行数
Row=Row*2;
}
for(i=0,PathNum=1;i<1;i++){//状态表列数
PathNum=PathNum*2;
}
BitSite=PathNum/2;
Column=PathNum*3;
PathStoreLength=m*7; //路径存储长度
if(PathStore!=NULL) //申请路径寄存器并清零
{
delete PathStore;
}
PathStore=new Byte[2*PathStoreLength*Row];
memset(PathStore,0,2*PathStoreLength*Row);
if(Measurement!=NULL) //申请比特度量寄存器并清零
{
delete Measurement;
}
Measurement=new int[2*Row];
memset(Measurement,0,sizeof(int)*2*Row);
if(RemainData!=NULL)
{
delete RemainData;
}
RemainData=new Byte[DivDataLen-1];
RemainDataLen=0;
if(CodeIn!=NULL)
delete CodeIn;
CodeIn=new Byte[2];
}

void MPuncturedDecoder::Input(Byte *Data,int DataLen)
{
int i,j,k,b,l,p,Counter,ByteNum,Counter1;
Byte CodeMeasurement,m;
int Max,MaxMeasurement,MaxPath,MaxFrontState,POldStartSite,PNewStartSite,MOldStartSite,MNewStartSite;
unsigned char Code;
if(DataLen==0)
{
if(Buffer!=NULL)
delete Buffer;
Buffer=NULL;
BufferLen=0;
return;
}
i=((((DataLen+RemainDataLen)/SendNum)*DivDataLen)-PathStoreLength*2+NowStoreLength*2)/2;//输出比特长度
// i=(((DataLen+RemainDataLen)/SendNum)*DivDataLen);//输出比特长度

if(BufferLen!=i)
{
if(Buffer!=NULL)
delete Buffer;
Buffer=NULL;
if(i>0){
BufferLen=i;
Buffer=new Byte[BufferLen];
memset(Buffer,0,BufferLen);
}
else{
BufferLen=0;
}
}
else{
if(BufferLen!=0)
{
memset(Buffer,0,BufferLen);
}
}
if(ReBufferLen!=(DataLen+RemainDataLen))
{
if(ReBuffer!=NULL)
delete ReBuffer;
ReBuffer=NULL;
ReBufferLen=DataLen+RemainDataLen;
ReBuffer=new Byte[ReBufferLen];
}
memcpy(ReBuffer,RemainData,RemainDataLen);
memcpy(ReBuffer+RemainDataLen,Data,DataLen);
//保留剩余数据
RemainDataLen=(DataLen+RemainDataLen)%SendNum;
for(i=0;i<RemainDataLen;i++)
{
if((ReBufferLen-RemainDataLen+i)>=0)
{
RemainData=ReBuffer[ReBufferLen-RemainDataLen+i];
}
}
Counter=0;
Counter1=0;
for(i=0;i<ReBufferLen-RemainDataLen;i=i+SendNum)
{
for(p=0;p<DivDataLen;p=p+2)
{
New=(Old+1)%2;
POldStartSite=Old*PathStoreLength*Row;//PathStore[]的起始位置
PNewStartSite=New*PathStoreLength*Row;//PathStore[]的起始位置
MOldStartSite=Old*Row; // Measurement[]的起始位置
MNewStartSite=New*Row; //(此四变量是为了减少下面循环的运算量)
MaxMeasurement=0; //寻找最大比特度量的中间变量(所有状态)
//取编码数据
if((PunSite[p])!=0)
{
CodeIn[0]=ReBuffer[Counter1];
Counter1++;
}
else
{
CodeIn[0]=2;
}
if(PunSite[p+1]!=0)
{
CodeIn[1]=ReBuffer[Counter1];
Counter1++;
}
else
{
CodeIn[1]=2;
}
for(j=0;j<Row;j++) //对每个状态进行计算
{
Max=0; //寻找最大比特度量路径(一个状态)的中间变量
for(k=0;k<PathNum;k++)//对进入一个状态的每条路径进行计算比特度量
{
Code=State[j*Column+k*3+1]; //取子码
CodeMeasurement=0;
for(l=0;l<2;l++)
{
if(CodeIn[l]==((Code>>(1-l))&0x01))
CodeMeasurement=CodeMeasurement+1;
}
if((b=CodeMeasurement+Measurement[MOldStartSite+State[j*Column+k*3]])>Max)//求bit度量最大的前态,输出及其度量
{
Max=b;
MaxPath=k; //最大比特度量路径(一个状态)
}
}
Measurement[MNewStartSite+j]=Max;//更新度量寄存器
if(Max>MaxMeasurement) //Max为最大比特度量(一个状态)
{
MaxMeasurement=Max; //MaxMeasurement为最大比特度量(所有状态)
MaxFrontState=State[j*Column+MaxPath*3]; //最大度量状态的前态(所有状态)
}
memcpy(&PathStore[PNewStartSite+j*PathStoreLength],&PathStore[POldStartSite+State[j*Column+MaxPath*3]*PathStoreLength],PathStoreLength);
PathStore[PNewStartSite+j*PathStoreLength+NowStoreSite]=State[j*Column+MaxPath*3+2];//最大比特度量的译码
} //NowStoreSite为PathStore[new]里进行更新的位置,同时也为PathStore[old]里进行输出的位置
if(MaxMeasurement>150000) //防止bit度量溢出
{
for(j=0;j<Row;j++)
Measurement[MNewStartSite+j]=Measurement[MNewStartSite+j]-100000;
}
if(NowStoreLength==PathStoreLength) //当路径存储器满时,输出结果
{
b=POldStartSite+MaxFrontState*PathStoreLength+NowStoreSite;//在PathStore[Old]里应输出结果的位置
if((PathStore&0x01)!=0)
Buffer[Counter]=1;
Counter++;
}
Old=New;
NowStoreSite=(NowStoreSite+1)%PathStoreLength; //更新
if(NowStoreLength<PathStoreLength) //存储记数加一
{
NowStoreLength++;
}
}
}
}

 

  
稿件编号:1843483号    
  • 小渔儿
  • 等 级:猪六戒
  • 信用值:
  • 能力值:
发布者已浏览查看所有交稿 时间:2008/04/16 22:04:58 评论:0票数:61   QQ:401745332  
稿件编号:1847578号    
  • 五龙山 爱心威客 VIP会员
  • 等 级:猪六戒
  • 信用值:
  • 能力值:
发布者已浏览查看所有交稿 时间:2008/04/18 05:48:53 评论:0票数:10   下来想想,这个价格..  
稿件编号:1848231号    
  • xxch229 爱心威客 VIP会员
  • 等 级:猪四戒
  • 信用值:
  • 能力值:
发布者已浏览查看所有交稿 时间:2008/04/18 11:11:24 评论:0票数:9   

我决定放弃了,不过还是要支持一下你们,希望你们能找到合适的作品

  
稿件编号:1852566号    
发布者已浏览查看所有交稿 时间:2008/04/19 17:14:21 评论:0票数:5   

加价吗?

  
稿件编号:1855478号    
  • 赵心瑞 爱心威客 VIP会员
  • 等 级:猪七戒
  • 信用值:
  • 能力值:
发布者已浏览查看所有交稿 时间:2008/04/20 16:27:35 评论:0票数:10   

 

看到已经发出的稿件还挺复杂的,

 

我希望任务发布者好运!