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

📄 ep.c

📁 基于Matlab
💻 C
字号:
#include "mex.h"#include <math.h>#include "ep.h"static complex zero={0,0};void mexFunction(nlhs,plhs,nrhs,prhs)int nlhs;mxArray *plhs[];int nrhs;const mxArray *prhs[];{   /* For T-spaced forward filters (spacing=1) */   /* Input args:  spacing,a,r,ahat,offset,F,G,delay,pdelay,    *              constellation,M,sig    */   double spacing;       /* spacing, i.e. BSE=1, FSE=2 */   double *ar,*ai;       /* T-spaced desired transmitted symbols */    double *rr,*ri;       /* T-spaced received data */    double *yr,*yi;       /* T-spaced equalizer output */    double *ahatr,*ahati; /* T-spaced symbol estimates */    int offset;           /* offset used to recover initial conditions */   double *Fr,*Fi;       /* T-spaced forward filters */    double *Gr,*Gi;       /* T-spaced feedback filter */   int delay;            /* transmission delay */    int pdelay;           /* processing delay */    int constellation;    /* constellation type */    int M;                /* constellation size */    double sig;           /* constellation power */    /* For T/2-spaced forward filters (spacing=0.5) */   /* Input args:  spacing,a,ra,rb,y,ahat,offset,Fa,Fb,G,delay,    *              pdelay,constellation,M,sig    */   double *rar,*rai;     /* T-spaced received even subchannel data */    double *rbr,*rbi;     /* T-spaced received odd subchannel data */    double *Far,*Fai;     /* T-spaced forward even subfilter */    double *Fbr,*Fbi;     /* T-spaced forward odd subfilter */       /* Intermediate variables */   int Nf,Nfa,Nfb,Ng;  /* Length of filters */    int L;              /* Lenght of simulation */   /* For T/2 and T-spaced forward filters (spacing=1) */   /* Output args: outy,outahat,outres,outq */   double *outyr,*outyi;    double *outahatr,*outahati;    double *outresr,*outresi;    double *outqr,*outqi;    /* Find out if BSE or FSE */   spacing=(double)mxGetScalar(prhs[0]);       /* Retrieve BSE variables */    /* Input args:  spacing,a,r,ahat,offset,F,G,delay,pdelay,    *              constellation,M,sig    */   if (spacing==1.0) {      /* Retrieve scalars */      L=(int)mxGetM(prhs[1]);      offset=(int)mxGetScalar(prhs[4]);          Nf=(int)mxGetM(prhs[5]);      Ng=(int)mxGetM(prhs[6]);      delay=(int)mxGetScalar(prhs[7]);      pdelay=(int)mxGetScalar(prhs[8]);      constellation=(int)mxGetScalar(prhs[9]);      M=(int)mxGetScalar(prhs[10]);      sig=(double)mxGetScalar(prhs[11]);      /* Get input pointers */      ar=mxGetPr(prhs[1]);      if (mxIsComplex(prhs[1]))         ai=mxGetPi(prhs[1]);      else         ai=(double *)mxCalloc(L,sizeof(double));      rr=mxGetPr(prhs[2]);      if (mxIsComplex(prhs[2]))         ri=mxGetPi(prhs[2]);      else         ri=(double *)mxCalloc(L,sizeof(double));      ahatr=mxGetPr(prhs[3]);      if (mxIsComplex(prhs[3]))         ahati=mxGetPi(prhs[3]);      else         ahati=(double *)mxCalloc(L,sizeof(double));      Fr=mxGetPr(prhs[5]);      if (mxIsComplex(prhs[5]))         Fi=mxGetPi(prhs[5]);      else         Fi=(double *)mxCalloc(Nf,sizeof(double));      Gr=mxGetPr(prhs[6]);      if (mxIsComplex(prhs[6]))         Gi=mxGetPi(prhs[6]);      else         Gi=(double *)mxCalloc(Ng,sizeof(double));      /* Allocate memory for outputs */      plhs[0]=mxCreateDoubleMatrix(L,1,mxCOMPLEX);       /* y */      plhs[1]=mxCreateDoubleMatrix(L,1,mxCOMPLEX);       /* ahat */      plhs[2]=mxCreateDoubleMatrix(L,1,mxCOMPLEX);       /* res */      plhs[3]=mxCreateDoubleMatrix(L,1,mxCOMPLEX);       /* q */      /* Get output pointers */      outyr=mxGetPr(plhs[0]);      outyi=mxGetPi(plhs[0]);      outahatr=mxGetPr(plhs[1]);      outahati=mxGetPi(plhs[1]);      outresr=mxGetPr(plhs[2]);      outresi=mxGetPi(plhs[2]);      outqr=mxGetPr(plhs[3]);      outqi=mxGetPi(plhs[3]);      /* Adapt! */         runBSE(Nf,Ng,Fr,Fi,Gr,Gi,               L,ar,ai,rr,ri,ahatr,ahati,offset,               delay,pdelay,               constellation,M,sig,               outyr,outyi,outahatr,outahati,               outresr,outresi,outqr,outqi);   }   /* Retrieve FSE variables */    /* Input args:  spacing,a,ra,rb,ahat,offset,Fa,Fb,G,delay,    *              pdelay,constellation,M,sig    */   else {      /* Retrieve scalars */      L=(int)mxGetM(prhs[1]);      offset=(int)mxGetScalar(prhs[5]);          Nfa=(int)mxGetM(prhs[6]);      Nfb=(int)mxGetM(prhs[7]);      Ng=(int)mxGetM(prhs[8]);      delay=(int)mxGetScalar(prhs[9]);      pdelay=(int)mxGetScalar(prhs[10]);      constellation=(int)mxGetScalar(prhs[11]);      M=(int)mxGetScalar(prhs[12]);      sig=(double)mxGetScalar(prhs[13]);      /* Get input pointers */      ar=mxGetPr(prhs[1]);      if (mxIsComplex(prhs[1]))         ai=mxGetPi(prhs[1]);      else         ai=(double *)mxCalloc(L,sizeof(double));      rar=mxGetPr(prhs[2]);      if (mxIsComplex(prhs[2]))         rai=mxGetPi(prhs[2]);      else         rai=(double *)mxCalloc(L,sizeof(double));      rbr=mxGetPr(prhs[3]);      if (mxIsComplex(prhs[3]))         rbi=mxGetPi(prhs[3]);      else         rbi=(double *)mxCalloc(L,sizeof(double));      ahatr=mxGetPr(prhs[4]);      if (mxIsComplex(prhs[4]))         ahati=mxGetPi(prhs[4]);      else         ahati=(double *)mxCalloc(L,sizeof(double));      Far=mxGetPr(prhs[6]);      if (mxIsComplex(prhs[6]))         Fai=mxGetPi(prhs[6]);      else         Fai=(double *)mxCalloc(Nfa,sizeof(double));      Fbr=mxGetPr(prhs[7]);      if (mxIsComplex(prhs[7]))         Fbi=mxGetPi(prhs[7]);      else         Fbi=(double *)mxCalloc(Nfb,sizeof(double));      Gr=mxGetPr(prhs[8]);      if (mxIsComplex(prhs[8]))         Gi=mxGetPi(prhs[8]);      else         Gi=(double *)mxCalloc(Ng,sizeof(double));      /* Allocate memory for outputs */      plhs[0]=mxCreateDoubleMatrix(L,1,mxCOMPLEX);        /* y */      plhs[1]=mxCreateDoubleMatrix(L,1,mxCOMPLEX);        /* ahat */      plhs[2]=mxCreateDoubleMatrix(L,1,mxCOMPLEX);        /* res */      plhs[3]=mxCreateDoubleMatrix(L,1,mxCOMPLEX);        /* q */      /* Get output pointers */      outyr=mxGetPr(plhs[0]);      outyi=mxGetPi(plhs[0]);      outahatr=mxGetPr(plhs[1]);      outahati=mxGetPi(plhs[1]);      outresr=mxGetPr(plhs[2]);      outresi=mxGetPi(plhs[2]);      outqr=mxGetPr(plhs[3]);      outqi=mxGetPi(plhs[3]);      /* Adapt! */         runFSE(Nfa,Nfb,Ng,Far,Fai,Fbr,Fbi,Gr,Gi,             L,ar,ai,rar,rai,rbr,rbi,ahatr,ahati,offset,             delay,pdelay,             constellation,M,sig,             outyr,outyi,outahatr,outahati,outresr,outresi,outqr,outqi);   }}voidrunBSE(Nf,Ng,Fr,Fi,Gr,Gi,       L,ar,ai,rr,ri,ahatr,ahati,offset,       delay,pdelay,       constellation,M,sig,       outyr,outyi,outahatr,outahati,       outresr,outresi,outqr,outqi)int Nf,Ng;double *Fr,*Fi;double *Gr,*Gi;int L;double *ar,*ai;double *rr,*ri;double *ahatr,*ahati;int offset;int delay,pdelay;int constellation,M;double sig;double *outyr,*outyi;double *outahatr,*outahati;double *outresr,*outresi;double *outqr,*outqi;{    complexVec F;              /* forward filter */    complexVec G;              /* feedback filter */   complex *a;                /* complex symbols */   complex *r;                /* complex received data */   complex y;                 /* equalizer output */   complex *ahat;             /* complex symbol estimates */   int i;                     /* Tap index */   int n;                     /* sample counter */   /* Initialize initial guess */   a=(complex *)mxCalloc(L,sizeof(complex));   r=(complex *)mxCalloc(L,sizeof(complex));   ahat=(complex *)mxCalloc(L,sizeof(complex));   for (n=0; n<L; n++) {      a[n].re=ar[n];      a[n].im=ai[n];      r[n].re=rr[n];      r[n].im=ri[n];      ahat[n].re=ahatr[n];      ahat[n].im=ahati[n];   }   /* Initialize regressors & filters */   F.len=Nf;   for (i=0; i<Nf; i++) {      F.v[i].re=Fr[i];      F.v[i].im=Fi[i];   }   G.len=Ng;   for (i=0; i<Ng; i++) {      G.v[i].re=Gr[i];      G.v[i].im=Gi[i];   }   /* Run adaptation until output variance is below threshold */    for (n=offset; n<L; n++) {       y=zero;      /* Compute equalizer output */      for (i=0; i<Nf; i++) {         y.re=y.re+(F.v[i].re*r[n-i].re-F.v[i].im*r[n-i].im);         y.im=y.im+(F.v[i].re*r[n-i].im+F.v[i].im*r[n-i].re);      }      for (i=0; i<Ng; i++) {         y.re=y.re-(G.v[i].re*ahat[n-pdelay-i].re-                    G.v[i].im*ahat[n-pdelay-i].im);         y.im=y.im-(G.v[i].re*ahat[n-pdelay-i].im+                    G.v[i].im*ahat[n-pdelay-i].re);      }      ahat[n]=quantize(y,constellation,M,sig);       /* Store output  */      outyr[n]=y.re;      outyi[n]=y.im;      outahatr[n]=ahat[n].re;      outahati[n]=ahat[n].im;      outresr[n]=a[n-delay].re-y.re;      outresi[n]=a[n-delay].im-y.im;      outqr[n]=a[n-delay].re-ahat[n].re;      outqi[n]=a[n-delay].im-ahat[n].im;   } }voidrunFSE(Nfa,Nfb,Ng,Far,Fai,Fbr,Fbi,Gr,Gi,       L,ar,ai,rar,rai,rbr,rbi,ahatr,ahati,offset,       delay,pdelay,       constellation,M,sig,       outyr,outyi,outahatr,outahati,outresr,outresi,outqr,outqi)int Nfa,Nfb,Ng;double *Far,*Fai;double *Fbr,*Fbi;double *Gr,*Gi;int L;double *ar,*ai;double *rar,*rai;double *rbr,*rbi;double *ahatr,*ahati;int offset;int delay;int pdelay;int constellation,M;double sig;double *outyr,*outyi;double *outahatr,*outahati;double *outresr,*outresi;double *outqr,*outqi;{    complexVec Fa;             /* even forward filter */    complexVec Fb;             /* odd forward filter */    complexVec G;              /* feedback filter */   complex *a;                /* complex symbols */   complex *ra;               /* complex even received data */   complex *rb;               /* complex odd received data */   complex y;                 /* complex equalizer output */   complex *ahat;             /* complex symbol estimates */   int i;                     /* Tap index */   int n;                     /* sample counter */   /* Initialize initial guess */   a=(complex *)mxCalloc(L,sizeof(complex));   ra=(complex *)mxCalloc(L,sizeof(complex));   rb=(complex *)mxCalloc(L,sizeof(complex));   ahat=(complex *)mxCalloc(L,sizeof(complex));   for (n=0; n<L; n++) {      a[n].re=ar[n];      a[n].im=ai[n];      ra[n].re=rar[n];      ra[n].im=rai[n];      rb[n].re=rbr[n];      rb[n].im=rbi[n];      ahat[n].re=ahatr[n];      ahat[n].im=ahati[n];   }   /* Initialize filters */   Fa.len=Nfa;   for (i=0; i<Nfa; i++) {      Fa.v[i].re=Far[i];      Fa.v[i].im=Fai[i];   }   Fb.len=Nfb;   for (i=0; i<Nfb; i++) {      Fb.v[i].re=Fbr[i];      Fb.v[i].im=Fbi[i];   }   G.len=Ng;   for (i=0; i<Ng; i++) {      G.v[i].re=Gr[i];      G.v[i].im=Gi[i];   }   /* Run adaptation until output variance is below threshold */    for (n=offset; n<L; n++) {       y=zero;      /* Compute equalizer output */      for (i=0; i<Nfa; i++) {         y.re=y.re+(Fa.v[i].re*ra[n-i].re-Fa.v[i].im*ra[n-i].im);         y.im=y.im+(Fa.v[i].re*ra[n-i].im+Fa.v[i].im*ra[n-i].re);      }      for (i=0; i<Nfb; i++) {         y.re=y.re+(Fb.v[i].re*rb[n-i].re-Fb.v[i].im*rb[n-i].im);         y.im=y.im+(Fb.v[i].re*rb[n-i].im+Fb.v[i].im*rb[n-i].re);      }      for (i=0; i<Ng; i++) {         y.re=y.re-(G.v[i].re*ahat[n-pdelay-i].re-                    G.v[i].im*ahat[n-pdelay-i].im);         y.im=y.im-(G.v[i].re*ahat[n-pdelay-i].im+                    G.v[i].im*ahat[n-pdelay-i].re);      }      ahat[n]=quantize(y,constellation,M,sig);       /* Store output & error */      outyr[n]=y.re;      outyi[n]=y.im;      outahatr[n]=ahat[n].re;      outahati[n]=ahat[n].im;      outresr[n]=a[n-delay].re-y.re;      outresi[n]=a[n-delay].im-y.im;      outqr[n]=a[n-delay].re-ahat[n].re;      outqi[n]=a[n-delay].im-ahat[n].im;   } }/*  * addComplex - add complex numbers a and b  */ complexaddComplex(a,b)complex a;complex b;{   complex c;   c.re=a.re+b.re;   c.im=a.im+b.im;   return c;}/*  * subComplex - subtract complex numbers a and b  */ complexsubComplex(a,b)complex a;complex b;{   complex c;   c.re=a.re-b.re;   c.im=a.im-b.im;   return c;} /*  * multComplex - multiply complex numbers a and b  */ complexmultComplex(a,b)complex a;complex b;{   complex c;   c.re=a.re*b.re-a.im*b.im;   c.im=a.re*b.im+a.im*b.re;   return c;}/*  * modulus - modulus |z| of z  */doublemodulus(z)complex z;{   return sqrt(z.re*z.re + z.im*z.im);}/*  * conj - conjugate of a=(x,y) is (x,-y)  */complexconj(a)complex a;{   complex c;   c.re=a.re;   c.im=-a.im;   return c;}/* * quantize - make a symbol estimate. */complexquantize(z,constellation,M,sig)complex z;int constellation;int M;double sig;{   complex a;   complex y;   y.re=z.re*sig;   y.im=z.im*sig;   if (constellation==1)      a=unpam(y,M);   else if (constellation==2)      a=unqam(y,M);   else if (constellation==3)      a=unpam(y,M);   a.re=a.re/sig;   a.im=a.im/sig;   return a;}     /* * constellationStats - 4th and 2nd moments of constellation */voidconstellationStats(constellation,M,m4,m2)int constellation;int M;double *m4;double *m2;{   int i,j;   complex a;   int rootM;   if (constellation==1) {      /* Compute 4th moment */      *m4=0;      for (i=1; i<=M/2; i++) {         *m4=*m4+2.0/(double)M*pow((double)(2*i-1),4.0);      }      /* Compute 2nd moment */      *m2=((double)M*M-1.0)/3.0;   }   else if (constellation==2) {      /* Compute 4th moment */      *m4=0;      rootM=sqrt((double) M);      for (i=1; i<=rootM/2; i++)  {         for (j=1; j<=rootM/2; j++)  {            a.re=2*i-1;            a.im=2*j-1;            *m4=*m4+4.0/(double)M*pow(modulus(a),4.0);         }      }      /* Compute 2nd moment */      *m2=(2.0*((double)M-1.0))/3.0;   }}/* * unpam - decode an M-PAM symbol to nearest neighbor. */complexunpam(z,M)complex z;int M;{   complex a=zero;   if (modulus(z)>M-1.0) {      a.re=sign(z.re)*((double)M-1.0);   }   else {      a.re=sign(z.re)*(round((modulus(z)+1.0)/2.0)*2.0-1.0);   }   return a;}/* * unqam - make a M-QAM estimate. */complexunqam(z,M)complex z;int M;{   complex zre=zero;   complex zim=zero;   complex a,are,aim;   int rootM;   rootM=sqrt(M);   zre.re=z.re;   are=unpam(zre,rootM);   zim.re=z.im;   aim=unpam(zim,rootM);   a.re=are.re;   a.im=aim.re;   return a;}/* * sign - signum function */doublesign(x)double x;{   double y;    if (x>0.0)      y=1.0;   else      y=-1.0;   return y;}/* * round - round to nearest integer */doubleround(x)double x;{   double y;   if (x>((double)floor(x)+(double)ceil(x))/2.0)      y=(double)ceil(x);   else      y=(double)floor(x);   return y;}

⌨️ 快捷键说明

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