⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rcpc.cpp

📁 本文件主要是用于RCPC码的编码
💻 CPP
字号:
/**********************************************************************************************************************
该程序可以将随机生成的0,1序列经过卷积编码器产生(4,1,4)卷积码,然后将卷积码经过4*8的删余矩阵,有三种速率(1/3,2/3,1/2)可供选择,
在编码端利用维特比译码方法进行译码
*****************************************************************************************************************************/


#include "iostream.h"
#include "stdio.h"
#include <stdlib.h>
#include <time.h> 	
#define M1 1000     //存储输入码字的数组容量
#define M2 4000      //存储编码后码字的数组容量  
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};   //定义删余矩阵

/*************************************************************************************************************************
    编码函数
*************************************************************************************************************************/

//以下为(4,1,4)卷积编码函数

unsigned int juanjiencode(
unsigned int *symbols,    /*编码输出*/
unsigned int *data,       /*编码输入*/
unsigned int nbytes,      /*nbytes=n/16,n为实际输入码字的数目*/
unsigned int startstate   /*定义初始化状态*/
)
{
  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;
}

//以下为经过删余矩阵的处理

unsigned int puncture(unsigned int *input,unsigned int *output,unsigned int m)   //删余函数
{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码还原成原先的卷积码,被删掉的比特补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)  //从状态a到b的输入值
{int c;
c=((b&8)>>3);
return c;
}


int tranouput(int a,int b,int s,int 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;
}

//以下为编码数据从state1到state2时的汉明距离,如果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;
}


//以下为维特比译码的主函数

void viterby(unsigned int *input,unsigned int *output,int initialstate,int N,int s)  //N为实际输入的码字大数量,initialstate表示输入的初始状态
{   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; //初始化每个状态的度量值为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++;         /*扩展第一步幸存路径*/  

 
   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++;
      }   /*计算出剩余的幸存路径*/
   }

         r=state[0][N-1].pm;       /*找出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; */    /*此行程序可用于检测第n列的度量值*/         

           
}

/*********************************************************************************************************************************
                                      译码主函数
*********************************************************************************************************************************/
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);
      
}

/*********************************************************************************************************************************
                 主函数开始部分                    
*********************************************************************************************************************************/

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<<"输入编码的个数:";
		cin>>n;
		cout<<'\n';
   srand((unsigned)time(NULL)); 
	for(i=0; i<n; i++) 
		encodeinput[i]=rand()%2;   //产生n个随机的0和1

   encodeinput[n]= encodeinput[n+1]=encodeinput[n+2]=encodeinput[n+3]=encodeinput[n+4]=0;  //在第n个数据输入以后持续输入5个数使寄存器清0

   juanjiencode(juanjioutput,encodeinput,n+4,0);  //调用卷积编码程序

	    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;  //计算选择不同码率的删余矩阵所产生的码字个数
       cout<<"经过删余矩阵后输出的码字为:";
	   cout<<num<<'\n';
	   for(i=0;i<num;i++)
		   cout<<encorderoutput[i];
	   cout<<'\n';

       

//以下程序可以对发送的卷积码进行修改以检测译码端的纠错能力
  /*  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<<"误码的个数为:"<<diff<<'\n';


}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -