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

📄 decode.cpp

📁 该函数可以实现任意行列数double型矩阵的张量乘积 用数组实现
💻 CPP
字号:
#include<iostream>
#include<cmath>
using namespace std;


//****************************************************************************
//  一个复数类(实现复数的加/减/乘/除/求模/与实数相乘/求共轭/求负共轭/赋值/显示)
//****************************************************************************


class complex
{
public:
	complex(float r=1,float i=1):x(r),y(i){}//构造函数,实现初始化
	complex operator+(complex &c2);//声明重载运算符的"+"函数
    complex operator-(complex &c2);//声明重载运算符的"-"函数
	complex operator*(complex &c2);//声明重载运算符的"*"函数(两个复数的乘法)
	complex operator/(complex &c2);//声明重载运算符的"/"函数
    complex operator*(float e);//声明重载运算符的"*"函数(实数与复数的乘法)
	float model();//求模
	complex conjugate();//求共轭
	complex negative();//求负共轭
    void display();//显示
    void fz(float ,float);//复数对象的赋值

private:
	float x;
	float y;
};

complex complex:: operator+(complex &c2)
{  complex c;
   c.x=x+c2.x;
   c.y=y+c2.y;
   return c;
}

complex complex::operator-(complex &c2)
{  complex c;
   c.x=x-c2.x;
   c.y=y-c2.y;
   return c;
}

complex complex::operator*(complex &c2)
{  complex c;
   c.x=x*c2.x-y*c2.y;
   c.y=x*c2.y+c2.x*y;
   return c;
}

complex complex::operator/(complex &c2)
{  complex c;
   c.x=(x*c2.x+y*c2.y)/(c2.x*c2.x+c2.y*c2.y);
   c.y=(c2.x*y-x*c2.y)/(c2.x*c2.x+c2.y*c2.y);
   return c;
}	

complex complex::operator*(float e)
{
	return complex(e*x,e*y);
}

void complex::fz (float r ,float i)
{
	x=r;
	y=i;
}

float complex::model()
{  return((float) sqrt(x*x+y*y));
	}

complex complex::conjugate()
{  
   return complex(x,-y);
}

complex complex::negative()
{ 
	return complex(-x,y);
}

void complex::display()
{  
	cout<<"("<<x<<","<<y<<"i)"<<endl;
}


//两个全局变量
int A[45];//发送端产生数据流
int b[45];//接收端产生数据流


//***********************************************
//          15位M序列发生器函数
//***********************************************
void msequence() 
{ int i,j;
int a[5]={1,0,1,0,1};

for(j=0;j<45;j++)              
{
int temp=(a[0]+a[3])%2;
if(j%15==0) cout<<endl;

A[j]=a[4];
for(i=4;i>=0;i--)
a[i]=a[i-1];
a[0]=temp;
}
}

//cout<<"********************************************"<<endl;
//cout<<"                  发送端                    "<<endl; 
//cout<<"********************************************"<<endl;


void main()//主程序
{
 int a[45];
 int i,j,d,g;
 float error=0,ber;
 float Z=sqrt(2)/2;//8PSK星座图中某些点的坐标值
 complex cm[8];
 complex t[45];//复数对象数组,便于存放每一时刻调制后发送的信号值
 complex c1,c2,c3,c4;

  void decode(complex &c1,complex &c2);//解调函数的声明
msequence();//调用m序列函数发生器产生一个15位的m序列

for(i=0;i<42;i++) cout<<A[i];//先将产生的序列输出
cout<<endl;
for(i=0;i<45;i++)  a[i]=A[i];
for(j=0;j<7;j++)//本程序中共有45个比特的数据,我们每次需要顺序取出6个比特来发射,故循环七次

{
 for(i=0;i<6;i++)//顺序取出6个比特来发射
 {cout<<A[i];}//输出这6个比特便于检测
 cout<<endl;

  d=A[2]*4+A[1]*2+A[0]*1;//取每3个比特来进行8PSK调制,先将二进制转化为十进制,该步是为了便于写后面的选择语句
  g=A[5]*4+A[4]*2+A[3]*1;//d为前3个输出的比特表示的十进制数,对应我们的X1;g为后3个输出的比特表示的十进制数,对应我们的X2;

for(i=0;i<42;i++) //每取6个比特后就将数组前移,便于后面取数
A[i]=A[i+6];

cout<<"t时刻第一根天线上发送的是:";

//8PSK中的映射关系,采用GRAY编码,这种编码可以使噪声引起的误差在3个比特的码元中仅出现一个比特的错
switch(d)//X1的8PSK映射;
{
case(0):c1.fz(1,0); c1.display();break;
case(1):c1.fz(Z,Z); c1.display();break;
case(3):c1.fz(0,1); c1.display();break;
case(2):c1.fz(-Z,Z); c1.display();break;
case(6):c1.fz(-1,0); c1.display();break;
case(7):c1.fz(-Z,-Z);c1.display();break;
case(5):c1.fz(0,-1); c1.display();break;
case(4):c1.fz(Z,-Z); c1.display();break;
}

cout<<"t时刻第二根天线上发送的是:";
switch(g)//X2的8PSK映射;
{
case(0):c2.fz(1,0); c2.display();break;
case(1):c2.fz(Z,Z); c2.display();break;
case(3):c2.fz(0,1); c2.display();break;
case(2):c2.fz(-Z,Z); c2.display();break;
case(6):c2.fz(-1,0); c2.display();break;
case(7):c2.fz(-Z,-Z);c2.display();break;
case(5):c2.fz(0,-1); c2.display();break;
case(4):c2.fz(Z,-Z); c2.display();break;
}

t[2*j]=c1;//将调制后的信号送到接收端(注:仅因为调试程序,在最终程序中,调制信息的传送由MIMO来实现)
t[2*j+1]=c2;

cout<<"t+T时刻第一根天线上发送的是:";
c3=c2.negative() ;//-X2*
c3.display();

cout<<"t+T时刻第二根天线上发送的是:";
c4=c1.conjugate() ;//X1*
c4.display();

cout<<endl;
}



//cout<<"********************************************"<<endl;
//cout<<"                  接收端                    "<<endl; 
//cout<<"********************************************"<<endl;


for(j=0;j<7;j++)//分为7组,每组两个调制符号,即x1和x2
{   
	cout<<endl;
	cout<<"调制后数据:"<<endl;
	t[2*j].display();
	t[2*j+1].display();
    decode(t[2*j],t[2*j+1]);//每次解调两个符号,共解调7次

}

cout<<"发送数据:"<<endl;//输出发送的数据
for(i=0;i<42;i++) 
cout<<a[i];
cout<<endl;

cout<<"接收数据:"<<endl;//输出接收端经过线性处理和解调后的数据
for(j=0;j<42;j++)
cout<<b[j];
cout<<endl;


for(i=0;i<42;i++)//误码率计算
{if(a[i]!=b[i])
error++;}
cout<<"错误比特数"<<endl;
cout<<error<<endl;
ber=error/42;
cout<<"误码率:"<<endl;
cout<<ber<<endl;


}

//**********************************************************
//            接收端线性处理和解调
//**********************************************************


void decode(complex &c1,complex &c2) //信道加扰 译码函数
{  
   static int  u;
   int B[45];
   float min1,min2;
   float Z=sqrt(2)/2;

 complex cm[8];       	
 complex s1,s2,h1(4,1),h2(4,2);//s为判决变量,h为信道衰落系数
 complex r1,r2,n1(0,1),n2(0,1);//r为接收信号,n为信道复噪声

 r1=h1*c1+h1*c2+n1;//接收信号的表达式(仅为调试时使用,在最终程序中,接收信号从MIMO中提取)
 r2=h1*c2.negative()+h1*c1.conjugate()+n2;
 
 int k=0,p=0; 

 /*****************************************************
 s1=r1*h1.conjugate()+r2.conjugate()*h2;线性处理
 s2=r1*h2.conjugate()-r2.conjugate()*h1;
*******************************************************/

 s1=c1*(h1.model()*h1.model()+h2.model()*h2.model())+h1.conjugate()*n1+h2*n2.conjugate();
 s2=c2*(h1.model()*h1.model()+h2.model()*h2.model())+h1*n2.negative()+h2.conjugate()*n1;


cm[0].fz(1,0);//解调(将星座点映射到十进制数据)
cm[1].fz(Z,Z);
cm[3].fz(0,1);
cm[2].fz(-Z,Z);
cm[6].fz(-1,0);
cm[7].fz(-Z,-Z);
cm[5].fz(0,-1);
cm[4].fz(Z,-Z);


  min1=(cm[0]-s1).model()*(cm[0]-s1).model();//比较欧式距离的暂定最小量
  min2=(cm[0]-s2).model()*(cm[0]-s2).model();

 for(int i=0;i<8;i++)//将原来调制的所有变量一起拿来比较,找出最小的平方欧式距离
{
 if((cm[i]-s1).model()*(cm[i]-s1).model()<min1)
 {min1=(cm[i]-s1).model()*(cm[i]-s1).model();  
 k=i;//保存判断接收信号判决变量s1欧式距离的最小值时的数组下标 
 }

 if((cm[i]-s2).model()*(cm[i]-s2).model()<min2)
 {min2=(cm[i]-s2).model()*(cm[i]-s2).model();  
 p=i;//保存判断接收信号判决变量s2欧式距离的最小值时的数组下标 
 } 

}

cout<<"解调后数据:"<<endl;
cout<<u<<" 时刻X1的译码输出为: ";
cm[k].display();

switch(k)//将十进制数据映射成二进制数据
{
case(0):B[2]=0;B[1]=0;B[0]=0;break;
case(1):B[2]=0;B[1]=0;B[0]=1;break;
case(3):B[2]=0;B[1]=1;B[0]=1;break;
case(2):B[2]=0;B[1]=1;B[0]=0;break;
case(6):B[2]=1;B[1]=1;B[0]=0;break;
case(7):B[2]=1;B[1]=1;B[0]=1;break;
case(5):B[2]=1;B[1]=0;B[0]=1;break;
case(4):B[2]=1;B[1]=0;B[0]=0;break;
}

cout<<u<<" 时刻X2的译码输出为: ";
cm[p].display();

switch(p)
{
case(0):B[5]=0;B[4]=0;B[3]=0;break;
case(1):B[5]=0;B[4]=0;B[3]=1;break;
case(3):B[5]=0;B[4]=1;B[3]=1;break;
case(2):B[5]=0;B[4]=1;B[3]=0;break;
case(6):B[5]=1;B[4]=1;B[3]=0;break;
case(7):B[5]=1;B[4]=1;B[3]=1;break;
case(5):B[5]=1;B[4]=0;B[3]=1;break;
case(4):B[5]=1;B[4]=0;B[3]=0;break;
}

 u++;

 cout<<"接收信息为"<<endl;
for(i=0;i<6;i++)
{cout<<B[i];}
cout<<endl;

 static int m=0;//将数据依次存入b[45]中
b[m]=B[0];
b[m+1]=B[1];
b[m+2]=B[2];
b[m+3]=B[3];
b[m+4]=B[4];
b[m+5]=B[5];
m=m+6;

 }



⌨️ 快捷键说明

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