astyle --recursive --indent=spaces=2 --style=kr --indent-col1-comments --break-blocks --convert-tabs --max-code-length=200

This is done for better merging branch/LG_PRE_RELEASE_0.3 into trunk (same process is applied on this branch)

git-svn-id: http://svn.eurecom.fr/openair4G/trunk@7073 818b1a75-f10b-46b9-bf7c-635c3b92a50f
This commit is contained in:
Lionel Gauthier
2015-04-09 09:29:12 +00:00
parent f0a8a0b3b5
commit 059a0a3fdc
2044 changed files with 1182666 additions and 1145123 deletions
+118 -89
View File
@@ -1,5 +1,5 @@
/*******************************************************************************
OpenAirInterface
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
@@ -14,15 +14,15 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
@@ -45,7 +45,8 @@ double **cos_lut=NULL,**sin_lut=NULL;
void init_freq_channel(channel_desc_t *desc,uint16_t nb_rb,int16_t n_samples) {
void init_freq_channel(channel_desc_t *desc,uint16_t nb_rb,int16_t n_samples)
{
double delta_f,freq; // 90 kHz spacing
@@ -56,33 +57,34 @@ void init_freq_channel(channel_desc_t *desc,uint16_t nb_rb,int16_t n_samples) {
cos_lut = (double **)malloc(n_samples*sizeof(double*));
sin_lut = (double **)malloc(n_samples*sizeof(double*));
delta_f = nb_rb*180000/(n_samples-1);
for (f=-(n_samples>>1);f<(n_samples>>1);f++) {
for (f=-(n_samples>>1); f<(n_samples>>1); f++) {
freq=delta_f*(double)f*1e-6;// due to the fact that delays is in mus
cos_lut[f+(n_samples>>1)] = (double *)malloc((int)desc->nb_taps*sizeof(double));
sin_lut[f+(n_samples>>1)] = (double *)malloc((int)desc->nb_taps*sizeof(double));
for (l=0;l<(int)desc->nb_taps;l++) {
if (desc->nb_taps==1)
delay = desc->delays[l];
for (l=0; l<(int)desc->nb_taps; l++) {
if (desc->nb_taps==1)
delay = desc->delays[l];
else
delay = desc->delays[l]+NB_SAMPLES_CHANNEL_OFFSET/desc->BW;
delay = desc->delays[l]+NB_SAMPLES_CHANNEL_OFFSET/desc->BW;
cos_lut[f+(n_samples>>1)][l] = cos(2*M_PI*freq*delay);
sin_lut[f+(n_samples>>1)][l] = sin(2*M_PI*freq*delay);
//printf("values cos:%d, sin:%d\n", cos_lut[f][l], sin_lut[f][l]);
}
}
}
void freq_channel(channel_desc_t *desc,uint16_t nb_rb,int16_t n_samples) {
void freq_channel(channel_desc_t *desc,uint16_t nb_rb,int16_t n_samples)
{
int16_t f,f2,d;
@@ -91,46 +93,51 @@ void freq_channel(channel_desc_t *desc,uint16_t nb_rb,int16_t n_samples) {
static int freq_channel_init=0;
static int n_samples_max=0;
// printf("no of samples:%d,",n_samples);
// printf("no of taps:%d,",(int)desc->nb_taps);
// printf("no of samples:%d,",n_samples);
// printf("no of taps:%d,",(int)desc->nb_taps);
if (freq_channel_init == 0) {
// we are initializing the lut for the largets possible n_samples=12*nb_rb+1
// we are initializing the lut for the largets possible n_samples=12*nb_rb+1
// if called with n_samples<12*nb_rb+1, we decimate the lut
n_samples_max=12*nb_rb+1;
init_freq_channel(desc,nb_rb,n_samples_max);
freq_channel_init=1;
}
d=n_samples_max/n_samples;
start_meas(&desc->interp_freq);
for (f=-n_samples_max/2,f2=-n_samples/2;f<n_samples_max/2;f+=d,f2++) {
clut = cos_lut[n_samples_max/2+f];
slut = sin_lut[n_samples_max/2+f];
for (aarx=0;aarx<desc->nb_rx;aarx++) {
for (aatx=0;aatx<desc->nb_tx;aatx++) {
desc->chF[aarx+(aatx*desc->nb_rx)][n_samples/2+f2].x=0.0;
desc->chF[aarx+(aatx*desc->nb_rx)][n_samples/2+f2].y=0.0;
for (l=0;l<(int)desc->nb_taps;l++) {
desc->chF[aarx+(aatx*desc->nb_rx)][n_samples/2+f2].x+=(desc->a[l][aarx+(aatx*desc->nb_rx)].x*clut[l]+
desc->a[l][aarx+(aatx*desc->nb_rx)].y*slut[l]);
desc->chF[aarx+(aatx*desc->nb_rx)][n_samples/2+f2].y+=(-desc->a[l][aarx+(aatx*desc->nb_rx)].x*slut[l]+
desc->a[l][aarx+(aatx*desc->nb_rx)].y*clut[l]);
}
}
for (f=-n_samples_max/2,f2=-n_samples/2; f<n_samples_max/2; f+=d,f2++) {
clut = cos_lut[n_samples_max/2+f];
slut = sin_lut[n_samples_max/2+f];
for (aarx=0; aarx<desc->nb_rx; aarx++) {
for (aatx=0; aatx<desc->nb_tx; aatx++) {
desc->chF[aarx+(aatx*desc->nb_rx)][n_samples/2+f2].x=0.0;
desc->chF[aarx+(aatx*desc->nb_rx)][n_samples/2+f2].y=0.0;
for (l=0; l<(int)desc->nb_taps; l++) {
desc->chF[aarx+(aatx*desc->nb_rx)][n_samples/2+f2].x+=(desc->a[l][aarx+(aatx*desc->nb_rx)].x*clut[l]+
desc->a[l][aarx+(aatx*desc->nb_rx)].y*slut[l]);
desc->chF[aarx+(aatx*desc->nb_rx)][n_samples/2+f2].y+=(-desc->a[l][aarx+(aatx*desc->nb_rx)].x*slut[l]+
desc->a[l][aarx+(aatx*desc->nb_rx)].y*clut[l]);
}
}
}
}
stop_meas(&desc->interp_freq);
}
double compute_pbch_sinr(channel_desc_t *desc,
channel_desc_t *desc_i1,
channel_desc_t *desc_i2,
double snr_dB,double snr_i1_dB,
double snr_i2_dB,
uint16_t nb_rb) {
channel_desc_t *desc_i1,
channel_desc_t *desc_i2,
double snr_dB,double snr_i1_dB,
double snr_i2_dB,
uint16_t nb_rb)
{
double avg_sinr,snr=pow(10.0,.1*snr_dB),snr_i1=pow(10.0,.1*snr_i1_dB),snr_i2=pow(10.0,.1*snr_i2_dB);
uint16_t f;
@@ -140,47 +147,53 @@ double compute_pbch_sinr(channel_desc_t *desc,
struct complex S_i2;
avg_sinr=0.0;
// printf("nb_rb %d\n",nb_rb);
for (f=(nb_rb-6);f<(nb_rb+6);f++) {
for (f=(nb_rb-6); f<(nb_rb+6); f++) {
S = 0.0;
S_i1.x =0.0;
S_i1.y =0.0;
S_i2.x =0.0;
S_i2.y =0.0;
for (aarx=0;aarx<desc->nb_rx;aarx++) {
for (aatx=0;aatx<desc->nb_tx;aatx++) {
S += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc->chF[aarx+(aatx*desc->nb_rx)][f].x +
desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc->chF[aarx+(aatx*desc->nb_rx)][f].y);
// printf("%d %d chF[%d] => (%f,%f)\n",aarx,aatx,f,desc->chF[aarx+(aatx*desc->nb_rx)][f].x,desc->chF[aarx+(aatx*desc->nb_rx)][f].y);
if (desc_i1) {
S_i1.x += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].x +
desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].y);
S_i1.y += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].y -
desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].x);
}
if (desc_i2) {
S_i2.x += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].x +
desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].y);
S_i2.y += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].y -
desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].x);
}
for (aarx=0; aarx<desc->nb_rx; aarx++) {
for (aatx=0; aatx<desc->nb_tx; aatx++) {
S += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc->chF[aarx+(aatx*desc->nb_rx)][f].x +
desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc->chF[aarx+(aatx*desc->nb_rx)][f].y);
// printf("%d %d chF[%d] => (%f,%f)\n",aarx,aatx,f,desc->chF[aarx+(aatx*desc->nb_rx)][f].x,desc->chF[aarx+(aatx*desc->nb_rx)][f].y);
if (desc_i1) {
S_i1.x += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].x +
desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].y);
S_i1.y += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].y -
desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].x);
}
if (desc_i2) {
S_i2.x += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].x +
desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].y);
S_i2.y += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].y -
desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].x);
}
}
}
}
// printf("snr %f f %d : S %f, S_i1 %f, S_i2 %f\n",snr,f-nb_rb,S,snr_i1*sqrt(S_i1.x*S_i1.x + S_i1.y*S_i1.y),snr_i2*sqrt(S_i2.x*S_i2.x + S_i2.y*S_i2.y));
avg_sinr += (snr*S/(desc->nb_tx+snr_i1*sqrt(S_i1.x*S_i1.x + S_i1.y*S_i1.y)+snr_i2*sqrt(S_i2.x*S_i2.x + S_i2.y*S_i2.y)));
}
// printf("avg_sinr %f (%f,%f,%f)\n",avg_sinr/12.0,snr,snr_i1,snr_i2);
return(10*log10(avg_sinr/12.0));
}
double compute_sinr(channel_desc_t *desc,
channel_desc_t *desc_i1,
channel_desc_t *desc_i2,
double snr_dB,double snr_i1_dB,
double snr_i2_dB,
uint16_t nb_rb) {
channel_desc_t *desc_i1,
channel_desc_t *desc_i2,
double snr_dB,double snr_i1_dB,
double snr_i2_dB,
uint16_t nb_rb)
{
double avg_sinr,snr=pow(10.0,.1*snr_dB),snr_i1=pow(10.0,.1*snr_i1_dB),snr_i2=pow(10.0,.1*snr_i2_dB);
uint16_t f;
@@ -190,53 +203,62 @@ double compute_sinr(channel_desc_t *desc,
struct complex S_i2;
DevAssert( nb_rb > 0 );
avg_sinr=0.0;
// printf("nb_rb %d\n",nb_rb);
for (f=0;f<2*nb_rb;f++) {
for (f=0; f<2*nb_rb; f++) {
S = 0.0;
S_i1.x =0.0;
S_i1.y =0.0;
S_i2.x =0.0;
S_i2.y =0.0;
for (aarx=0;aarx<desc->nb_rx;aarx++) {
for (aatx=0;aatx<desc->nb_tx;aatx++) {
S += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc->chF[aarx+(aatx*desc->nb_rx)][f].x +
desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc->chF[aarx+(aatx*desc->nb_rx)][f].y);
if (desc_i1) {
S_i1.x += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].x +
desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].y);
S_i1.y += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].y -
desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].x);
}
if (desc_i2) {
S_i2.x += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].x +
desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].y);
S_i2.y += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].y -
desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].x);
}
for (aarx=0; aarx<desc->nb_rx; aarx++) {
for (aatx=0; aatx<desc->nb_tx; aatx++) {
S += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc->chF[aarx+(aatx*desc->nb_rx)][f].x +
desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc->chF[aarx+(aatx*desc->nb_rx)][f].y);
if (desc_i1) {
S_i1.x += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].x +
desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].y);
S_i1.y += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].y -
desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].x);
}
if (desc_i2) {
S_i2.x += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].x +
desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].y);
S_i2.y += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].y -
desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].x);
}
}
}
// printf("f %d : S %f, S_i1 %f, S_i2 %f\n",f-nb_rb,snr*S,snr_i1*sqrt(S_i1.x*S_i1.x + S_i1.y*S_i1.y),snr_i2*sqrt(S_i2.x*S_i2.x + S_i2.y*S_i2.y));
avg_sinr += (snr*S/(desc->nb_tx+snr_i1*sqrt(S_i1.x*S_i1.x + S_i1.y*S_i1.y)+snr_i2*sqrt(S_i2.x*S_i2.x + S_i2.y*S_i2.y)));
}
// printf("avg_sinr %f (%f,%f,%f)\n",avg_sinr/12.0,snr,snr_i1,snr_i2);
return(10*log10(avg_sinr/(nb_rb*2)));
}
int pbch_polynomial_degree=6;
double pbch_awgn_polynomial[7]={-7.2926e-05, -2.8749e-03, -4.5064e-02, -3.5301e-01, -1.4655e+00, -3.6282e+00, -6.6907e+00};
double pbch_awgn_polynomial[7]= {-7.2926e-05, -2.8749e-03, -4.5064e-02, -3.5301e-01, -1.4655e+00, -3.6282e+00, -6.6907e+00};
void load_pbch_desc(FILE *pbch_file_fd) {
void load_pbch_desc(FILE *pbch_file_fd)
{
int i, ret;
char dummy[25];
ret = fscanf(pbch_file_fd,"%d",&pbch_polynomial_degree);
if (ret < 0) {
printf("fscanf failed: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
if (pbch_polynomial_degree>6) {
printf("Illegal degree for pbch interpolation polynomial %d\n",pbch_polynomial_degree);
exit(-1);
@@ -244,38 +266,45 @@ void load_pbch_desc(FILE *pbch_file_fd) {
printf("PBCH polynomial : ");
for (i=0;i<=pbch_polynomial_degree;i++) {
for (i=0; i<=pbch_polynomial_degree; i++) {
ret = fscanf(pbch_file_fd,"%s",dummy);
if (ret < 0) {
printf("fscanf failed: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
pbch_awgn_polynomial[i] = strtod(dummy,NULL);
printf("%f ",pbch_awgn_polynomial[i]);
}
printf("\n");
}
double pbch_bler(double sinr) {
printf("\n");
}
double pbch_bler(double sinr)
{
int i;
double log10_bler=pbch_awgn_polynomial[pbch_polynomial_degree];
double sinrpow=sinr;
double bler=0.0;
// printf("log10bler %f\n",log10_bler);
if (sinr<-10.0)
bler= 1.0;
else if (sinr>=0.0)
bler=0.0;
else {
for (i=1;i<=pbch_polynomial_degree;i++) {
for (i=1; i<=pbch_polynomial_degree; i++) {
// printf("sinrpow %f\n",sinrpow);
log10_bler += (pbch_awgn_polynomial[pbch_polynomial_degree-i]*sinrpow);
sinrpow *= sinr;
// printf("log10bler %f\n",log10_bler);
}
bler = pow(10.0,log10_bler);
}
//printf ("sinr %f bler %f\n",sinr,bler);
return(bler);
+134 -112
View File
@@ -1,5 +1,5 @@
/*******************************************************************************
OpenAirInterface
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
@@ -14,15 +14,15 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
@@ -38,25 +38,27 @@
enum sector {SEC1, SEC2, SEC3};
scenario_desc_t scenario;
void get_chan_desc(node_desc_t* node_tx, node_desc_t* node_rx, channel_desc_t *ch_desc, scenario_desc_t* scenario) {
double dist;
void get_chan_desc(node_desc_t* node_tx, node_desc_t* node_rx, channel_desc_t *ch_desc, scenario_desc_t* scenario)
{
double dist;
dist = sqrt(pow((node_tx->x - node_rx->x), 2) + pow((node_tx->y - node_rx->y), 2));
/* conversion of distance into KM 3gpp (36-942)*/
ch_desc->path_loss_dB = (128.1 + 37.6 * log10(dist/1000));
ch_desc->path_loss_dB = (128.1 + 37.6 * log10(dist/1000));
}
int main() {
int main()
{
int enb_count = 16;
int ue_count = 50;
double sect_angle[3]={0,2*PI/3,4*PI/3};
double sect_angle[3]= {0,2*PI/3,4*PI/3};
double gain_max;
double theta;
double min_path_loss = 0;
int att_enb_index;
node_desc_t *enb_data[enb_count];
node_desc_t *enb_data[enb_count];
node_desc_t *ue_data[ue_count];
channel_desc_t *ul_channel[ue_count][enb_count];
channel_desc_t *ul_channel[ue_count][enb_count];
channel_desc_t *dl_channel[ue_count][enb_count];
int count;
int mcs;
@@ -77,30 +79,34 @@ int main() {
double tlu_bler;
int line_num;
char *file_name[]= {"bler_1.csv", "bler_2.csv", "bler_3.csv", "bler_4.csv", "bler_5.csv", "bler_6.csv", "bler_7.csv", "bler_8.csv",
"bler_9.csv", "bler_10.csv", "bler_11.csv", "bler_12.csv", "bler_13.csv", "bler_14.csv", "bler_15.csv", "bler_16.csv",
"bler_17.csv", "bler_18.csv", "bler_19.csv", "bler_20.csv", "bler_21.csv", "bler_22.csv"};
"bler_9.csv", "bler_10.csv", "bler_11.csv", "bler_12.csv", "bler_13.csv", "bler_14.csv", "bler_15.csv", "bler_16.csv",
"bler_17.csv", "bler_18.csv", "bler_19.csv", "bler_20.csv", "bler_21.csv", "bler_22.csv"
};
double beta[MCS_COUNT] = {0, 0, 0, 0, 0.9459960937499999, 1.2912109374999994, 1.0133789062499998, 1.000390625,
double beta[MCS_COUNT] = {0, 0, 0, 0, 0.9459960937499999, 1.2912109374999994, 1.0133789062499998, 1.000390625,
1.02392578125, 1.8595703124999998, 2.424389648437498, 2.3946533203124982, 2.5790039062499988,
2.4084960937499984, 2.782617187499999, 2.7868652343749996, 3.92099609375, 4.0392578125,
4.56109619140625, 5.03338623046875, 5.810888671875, 6.449108886718749};
4.56109619140625, 5.03338623046875, 5.810888671875, 6.449108886718749
};
double enb_position[][2] = {{1100,1100},{1100,2100},{1100,3100},{1100,4100},
{2100,1100},{2100,2100},{2100,3100},{2100,4100},
{3100,1100},{3100,2100},{3100,3100},{3100,4100},
{4100,1100},{4100,2100},{4100,3100},{4100,4100}};
{2100,1100},{2100,2100},{2100,3100},{2100,4100},
{3100,1100},{3100,2100},{3100,3100},{3100,4100},
{4100,1100},{4100,2100},{4100,3100},{4100,4100}
};
double ue_position[][2] = {{3340,4740},{1500,620},{1780,4220},{1300,3540},{780,3100},
{1140,540},{1340,3660},{860,1220},{2700,2140},{3860,3060},
{3740,1060},{1700,3060},{2180,1620},{4420,1060},{1300,3340},
{3700,3180},{3780,540},{1700,4380},{4140,4740},{820,4380},
{3300,1540},{2100,1780},{1780,2260},{1940,2620},{1580,1700},
{1460,1940},{940,1340},{2100,3540},{1260,4340},{2940,4060},
{3980,940},{540,2220},{3060,2140},{4620,3940},{4260,2820},
{3860,3500},{4140,4140},{3900,3500},{1500,2140},{2620,3820},
{3420,2820},{1580,3940},{660,2100},{2740,1180},{2500,2500},
{3580,3580},{3740,3140},{3020,3020},{4340,4140},{980,4300}};
{1140,540},{1340,3660},{860,1220},{2700,2140},{3860,3060},
{3740,1060},{1700,3060},{2180,1620},{4420,1060},{1300,3340},
{3700,3180},{3780,540},{1700,4380},{4140,4740},{820,4380},
{3300,1540},{2100,1780},{1780,2260},{1940,2620},{1580,1700},
{1460,1940},{940,1340},{2100,3540},{1260,4340},{2940,4060},
{3980,940},{540,2220},{3060,2140},{4620,3940},{4260,2820},
{3860,3500},{4140,4140},{3900,3500},{1500,2140},{2620,3820},
{3420,2820},{1580,3940},{660,2100},{2740,1180},{2500,2500},
{3580,3580},{3740,3140},{3020,3020},{4340,4140},{980,4300}
};
randominit(0);
/////////////////////////////////////////////////////////////////////////////////////////////////
@@ -110,25 +116,29 @@ int main() {
for (mcs = 5; mcs <= MCS_COUNT; mcs++) {
fp = fopen(file_name[mcs - 1],"r");
if (fp == NULL) {
printf("ERROR: Unable to open the file\n");
}
else {
} else {
fgets(buffer, 100, fp);
tabl_len=0;
while (!feof(fp)) {
sinr_bler = strtok(buffer, ";");
local_table[mcs-1][0][tabl_len] = atof(sinr_bler);
sinr_bler = strtok(NULL,";");
local_table[mcs-1][1][tabl_len] = atof(sinr_bler);
tabl_len++;
fgets(buffer, 100, fp);
sinr_bler = strtok(buffer, ";");
local_table[mcs-1][0][tabl_len] = atof(sinr_bler);
sinr_bler = strtok(NULL,";");
local_table[mcs-1][1][tabl_len] = atof(sinr_bler);
tabl_len++;
fgets(buffer, 100, fp);
}
fclose(fp);
}
printf("\n table for mcs %d\n",mcs);
for (tabl_len=0;tabl_len<9;tabl_len++)
for (tabl_len=0; tabl_len<9; tabl_len++)
printf("%lf %lf \n ",local_table[mcs-1][0][tabl_len],local_table[mcs-1][1][tabl_len]);
@@ -138,13 +148,13 @@ int main() {
////////////////////////////////////////////////////////////////////////////////////////////////////
for (enb_index = 0; enb_index < enb_count; enb_index++)
for (enb_index = 0; enb_index < enb_count; enb_index++)
enb_data[enb_index] = (node_desc_t *)(malloc(sizeof(node_desc_t)));
for (ue_index = 0; ue_index < ue_count; ue_index++)
ue_data[ue_index] = (node_desc_t *)(malloc(sizeof(node_desc_t)));
for (enb_index = 0; enb_index < enb_count; enb_index++) {
for (ue_index = 0; ue_index < ue_count; ue_index++)
ue_data[ue_index] = (node_desc_t *)(malloc(sizeof(node_desc_t)));
for (enb_index = 0; enb_index < enb_count; enb_index++) {
enb_data[enb_index]->x = enb_position[enb_index][0];
enb_data[enb_index]->y = enb_position[enb_index][1];
enb_data[enb_index]->tx_power_dBm = 40;
@@ -161,82 +171,90 @@ int main() {
ue_data[ue_index]->ant_gain_dBi = 0;
ue_data[ue_index]->rx_noise_level = 9; //value in db
}
for (ue_index = 0; ue_index < ue_count; ue_index++) {
min_path_loss = 10000;
for (enb_index = 0; enb_index < enb_count; enb_index++) {
ul_channel[ue_index][enb_index] = new_channel_desc_scm(1, 1, SCM_C, 7.68, 0, 0, 0);
dl_channel[ue_index][enb_index] = new_channel_desc_scm(1, 1, SCM_C, 7.68, 0, 0, 0);
//printf("ue %d enb %d\n", ue_index, enb_index);
//printf("ue %d enb %d\n", ue_index, enb_index);
/* Calculating the angle in the range -pi to pi from the slope */
//(ue_data[ue_index])->alpha_rad[enb_index] = (double)(atan2((ue_data[ue_index]->x - enb_data[enb_index]->x), (ue_data[ue_index]->y - enb_data[enb_index]->y)));
ue_data[ue_index]->alpha_rad[enb_index] = atan2((ue_data[ue_index]->x - enb_data[enb_index]->x), (ue_data[ue_index]->y - enb_data[enb_index]->y));
//printf("angle is tan %lf\n", ue_data[ue_index]->alpha_rad[enb_index]);
if ((ue_data[ue_index]->alpha_rad[enb_index]) < 0) {
ue_data[ue_index]->alpha_rad[enb_index] = 2*PI + ue_data[ue_index]->alpha_rad[enb_index];
ue_data[ue_index]->alpha_rad[enb_index] = 2*PI + ue_data[ue_index]->alpha_rad[enb_index];
//printf("angle in radians is %lf\n", ue_data[ue_index]->alpha_rad[enb_index]);
}
for(count = 0; count < enb_data[enb_index]->n_sectors; count++) {
theta = sect_angle[count] - ue_data[ue_index]->alpha_rad[enb_index];
gain_sec[count] = -(Am < (12 * pow((theta/theta_3dB),2)) ? Am : (12 * pow((theta/theta_3dB),2)));
theta = sect_angle[count] - ue_data[ue_index]->alpha_rad[enb_index];
gain_sec[count] = -(Am < (12 * pow((theta/theta_3dB),2)) ? Am : (12 * pow((theta/theta_3dB),2)));
}
/* gain = -min(Am , 12 * (theta/theta_3dB)^2) */
gain_max = (gain_sec[SEC1] > gain_sec[SEC2]) ? ((gain_sec[SEC1] > gain_sec[SEC3]) ? gain_sec[SEC1]:gain_sec[SEC3]) :
((gain_sec[SEC2] > gain_sec[SEC3]) ? gain_sec[SEC2]:gain_sec[SEC3]);
gain_max = (gain_sec[SEC1] > gain_sec[SEC2]) ? ((gain_sec[SEC1] > gain_sec[SEC3]) ? gain_sec[SEC1]:gain_sec[SEC3]) :
((gain_sec[SEC2] > gain_sec[SEC3]) ? gain_sec[SEC2]:gain_sec[SEC3]);
get_chan_desc(enb_data[enb_index], ue_data[ue_index], ul_channel[ue_index][enb_index], &scenario);
get_chan_desc(enb_data[enb_index], ue_data[ue_index], dl_channel[ue_index][enb_index], &scenario);
//printf("Path loss for link between ue %d and enb %d is %lf and gain is %lf \n", ue_index, enb_index, dl_channel[ue_index][enb_index]->path_loss_dB, gain_max);
//printf("Path loss for link between ue %d and enb %d is %lf and gain is %lf \n", ue_index, enb_index, dl_channel[ue_index][enb_index]->path_loss_dB, gain_max);
if (dl_channel[ue_index][enb_index]->path_loss_dB < min_path_loss) {
min_path_loss = dl_channel[ue_index][enb_index]->path_loss_dB;
att_enb_index = enb_index;
}
//return_value = random_channel(ul_channel[ue_index][enb_index]);
return_value = random_channel(dl_channel[ue_index][enb_index]);
/* Thermal noise is calculated using 10log10(K*T*B) K = Boltzmann´s constant T = room temperature B = bandwidth */
/* Taken as constant for the time being since the BW is not changing */
thermal_noise = -105; //value in dBm
thermal_noise = -105; //value in dBm
if (0 == return_value) {
//freq_channel(ul_channel[ue_index][enb_index], nb_rb);
freq_channel(dl_channel[ue_index][enb_index], nb_rb);
coupling = MCL > (dl_channel[ue_index][enb_index]->path_loss_dB-(enb_data[enb_index]->ant_gain_dBi + gain_max)) ?
MCL : (dl_channel[ue_index][enb_index]->path_loss_dB-(enb_data[enb_index]->ant_gain_dBi + gain_max));
//printf ("coupling factor is %lf\n", coupling);
MCL : (dl_channel[ue_index][enb_index]->path_loss_dB-(enb_data[enb_index]->ant_gain_dBi + gain_max));
//printf ("coupling factor is %lf\n", coupling);
for (count = 0; count < (2 * nb_rb); count++) {
sinr[enb_index][count] = enb_data[enb_index]->tx_power_dBm
- coupling
- (thermal_noise + ue_data[ue_index]->rx_noise_level)
+ 10 * log10 (pow(dl_channel[ue_index][enb_index]->chF[0][count].r, 2)
+ pow(dl_channel[ue_index][enb_index]->chF[0][count].i, 2));
sinr[enb_index][count] = enb_data[enb_index]->tx_power_dBm
- coupling
- (thermal_noise + ue_data[ue_index]->rx_noise_level)
+ 10 * log10 (pow(dl_channel[ue_index][enb_index]->chF[0][count].r, 2)
+ pow(dl_channel[ue_index][enb_index]->chF[0][count].i, 2));
//printf("Dl_link SNR for res. block %d is %lf\n", count, sinr[enb_index][count]);
}
}
}
}
for (count = 0; count < 2 * nb_rb; count++) {
interference = 0;
for (enb_index = 0; enb_index < enb_count; enb_index++) {
if (att_enb_index != enb_index) {
interference += pow(10, 0.1 * sinr[enb_index][count]);
}
}
sinr[att_enb_index][count] -= 10*log10(1 + interference);
//printf("***Dl_link SINR for res. block %d is %lf\n", count, sinr[att_enb_index][count]);
for (mcs = 5; mcs <= MCS_COUNT; mcs++) {
sinr_eff[ue_index][mcs-1] += exp(-(pow(10, (sinr[att_enb_index][count])/10))/beta[mcs-1]);
//printf("Effective snr %lf\n",sinr_eff[ue_index][mcs-1]);
//printf("Effective snr %lf\n",sinr_eff[ue_index][mcs-1]);
//sinr_eff[ue_index][mcs] += exp(-(sinr[att_enb_index][count])/beta[mcs]);
}
}
}
for (mcs = 5; mcs <= MCS_COUNT; mcs++) {
//printf("mcs value %d \n",mcs);
//printf("beta value %lf \n",-beta[mcs-1]);
@@ -247,74 +265,78 @@ int main() {
sinr_eff[ue_index][mcs-1] = 10 * log10(sinr_eff[ue_index][mcs-1]);
sinr_eff[ue_index][mcs-1] *= 10;
sinr_eff[ue_index][mcs-1] = floor(sinr_eff[ue_index][mcs-1]);
if ((int)sinr_eff[ue_index][mcs-1]%2) {
sinr_eff[ue_index][mcs-1] += 1;
}
sinr_eff[ue_index][mcs-1] /= 10;
//printf("Effective snr %lf \n",sinr_eff[ue_index][mcs-1]);
bler[ue_index][mcs-1] = 0;
/*line_num = 0;
fp = fopen(file_name[mcs - 1],"r");
if (fp == NULL) {
fp = fopen(file_name[mcs - 1],"r");
if (fp == NULL) {
printf("ERROR: Unable to open the file\n");
}
else {
}
else {
fgets(buffer, 100, fp);
while (!feof(fp)) {
line_num++;
sinr_bler = strtok(buffer, ";");
tlu_sinr = atof(sinr_bler);
sinr_bler = strtok(NULL,";");
tlu_bler = atof(sinr_bler);
if (1 == line_num) {
if (sinr_eff[ue_index][mcs-1] < tlu_sinr) {
bler[ue_index][mcs-1] = 1;
break;
}
}
if (sinr_eff[ue_index][mcs-1] == tlu_sinr) {
bler[ue_index][mcs-1] = tlu_bler;
}
fgets(buffer, 100, fp);
line_num++;
sinr_bler = strtok(buffer, ";");
tlu_sinr = atof(sinr_bler);
sinr_bler = strtok(NULL,";");
tlu_bler = atof(sinr_bler);
if (1 == line_num) {
if (sinr_eff[ue_index][mcs-1] < tlu_sinr) {
bler[ue_index][mcs-1] = 1;
break;
}
}
if (sinr_eff[ue_index][mcs-1] == tlu_sinr) {
bler[ue_index][mcs-1] = tlu_bler;
}
fgets(buffer, 100, fp);
}
fclose(fp);*/
for (tabl_len=0;tabl_len<9;tabl_len++) {
for (tabl_len=0; tabl_len<9; tabl_len++) {
if(tabl_len==0)
if (sinr_eff[ue_index][mcs-1] < local_table[mcs-1][0][tabl_len]) {
bler[ue_index][mcs-1] = 1;
break;
}
if(tabl_len==0)
if (sinr_eff[ue_index][mcs-1] < local_table[mcs-1][0][tabl_len]) {
bler[ue_index][mcs-1] = 1;
break;
}
if (sinr_eff[ue_index][mcs-1] == local_table[mcs-1][0][tabl_len]) {
bler[ue_index][mcs-1] = local_table[mcs-1][1][tabl_len];
}
if (sinr_eff[ue_index][mcs-1] == local_table[mcs-1][0][tabl_len]) {
bler[ue_index][mcs-1] = local_table[mcs-1][1][tabl_len];
}
}
//printf("\n###Dl_link UE %d attached to eNB %d \n MCS %d effective SNR %lf BLER %lf", ue_index, att_enb_index, mcs,sinr_eff[ue_index][mcs-1],bler[ue_index][mcs-1]);
}
}
//printf("\n\n");
printf("\n Ue_ix enb_ix mcs5 mcs6 mcs7 mcs8 mcs9 mcs10 mcs11 mcs12 mcs13\
mcs14 mcs15 mcs16 mcs17 mcs18 mcs19 mcs20 mcs21 mcs22\n");
mcs14 mcs15 mcs16 mcs17 mcs18 mcs19 mcs20 mcs21 mcs22\n");
printf("SINR %4d %4d %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f\
%+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f\n",
ue_index, att_enb_index, sinr_eff[ue_index][4], sinr_eff[ue_index][5], sinr_eff[ue_index][6], sinr_eff[ue_index][7],
sinr_eff[ue_index][8], sinr_eff[ue_index][9], sinr_eff[ue_index][10], sinr_eff[ue_index][11], sinr_eff[ue_index][12],
sinr_eff[ue_index][13], sinr_eff[ue_index][14], sinr_eff[ue_index][15], sinr_eff[ue_index][16], sinr_eff[ue_index][17],
sinr_eff[ue_index][18], sinr_eff[ue_index][19], sinr_eff[ue_index][20], sinr_eff[ue_index][21], sinr_eff[ue_index][22]);
ue_index, att_enb_index, sinr_eff[ue_index][4], sinr_eff[ue_index][5], sinr_eff[ue_index][6], sinr_eff[ue_index][7],
sinr_eff[ue_index][8], sinr_eff[ue_index][9], sinr_eff[ue_index][10], sinr_eff[ue_index][11], sinr_eff[ue_index][12],
sinr_eff[ue_index][13], sinr_eff[ue_index][14], sinr_eff[ue_index][15], sinr_eff[ue_index][16], sinr_eff[ue_index][17],
sinr_eff[ue_index][18], sinr_eff[ue_index][19], sinr_eff[ue_index][20], sinr_eff[ue_index][21], sinr_eff[ue_index][22]);
printf("BLER %4d %4d %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f\
%+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f\n",
ue_index, att_enb_index, bler[ue_index][4], bler[ue_index][5], bler[ue_index][6], bler[ue_index][7],
bler[ue_index][8], bler[ue_index][9], bler[ue_index][10], bler[ue_index][11], bler[ue_index][12],
bler[ue_index][13], bler[ue_index][14], bler[ue_index][15], bler[ue_index][16], bler[ue_index][17],
bler[ue_index][18], bler[ue_index][19], bler[ue_index][20], bler[ue_index][21], bler[ue_index][22]);
ue_index, att_enb_index, bler[ue_index][4], bler[ue_index][5], bler[ue_index][6], bler[ue_index][7],
bler[ue_index][8], bler[ue_index][9], bler[ue_index][10], bler[ue_index][11], bler[ue_index][12],
bler[ue_index][13], bler[ue_index][14], bler[ue_index][15], bler[ue_index][16], bler[ue_index][17],
bler[ue_index][18], bler[ue_index][19], bler[ue_index][20], bler[ue_index][21], bler[ue_index][22]);
}
}
+105 -105
View File
@@ -1,5 +1,5 @@
/*******************************************************************************
OpenAirInterface
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
@@ -14,15 +14,15 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
@@ -40,7 +40,7 @@ The present clause specifies several numerical functions for testing of digital
-# Generic Multipath Channel Generator
* @defgroup _channel_ Multipath channel generator
* @ingroup _numerical_
* @ingroup _numerical_
* @{
*/
@@ -49,49 +49,49 @@ The present clause specifies several numerical functions for testing of digital
typedef struct {
///Number of tx antennas
uint8_t nb_tx;
uint8_t nb_tx;
///Number of rx antennas
uint8_t nb_rx;
///number of taps
uint8_t nb_taps;
uint8_t nb_taps;
///linear amplitudes of taps
double *amps;
///Delays of the taps in mus. length(delays)=nb_taps. Has to be between 0 and Td.
double *delays;
///length of impulse response. should be set to 11+2*bw*t_max
uint8_t channel_length;
double *amps;
///Delays of the taps in mus. length(delays)=nb_taps. Has to be between 0 and Td.
double *delays;
///length of impulse response. should be set to 11+2*bw*t_max
uint8_t channel_length;
///channel state vector. size(state) = nb_taps * (n_tx * n_rx);
struct complex **a;
struct complex **a;
///interpolated (sample-spaced) channel impulse response. size(ch) = (n_tx * n_rx) * channel_length. ATTENTION: the dimensions of ch are the transposed ones of a. This is to allow the use of BLAS when applying the correlation matrices to the state.
struct complex **ch;
struct complex **ch;
///Sampled frequency response (90 kHz resolution)
struct complex **chF;
struct complex **chF;
///Maximum path delay in mus.
double Td;
double Td;
///Channel bandwidth in MHz.
double BW;
double BW;
///Ricean factor of first tap wrt other taps (0..1, where 0 means AWGN and 1 means Rayleigh channel).
double ricean_factor;
///Angle of arrival of wavefront (in radians). For Ricean channel only. This assumes that both RX and TX have linear antenna arrays with lambda/2 antenna spacing. Furhter it is assumed that the arrays are parallel to each other and that they are far enough apart so that we can safely assume plane wave propagation.
double aoa;
///If set to 1, aoa is randomized according to a uniform random distribution
double ricean_factor;
///Angle of arrival of wavefront (in radians). For Ricean channel only. This assumes that both RX and TX have linear antenna arrays with lambda/2 antenna spacing. Furhter it is assumed that the arrays are parallel to each other and that they are far enough apart so that we can safely assume plane wave propagation.
double aoa;
///If set to 1, aoa is randomized according to a uniform random distribution
int8_t random_aoa;
///in Hz. if >0 generate a channel with a Clarke's Doppler profile with a maximum Doppler bandwidth max_Doppler. CURRENTLY NOT IMPLEMENTED!
double max_Doppler;
double max_Doppler;
///Square root of the full correlation matrix size(R_tx) = nb_taps * (n_tx * n_rx) * (n_tx * n_rx).
struct complex **R_sqrt;
///path loss including shadow fading in dB
struct complex **R_sqrt;
///path loss including shadow fading in dB
double path_loss_dB;
///additional delay of channel in samples.
int32_t channel_offset;
///additional delay of channel in samples.
int32_t channel_offset;
///This parameter (0...1) allows for simple 1st order temporal variation. 0 means a new channel every call, 1 means keep channel constant all the time
double forgetting_factor;
///needs to be set to 1 for the first call, 0 otherwise.
uint8_t first_run;
/// initial phase for frequency offset simulation
/// initial phase for frequency offset simulation
double ip;
/// number of paths taken by transmit signal
uint16_t nb_paths;
uint16_t nb_paths;
/// timing measurements
time_stats_t random_channel;
time_stats_t interp_time;
@@ -104,7 +104,7 @@ typedef struct {
uint8_t n_sectors;
/// Antenna orientation for each sector (for non-omnidirectional antennas) in radians wrt north
double alpha_rad[3];
/// Antenna 3dB beam width (in radians)
/// Antenna 3dB beam width (in radians)
double phi_rad;
/// Antenna gain (dBi)
double ant_gain_dBi;
@@ -113,9 +113,9 @@ typedef struct {
/// Rx noise level (dB)
double rx_noise_level;
///x coordinate (cartesian, in m)
double x;
double x;
///y coordinate (cartesian, in m)
double y;
double y;
///z coordinate (antenna height, in m)
double z;
/// direction of travel in radians wrt north
@@ -129,7 +129,7 @@ typedef enum {
urban,
indoor
} scenario_t;
typedef struct {
/// Scenario classifcation
scenario_t scenario;
@@ -139,11 +139,11 @@ typedef struct {
double bandwidth;
/// path loss at 0m distance in dB
double path_loss_0;
/// path loss exponent
/// path loss exponent
double path_loss_exponent;
/// shadow fading standard deviation [dB] (assuming log-normal shadow fading with 0 mean)
double shadow_fading_std;
/// correlation distance of shadow fading
/// correlation distance of shadow fading
double shadow_fading_correlation_distance;
/// Shadowing correlation between cells
double shadow_fading_correlation_cells;
@@ -156,7 +156,7 @@ typedef struct {
} scenario_desc_t;
typedef enum {
custom=0,
custom=0,
SCM_A,
SCM_B,
SCM_C,
@@ -177,14 +177,14 @@ typedef enum {
AWGN
} SCM_t;
/**
/**
\brief This routine initializes a new channel descriptor
\param nb_tx Number of TX antennas
\param nb_rx Number of RX antennas
\param nb_taps Number of taps
\param channel_length Length of the interpolated channel impulse response
\param amps Linear amplitudes of the taps (length(amps)=channel_length). The values should sum up to 1.
\param delays Delays of the taps. If delays==NULL the taps are assumed to be spaced equidistantly between 0 and t_max.
\param delays Delays of the taps. If delays==NULL the taps are assumed to be spaced equidistantly between 0 and t_max.
\param R_sqrt Channel correlation matrix. If R_sqrt==NULL, no channel correlation is applied.
\param Td Maximum path delay in mus.
\param BW Channel bandwidth in MHz.
@@ -200,33 +200,33 @@ typedef enum {
//channel_desc_t *new_channel_desc(uint8_t nb_tx,uint8_t nb_rx, uint8_t nb_taps, uint8_t channel_length, double *amps, double* delays, struct complex** R_sqrt, double Td, double BW, double ricean_factor, double aoa, double forgetting_factor, double max_Doppler, int32_t channel_offset, double path_loss_dB,uint8_t random_aoa);
channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
uint8_t nb_rx,
SCM_t channel_model,
double BW,
double forgetting_factor,
int32_t channel_offset,
double path_loss_dB);
uint8_t nb_rx,
SCM_t channel_model,
double BW,
double forgetting_factor,
int32_t channel_offset,
double path_loss_dB);
/** \fn void random_channel(channel_desc_t *desc)
\brief This routine generates a random channel response (time domain) according to a tapped delay line model.
\brief This routine generates a random channel response (time domain) according to a tapped delay line model.
\param desc Pointer to the channel descriptor
*/
int random_channel(channel_desc_t *desc, uint8_t abstraction_flag);
/**\fn void multipath_channel(channel_desc_t *desc,
double **tx_sig_re,
double **tx_sig_im,
double **rx_sig_re,
double **rx_sig_im,
uint32_t length,
uint8_t keep_channel)
double **tx_sig_re,
double **tx_sig_im,
double **rx_sig_re,
double **rx_sig_im,
uint32_t length,
uint8_t keep_channel)
\brief This function generates and applys a random frequency selective random channel model.
@param desc Pointer to channel descriptor
@param tx_sig_re input signal (real component)
@param tx_sig_im input signal (imaginary component)
@param tx_sig_re input signal (real component)
@param tx_sig_im input signal (imaginary component)
@param rx_sig_re output signal (real component)
@param rx_sig_im output signal (imaginary component)
@param length Length of input signal
@@ -234,19 +234,19 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag);
*/
void multipath_channel(channel_desc_t *desc,
double **tx_sig_re,
double **tx_sig_im,
double **rx_sig_re,
double **rx_sig_im,
uint32_t length,
uint8_t keep_channel);
double **tx_sig_re,
double **tx_sig_im,
double **rx_sig_re,
double **rx_sig_im,
uint32_t length,
uint8_t keep_channel);
/*
\fn double compute_pbch_sinr(channel_desc_t *desc,
channel_desc_t *desc_i1,
channel_desc_t *desc_i2,
double snr_dB,double snr_i1_dB,
double snr_i2_dB,
uint16_t nb_rb)
channel_desc_t *desc_i1,
channel_desc_t *desc_i2,
double snr_dB,double snr_i1_dB,
double snr_i2_dB,
uint16_t nb_rb)
\brief This function computes the average SINR over all frequency resources of the PBCH. It is used for PHY abstraction of the PBCH BLER
@param desc Pointer to channel descriptor of eNB
@@ -258,18 +258,18 @@ void multipath_channel(channel_desc_t *desc,
@param nb_rb Number of RBs in system
*/
double compute_pbch_sinr(channel_desc_t *desc,
channel_desc_t *desc_i1,
channel_desc_t *desc_i2,
double snr_dB,double snr_i1_dB,
double snr_i2_dB,
uint16_t nb_rb);
channel_desc_t *desc_i1,
channel_desc_t *desc_i2,
double snr_dB,double snr_i1_dB,
double snr_i2_dB,
uint16_t nb_rb);
double compute_sinr(channel_desc_t *desc,
channel_desc_t *desc_i1,
channel_desc_t *desc_i2,
double snr_dB,double snr_i1_dB,
double snr_i2_dB,
uint16_t nb_rb);
channel_desc_t *desc_i1,
channel_desc_t *desc_i2,
double snr_dB,double snr_i1_dB,
double snr_i2_dB,
uint16_t nb_rb);
double pbch_bler(double sinr);
@@ -279,16 +279,16 @@ void load_pbch_desc(FILE *pbch_file_fd);
/**
* @defgroup _taus_ Tausworthe Uniform Random Variable Generator
* @ingroup _numerical_
* @ingroup _numerical_
* @{
\fn unsigned int taus()
\brief Tausworthe Uniform Random Generator. This is based on the hardware implementation described in
\brief Tausworthe Uniform Random Generator. This is based on the hardware implementation described in
Lee et al, "A Hardware Gaussian Noise Generator Usign the Box-Muller Method and its Error Analysis," IEEE Trans. on Computers, 2006.
*/
unsigned int taus(void);
/**
/**
\fn void set_taus_seed(unsigned int seed_init)
\brief Sets the seed for the Tausworthe generator.
@param seed_init 0 means generate based on CPU time, otherwise provide the seed
@@ -296,27 +296,27 @@ unsigned int taus(void);
void set_taus_seed(unsigned int seed_init);
/**@} */
/** @defgroup _gauss_ Generation of Quantized Gaussian Random Variables
/** @defgroup _gauss_ Generation of Quantized Gaussian Random Variables
* @ingroup _numerical_
* @{
This set of routines are used to generate quantized (i.e. fixed-point) Gaussian random noise efficiently.
The use of these routines allows for rapid computer simulation of digital communication systems. The method
is based on a lookup-table of the quantized normal probability distribution. The routines assume that the
This set of routines are used to generate quantized (i.e. fixed-point) Gaussian random noise efficiently.
The use of these routines allows for rapid computer simulation of digital communication systems. The method
is based on a lookup-table of the quantized normal probability distribution. The routines assume that the
continuous-valued Gaussian random-variable,\f$x\f$ is quantized
to \f$N\f$ bits over the interval \f$[-L\sigma,L\sigma)\f$ where \f$N\f$ and \f$L\f$ control the precision
and range of the quantization. The
random variable, \f$l\in\{-2^{N-1},-2^{N-1}+1,\cdots,0,1,\cdots,2^{N-1}-1\}\f$ corresponds to the event,
\f$E_l =
\begin{cases}
x\in\left[-\infty,-L\sigma\right) & l=-2^{N-1}, \\
x\in\left[\frac{lL\sigma}{2^{N-1}},\frac{(l+1)L\sigma}{2^{N-1}}\right) & <l>-2^{N-1}, \\
to \f$N\f$ bits over the interval \f$[-L\sigma,L\sigma)\f$ where \f$N\f$ and \f$L\f$ control the precision
and range of the quantization. The
random variable, \f$l\in\{-2^{N-1},-2^{N-1}+1,\cdots,0,1,\cdots,2^{N-1}-1\}\f$ corresponds to the event,
\f$E_l =
\begin{cases}
x\in\left[-\infty,-L\sigma\right) & l=-2^{N-1}, \\
x\in\left[\frac{lL\sigma}{2^{N-1}},\frac{(l+1)L\sigma}{2^{N-1}}\right) & <l>-2^{N-1}, \\
x\in\left[L\sigma,\infty\right) & l>-2^{N-1},
\end{cases}\f$
which occurs with probability
\f$\Pr(E_l) =
\begin{cases}
\mathrm{erfc}(L) & l=-2^{N-1}, \\
\mathrm{erfc}(L) & l>-2^{N-1}, \\
\f$\Pr(E_l) =
\begin{cases}
\mathrm{erfc}(L) & l=-2^{N-1}, \\
\mathrm{erfc}(L) & l>-2^{N-1}, \\
\mathrm{erf}\left(\frac{lL}{2^{N-1}}\right) \mathrm{erfc}\left(\frac{(l-1)L}{2^{N-1}}\right)& l>-2^{N-1}.
\end{cases}\f$
*/
@@ -324,7 +324,7 @@ which occurs with probability
/** \fn unsigned int *generate_gauss_LUT(unsigned char Nbits,unsigned char L)
\brief This routine generates a Gaussian pdf lookup table (LUT). The table has \f$2^{\mathrm{Nbits}-1}\f$ entries which represent
the right half of the pdf. The data stored in position \f$i\f$ is actually the scaled cumulative probability distribution,
the right half of the pdf. The data stored in position \f$i\f$ is actually the scaled cumulative probability distribution,
\f$2^{31}\mathrm{erf}\left(\frac{iL}{2^{N-1}}\right)\f$. This represents the average number of times that the random variable
falls in the interval \f$\left[0,\frac{i}{2^{N-1}}\right)\f$. This format allows for rapid conversion of uniform 32-bit
random variables to \f$N\f$-bit Gaussian random variables using binary search.
@@ -333,18 +333,18 @@ random variables to \f$N\f$-bit Gaussian random variables using binary search.
@param L Number of standard deviations in range
*/
unsigned int *generate_gauss_LUT(unsigned char Nbits,unsigned char L);
/** \fn int gauss(unsigned int *gauss_LUT,unsigned char Nbits);
\brief This routine returns a zero-mean unit-variance Gaussian random variable.
Given a 32-bit uniform random variable,
\f$\mathrm{u}\f$ (from \ref _taus_, we first extract the sign and then search in the monotonically increasing Gaussian LUT for
the two entries \f$(i,i+1)\f$ for which
\f$ 2^{31}\mathrm{erf}\left(\frac{i}{2^{Nbits-1}}\right) < |u| \leq 2^{31}\mathrm{erf}\left(\frac{i+1}{2^{Nbits-1}}\right) \f$ and assign
\brief This routine returns a zero-mean unit-variance Gaussian random variable.
Given a 32-bit uniform random variable,
\f$\mathrm{u}\f$ (from \ref _taus_, we first extract the sign and then search in the monotonically increasing Gaussian LUT for
the two entries \f$(i,i+1)\f$ for which
\f$ 2^{31}\mathrm{erf}\left(\frac{i}{2^{Nbits-1}}\right) < |u| \leq 2^{31}\mathrm{erf}\left(\frac{i+1}{2^{Nbits-1}}\right) \f$ and assign
the value \f$\mathrm{sgn}(u)i\f$. The search requires at most \f$Nbits-1\f$ comparisons.
@see generate_gauss_LUT
@see taus
@param gauss_LUT pointer to lookup-table
@param Nbits number of bits for output variable ( between 1 and 16)
@param Nbits number of bits for output variable ( between 1 and 16)
*/
int gauss(unsigned int *gauss_LUT,unsigned char Nbits);
@@ -355,12 +355,12 @@ void freq_channel(channel_desc_t *desc,uint16_t nb_rb, int16_t n_samples);
void init_freq_channel(channel_desc_t *desc,uint16_t nb_rb,int16_t n_samples);
uint8_t multipath_channel_nosigconv(channel_desc_t *desc);
void multipath_tv_channel(channel_desc_t *desc,
double **tx_sig_re,
double **tx_sig_im,
double **rx_sig_re,
double **rx_sig_im,
uint16_t length,
uint8_t keep_channel);
double **tx_sig_re,
double **tx_sig_im,
double **rx_sig_re,
double **rx_sig_im,
uint16_t length,
uint8_t keep_channel);
/**@} */
/**@} */
+37 -34
View File
@@ -1,5 +1,5 @@
/*******************************************************************************
OpenAirInterface
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
@@ -14,15 +14,15 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
@@ -32,9 +32,9 @@
#include "defs.h"
unsigned int *generate_gauss_LUT(unsigned char Nbits,
unsigned char L
)
unsigned int *generate_gauss_LUT(unsigned char Nbits,
unsigned char L
)
{
unsigned int *LUT_ptr,i;
@@ -43,7 +43,7 @@ unsigned int *generate_gauss_LUT(unsigned char Nbits,
assert(LUT_ptr);
for (i=0;i<(1<<(Nbits-1));i++) {
for (i=0; i<(1<<(Nbits-1)); i++) {
LUT_ptr[i] = (unsigned int)((double)((unsigned int)(1<<31))*erf(i*L/(double)(1<<(Nbits-1))));
#ifdef LUTDEBUG
@@ -52,21 +52,22 @@ unsigned int *generate_gauss_LUT(unsigned char Nbits,
}
return(LUT_ptr);
}
}
int gauss(unsigned int *gauss_LUT,
unsigned char Nbits
) {
int gauss(unsigned int *gauss_LUT,
unsigned char Nbits
)
{
unsigned int search_pos,step_size,u,tmp,tmpm1,tmpp1,s;
// Get a 32-bit uniform random-variable
u = taus();
#ifdef DEBUG
printf("u = %u\n",u);
printf("u = %u\n",u);
#endif //DEBUG
// if it is larger than 2^31 (here negative), save the sign and rescale down to 31-bits.
@@ -75,36 +76,35 @@ int gauss(unsigned int *gauss_LUT,
u &= 0x7fffffff;
#ifdef DEBUG
printf("u = %x,s=%d\n",u,s);
#ifdef DEBUG
printf("u = %x,s=%d\n",u,s);
#endif //DEBUG
search_pos = (1<<(Nbits-2)); // starting position of the binary search
step_size = search_pos;
do {
step_size >>= 1;
tmp = gauss_LUT[search_pos];
tmpm1 = gauss_LUT[search_pos-1];
tmpp1 = gauss_LUT[search_pos+1];
#ifdef DEBUG
printf("search_pos %d, step_size %d: t %x tm %x,tp %x\n",search_pos,step_size,tmp,tmpm1,tmpp1);
#endif //DEBUG
if (u <= tmp)
if (u >tmpm1)
return s==0 ? (search_pos-1) : 1-search_pos;
if (u <= tmp)
if (u >tmpm1)
return s==0 ? (search_pos-1) : 1-search_pos;
else
search_pos -= step_size;
search_pos -= step_size;
else if (u <= tmpp1)
return s==0 ? search_pos : - search_pos;
else
if (u <= tmpp1)
return s==0 ? search_pos : - search_pos;
else
search_pos += step_size;
}
while (step_size > 0);
search_pos += step_size;
} while (step_size > 0);
// If it gets here we're beyond the positive edge so return max
return s==0 ? (1<<(Nbits-1))-1 : 1-((1<<(Nbits-1)));
@@ -116,7 +116,8 @@ int gauss(unsigned int *gauss_LUT,
#define Nhistbits 8
void main(int argc,char **argv) {
void main(int argc,char **argv)
{
unsigned int *gauss_LUT_ptr,i;
unsigned int hist[(1<<Nhistbits)];
@@ -136,14 +137,16 @@ void main(int argc,char **argv) {
// Generate Gaussian LUT 12-bit quantization over 5 standard deviations
gauss_LUT_ptr = generate_gauss_LUT(Nbits,L);
for (i=0;i<(1<<Nhistbits);i++)
for (i=0; i<(1<<Nhistbits); i++)
hist[i] = 0;
for (i=0;i<Ntrials;i++) {
for (i=0; i<Ntrials; i++) {
gvar = gauss(gauss_LUT_ptr,Nbits);
if (gvar == ((1<<(Nbits-1))-1))
maxnum++;
maxg = gvar > maxg ? gvar : maxg;
ming = gvar < ming ? gvar : ming;
meang += (double)gvar/Ntrials;
@@ -156,8 +159,8 @@ void main(int argc,char **argv) {
printf("Tail probability = %e(%x)\n",2*erfc((double)L*gauss_LUT_ptr[(1<<(Nbits-1))-1]/(unsigned int)(1<<31)),gauss_LUT_ptr[(1<<(Nbits-1))-1]);
printf("max %d, min %d, mean %f, stddev %f, Pr(maxnum)=%e(%d)\n",maxg,ming,meang,sqrt(varg),(double)maxnum/Ntrials,maxnum);
// for (i=0;i<(1<<Nhistbits);i++)
// printf("%d : %u\n",i,hist[i]);
// for (i=0;i<(1<<Nhistbits);i++)
// printf("%d : %u\n",i,hist[i]);
free(gauss_LUT_ptr);
}
+141 -134
View File
@@ -1,5 +1,5 @@
/*******************************************************************************
OpenAirInterface
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
@@ -14,15 +14,15 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
@@ -36,81 +36,86 @@
short max_array(const short *p, unsigned int size)
{
short max = *p;
unsigned int i;
short max = *p;
unsigned int i;
for (i = 1; i < size; ++i)
if (max < p[i])
max = p[i];
return max;
for (i = 1; i < size; ++i)
if (max < p[i])
max = p[i];
return max;
}
short min_array(const short *p, unsigned int size)
{
short min = *p;
unsigned int i;
short min = *p;
unsigned int i;
for (i = 1; i < size; ++i)
if (min > p[i])
min = p[i];
return min;
for (i = 1; i < size; ++i)
if (min > p[i])
min = p[i];
return min;
}
// Note that 'arraySize = 8*((3*8*6144)+12)';
// Note that 'arraySize = 8*((3*8*6144)+12)';
void dlsch_LLR_quant(const short *llr, const unsigned int arraySize, const short Mlevel, short *llr_quant)
{
unsigned int i, j;
short max_llr, min_llr;
short llr_interval;
float quant_step;
float *transLevelArray;
min_llr = min_array(llr, arraySize);
max_llr = max_array(llr, arraySize);
llr_interval = (max_llr - min_llr);
quant_step = (float)llr_interval / Mlevel;
unsigned int i, j;
short max_llr, min_llr;
short llr_interval;
float quant_step;
float *transLevelArray;
min_llr = min_array(llr, arraySize);
max_llr = max_array(llr, arraySize);
llr_interval = (max_llr - min_llr);
quant_step = (float)llr_interval / Mlevel;
if ((Mlevel%2) != 0){
printf("Mlevel should be mutiple of 2...\n");
exit(-1);
}
transLevelArray = (float *)malloc((Mlevel+1)*sizeof(float));
if (!transLevelArray){
printf("Cannot allocate memory for transLevelArray...!\n");
exit(-1);
}
for(j=0; j < Mlevel+1; j++){
transLevelArray[j] = min_llr + j*quant_step;
}
if ((Mlevel%2) != 0) {
printf("Mlevel should be mutiple of 2...\n");
exit(-1);
}
transLevelArray = (float *)malloc((Mlevel+1)*sizeof(float));
if (!transLevelArray) {
printf("Cannot allocate memory for transLevelArray...!\n");
exit(-1);
}
for(j=0; j < Mlevel+1; j++) {
transLevelArray[j] = min_llr + j*quant_step;
}
for (i=0; i < arraySize; i++) {
for(j=0; j < Mlevel; j++) {
if ((transLevelArray[j] <= llr[i]) && (llr[i] <= transLevelArray[j+1])) {
llr_quant[i] = (short)(transLevelArray[j] + quant_step/2); // mid-points are selected;
break;
}
if (transLevelArray[j+1] <= llr[i]) { // the last term;
llr_quant[i] = (short)(transLevelArray[j] + quant_step/2); // mid-points are selected;
}
}
}
#ifdef TEST_DEBUG
printf("min_llr: %d : max_llr: %d \n", min_llr, max_llr);
printf("llr_interval: %d : quant_step: %f \n", llr_interval, quant_step);
printf("transLevelArray = [");
for(j=0; j < Mlevel+1; j++)
printf("%f ", transLevelArray[j]);
printf("] \n\n");
#endif // TEST_DEBUG
for (i=0; i < arraySize; i++){
for(j=0; j < Mlevel; j++){
if ((transLevelArray[j] <= llr[i]) && (llr[i] <= transLevelArray[j+1])){
llr_quant[i] = (short)(transLevelArray[j] + quant_step/2); // mid-points are selected;
break;
}
if (transLevelArray[j+1] <= llr[i]){ // the last term;
llr_quant[i] = (short)(transLevelArray[j] + quant_step/2); // mid-points are selected;
}
}
}
#ifdef TEST_DEBUG
printf("min_llr: %d : max_llr: %d \n", min_llr, max_llr);
printf("llr_interval: %d : quant_step: %f \n", llr_interval, quant_step);
printf("transLevelArray = [");
for(j=0; j < Mlevel+1; j++)
printf("%f ", transLevelArray[j]);
printf("] \n\n");
#endif // TEST_DEBUG
}
/*
@@ -118,81 +123,82 @@ void dlsch_LLR_quant(const short *llr, const unsigned int arraySize, const short
void dlsch_LLR_quant2(const short *llr, const unsigned int arraySize, const short bitsPerLLR, short *llr_quant)
{
unsigned int i;
short max_llr, min_llr;
short peak_llr;
unsigned char shift;
min_llr = min_array(llr, arraySize);
max_llr = max_array(llr, arraySize);
peak_llr = max(abs(max_llr), abs(min_llr));
shift = log2_approx(peak_llr);
unsigned int i;
short max_llr, min_llr;
short peak_llr;
unsigned char shift;
if (bitsPerLLR < 1){
printf("Bits per LLR should be greater than 0\n");
exit(-1);
}
for (i=0; i < 6072; i++){
llr_quant[i] = llr[i] >> max(0, shift-bitsPerLLR); // quantize the LLRs;
llr_quant[i] <<= max(0, shift-bitsPerLLR); // reconstruct the LLRs;
printf("[%d] llr: %d : llr_quant %d \n",i, llr[i], llr_quant[i]);
}
exit(-1);
min_llr = min_array(llr, arraySize);
max_llr = max_array(llr, arraySize);
peak_llr = max(abs(max_llr), abs(min_llr));
shift = log2_approx(peak_llr);
if (bitsPerLLR < 1){
printf("Bits per LLR should be greater than 0\n");
exit(-1);
}
for (i=0; i < 6072; i++){
llr_quant[i] = llr[i] >> max(0, shift-bitsPerLLR); // quantize the LLRs;
llr_quant[i] <<= max(0, shift-bitsPerLLR); // reconstruct the LLRs;
printf("[%d] llr: %d : llr_quant %d \n",i, llr[i], llr_quant[i]);
}
exit(-1);
}
void clearbits(short *llr, const unsigned short startbit, const unsigned short nbits)
{
unsigned short i;
for (i=0; i < nbits; i++){
*llr &= ~(1 << (startbit + i));
}
unsigned short i;
for (i=0; i < nbits; i++){
*llr &= ~(1 << (startbit + i));
}
}
void dlsch_LLR_quant3(const short *llr, const unsigned int arraySize, const short bitsPerLLR, short *llr_quant)
{
unsigned int i;
unsigned char shift;
unsigned int abs_mean_llr = 0;
//mean of the LLRs;
for(i=0; i < 6072; i++){
abs_mean_llr += abs(llr[i]);
}
abs_mean_llr /= 6072;
shift = log2_approx(abs_mean_llr);
printf("abs_mean_llr=%d, shift = %d\n", abs_mean_llr, shift);
exit(-1);
for (i=0; i < 6072; i++){
llr_quant[i] = llr[i] >> max(0, shift-bitsPerLLR); // quantize the LLRs;
printf("[%d] llr: %d : ", i, llr[i]);
//mask the llr_quant values such that their values do not exceed 2^(bitsPerLLR);
clearbits(&llr_quant[i], bitsPerLLR, sizeof(short)-bitsPerLLR-1);
printf("llr_quant_mask: %d : ", llr_quant[i]);
llr_quant[i] <<= max(0, shift-bitsPerLLR); // reconstruct the LLRs;
printf("llr_quant: %d \n", llr_quant[i]);
}
}
unsigned int i;
unsigned char shift;
unsigned int abs_mean_llr = 0;
//mean of the LLRs;
for(i=0; i < 6072; i++){
abs_mean_llr += abs(llr[i]);
}
abs_mean_llr /= 6072;
shift = log2_approx(abs_mean_llr);
printf("abs_mean_llr=%d, shift = %d\n", abs_mean_llr, shift);
exit(-1);
for (i=0; i < 6072; i++){
llr_quant[i] = llr[i] >> max(0, shift-bitsPerLLR); // quantize the LLRs;
printf("[%d] llr: %d : ", i, llr[i]);
//mask the llr_quant values such that their values do not exceed 2^(bitsPerLLR);
clearbits(&llr_quant[i], bitsPerLLR, sizeof(short)-bitsPerLLR-1);
printf("llr_quant_mask: %d : ", llr_quant[i]);
llr_quant[i] <<= max(0, shift-bitsPerLLR); // reconstruct the LLRs;
printf("llr_quant: %d \n", llr_quant[i]);
}
}
*/
void dlsch_MRC_relay_LLR(const short *llr_quant, const unsigned int arraySize, short *llr_quant_sum){
unsigned int i;
for (i=0; i < arraySize; i++){
llr_quant_sum[i] += llr_quant[i];
}
void dlsch_MRC_relay_LLR(const short *llr_quant, const unsigned int arraySize, short *llr_quant_sum)
{
unsigned int i;
for (i=0; i < arraySize; i++) {
llr_quant_sum[i] += llr_quant[i];
}
}
@@ -201,23 +207,24 @@ void dlsch_MRC_relay_LLR(const short *llr_quant, const unsigned int arraySize,
void test_llr_quant()
{
short test[10] = {-1800, -5446, 345, 243, 130, -2111, 433, 4210, -10, -134};
short channel_output[10];
unsigned int i;
short test[10] = {-1800, -5446, 345, 243, 130, -2111, 433, 4210, -10, -134};
short channel_output[10];
dlsch_LLR_quant(test, 10, 2, channel_output);
for (i = 0; i < 10; i++){
printf("llr: %d : llr_quant %d \n",test[i], channel_output[i]);
}
unsigned int i;
dlsch_LLR_quant(test, 10, 2, channel_output);
for (i = 0; i < 10; i++) {
printf("llr: %d : llr_quant %d \n",test[i], channel_output[i]);
}
}
void main() {
void main()
{
test_llr_quant();
test_llr_quant();
}
#endif // TEST_DEBUG
+96 -82
View File
@@ -1,5 +1,5 @@
/*******************************************************************************
OpenAirInterface
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
@@ -14,15 +14,15 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
@@ -34,22 +34,24 @@
#include "SIMULATION/RF/defs.h"
//#define DEBUG_CH
uint8_t multipath_channel_nosigconv(channel_desc_t *desc){
uint8_t multipath_channel_nosigconv(channel_desc_t *desc)
{
random_channel(desc,0);
return(1);
return(1);
}
#define CHANNEL_SSE
#ifdef CHANNEL_SSE
void multipath_channel(channel_desc_t *desc,
double **tx_sig_re,
double **tx_sig_im,
double **rx_sig_re,
double **rx_sig_im,
uint32_t length,
uint8_t keep_channel) {
double **tx_sig_re,
double **tx_sig_im,
double **rx_sig_re,
double **rx_sig_im,
uint32_t length,
uint8_t keep_channel)
{
int i,ii,j,l;
int length1, length2, tail;
__m128d rx_tmp128_re_f,rx_tmp128_im_f,rx_tmp128_re,rx_tmp128_im, rx_tmp128_1,rx_tmp128_2,rx_tmp128_3,rx_tmp128_4,tx128_re,tx128_im,ch128_x,ch128_y,pathloss128;
@@ -63,61 +65,68 @@ void multipath_channel(channel_desc_t *desc,
printf("[CHANNEL] keep = %d : path_loss = %g (%f), nb_rx %d, nb_tx %d, dd %d, len %d \n",keep_channel,path_loss,desc->path_loss_dB,desc->nb_rx,desc->nb_tx,dd,desc->channel_length);
#endif
if (keep_channel) {
// do nothing - keep channel
} else {
random_channel(desc,0);
}
if (keep_channel) {
// do nothing - keep channel
} else {
random_channel(desc,0);
}
start_meas(&desc->convolution);
start_meas(&desc->convolution);
#ifdef DEBUG_CH
for (l = 0;l<(int)desc->channel_length;l++) {
for (l = 0; l<(int)desc->channel_length; l++) {
printf("%p (%f,%f) ",desc->ch[0],desc->ch[0][l].x,desc->ch[0][l].y);
}
printf("\n");
#endif
tail = ((int)length-dd)%2;
if(tail)
length1 = ((int)length-dd)-1;
else
length1 = ((int)length-dd);
length2 = length1/2;
for (i=0;i<length2;i++) { //
for (ii=0;ii<desc->nb_rx;ii++) {
for (i=0; i<length2; i++) { //
for (ii=0; ii<desc->nb_rx; ii++) {
// rx_tmp.x = 0;
// rx_tmp.y = 0;
rx_tmp128_re_f = _mm_setzero_pd();
rx_tmp128_im_f = _mm_setzero_pd();
for (j=0;j<desc->nb_tx;j++) {
for (l = 0;l<(int)desc->channel_length;l++) {
if ((i>=0) && (i-l)>=0) { //SIMD correct only if length1 > 2*channel_length...which is almost always satisfied
// tx.x = tx_sig_re[j][i-l];
// tx.y = tx_sig_im[j][i-l];
tx128_re = _mm_loadu_pd(&tx_sig_re[j][2*i-l]); // tx_sig_re[j][i-l+1], tx_sig_re[j][i-l]
tx128_im = _mm_loadu_pd(&tx_sig_im[j][2*i-l]);
}
else {
//tx.x =0;
//tx.y =0;
tx128_re = _mm_setzero_pd();
tx128_im = _mm_setzero_pd();
}
ch128_x = _mm_set1_pd(desc->ch[ii+(j*desc->nb_rx)][l].x);
ch128_y = _mm_set1_pd(desc->ch[ii+(j*desc->nb_rx)][l].y);
// rx_tmp.x += (tx.x * desc->ch[ii+(j*desc->nb_rx)][l].x) - (tx.y * desc->ch[ii+(j*desc->nb_rx)][l].y);
// rx_tmp.y += (tx.y * desc->ch[ii+(j*desc->nb_rx)][l].x) + (tx.x * desc->ch[ii+(j*desc->nb_rx)][l].y);
rx_tmp128_1 = _mm_mul_pd(tx128_re,ch128_x);
rx_tmp128_2 = _mm_mul_pd(tx128_re,ch128_y);
rx_tmp128_3 = _mm_mul_pd(tx128_im,ch128_x);
rx_tmp128_4 = _mm_mul_pd(tx128_im,ch128_y);
rx_tmp128_re = _mm_sub_pd(rx_tmp128_1,rx_tmp128_4);
rx_tmp128_im = _mm_add_pd(rx_tmp128_2,rx_tmp128_3);
rx_tmp128_re_f = _mm_add_pd(rx_tmp128_re_f,rx_tmp128_re);
rx_tmp128_im_f = _mm_add_pd(rx_tmp128_im_f,rx_tmp128_im);
} //l
for (j=0; j<desc->nb_tx; j++) {
for (l = 0; l<(int)desc->channel_length; l++) {
if ((i>=0) && (i-l)>=0) { //SIMD correct only if length1 > 2*channel_length...which is almost always satisfied
// tx.x = tx_sig_re[j][i-l];
// tx.y = tx_sig_im[j][i-l];
tx128_re = _mm_loadu_pd(&tx_sig_re[j][2*i-l]); // tx_sig_re[j][i-l+1], tx_sig_re[j][i-l]
tx128_im = _mm_loadu_pd(&tx_sig_im[j][2*i-l]);
} else {
//tx.x =0;
//tx.y =0;
tx128_re = _mm_setzero_pd();
tx128_im = _mm_setzero_pd();
}
ch128_x = _mm_set1_pd(desc->ch[ii+(j*desc->nb_rx)][l].x);
ch128_y = _mm_set1_pd(desc->ch[ii+(j*desc->nb_rx)][l].y);
// rx_tmp.x += (tx.x * desc->ch[ii+(j*desc->nb_rx)][l].x) - (tx.y * desc->ch[ii+(j*desc->nb_rx)][l].y);
// rx_tmp.y += (tx.y * desc->ch[ii+(j*desc->nb_rx)][l].x) + (tx.x * desc->ch[ii+(j*desc->nb_rx)][l].y);
rx_tmp128_1 = _mm_mul_pd(tx128_re,ch128_x);
rx_tmp128_2 = _mm_mul_pd(tx128_re,ch128_y);
rx_tmp128_3 = _mm_mul_pd(tx128_im,ch128_x);
rx_tmp128_4 = _mm_mul_pd(tx128_im,ch128_y);
rx_tmp128_re = _mm_sub_pd(rx_tmp128_1,rx_tmp128_4);
rx_tmp128_im = _mm_add_pd(rx_tmp128_2,rx_tmp128_3);
rx_tmp128_re_f = _mm_add_pd(rx_tmp128_re_f,rx_tmp128_re);
rx_tmp128_im_f = _mm_add_pd(rx_tmp128_im_f,rx_tmp128_im);
} //l
} // j
//rx_sig_re[ii][i+dd] = rx_tmp.x*path_loss;
//rx_sig_im[ii][i+dd] = rx_tmp.y*path_loss;
rx_tmp128_re_f = _mm_mul_pd(rx_tmp128_re_f,pathloss128);
@@ -126,12 +135,12 @@ void multipath_channel(channel_desc_t *desc,
_mm_storeu_pd(&rx_sig_im[ii][2*i+dd],rx_tmp128_im_f);
/*
if ((ii==0)&&((i%32)==0)) {
printf("%p %p %f,%f => %e,%e\n",rx_sig_re[ii],rx_sig_im[ii],rx_tmp.x,rx_tmp.y,rx_sig_re[ii][i-dd],rx_sig_im[ii][i-dd]);
printf("%p %p %f,%f => %e,%e\n",rx_sig_re[ii],rx_sig_im[ii],rx_tmp.x,rx_tmp.y,rx_sig_re[ii][i-dd],rx_sig_im[ii][i-dd]);
}
*/
//rx_sig_re[ii][i] = sqrt(.5)*(tx_sig_re[0][i] + tx_sig_re[1][i]);
//rx_sig_im[ii][i] = sqrt(.5)*(tx_sig_im[0][i] + tx_sig_im[1][i]);
} // ii
} // i
@@ -141,13 +150,14 @@ void multipath_channel(channel_desc_t *desc,
#else
void multipath_channel(channel_desc_t *desc,
double **tx_sig_re,
double **tx_sig_im,
double **rx_sig_re,
double **rx_sig_im,
uint32_t length,
uint8_t keep_channel) {
double **tx_sig_re,
double **tx_sig_im,
double **rx_sig_re,
double **rx_sig_im,
uint32_t length,
uint8_t keep_channel)
{
int i,ii,j,l;
struct complex rx_tmp,tx;
@@ -159,47 +169,51 @@ void multipath_channel(channel_desc_t *desc,
printf("[CHANNEL] keep = %d : path_loss = %g (%f), nb_rx %d, nb_tx %d, dd %d, len %d \n",keep_channel,path_loss,desc->path_loss_dB,desc->nb_rx,desc->nb_tx,dd,desc->channel_length);
#endif
if (keep_channel) {
// do nothing - keep channel
} else {
random_channel(desc,0);
}
if (keep_channel) {
// do nothing - keep channel
} else {
random_channel(desc,0);
}
#ifdef DEBUG_CH
for (l = 0;l<(int)desc->channel_length;l++) {
for (l = 0; l<(int)desc->channel_length; l++) {
printf("%p (%f,%f) ",desc->ch[0],desc->ch[0][l].x,desc->ch[0][l].y);
}
printf("\n");
#endif
for (i=0;i<((int)length-dd);i++) {
for (ii=0;ii<desc->nb_rx;ii++) {
for (i=0; i<((int)length-dd); i++) {
for (ii=0; ii<desc->nb_rx; ii++) {
rx_tmp.x = 0;
rx_tmp.y = 0;
for (j=0;j<desc->nb_tx;j++) {
for (l = 0;l<(int)desc->channel_length;l++) {
if ((i>=0) && (i-l)>=0) {
tx.x = tx_sig_re[j][i-l];
tx.y = tx_sig_im[j][i-l];
}
else {
tx.x =0;
tx.y =0;
}
rx_tmp.x += (tx.x * desc->ch[ii+(j*desc->nb_rx)][l].x) - (tx.y * desc->ch[ii+(j*desc->nb_rx)][l].y);
rx_tmp.y += (tx.y * desc->ch[ii+(j*desc->nb_rx)][l].x) + (tx.x * desc->ch[ii+(j*desc->nb_rx)][l].y);
} //l
for (j=0; j<desc->nb_tx; j++) {
for (l = 0; l<(int)desc->channel_length; l++) {
if ((i>=0) && (i-l)>=0) {
tx.x = tx_sig_re[j][i-l];
tx.y = tx_sig_im[j][i-l];
} else {
tx.x =0;
tx.y =0;
}
rx_tmp.x += (tx.x * desc->ch[ii+(j*desc->nb_rx)][l].x) - (tx.y * desc->ch[ii+(j*desc->nb_rx)][l].y);
rx_tmp.y += (tx.y * desc->ch[ii+(j*desc->nb_rx)][l].x) + (tx.x * desc->ch[ii+(j*desc->nb_rx)][l].y);
} //l
} // j
rx_sig_re[ii][i+dd] = rx_tmp.x*path_loss;
rx_sig_im[ii][i+dd] = rx_tmp.y*path_loss;
/*
if ((ii==0)&&((i%32)==0)) {
printf("%p %p %f,%f => %e,%e\n",rx_sig_re[ii],rx_sig_im[ii],rx_tmp.x,rx_tmp.y,rx_sig_re[ii][i-dd],rx_sig_im[ii][i-dd]);
printf("%p %p %f,%f => %e,%e\n",rx_sig_re[ii],rx_sig_im[ii],rx_tmp.x,rx_tmp.y,rx_sig_re[ii][i-dd],rx_sig_im[ii][i-dd]);
}
*/
//rx_sig_re[ii][i] = sqrt(.5)*(tx_sig_re[0][i] + tx_sig_re[1][i]);
//rx_sig_im[ii][i] = sqrt(.5)*(tx_sig_im[0][i] + tx_sig_im[1][i]);
} // ii
} // i
}
+130 -114
View File
@@ -1,5 +1,5 @@
/*******************************************************************************
OpenAirInterface
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
@@ -14,15 +14,15 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
@@ -39,156 +39,169 @@ double frand_a_b(double a, double b);
void tv_conv(double complex **h, double complex *x, double complex *y, uint16_t nb_samples, uint8_t nb_taps, int delay);
void multipath_tv_channel(channel_desc_t *desc,
double **tx_sig_re,
double **tx_sig_im,
double **rx_sig_re,
double **rx_sig_im,
uint16_t length,
uint8_t keep_channel) {
double complex **tx,**rx,***H_t,*rx_temp;//, *tv_H_t;
double **tx_sig_re,
double **tx_sig_im,
double **rx_sig_re,
double **rx_sig_im,
uint16_t length,
uint8_t keep_channel)
{
double complex **tx,**rx,***H_t,*rx_temp;//, *tv_H_t;
double path_loss = pow(10,desc->path_loss_dB/20);
int i,j,k,dd;
dd = abs(desc->channel_offset);
#ifdef DEBUG_CH
printf("[TV CHANNEL] keep = %d : path_loss = %g (%f), nb_rx %d, nb_tx %d, dd %d, len %d max_doppler %d\n",keep_channel,path_loss,desc->path_loss_dB,desc->nb_rx,desc->nb_tx,dd,desc->channel_length,desc->max_Doppler);
printf("[TV CHANNEL] keep = %d : path_loss = %g (%f), nb_rx %d, nb_tx %d, dd %d, len %d max_doppler %d\n",keep_channel,path_loss,desc->path_loss_dB,desc->nb_rx,desc->nb_tx,dd,desc->channel_length,
desc->max_Doppler);
#endif
tx = (double complex **)malloc(desc->nb_tx*sizeof(double complex));
rx = (double complex **)malloc(desc->nb_rx*sizeof(double complex));
H_t= (double complex ***) malloc(desc->nb_tx*desc->nb_rx*sizeof(double complex **));
// tv_H_t = (double complex *) malloc(length*sizeof(double complex));
rx_temp= (double complex *) calloc(length,sizeof(double complex));
for(i=0;i<desc->nb_tx;i++){
tx[i] = (double complex *)calloc(length,sizeof(double complex));
}
for(i=0;i<desc->nb_rx;i++){
rx[i] = (double complex *)calloc(length,sizeof(double complex));
}
for(i=0;i<desc->nb_tx*desc->nb_rx;i++){
H_t[i] = (double complex **) malloc(length*sizeof(double complex *));
for(j=0;j<length;j++) {
H_t[i][j] = (double complex *) calloc (desc->nb_taps,sizeof(double complex));
}
}
for (i=0;i<desc->nb_tx;i++){
for(j=0;j<length;j++) {
tx[i][j] = tx_sig_re[i][j] +I*tx_sig_im[i][j];
}
}
if (keep_channel) {
// do nothing - keep channel
} else {
tv_channel(desc,H_t,length);
}
for(i=0;i<desc->nb_rx;i++){
for(j=0;j<desc->nb_tx;j++){
tv_conv(H_t[i+(j*desc->nb_rx)],tx[j],rx_temp,length,desc->nb_taps,dd);
for(k=0;k<length;k++){
rx[i][k] += rx_temp[k];
}
}
for(i=0; i<desc->nb_tx; i++) {
tx[i] = (double complex *)calloc(length,sizeof(double complex));
}
for(i=0;i<desc->nb_rx;i++){
for(j=0;j<length;j++){
rx_sig_re[i][j] = creal(rx[i][j])*path_loss;
rx_sig_im[i][j] = cimag(rx[i][j])*path_loss;
for(i=0; i<desc->nb_rx; i++) {
rx[i] = (double complex *)calloc(length,sizeof(double complex));
}
for(i=0; i<desc->nb_tx*desc->nb_rx; i++) {
H_t[i] = (double complex **) malloc(length*sizeof(double complex *));
for(j=0; j<length; j++) {
H_t[i][j] = (double complex *) calloc (desc->nb_taps,sizeof(double complex));
}
}
for (i=0; i<desc->nb_tx; i++) {
for(j=0; j<length; j++) {
tx[i][j] = tx_sig_re[i][j] +I*tx_sig_im[i][j];
}
}
if (keep_channel) {
// do nothing - keep channel
} else {
tv_channel(desc,H_t,length);
}
for(i=0; i<desc->nb_rx; i++) {
for(j=0; j<desc->nb_tx; j++) {
tv_conv(H_t[i+(j*desc->nb_rx)],tx[j],rx_temp,length,desc->nb_taps,dd);
for(k=0; k<length; k++) {
rx[i][k] += rx_temp[k];
}
}
}
for(i=0; i<desc->nb_rx; i++) {
for(j=0; j<length; j++) {
rx_sig_re[i][j] = creal(rx[i][j])*path_loss;
rx_sig_im[i][j] = cimag(rx[i][j])*path_loss;
}
}
/* for(k=0;k<length;k++) {
tv_H_t[k] = H_t[0][k][0];
}*/
for(i=0;i<desc->nb_tx;i++){
free(tx[i]);
for(i=0; i<desc->nb_tx; i++) {
free(tx[i]);
}
free(tx);
for(i=0;i<desc->nb_rx;i++) {
free(rx[i]);
for(i=0; i<desc->nb_rx; i++) {
free(rx[i]);
}
free(rx);
for(i=0;i<desc->nb_rx*desc->nb_tx;i++){
for(j=0;j<length;j++){
free(H_t[i][j]);
}
free(H_t[i]);
for(i=0; i<desc->nb_rx*desc->nb_tx; i++) {
for(j=0; j<length; j++) {
free(H_t[i][j]);
}
free(H_t[i]);
}
free(H_t);
free(rx_temp);
}
//TODO: make phi_rad a parameter of this function
void tv_channel(channel_desc_t *desc,double complex ***H,uint16_t length){
void tv_channel(channel_desc_t *desc,double complex ***H,uint16_t length)
{
int i,j,p,l,k;
double *alpha,*phi_rad,pi=acos(-1),*w_Hz;
alpha = (double *)calloc(desc->nb_paths,sizeof(double));
phi_rad = (double *)calloc(desc->nb_paths,sizeof(double));
w_Hz = (double *)calloc(desc->nb_paths,sizeof(double));
for(i=0;i<desc->nb_paths;i++) {
w_Hz[i]=desc->max_Doppler*cos(frand_a_b(0,2*pi));
phi_rad[i]=frand_a_b(0,2*pi);
for(i=0; i<desc->nb_paths; i++) {
w_Hz[i]=desc->max_Doppler*cos(frand_a_b(0,2*pi));
phi_rad[i]=frand_a_b(0,2*pi);
}
if(desc->ricean_factor == 1){
for(i=0;i<desc->nb_paths;i++) {
alpha[i]=1/sqrt(desc->nb_paths);
}
}
else {
alpha[0]=sqrt(desc->ricean_factor/(desc->ricean_factor+1));
for(i=1;i<desc->nb_paths;i++) {
alpha[i] = (1/sqrt(desc->nb_paths-1))*(sqrt(1/(desc->ricean_factor+1)));
}
if(desc->ricean_factor == 1) {
for(i=0; i<desc->nb_paths; i++) {
alpha[i]=1/sqrt(desc->nb_paths);
}
} else {
alpha[0]=sqrt(desc->ricean_factor/(desc->ricean_factor+1));
for(i=1; i<desc->nb_paths; i++) {
alpha[i] = (1/sqrt(desc->nb_paths-1))*(sqrt(1/(desc->ricean_factor+1)));
}
}
/*
// This is the code when we only consider a SISO case
for(i=0;i<length;i++)
{
for(j=0;j<desc->nb_taps;j++)
{
for(p=0;p<desc->nb_paths;p++)
{
H[i][j] += sqrt(desc->amps[j]/2)*alpha[p]*cexp(-I*(2*pi*w_Hz[p]*i*(1/(desc->BW*1e6))+phi_rad[p]));
}
}
for(j=0;j<desc->nb_taps;j++)
{
for(p=0;p<desc->nb_paths;p++)
{
H[i][j] += sqrt(desc->amps[j]/2)*alpha[p]*cexp(-I*(2*pi*w_Hz[p]*i*(1/(desc->BW*1e6))+phi_rad[p]));
}
}
}
for(j=0;j<desc->nb_paths;j++)
for(j=0;j<desc->nb_paths;j++)
{
phi_rad[j] = fmod(2*pi*w_Hz[j]*(length-1)*(1/desc->BW)+phi_rad[j],2*pi);
phi_rad[j] = fmod(2*pi*w_Hz[j]*(length-1)*(1/desc->BW)+phi_rad[j],2*pi);
}
*/
// if MIMO
for (i=0;i<desc->nb_rx;i++){
for(j=0;j<desc->nb_tx;j++){
for(k=0;k<length;k++){
for(l=0;l<desc->nb_taps;l++){
H[i+(j*desc->nb_rx)][k][l] = 0;
for(p=0;p<desc->nb_paths;p++){
H[i+(j*desc->nb_rx)][k][l] += sqrt(desc->amps[l]/2)*alpha[p]*cexp(I*(2*pi*w_Hz[p]*k*(1/(desc->BW*1e6))+phi_rad[p]));
}
}
}
for(j=0;j<desc->nb_paths;j++){
phi_rad[j] = fmod(2*pi*w_Hz[j]*(length-1)*(1/desc->BW)+phi_rad[j],2*pi);
for (i=0; i<desc->nb_rx; i++) {
for(j=0; j<desc->nb_tx; j++) {
for(k=0; k<length; k++) {
for(l=0; l<desc->nb_taps; l++) {
H[i+(j*desc->nb_rx)][k][l] = 0;
for(p=0; p<desc->nb_paths; p++) {
H[i+(j*desc->nb_rx)][k][l] += sqrt(desc->amps[l]/2)*alpha[p]*cexp(I*(2*pi*w_Hz[p]*k*(1/(desc->BW*1e6))+phi_rad[p]));
}
}
}
for(j=0; j<desc->nb_paths; j++) {
phi_rad[j] = fmod(2*pi*w_Hz[j]*(length-1)*(1/desc->BW)+phi_rad[j],2*pi);
}
}
}
free(alpha);
@@ -196,19 +209,22 @@ for(j=0;j<desc->nb_paths;j++)
free(phi_rad);
}
// time varying convolution
void tv_conv(double complex **h, double complex *x, double complex *y, uint16_t nb_samples, uint8_t nb_taps, int dd) {
// time varying convolution
void tv_conv(double complex **h, double complex *x, double complex *y, uint16_t nb_samples, uint8_t nb_taps, int dd)
{
int i,j;
for(i=0;i<((int)nb_samples-dd);i++) {
for(j=0;j<nb_taps;j++) {
if(i>j)
y[i+dd] += creal(h[i][j])*creal(x[i-j])-cimag(h[i][j])*cimag(x[i-j]) + I*(creal(h[i][j])*cimag(x[i-j])+cimag(h[i][j])*creal(x[i-j]));
}
for(i=0; i<((int)nb_samples-dd); i++) {
for(j=0; j<nb_taps; j++) {
if(i>j)
y[i+dd] += creal(h[i][j])*creal(x[i-j])-cimag(h[i][j])*cimag(x[i-j]) + I*(creal(h[i][j])*cimag(x[i-j])+cimag(h[i][j])*creal(x[i-j]));
}
}
}
double frand_a_b(double a, double b){
return (rand()/(double)RAND_MAX)*(b-a)+a;
double frand_a_b(double a, double b)
{
return (rand()/(double)RAND_MAX)*(b-a)+a;
}
File diff suppressed because it is too large Load Diff
+35 -32
View File
@@ -1,5 +1,5 @@
/*******************************************************************************
OpenAirInterface
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
@@ -14,15 +14,15 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
@@ -32,12 +32,12 @@
#include <math.h>
#include <time.h>
#endif
#include "defs.h"
static unsigned int seed, iy, ir[98];
/*
@defgroup _uniformdouble
@defgroup _uniformdouble
@ingroup numerical Uniform linear congruential random number generator.
*/
@@ -50,24 +50,24 @@ static unsigned int seed, iy, ir[98];
void randominit(unsigned seed_init)
{
int i;
// this need to be integrated with the existing rng, like taus: navid
// this need to be integrated with the existing rng, like taus: navid
msg("Initializing random number generator, seed %x\n",seed_init);
if (seed_init == 0) {
srand((unsigned)time(NULL));
seed = (unsigned int) rand();
}
else {
} else {
seed = seed_init;
}
if (seed % 2 == 0) seed += 1; /* seed and mod are relative prime */
for (i=1; i<=97; i++)
{
seed = a*seed; /* mod 2**32 */
ir[i]= seed; /* initialize the shuffle table */
for (i=1; i<=97; i++) {
seed = a*seed; /* mod 2**32 */
ir[i]= seed; /* initialize the shuffle table */
}
iy=1;
}
@@ -75,8 +75,8 @@ void randominit(unsigned seed_init)
double uniformrandom(void)
{
#define a 1664525lu
#define mod 4294967296.0 /* is 2**32 */
#define a 1664525lu
#define mod 4294967296.0 /* is 2**32 */
int j;
@@ -88,8 +88,8 @@ double uniformrandom(void)
}
/*
@defgroup _gaussdouble Gaussian random number generator based on modified Box-Muller transformation.
@ingroup numerical
@defgroup _gaussdouble Gaussian random number generator based on modified Box-Muller transformation.
@ingroup numerical
*/
/*!\brief Gaussian random number generator based on modified Box-Muller transformation.Returns a double-precision floating-point number. */
@@ -100,31 +100,34 @@ double gaussdouble(double mean, double variance)
static double gset;
double fac,r,v1,v2;
if (iset == 0){
do{
v1 = 2.0*uniformrandom()-1.0;
v2 = 2.0*uniformrandom()-1.0;
r = v1*v1+v2*v2;
} while (r >= 1.0);
fac = sqrt(-2.0*log(r)/r);
gset= v1*fac;
iset=1;
return(sqrt(variance)*v2*fac + mean);
if (iset == 0) {
do {
v1 = 2.0*uniformrandom()-1.0;
v2 = 2.0*uniformrandom()-1.0;
r = v1*v1+v2*v2;
} while (r >= 1.0);
fac = sqrt(-2.0*log(r)/r);
gset= v1*fac;
iset=1;
return(sqrt(variance)*v2*fac + mean);
} else {
iset=0;
return(sqrt(variance)*gset + mean);
iset=0;
return(sqrt(variance)*gset + mean);
}
}
#ifdef MAIN
main(int argc,char **argv) {
main(int argc,char **argv)
{
int i;
randominit();
for (i=0;i<10;i++) {
for (i=0; i<10; i++) {
printf("%f\n",gaussdouble(0.0,1.0));
}
}
+22 -22
View File
@@ -1,5 +1,5 @@
/*******************************************************************************
OpenAirInterface
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
@@ -14,39 +14,39 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
double R22_sqrt[6][32] = {
{0.921700, -0.000000, 0.010380, -0.027448, -0.250153, 0.294754, 0.005961, 0.010769, 0.010380, 0.027448, 0.921700, 0.000000, -0.011595, -0.004130, -0.250153, 0.294754, -0.250153, -0.294754, -0.011595, 0.004130, 0.921700, 0.000000, 0.010380, -0.027448, 0.005961, -0.010769, -0.250153, -0.294754, 0.010380, 0.027448, 0.921700, 0.000000},
{0.923810, 0.000000, 0.004069, 0.027832, 0.151730, 0.350180, -0.009882, 0.006114, 0.004069, -0.027832, 0.923810, 0.000000, 0.011218, -0.003029, 0.151730, 0.350180, 0.151730, -0.350180, 0.011218, 0.003029, 0.923810, -0.000000, 0.004069, 0.027832, -0.009882, -0.006114, 0.151730, -0.350180, 0.004069, -0.027832, 0.923810, 0.000000},
{0.927613, 0.000000, 0.014253, 0.025767, -0.061171, -0.367133, 0.009258, -0.007340, 0.014253, -0.025767, 0.927613, -0.000000, -0.011138, -0.003942, -0.061171, -0.367133, -0.061171, 0.367133, -0.011138, 0.003942, 0.927613, 0.000000, 0.014253, 0.025767, 0.009258, 0.007340, -0.061171, 0.367133, 0.014253, -0.025767, 0.927613, 0.000000},
{0.869794, -0.000000, -0.010613, -0.001218, 0.399115, 0.289852, -0.004464, -0.004096, -0.010613, 0.001218, 0.869794, -0.000000, -0.005276, -0.002978, 0.399115, 0.289852, 0.399115, -0.289852, -0.005276, 0.002978, 0.869794, -0.000000, -0.010613, -0.001218, -0.004464, 0.004096, 0.399115, -0.289852, -0.010613, 0.001218, 0.869794, 0.000000},
{0.919726, -0.000000, 0.038700, -0.111146, 0.217804, 0.300925, 0.045531, -0.013659, 0.038700, 0.111146, 0.919726, 0.000000, -0.027201, 0.038983, 0.217804, 0.300925, 0.217804, -0.300925, -0.027201, -0.038983, 0.919726, 0.000000, 0.038700, -0.111146, 0.045531, 0.013659, 0.217804, -0.300925, 0.038700, 0.111146, 0.919726, 0.000000},
{0.867608, -0.000000, 0.194097, -0.112414, -0.418811, 0.095938, -0.081264, 0.075727, 0.194097, 0.112414, 0.867608, -0.000000, -0.106125, -0.032801, -0.418811, 0.095938, -0.418811, -0.095938, -0.106125, 0.032801, 0.867608, 0.000000, 0.194097, -0.112414, -0.081264, -0.075727, -0.418811, -0.095938, 0.194097, 0.112414, 0.867608, 0.000000},
{0.921700, -0.000000, 0.010380, -0.027448, -0.250153, 0.294754, 0.005961, 0.010769, 0.010380, 0.027448, 0.921700, 0.000000, -0.011595, -0.004130, -0.250153, 0.294754, -0.250153, -0.294754, -0.011595, 0.004130, 0.921700, 0.000000, 0.010380, -0.027448, 0.005961, -0.010769, -0.250153, -0.294754, 0.010380, 0.027448, 0.921700, 0.000000},
{0.923810, 0.000000, 0.004069, 0.027832, 0.151730, 0.350180, -0.009882, 0.006114, 0.004069, -0.027832, 0.923810, 0.000000, 0.011218, -0.003029, 0.151730, 0.350180, 0.151730, -0.350180, 0.011218, 0.003029, 0.923810, -0.000000, 0.004069, 0.027832, -0.009882, -0.006114, 0.151730, -0.350180, 0.004069, -0.027832, 0.923810, 0.000000},
{0.927613, 0.000000, 0.014253, 0.025767, -0.061171, -0.367133, 0.009258, -0.007340, 0.014253, -0.025767, 0.927613, -0.000000, -0.011138, -0.003942, -0.061171, -0.367133, -0.061171, 0.367133, -0.011138, 0.003942, 0.927613, 0.000000, 0.014253, 0.025767, 0.009258, 0.007340, -0.061171, 0.367133, 0.014253, -0.025767, 0.927613, 0.000000},
{0.869794, -0.000000, -0.010613, -0.001218, 0.399115, 0.289852, -0.004464, -0.004096, -0.010613, 0.001218, 0.869794, -0.000000, -0.005276, -0.002978, 0.399115, 0.289852, 0.399115, -0.289852, -0.005276, 0.002978, 0.869794, -0.000000, -0.010613, -0.001218, -0.004464, 0.004096, 0.399115, -0.289852, -0.010613, 0.001218, 0.869794, 0.000000},
{0.919726, -0.000000, 0.038700, -0.111146, 0.217804, 0.300925, 0.045531, -0.013659, 0.038700, 0.111146, 0.919726, 0.000000, -0.027201, 0.038983, 0.217804, 0.300925, 0.217804, -0.300925, -0.027201, -0.038983, 0.919726, 0.000000, 0.038700, -0.111146, 0.045531, 0.013659, 0.217804, -0.300925, 0.038700, 0.111146, 0.919726, 0.000000},
{0.867608, -0.000000, 0.194097, -0.112414, -0.418811, 0.095938, -0.081264, 0.075727, 0.194097, 0.112414, 0.867608, -0.000000, -0.106125, -0.032801, -0.418811, 0.095938, -0.418811, -0.095938, -0.106125, 0.032801, 0.867608, 0.000000, 0.194097, -0.112414, -0.081264, -0.075727, -0.418811, -0.095938, 0.194097, 0.112414, 0.867608, 0.000000},
};
double R21_sqrt[6][8] = {
{0.922167, 0.000000,-0.250280, 0.294903,-0.250280, -0.294903,0.922167, 0.000000},
{0.924238, 0.000000,0.151801, 0.350342,0.151801, -0.350342,0.924238, 0.000000},
{0.928080, 0.000000,-0.061202, -0.367318,-0.061202, 0.367318,0.928080, 0.000000},
{0.869860, 0.000000,0.399145, 0.289874,0.399145, -0.289874,0.869860, 0.000000},
{0.927225, 0.000000,0.219580, 0.303378,0.219580, -0.303378,0.927225, 0.000000},
{0.896133, 0.000000,-0.432581, 0.099092,-0.432581, -0.099092,0.896133, 0.000000},
{0.922167, 0.000000,-0.250280, 0.294903,-0.250280, -0.294903,0.922167, 0.000000},
{0.924238, 0.000000,0.151801, 0.350342,0.151801, -0.350342,0.924238, 0.000000},
{0.928080, 0.000000,-0.061202, -0.367318,-0.061202, 0.367318,0.928080, 0.000000},
{0.869860, 0.000000,0.399145, 0.289874,0.399145, -0.289874,0.869860, 0.000000},
{0.927225, 0.000000,0.219580, 0.303378,0.219580, -0.303378,0.927225, 0.000000},
{0.896133, 0.000000,-0.432581, 0.099092,-0.432581, -0.099092,0.896133, 0.000000},
};
double R12_sqrt[6][8] = {
{0.999494, 0.000000,0.011256, -0.029765,0.011256, 0.029765,0.999494, 0.000000},
{0.999537, 0.000000,0.004402, 0.030114,0.004402, -0.030114,0.999537, 0.000000},
{0.999497, 0.000000,0.015358, 0.027764,0.015358, -0.027764,0.999497, 0.000000},
{0.999925, -0.000000,-0.012201, -0.001400,-0.012201, 0.001400,0.999925, 0.000000},
{0.991912, 0.000000,0.041738, -0.119870,0.041738, 0.119870,0.991912, 0.000000},
{0.968169, 0.000000,0.216594, -0.125443,0.216594, 0.125443,0.968169, 0.000000},
{0.999494, 0.000000,0.011256, -0.029765,0.011256, 0.029765,0.999494, 0.000000},
{0.999537, 0.000000,0.004402, 0.030114,0.004402, -0.030114,0.999537, 0.000000},
{0.999497, 0.000000,0.015358, 0.027764,0.015358, -0.027764,0.999497, 0.000000},
{0.999925, -0.000000,-0.012201, -0.001400,-0.012201, 0.001400,0.999925, 0.000000},
{0.991912, 0.000000,0.041738, -0.119870,0.041738, 0.119870,0.991912, 0.000000},
{0.968169, 0.000000,0.216594, -0.125443,0.216594, 0.125443,0.968169, 0.000000},
};
+17 -15
View File
@@ -1,5 +1,5 @@
/*******************************************************************************
OpenAirInterface
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
@@ -14,15 +14,15 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
@@ -47,7 +47,8 @@ unsigned int s0, s1, s2, b;
*/
//
unsigned int taus(void) {
unsigned int taus(void)
{
b = (((s0 << 13) ^ s0) >> 19);
s0 = (((s0 & 0xFFFFFFFE) << 12)^ b);
@@ -58,7 +59,8 @@ unsigned int taus(void) {
return s0 ^ s1 ^ s2;
}
void set_taus_seed(unsigned int seed_init) {
void set_taus_seed(unsigned int seed_init)
{
#ifdef USER_MODE
struct drand48_data buffer;
@@ -66,11 +68,10 @@ void set_taus_seed(unsigned int seed_init) {
#endif
if (seed_init == 0) {
s0 = (unsigned int)time(NULL);
s1 = (unsigned int)time(NULL);
s2 = (unsigned int)time(NULL);
}
else {
s0 = (unsigned int)time(NULL);
s1 = (unsigned int)time(NULL);
s2 = (unsigned int)time(NULL);
} else {
#ifndef USER_MODE
s0 = (unsigned int)0x1e23d852;
s1 = (unsigned int)0x81f38a1c;
@@ -90,13 +91,14 @@ void set_taus_seed(unsigned int seed_init) {
#ifdef MAIN
main() {
main()
{
unsigned int i,rand;
set_taus_seed();
for (i=0;i<10;i++){
for (i=0; i<10; i++) {
rand = taus();
printf("%u\n",rand);
@@ -105,5 +107,5 @@ main() {
}
#endif //MAIN