?? channelfading.c
字號:
/*********************************************************************
* 文件名稱: ChannelFading.c
* 主要內容: GSM系統六徑衰落信道仿真。采用Jakes衰落模型。
* 本程序Model A選用第二組數據。
The reduced setting (6 taps) is defined thereunder.
model A (Typical case for hilly terrain)
number Relative Average relative doppler
time (μs) power (dB) spectrum
(1) (2) (1) (2)
1 0.0 0.0 0.0 0.0 CLASS
2 0.1 0.2 -1.5 -2.0 CLASS
3 0.3 0.4 -4.5 -4.0 CLASS
4 0.5 0.6 -7.5 -7.0 CLASS
5 15.0 15.0 -8.0 -6.0 CLASS
6 17.2 17.2 -17.7 -12.0 CLASS
model B (Profile for equalization test)
Tap Relative Average relative doppler
number time (μs) power (dB) spectrum
1 0.0 0.0 CLASS
2 3.2 0.0 CLASS
3 6.4 0.0 CLASS
4 9.6 0.0 CLASS
5 12.8 0.0 CLASS
6 16.0 0.0 CLASS
*=====================================================================
* 版權:作者個人所有
*
* 當前版本: 0.1.3
* 作 者: 金利忠,蔣登峰, 高霽
* 完成日期: 2004年5月25日
*=====================================================================
**********************************************************************/
#include "ChannelFading.h"
/*void main()
{
double in_Xdata[FRAME_LEN];
double in_Ydata[FRAME_LEN];
double out_Xdata[FRAME_LEN+maxDELAY];
double out_Ydata[FRAME_LEN+maxDELAY];
int i;
in_Xdata[0]=1;
in_Ydata[0]=1;
for (i = 1; i<FRAME_LEN; i++)
{
in_Xdata[i] =0; // generate the random data
in_Ydata[i] =0;
//printf("%f,%f\n", in_Xdata[i],in_Ydata[i]);
}
JakesModel(in_Xdata,in_Ydata,out_Xdata,out_Ydata);
for (i = 0; i<FRAME_LEN+maxDELAY; i++)
{
printf("%f,,,%f---Time:%d\n", out_Xdata[i],out_Ydata[i],i);
}
}*/
/*****************************************************
函數名:void JakesModel(const double *Xcomplex, const double *Ycomplex,
double *oXcomplex, double *oYcomplex)
函數功能:每一徑平坦衰落和延時后合成函數。
輸入參數說明:
Xcomplex: 輸入數據實部分量,double型指針
Ycomplex: 輸入數據虛部分量,double型指針
輸出參數說明:
oXcomplex:輸出數據實部分量,double型指針
返回值:oYcomplex:輸出數據虛部分量,double型指針
無
其它說明:這個程序中,直接對輸出數據進行處理,沒有在數據處理是額外的寄存器的需求。
具體可參考程序文檔。
修改日期 版本號 修改人 修改內容
------------------------------------------------------
2004/05/25 V1.0 金利忠 創建
2004/05/26 V1.1 金利忠
2004/05/29 V1.2 金利忠
2004/05/30 V1.3 金利忠
******************************************************/
void JakesModel(const double *Xcomplex, const double *Ycomplex,
double *oXcomplex, double *oYcomplex, int lasttime[1],
unsigned int gseed[2],double SNR,const int chchoice,
const int vchoice,const double chfac)
{
/*****************************************
先對模型中用到的參數初始化。
*****************************************/
int jj,n,i;
int j;
int delay[]={0,0,0,1,16,19};//延時初始化
double power_rela[]={0,-2.0,-4.0,-7.0,-6.0,-12.0};//相對功率的初始化
//For debug
//int delay[TAP_NUMBER]={0,0,0,1,16,19};//延時初始化
//double power_rela[6]={0,-200,-200,-200,-200,-1200};//相對功率的初始化
double power[6];
int p;
double sum_power=0.0;
double gM[FRAME_LEN];
double gN[FRAME_LEN];
double Xcc[1];
double Xss[1];
double outX;
double outY;
int tap_num; //TAP計數器
double sigma;
int maxDELAY = 19;
double jakesWM;
jakesWM = (2*PI*vchoice*1000.0*9)/(3600.0*3.0);
if (chchoice == 2)
{
delay[0] = 0;
delay[1] = 3;
delay[2] = 7;
delay[3] = 10;
delay[4] = 14;
delay[5] = 17;
power_rela[0] = 0;
power_rela[1] = 0;
power_rela[2] = 0;
power_rela[3] = 0;
power_rela[4] = 0;
power_rela[5] = 0;
maxDELAY = 17;
}
/* for(jj=1;jj<JAKES_N0+1;jj++) //取得gama和sita
{
for(i=1;i<TAP_NUMBER+1;i++)
{
beta[jj-1][i-1]=PI*jj*i/(JAKES_N0+1);
gama[i-1]=(2*PI*(i-1))/(JAKES_N0+1);
sita[jj-1][i-1]=beta[jj-1][i-1]+gama[i-1];
}
}
for(n=1;n<JAKES_N+1;n++) //取得alfa和Wn
{
alfa[n-1]=(2*PI*n)/JAKES_N;
JAKES_Wn[n-1]=jakesWM*cos(alfa[n-1]);
}
*/
for (p=0; p<TAP_NUMBER; p++)
{
power[p]=pow(10.0,power_rela[p]/10);
sum_power=sum_power+power[p]; //取相對功率的和。
}
/*****************************************
產生高斯噪聲。
*****************************************/
G_rand(gM,gN,gseed);
sigma = pow(10.0,(SNR/10));
/*****************************************
開始進行多徑衰落合成。
*****************************************/
//初始化輸出數據前maxDELAY位
for(j=0;j<maxDELAY;j++)
{
oXcomplex[j]=0;
oYcomplex[j]=0;
}
Xcc[0]=0;
Xss[0]=0;
if (lasttime[0]>=1073741824) //prevent overflow
{
lasttime[0] = 0;
}
for(j=0;j<FRAME_LEN;j++) //j時刻
{
//kkkk=Xcomplex[j];
oXcomplex[j+maxDELAY]=Xcomplex[j];
oYcomplex[j+maxDELAY]=Ycomplex[j];
//最大延時的一徑先算
h_gen(TAP_NUMBER, j+lasttime[0], Xcc, Xss, jakesWM);
outX=sqrt(power[TAP_NUMBER-1]/sum_power)*oXcomplex[j];
outY=sqrt(power[TAP_NUMBER-1]/sum_power)*oYcomplex[j];
oXcomplex[j]=outX*(*Xcc)-outY*(*Xss);
oYcomplex[j]=outY*(*Xcc)+outX*(*Xss);
//再從第一徑開始算,一共剩下5徑
for(tap_num=1;tap_num<TAP_NUMBER;tap_num++)
{
h_gen(tap_num, j+lasttime[0], Xcc, Xss, jakesWM);
outX=sqrt(power[tap_num-1]/sum_power)*oXcomplex[j+maxDELAY-delay[tap_num-1]];
outY=sqrt(power[tap_num-1]/sum_power)*oYcomplex[j+maxDELAY-delay[tap_num-1]];
oXcomplex[j]=(outX*(Xcc[0])-outY*(Xss[0]))+oXcomplex[j];
oYcomplex[j]=(outY*(Xcc[0])+outX*(Xss[0]))+oYcomplex[j];
}
oXcomplex[j]=gM[j]/(sqrt(2*sigma))+oXcomplex[j]/(sqrt(chfac));//加入噪聲M[j]
oYcomplex[j]=gN[j]/(sqrt(2*sigma))+oYcomplex[j]/(sqrt(chfac));//加入噪聲N[j]
}
lasttime[0]=j+lasttime[0];
}
/*****************************************************
函數名:void h_gen(const int tap, const int tim, double *Xc, double *Xs)
函數功能:產生每一徑的衰落系數h(j,tap),使用的是Jakes模型。
輸入參數說明:
tap: 輸入多徑的徑數,int型
tim: 輸入時間,int型
輸出參數說明:
oXcomplex:輸出數據實部分量,double型指針
oYcomplex:輸出數據虛部分量,double型指針
返回值:
無
其它說明
修改日期 版本號 修改人 修改內容
------------------------------------------------------
2004/05/25 V1.0 金利忠 創建
2004/05/26 V1.1 金利忠
2004/05/29 V1.2 金利忠
2004/05/30 V1.3 金利忠
******************************************************/
void h_gen(const int tap, const int tim, double Xc[1], double Xs[1], double jakesWM)
{
double XsS=0;
double XcS=0;
double cos_w;
double cos_alfa;
double factor_n;
double Nalpha=PI; //待定
//double alpha_hat=0.5*PI; //待定
double betan[JAKES_N0];
int i,jj,n;
//Classical Jakes
/* for(jj=1;jj<JAKES_N0+1;jj++) //取得gama和sita
{
betan[jj-1] = (PI*jj)/(JAKES_N0);
}
for(jj=1;jj<JAKES_N0+1;jj++) //取得gama和sita
{
for(i=1;i<TAP_NUMBER+1;i++)
{
beta[jj-1][i-1]=(PI*jj)/(JAKES_N0+1);
gama[i-1]=(2*PI*(i-1))/(JAKES_N0+1);
sita[jj-1][i-1]=beta[jj-1][i-1]+gama[i-1];
}
}
for(n=1;n<JAKES_N+1;n++) //取得alfa和Wn
{
alfa[n-1]=(2*PI*n)/JAKES_N;
JAKES_Wn[n-1]=(jakesWM)*cos(alfa[n-1]);
}
for(i=1;i<JAKES_N0+1;i++)
{
cos_w=cos(JAKES_Wn[i-1]*tim*(SYMBLE_T1)+sita[i-1][tap-1]);
//XcS=XcS+2*cos(beta[i-1][tap-1])*cos_w;
//XsS=XsS+2*sin(beta[i-1][tap-1])*cos_w;
XcS=XcS+2*cos(betan[i-1])*cos_w;
XsS=XsS+2*sin(betan[i-1])*cos_w;
}
cos_alfa=cos(jakesWM*tim*(SYMBLE_T1)+(tap)*(PI/2));
factor_n=sqrt(2.0/JAKES_N);
//XcS=2*XcS+sqrt(2)*fabs(cos(Nalpha*tap))*cos_alfa;
//XsS=2*XsS+sqrt(2)*sin(Nalpha*tap)*cos_alfa;
XcS = XcS+cos_alfa;
XsS = XsS+cos_alfa;
Xc[0]=factor_n*XcS;
Xs[0]=factor_n*XsS;
*/
//Modified (Ref to IEEE)
for(jj=1;jj<JAKES_N0+1;jj++) //取得gama和sita
{
for(i=1;i<TAP_NUMBER+1;i++)
{
beta[jj-1][i-1]=(PI*jj*i)/(JAKES_N0+1);
gama[i-1]=(2*PI*(i-1))/(JAKES_N0+1);
sita[jj-1][i-1]=beta[jj-1][i-1]+gama[i-1];
}
}
for(n=1;n<JAKES_N+1;n++) //取得alfa和Wn
{
alfa[n-1]=(2*PI*n)/JAKES_N;
JAKES_Wn[n-1]=(jakesWM)*cos(alfa[n-1]);
}
for(i=1;i<JAKES_N0+1;i++)
{
cos_w=cos(JAKES_Wn[i-1]*tim*(SYMBLE_T1)+(tap*PI/2));
XcS=XcS+2*cos(beta[i-1][tap-1])*cos_w;
XsS=XsS+2*sin(beta[i-1][tap-1])*cos_w;
//XcS=XcS+2*cos(betan[i-1])*cos_w;
//XsS=XsS+2*sin(betan[i-1])*cos_w;
}
cos_alfa=cos(jakesWM*tim*(SYMBLE_T1)+(tap)*(PI/2));
factor_n=sqrt(2.0/JAKES_N);
XcS=XcS+2*cos_alfa*fabs(cos(PI*tap));
XsS=XsS+2*cos_alfa*sin(PI*tap);
//XcS = XcS+cos_alfa;
//XsS = XsS+cos_alfa;
Xc[0]=factor_n*XcS;
Xs[0]=factor_n*XsS;
}
/*void h_gen(const int tap, const int tim, double Xc[1], double Xs[1])
{
double XsS=0;
double XcS=0;
double cos_w;
double cos_alfa;
double factor_n;
double Nalpha=PI; //待定
double alpha_hat=0.5*PI; //待定
int i,jj,n;
double betan[JAKES_N0];
//printf("%d\n",JAKES_N0);
for(jj=1;jj<JAKES_N0+1;jj++) //取得gama和sita
{
betan[jj-1] = (PI*jj)/(JAKES_N0);
}
for(n=1;n<JAKES_N+1;n++) //取得alfa和Wn
{
alfa[n-1]=(2*PI*n)/JAKES_N;
JAKES_Wn[n-1]=jakesWM*cos(alfa[n-1]);
}
for(i=1;i<JAKES_N0+1;i++)
{
cos_w=cos(JAKES_Wn[i-1]*tim*(SYMBLE_T1));//+alpha_hat*tap);//sita[i-1][tap-1]);
XcS=XcS+2*cos(betan[i-1])*cos_w;
XsS=XsS+2*sin(betan[i-1])*cos_w;
}
cos_alfa=cos(jakesWM*tim*SYMBLE_T1);//+alpha_hat*tap);//gama[tap-1]
factor_n=sqrt(2.0/JAKES_N);
//XcS=2*XcS+2*fabs(cos(Nalpha*tap))*cos_alfa;//sqrt(2)
//XcS=2*XcS+2*cos(Nalpha*tap)*cos_alfa;//sqrt(2)
//XsS=2*XsS+2*sin(Nalpha*tap)*cos_alfa;//sqrt(2)
XcS = XcS+cos_alfa;
XsS = XsS+cos_alfa;
Xc[0]=factor_n*XcS;
Xs[0]=factor_n*XsS;
}*/
/*****************************************************
函數名:void G_rand(double *M, double *N)
函數功能:產生高斯隨機變量,采用Box-Muller方法。
無輸出參數
輸出參數說明:
M: 輸出復數X變量,double型
N: 輸出復數Y變量,double型
返回值:
無
其它說明:均值為0,方差為1
修改日期 版本號 修改人 修改內容
------------------------------------------------------
2004/05/27 V1.0 高霽 創建
2004/05/30 V1.1 金利忠 原型:if (ii == 1)
{
X[1] = 999987256;
Y[1] = 198102025;
}
******************************************************/
void G_rand(double *M, double *N, unsigned int gseed[2])
{
unsigned long int X[FRAME_LEN];
unsigned long int Y[FRAME_LEN];
double XX[FRAME_LEN];
double YY[FRAME_LEN];
unsigned long int a = 16807;
unsigned long int b = 0;
unsigned long int c = 2147483647;
int ii;
double d,e,f,g;
for(ii = 0;ii < FRAME_LEN;ii++)
{
if (ii == 0)
{
X[0] = gseed[0];
Y[0] = gseed[1];
}
else
{
X[ii] = (a * X[ii-1] + b)%c;
Y[ii] = (a * Y[ii-1] + b)%c;
}
XX[ii] = X[ii] / (double)c;
YY[ii] = Y[ii] / (double)c;
d=sqrt(-2 * log(XX[ii]));
e=cos(2 * PI * YY[ii]);
f=sqrt(-2 * log(XX[ii]));
g=sin(2 * PI * YY[ii]);
M[ii] = d * e;
N[ii] = f * g;
}
gseed[0] = X[FRAME_LEN - 1];
gseed[1] = Y[FRAME_LEN - 1];
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -