📄 decode.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 + -