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

📄 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(float r,float i){x=0;y=0;}
	//complex(float r,float i){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);
	//cout<<"("<<x<<","<<-y<<"i)"<<endl;
}

complex complex::negative()
{ return complex(-x,y);
	//cout<<"("<<-x<<","<<y<<"i)"<<endl;
}

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



int A[45];//定义全局变量A数组,在程序中,这个数组表示的是我们得到的伪随机序列

void msequence() //15位M序列发生器函数
{ 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;
}
}

complex cm[8];
complex t[14];//复数对象数组,便于存放每一时刻调制后发送的信号值
void main()//主程序
{
 int i,j,d,g;
 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=44;i>=0;i--) cout<<A[i];//先将产生的序列输出(与产生顺序相反的方向输出,便于检测)
cout<<endl;

for(j=0;j<7;j++)//本程序中共有45个比特的数据,我们每次需要顺序取出6个比特来发射,故循环七次

{
 for(i=5;i>=0;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;
t[2*j+1]=c2;

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

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


cout<<endl;
}



cout<<"************************************************"<<endl;
cout<<"                     开始译码                 "<<endl;
cout<<"************************************************"<<endl;

for(j=0;j<7;j++)//分为7组,每组两个调制符号,即x1和x2
{
	t[2*j].display();
	t[2*j+1].display();
    decode(t[2*j],t[2*j+1]);//每次解调两个符号,共解调7次
    //decode(complex &c1,complex &c2);
}
}




/*********************************************************************
                       模拟信道  并接收  解调函数
  ********************************************************************/


void decode(complex &c1,complex &c2) //信道加扰 译码函数
{  
 static int  u;
 //float cm[8];
 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;
 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;

 float min1,min2;

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=(t[0]-s1).model()*(t[0]-s1).model();//min1为s1的比较变量
 //min2=(t[0]-s2).model()*(t[0]-s2).model();//min2为s2的比较变量
 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<<u<<" 时刻c1的译码输出为: ";
cm[k].display();
cout<<u<<" 时刻c2的译码输出为: ";
cm[p].display();

 u++;
}




⌨️ 快捷键说明

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