?? rcpc.txt
字號(hào):
/**********************************************************************************************************************
該程序可以將隨機(jī)生成的0,1序列經(jīng)過卷積編碼器產(chǎn)生(4,1,4)卷積碼,然后將卷積碼經(jīng)過4*8的刪余矩陣,有三種速率(1/3,2/3,1/2)可供選擇,
在編碼端利用維特比譯碼方法進(jìn)行譯碼
*****************************************************************************************************************************/
#include <iostream>
using namespace std;
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define M1 1000 //存儲(chǔ)輸入碼字的數(shù)組容量
#define M2 4000 //存儲(chǔ)編碼后碼字的數(shù)組容量
static int g1[4]={0x13,0x1d,0x17,0x1b};//定義生成矩陣
static int
A0[13]={0XC8,0XC8,0XC8,0XCC,0XCC,0XEC,0XEE,0XEE,0XEE,0XFE,0XFE,0XFE,0XFF},
A1[13]={0X88,0X88,0XC8,0XC8,0XCC,0XCC,0XCC,0XEC,0XEE,0XEE,0XFE,0XFE,0XFF},
A2[13]={0X48,0XC8,0XC8,0XCC,0XCC,0XEC,0XEE,0XEE,0XEE,0XFE,0XFE,0XFF,0XFF},
A3[13]={0x88,0x88,0xC8,0XC8,0XCC,0XCC,0XCC,0XEC,0XEE,0XEE,0XFE,0XFE,0XFF}; //定義刪余矩陣
/*************************************************************************************************************************
編碼函數(shù)
*************************************************************************************************************************/
//以下為(4,1,4)卷積編碼函數(shù)
unsigned int juanjiencode(
unsigned int *symbols, /*編碼輸出*/
unsigned int *data, /*編碼輸入*/
unsigned int nbytes, /*nbytes=n/16,n為實(shí)際輸入碼字的數(shù)目*/
unsigned int startstate /*定義初始化狀態(tài)*/
)
{
unsigned int j;
unsigned int input,a1=0,a2=0,a3=0,a4=0;
for(j=0;j<nbytes;j++)
{ input=*data;
data++;
*symbols = input^(((g1[0]>>3)&1)*a1)^(((g1[0]>>2)&1)*a2)^(((g1[0]>>1)&1)*a3)^((g1[0]&1)*a4);
symbols++;
*symbols = input^(((g1[1]>>3)&1)*a1)^(((g1[1]>>2)&1)*a2)^(((g1[1]>>1)&1)*a3)^((g1[1]&1)*a4);
symbols++;
*symbols = input^(((g1[2]>>3)&1)*a1)^(((g1[2]>>2)&1)*a2)^(((g1[2]>>1)&1)*a3)^((g1[2]&1)*a4);
symbols++;
*symbols = input^(((g1[3]>>3)&1)*a1)^(((g1[3]>>2)&1)*a2)^(((g1[3]>>1)&1)*a3)^((g1[3]&1)*a4);
symbols++;
a4=a3;
a3=a2;
a2=a1;
a1=input;
}
return 0;
}
//以下為經(jīng)過刪余矩陣的處理
unsigned int puncture(unsigned int *input,unsigned int *output,unsigned int m) //刪余函數(shù)
{int i,s,num_of_rcpc=0;
unsigned int mem;
cout<<"選擇刪余矩陣:"<<'\n'<<"s=0,碼率為8/9"<<';'<<"s=1,碼率為8/10"<<';'<<"s=2,碼率為8/12"<<';'<<"s=3,碼率為8/14"<<';'<<'\n';
cout<<"s=4,碼率為8/16"<<';'<<"s=5,碼率為8/18"<<';'<<"s=6,碼率為8/20"<<';'<<"7=2,碼率為8/22"<<';'<<'\n';
cout<<"8=0,碼率為9/24"<<';'<<"s=9,碼率為8/26"<<';'<<"s=11,碼率為10/28"<<';'<<"s=11,碼率為8/30"<<';'<<'\n';
cout<<"8=0,碼率為9/32"<<'\n';
cout<<"s=";
cin>>s;
cout<<'\n';
while(m--!=0)
{
for(i=7;i>=0;i--)
{
if((A0[s]>>i)&1) {mem=*input++;*output++=mem;num_of_rcpc++;}
else input++;
if((A1[s]>>i)&1) {mem=*input++;*output++=mem;num_of_rcpc++;}
else input++;
if((A2[s]>>i)&1) {mem=*input++;*output++=mem;num_of_rcpc++;}
else input++;
if((A3[s]>>i)&1) {mem=*input++;*output++=mem;num_of_rcpc++;}
else input++;
}
}
return s;
}
void bsc(unsigned int *input,unsigned int *output,int num) //bsc信道
{ int i,j;
unsigned int data[M2];
cout<<'\n';
srand( (unsigned)time( NULL ) );
for(i=0;i<num;i++)
{ data[i]=rand()%2;
cout<<data[i];
if(data[i]==1)
*output++=*input++;
else *output++=*input++^1;
}
cout<<'\n';
}
//以下將接收的RCPC碼還原成原先的卷積碼,被刪掉的比特補(bǔ)0
void huanyuan(unsigned int *input,unsigned int *output,int num,int s)
{int i;
while(num--!=0)
{for(i=7;i>=0;i--)
{
if(A0[s]>>i&1) *output=*input++;
else *output=0;
output++;
if(A1[s]>>i&1) *output=*input++;
else *output=0;
output++;
if(A2[s]>>i&1) *output=*input++;
else *output=0;
output++;
if(A3[s]>>i&1) *output=*input++;
else *output=0;
output++;
}
}
}
/*********************************************************************************************************************
* 維特比譯碼部分 *
*********************************************************************************************************************/
int traninput(int a,int b) //從狀態(tài)a到b的輸入值
{int c;
c=((b&8)>>3);
return c;
}
int tranouput(int a,int b,int s,int i) //從狀態(tài)a到b的輸出的值
{int c,s1,s2,s3,s4;
if(A0[s]>>i&1)
s1=(b>>3&1)^((a>>3&1)*(g1[0]>>3&1))^((a>>2&1)*(g1[0]>>2&1))^((a>>1&1)*(g1[0]>>1&1))^((a&1)*(g1[0]&1));
else s1=0;
if(A1[s]>>i&1)
s2=(b>>3&1)^((a>>3&1)*(g1[1]>>3&1))^((a>>2&1)*(g1[1]>>2&1))^((a>>1&1)*(g1[1]>>1&1))^((a&1)*(g1[1]&1));
else s2=0;
if(A2[s]>>i&1)
s3=(b>>3&1)^((a>>3&1)*(g1[2]>>3&1))^((a>>2&1)*(g1[2]>>2&1))^((a>>1&1)*(g1[2]>>1&1))^((a&1)*(g1[2]&1));
else s3=0;
if(A3[s]>>i&1)
s4=(b>>3&1)^((a>>3&1)*(g1[3]>>3&1))^((a>>2&1)*(g1[3]>>2&1))^((a>>1&1)*(g1[3]>>1&1))^((a&1)*(g1[3]&1));
else s4=0;
c=(s1<<3)|(s2<<2)|(s3<<1)|s4;
return c;
}
//以下為編碼數(shù)據(jù)從state1到state2時(shí)的漢明距離,如果state1無法到state2則輸出度量值為100
int hanmingjuli(int data,int state1,int state2,int s,int i)
{ int d,e,f;
e=tranouput(state1,state2,s,i);
f=e^data;
if(((state1>>1)==state2)||(((state1>>1)^8)==state2))
d=((f>>3)&1)+((f>>2)&1)+((f>>1)&1)+(f&1);
else d=100;
return d;
}
//以下為維特比譯碼的主函數(shù)
void viterby(unsigned int *input,unsigned int *output,int initialstate,int N,int s) //N為實(shí)際輸入的碼字大數(shù)量,initialstate表示輸入的初始狀態(tài)
{ int i,j,l,r,u,t,p,q,y,x=0;
struct wange
{int pm;
int value;
struct wange *last; //pm表示路徑量度,value表示譯碼輸出的碼字
};
struct wange state[16][M1];
struct wange *g,*head;
for(i=0;i<16;i++)
for(j=0;j<N;j++)
state[i][j].pm=0; //初始化每個(gè)狀態(tài)的度量值為0
for(l=0;l<16;l++)
{state[l][0].pm=hanmingjuli(*input,initialstate,l,s,7);
state[l][0].value=traninput(initialstate,l);
state[l][0].last=NULL;
}
input++; /*擴(kuò)展第一步幸存路徑*/
for(i=0;i<N/8;i++)
{for(j=0;j<=7;j++)
if(i==0&&j==0)
x++;
else
{for(p=0;p<16;p++)
{t=j+8*i;
y=7-j;
if(i==0)
{state[p][t].pm=state[0][t-1].pm+hanmingjuli(*input,0,p,s,y-1);
state[p][t].value=traninput(0,p);
state[p][t].last=&state[0][t-1];
}
else
{state[p][t].pm=state[0][t-1].pm+hanmingjuli(*input,0,p,s,y);
state[p][t].value=traninput(0,p);
state[p][t].last=&state[0][t-1];
}
for(q=0;q<16;q++)
{if(state[q][t-1].pm+hanmingjuli(*input,q,p,s,y)<state[p][t].pm)
{state[p][t].pm=state[q][t-1].pm+hanmingjuli(*input,q,p,s,y);
state[p][t].value=traninput(q,p);
state[p][t].last=&state[q][t-1];
}
}
}
input++;
} /*計(jì)算出剩余的幸存路徑*/
}
r=state[0][N-1].pm; /*找出n步后度量值最小的狀態(tài),準(zhǔn)備回溯路由*/
g=&state[0][N-1];
for(u=N;u>0;u--) /*向前遞歸的找出最大似然路徑 */
{*(output+(u-1))=g->value;
g=g->last;
}
/* for(u=0;u<8;u++)
*(viterbioutput+u)=state[u][2].pm; */ /*此行程序可用于檢測(cè)第n列的度量值*/
}
/*********************************************************************************************************************************
譯碼主函數(shù)
*********************************************************************************************************************************/
void decode(unsigned int *input,unsigned int *output,int n,int num,int s)
{
unsigned int viterbiinput1[M2],viterbiinput[M1];
int j,i;
huanyuan(input,viterbiinput1,(n+4)/8,s);
/* cout<<"輸入到維特比譯碼器的碼字為:"<<'\n';
for(j=0;j<(n+4)*4;j++)
{cout<<viterbiinput1[j];
if((j+1)%4==0) cout<<' ';
if(j%20==19)
cout<<'\n';
}*/
cout<<'\n';
for(j=0;j<n+4;j++)
viterbiinput[j]=(viterbiinput1[4*j]<<3)|(viterbiinput1[4*j+1]<<2)|(viterbiinput1[4*j+2]<<1)|viterbiinput1[4*j+3];
viterby(viterbiinput,output,0,n+4,s);
}
/*********************************************************************************************************************************
主函數(shù)開始部分
*********************************************************************************************************************************/
void main()
{unsigned int encodeinput[M1],wrong[10]={0,0,0,0,0,0,0,0,0,0},juanjioutput[M2],encorderoutput[M2],decodeinput[M2],decodeoutput[M1];
int n,m,s,num,i,j=0,diff=0;
cout<<"輸入編碼的個(gè)數(shù):";
cin>>n;
cout<<'\n';
srand((unsigned)time(NULL));
for(i=0; i<n; i++)
encodeinput[i]=rand()%2; //產(chǎn)生n個(gè)隨機(jī)的0和1
encodeinput[n]= encodeinput[n+1]=encodeinput[n+2]=encodeinput[n+3]=encodeinput[n+4]=0; //在第n個(gè)數(shù)據(jù)輸入以后持續(xù)輸入5個(gè)數(shù)使寄存器清0
juanjiencode(juanjioutput,encodeinput,n+4,0); //調(diào)用卷積編碼程序
cout<<"the input of encoder is :"<<n<<'\n';
for(i=0;i<n; i++)
cout<<encodeinput[i];
cout<<'\n';
cout<<"the output of juanjiencoder is :"<<(n+4)*4<<'\n';
for(i=0;i<(n+4)*4;i++)
{cout<<juanjioutput[i];
if((i+1)%4==0) cout<<' ';
if(i%40==39)
cout<<'\n';
}
cout<<'\n';
s=puncture(juanjioutput,encorderoutput,(n+4)/8);
if(s==0) num=(n+4)*4*9/32;
else num=(n+4)*4*(8+2*s)/32; //計(jì)算選擇不同碼率的刪余矩陣所產(chǎn)生的碼字個(gè)數(shù)
cout<<"經(jīng)過刪余矩陣后輸出的碼字為:";
cout<<num<<'\n';
for(i=0;i<num;i++)
cout<<encorderoutput[i];
cout<<'\n';
//以下程序可以對(duì)發(fā)送的卷積碼進(jìn)行修改以檢測(cè)譯碼端的糾錯(cuò)能力
/* cout<<"please input the number of the wrong bit"<<'\n';
cin>>m;
cout<<"please input the positions of the wrong bit(0-100)"<<'\n';
for(i=0;i<m;i++)
{cin>>wrong[m];
if(encorderoutput[wrong[m]]==0)
encorderoutput[wrong[m]]=1;
else
encorderoutput[wrong[m]]=0;
}
cout<<"the input of decoder is :"<<'\n';
for(i=0;i<num;i++)
cout<<encorderoutput[i];
cout<<'\n';*/
/* bsc(encorderoutput,decodeinput,num);
cout<<'\n';
cout<<"譯碼端的輸入碼字:"<<'\n';
for(i=0;i<num;i++)
cout<<decodeinput[i];*/
cout<<'\n';
decode(encorderoutput,decodeoutput,n,num,s); //s代表選擇的刪余矩陣
cout<<"譯碼后輸出的碼字為:";
cout<<'\n';
for(i=0;i<n;i++)
cout<<decodeoutput[i];
cout<<'\n';
for(i=0;i<n;i++)
{if(encodeinput[i]!=decodeoutput[i])
diff++;
}
cout<<"誤碼的個(gè)數(shù)為:"<<diff<<'\n';
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -