📄 improjakes.cpp
字号:
/**************************************************************
* Copyright (c) 2006, francis. All rights reserved. :)
* Type :ANSI C source code
* MODULE NAME :ImproJakes.c
* ABSTRACT :to generate rayleigh fading using revised jakes
* VERSION :V0.01
* AUTHOR :zhengkang
* COMPILER :Visual studio2003.net
* REVISION HISTORY :V0.01 zhengkang 2006-11-3 created
***************************************************************/
#include "ImproJakes.h"
#include "GlobalVariables.h"
#include "GlobalStruct.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <memory.h>
#define M 8
/**************************************************************************
*
* to produce uniform iid sequence within [0.0 1.0)
* input :none
* output:
* return: a uniformly distributed number within [0.0 1.0)
* function reference:following method according to R.F.W.Coates,G.J.Janacek and K.V.Lever
*"Monte Carlo simulation and random number generation,"IEEE J.Select.Area
*Commun.,vol 6,no.1,pp 58-66,Jan.1988
**************************************************************************/
void SetRunRand(int seed_set)
{
jakes_seed.ix=seed_set;
jakes_seed.iy=seed_set;
jakes_seed.iz=seed_set;
}
// 产生(0,1)的平均随机数
double RunRand()
{
double rand_uni;
jakes_seed.ix = (jakes_seed.ix * 249) % 61967;
jakes_seed.iy = (jakes_seed.iy * 251) % 63443;
jakes_seed.iz = (jakes_seed.iz * 252) % 63599;
rand_uni = (jakes_seed.ix/61967.0 + jakes_seed.iy/63443.0 + jakes_seed.iz/63599.0) - (int)(jakes_seed.ix/61967.0 + jakes_seed.iy/63443.0 + jakes_seed.iz/63599.0);
return rand_uni;
}
//程序执行完毕释放内存
void ReleaseRunRand(void)
{
}
/**************************************************************************
* 读取信道的profile
* input :信道参数结构parameter
* output:把存在 jakes_profile.txt中的信道参数读取到parameter中,并且计算有关数据
* function reference: "The generation of Independent Rayleigh Faders"
* Motorola Austrlian Reserach Center ,Yuxin Li and Xiaojing Huang
**************************************************************************/
void ReadChannelProfile(struct JAKES_PROFILE & parameter)
{
int k=0;
int n=0;
FILE * fp;
if((fp=fopen("jakes_profile.txt","r"))==NULL)
{
printf("Profile Cannot be Open\n");
getchar();
exit(0);
}
char ch;
int i=0;
parameter.path_num=0;
while ((ch=getc(fp))!=':'){}
fscanf(fp,"%d",&(parameter.path_num));//获取径数目
//根据径数目分配内存
if((parameter.power_db = (double *)malloc(parameter.path_num* sizeof(double)))==NULL)
{
printf("power_db Cannot be Allocated\n");
getchar();
exit(0);
}
if((parameter.delay_us = (double *)malloc(parameter.path_num* sizeof(double)))==NULL)
{
printf("delay_us Cannot be Allocated\n");
getchar();
exit(0);
}
if((parameter.power = (double *)malloc(parameter.path_num* sizeof(double)))==NULL)
{
printf("power Cannot be Allocated\n");
getchar();
exit(0);
}
if((parameter.delay = (int *)malloc(parameter.path_num* sizeof(int)))==NULL)
{
printf("delay Cannot be Allocated\n");
getchar();
exit(0);
}
while ((ch=getc(fp))!=':'){} //读取每个径的功率dB
for (i=0; i<parameter.path_num; i++)
{
fscanf(fp,"%lf",parameter.power_db+i); //获取径数目
}
while ((ch=getc(fp))!=':'){} //读三个径的延时
for (i=0; i<parameter.path_num; i++)
{
fscanf(fp,"%lf",parameter.delay_us+i); //获取径的功率
}
parameter.sample_rate = 0; //初试化
while ((ch=getc(fp))!=':'){}
fscanf(fp,"%lf",&(parameter.sample_rate)); //获取采样速率
parameter.carrier_freq = 0;
while ((ch=getc(fp))!=':'){} //获取载频频率
fscanf(fp,"%lf",&(parameter.carrier_freq));
parameter.velocity = 0;
while ((ch=getc(fp))!=':'){} //获取车速
fscanf(fp,"%lf",&(parameter.velocity));
parameter.n_sin = 0;
while ((ch=getc(fp))!=':'){} //获得Sin函数的个数
fscanf(fp,"%d",&(parameter.n_sin));
fclose(fp);
fp=NULL;
parameter.current_time = 0;
parameter.time_step=1.0 / parameter.sample_rate; //计算步长
//计算Doppler频偏
parameter.doppler = 2 * PI * (parameter.velocity /3.6) * parameter.carrier_freq / (3*100000000);
double sum = 0;
for (i=0; i<parameter.path_num; i++)
{
*(parameter.power+i) = sqrt(pow(10.0, *(parameter.power_db+i)/10.0));
sum += (*(parameter.power+i) * (*(parameter.power+i)));
}
for (i=0; i<parameter.path_num; i++)
{
*(parameter.power+i) /= sqrt(sum);
}
for (i=0; i<parameter.path_num; i++)
{
*(parameter.delay+i) = (int)(*(parameter.delay_us+i)/parameter.time_step+0.5);
//为了实现四舍五入
}
/*******************************************************************************************************/
//
parameter.normalized_factor = sqrt( 1/(double)parameter.n_sin);
printf("%f",parameter.normalized_factor);
if ((parameter.theta=(double *)malloc(parameter.path_num * sizeof(double)))==NULL)
{
printf("Theta Cannot be Allocated\n");
getchar();
exit(0);
}
/*******************************************************************************************************/
if ((parameter.coef_inphase=(double*)malloc(parameter.path_num * parameter.n_sin * sizeof(double)))==NULL)
{
printf("coef_inphase Cannot be Allocated\n");
getchar();
exit(0);
}
if ((parameter.coef_quadrature=(double*)malloc(parameter.path_num * parameter.n_sin * sizeof(double)))==NULL)
{
printf("coef_quadrature Cannot be Allocated\n");
getchar();
exit(0);
}
if ((parameter.rand_inphase=(double*)malloc(parameter.path_num * parameter.n_sin * sizeof(double)))==NULL)
{
printf("rand_inphase Cannot be Allocated\n");
getchar();
exit(0);
}
if ((parameter.rand_quadrature=(double*)malloc(parameter.path_num * parameter.n_sin * sizeof(double)))==NULL)
{
printf("rand_quadrature Cannot be Allocated\n");
getchar();
exit(0);
}
/*******************************************************************************************************/
double alpha; // alpha=2*PI/N+2*PI*k/(M*N)+PI/(2*M*N)
for (k=0; k < parameter.path_num; k++)
{
*(parameter.theta + k) = (2 * RunRand() - 1) * PI; // theta 赋值[0,2pi]随机分布
for (n=0; n < parameter.n_sin; n++)
{
*(parameter.rand_inphase + k*parameter.n_sin + n) = 2 * RunRand() * PI;
*(parameter.rand_quadrature+ k*parameter.n_sin + n) = 2 * RunRand() * PI;
alpha = 2 * PI*n / parameter.n_sin +2 * PI * k / (M * parameter.n_sin * 4) + PI / ( 2 * M * parameter.n_sin );
*(parameter.coef_inphase + k*parameter.n_sin + n) = parameter.doppler * cos(alpha);
*(parameter.coef_quadrature+ k*parameter.n_sin + n) = parameter.doppler * sin(alpha);
// printf("%f\t",*(parameter.rand_inphase + k*parameter.n_sin + n));
}
// printf("\n");
}
/*******************************************************************************************************/
if ((parameter.current_channel=(Complex *)malloc(parameter.path_num * sizeof(Complex)))==NULL)
{
printf("rand_quadrature Cannot be Allocated\n");
getchar();
exit(0);
}
memset(parameter.current_channel,0,parameter.path_num * sizeof(Complex));
//将信道输出置零
}
/**************************************************************************
* 产生jakes模型的输出,根据采样间隔
**************************************************************************/
void GenerateChannel(JAKES_PROFILE & parameter ,int step)
{
int k;
int n;
double time = 0;
time = parameter.current_time * parameter.time_step;
memset(parameter.current_channel,0,parameter.path_num * sizeof(Complex));
//将信道初始化输出置零
for (k=0; k < parameter.path_num; k++)
{
//信道输出值清0
memset(parameter.current_channel,0,parameter.path_num * sizeof(Complex));
//分别计算第k径的当前输出值
for (n=0; n<parameter.n_sin; n++)
{
(parameter.current_channel+k)->real
+=cos(time * (*(parameter.coef_inphase+k*parameter.n_sin + n)) + *(parameter.rand_inphase+k*parameter.n_sin+n));
//注意这里参量的储存形式,使用指针构成数组
(parameter.current_channel+k)->imag
+=cos(time * (*(parameter.coef_quadrature+ k*parameter.n_sin + n))+ *(parameter.rand_quadrature+ k*parameter.n_sin + n));
}
//最后归一化,为了减少运算量
(parameter.current_channel+k)->real
*=(parameter.normalized_factor* (*(parameter.power+k)));
(parameter.current_channel+k)->imag
*=(parameter.normalized_factor* (*(parameter.power+k)));
}
parameter.current_time += (double)step;
}
void FreeChannel(JAKES_PROFILE & parameter)
{
free(parameter.rand_inphase);
parameter.rand_inphase = NULL;
free(parameter.rand_quadrature);
parameter.rand_quadrature = NULL;
free(parameter.coef_inphase);
parameter.coef_inphase = NULL;
free(parameter.coef_quadrature);
parameter.coef_quadrature = NULL;
free(parameter.current_channel);
parameter.current_channel = NULL;
free(parameter.delay);
parameter.delay = NULL;
free(parameter.delay_us);
parameter.delay_us = NULL;
free(parameter.power);
parameter.power = NULL;
free(parameter.power_db);
parameter.power_db = NULL;
free(parameter.theta);
parameter.theta = NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -