From 255ad2441053df7fc88ad1b44a42372fc346f796 Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta <rmagueta@allbesmart.pt> Date: Wed, 2 Nov 2022 12:30:22 +0000 Subject: [PATCH] Replace gaussdouble() by gaussZiggurat() in random_channel() and add_noise() --- CMakeLists.txt | 1 - openair1/SIMULATION/TOOLS/multipath_channel.c | 4 +- openair1/SIMULATION/TOOLS/random_channel.c | 19 ++- openair1/SIMULATION/TOOLS/rangen_double.c | 71 ++++++++++++ openair1/SIMULATION/TOOLS/sim.h | 2 + radio/rfsimulator/new_channel_sim.c | 108 ------------------ radio/rfsimulator/rfsimulator.h | 2 - 7 files changed, 90 insertions(+), 117 deletions(-) delete mode 100644 radio/rfsimulator/new_channel_sim.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 8559320d514..4bb1fa6545a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2546,7 +2546,6 @@ target_link_libraries(nrscope ${XFORMS_LIBRARIES}) add_library(rfsimulator MODULE ${OPENAIR_DIR}/radio/rfsimulator/simulator.c ${OPENAIR_DIR}/radio/rfsimulator/apply_channelmod.c - ${OPENAIR_DIR}/radio/rfsimulator/new_channel_sim.c ${OPENAIR1_DIR}/PHY/TOOLS/signal_energy.c ) target_link_libraries(rfsimulator SIMU_COMMON ${ATLAS_LIBRARIES}) diff --git a/openair1/SIMULATION/TOOLS/multipath_channel.c b/openair1/SIMULATION/TOOLS/multipath_channel.c index 6adc33b6462..c1bc2689168 100644 --- a/openair1/SIMULATION/TOOLS/multipath_channel.c +++ b/openair1/SIMULATION/TOOLS/multipath_channel.c @@ -160,8 +160,8 @@ void add_noise(c16_t **rxdata, for (int i = 0; i < length; i++) { for (int ap = 0; ap < nb_antennas_rx; ap++) { c16_t *rxd = &rxdata[ap][slot_offset + i + delay]; - rxd->r = r_re[ap][i] + sqrt(sigma / 2) * gaussdouble(0.0, 1.0); // convert to fixed point - rxd->i = r_im[ap][i] + sqrt(sigma / 2) * gaussdouble(0.0, 1.0); + rxd->r = r_re[ap][i] + sqrt(sigma / 2) * gaussZiggurat(0.0, 1.0); // convert to fixed point + rxd->i = r_im[ap][i] + sqrt(sigma / 2) * gaussZiggurat(0.0, 1.0); /* Add phase noise if enabled */ if (pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) { phase_noise(ts, &rxdata[ap][slot_offset + i + delay].r, &rxdata[ap][slot_offset + i + delay].i); diff --git a/openair1/SIMULATION/TOOLS/random_channel.c b/openair1/SIMULATION/TOOLS/random_channel.c index 8f7cc8ea0e5..b11e4b7f675 100644 --- a/openair1/SIMULATION/TOOLS/random_channel.c +++ b/openair1/SIMULATION/TOOLS/random_channel.c @@ -467,8 +467,9 @@ double get_normalization_ch_factor(channel_desc_t *desc) for (int l = 0; l < (int)desc->nb_taps; l++) { for (int aarx = 0; aarx < desc->nb_rx; aarx++) { for (int aatx = 0; aatx < desc->nb_tx; aatx++) { - anew[aarx + (aatx * desc->nb_rx)].r = sqrt(desc->ricean_factor * desc->amps[l] / 2) * gaussdouble(0.0, 1.0); - anew[aarx + (aatx * desc->nb_rx)].i = sqrt(desc->ricean_factor * desc->amps[l] / 2) * gaussdouble(0.0, 1.0); + struct complexd *anewp = &anew[aarx + (aatx * desc->nb_rx)]; + anewp->r = sqrt(desc->ricean_factor * desc->amps[l] / 2) * gaussZiggurat(0.0, 1.0); + anewp->i = sqrt(desc->ricean_factor * desc->amps[l] / 2) * gaussZiggurat(0.0, 1.0); if ((l == 0) && (desc->ricean_factor != 1.0)) { anew[aarx + (aatx * desc->nb_rx)].r += sqrt((1.0 - desc->ricean_factor) / 2); anew[aarx + (aatx * desc->nb_rx)].i += sqrt((1.0 - desc->ricean_factor) / 2); @@ -527,6 +528,15 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, int32_t channel_offset, double path_loss_dB, float noise_power_dB) { + + // To create tables for normal distribution + uint64_t rand; + FILE *h = fopen("/dev/random", "r"); + if (fread(&rand, sizeof(rand), 1, h) != 1) { + LOG_W(HW, "Simulator can't read /dev/random\n"); + } + tableNor(rand); + channel_desc_t *chan_desc = (channel_desc_t *)calloc(1,sizeof(channel_desc_t)); for(int i=0; i<max_chan; i++) { @@ -1712,8 +1722,9 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) { for (aarx=0; aarx<desc->nb_rx; aarx++) { for (aatx=0; aatx<desc->nb_tx; aatx++) { - anew[aarx + (aatx * desc->nb_rx)].r = sqrt(desc->ricean_factor * desc->amps[i] / 2) * gaussdouble(0.0, 1.0) * desc->normalization_ch_factor; - anew[aarx + (aatx * desc->nb_rx)].i = sqrt(desc->ricean_factor * desc->amps[i] / 2) * gaussdouble(0.0, 1.0) * desc->normalization_ch_factor; + struct complexd *anewp = &anew[aarx + (aatx * desc->nb_rx)]; + anewp->r = sqrt(desc->ricean_factor * desc->amps[i] / 2) * gaussZiggurat(0.0, 1.0) * desc->normalization_ch_factor; + anewp->i = sqrt(desc->ricean_factor * desc->amps[i] / 2) * gaussZiggurat(0.0, 1.0) * desc->normalization_ch_factor; if ((i==0) && (desc->ricean_factor != 1.0)) { if (desc->random_aoa==1) { diff --git a/openair1/SIMULATION/TOOLS/rangen_double.c b/openair1/SIMULATION/TOOLS/rangen_double.c index 0ba9e196b13..20bd9c1ecb0 100644 --- a/openair1/SIMULATION/TOOLS/rangen_double.c +++ b/openair1/SIMULATION/TOOLS/rangen_double.c @@ -109,7 +109,78 @@ double gaussdouble(double mean, double variance) } } +// Ziggurat +static double wn[128], fn[128]; +static uint32_t iz, jz, jsr = 123456789, kn[128]; +static int32_t hz; +#define SHR3 (jz = jsr, jsr ^= (jsr << 13), jsr ^= (jsr >> 17), jsr ^= (jsr << 5), jz + jsr) +#define UNI (0.5 + (signed)SHR3 * 0.2328306e-9) + +double nfix(void) +{ + const double r = 3.442620; + static double x, y; + + for (;;) { + x = hz * wn[iz]; + + if (iz == 0) { + do { + x = -0.2904764 * log(UNI); + y = -log(UNI); + } while (y + y < x * x); + + return (hz > 0) ? r + x : -r - x; + } + + if (fn[iz] + UNI * (fn[iz - 1] - fn[iz]) < exp(-0.5 * x * x)) { + return x; + } + + hz = SHR3; + iz = hz & 127; + + if (abs(hz) < kn[iz]) { + return ((hz)*wn[iz]); + } + } +} +/*!\Procedure to create tables for normal distribution kn,wn and fn. */ +void tableNor(unsigned long seed) +{ + jsr = seed; + double dn = 3.442619855899; + int i; + const double m1 = 2147483648.0; + double q; + double tn = 3.442619855899; + const double vn = 9.91256303526217E-03; + q = vn / exp(-0.5 * dn * dn); + kn[0] = ((dn / q) * m1); + kn[1] = 0; + wn[0] = (q / m1); + wn[127] = (dn / m1); + fn[0] = 1.0; + fn[127] = (exp(-0.5 * dn * dn)); + + for (i = 126; 1 <= i; i--) { + dn = sqrt(-2.0 * log(vn / dn + exp(-0.5 * dn * dn))); + kn[i + 1] = ((dn / tn) * m1); + tn = dn; + fn[i] = (exp(-0.5 * dn * dn)); + wn[i] = (dn / m1); + } + + return; +} + +double gaussZiggurat(double mean, double variance) +{ + hz = SHR3; + iz = hz & 127; + return abs(hz) < kn[iz] ? hz * wn[iz] : nfix(); +} #ifdef MAIN main(int argc,char **argv) diff --git a/openair1/SIMULATION/TOOLS/sim.h b/openair1/SIMULATION/TOOLS/sim.h index 9b3fd98ae62..1e2602650ff 100644 --- a/openair1/SIMULATION/TOOLS/sim.h +++ b/openair1/SIMULATION/TOOLS/sim.h @@ -513,6 +513,8 @@ int gauss(unsigned int *gauss_LUT,unsigned char Nbits); double gaussdouble(double,double); void randominit(unsigned int seed_init); double uniformrandom(void); +double gaussZiggurat(double mean, double variance); +void tableNor(unsigned long seed); int freq_channel(channel_desc_t *desc,uint16_t nb_rb, int16_t n_samples,int scs); int init_freq_channel(channel_desc_t *desc,uint16_t nb_rb,int16_t n_samples,int scs); void term_freq_channel(void); diff --git a/radio/rfsimulator/new_channel_sim.c b/radio/rfsimulator/new_channel_sim.c deleted file mode 100644 index fcfa85265b2..00000000000 --- a/radio/rfsimulator/new_channel_sim.c +++ /dev/null @@ -1,108 +0,0 @@ -/* -* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The OpenAirInterface Software Alliance licenses this file to You under -* the OAI Public License, Version 1.1 (the "License"); you may not use this file -* except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.openairinterface.org/?page_id=698 -* -* Author and copyright: Laurent Thomas, open-cells.com -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*------------------------------------------------------------------------------- -* For more information about the OpenAirInterface (OAI) Software Alliance: -* contact@openairinterface.org -*/ - - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <stdbool.h> -#include <errno.h> - - -#include <common/utils/assertions.h> -#include <common/utils/LOG/log.h> -#include <common/config/config_userapi.h> -#include <openair1/SIMULATION/TOOLS/sim.h> -#include "rfsimulator.h" - -// Ziggurat -static double wn[128],fn[128]; -static uint32_t iz,jz,jsr=123456789,kn[128]; -static int32_t hz; -#define SHR3 (jz=jsr, jsr^=(jsr<<13),jsr^=(jsr>>17),jsr^=(jsr<<5),jz+jsr) -#define UNI (0.5+(signed) SHR3 * 0.2328306e-9) - -double nfix(void) { - const double r = 3.442620; - static double x, y; - - for (;;) { - x=hz * wn[iz]; - - if (iz==0) { - do { - x = - 0.2904764 * log (UNI); - y = - log (UNI); - } while (y+y < x*x); - - return (hz>0)? r+x : -r-x; - } - - if (fn[iz]+UNI*(fn[iz-1]-fn[iz])<exp(-0.5*x*x)) { - return x; - } - - hz = SHR3; - iz = hz&127; - - if (abs(hz) < kn[iz]) { - return ((hz)*wn[iz]); - } - } -} - -/*!\Procedure to create tables for normal distribution kn,wn and fn. */ - -void tableNor(unsigned long seed) { - jsr=seed; - double dn = 3.442619855899; - int i; - const double m1 = 2147483648.0; - double q; - double tn = 3.442619855899; - const double vn = 9.91256303526217E-03; - q = vn/exp(-0.5*dn*dn); - kn[0] = ((dn/q)*m1); - kn[1] = 0; - wn[0] = ( q / m1 ); - wn[127] = ( dn / m1 ); - fn[0] = 1.0; - fn[127] = ( exp ( - 0.5 * dn * dn ) ); - - for ( i = 126; 1 <= i; i-- ) { - dn = sqrt (-2.0 * log ( vn/dn + exp(-0.5*dn*dn))); - kn[i+1] = ((dn / tn)*m1); - tn = dn; - fn[i] = (exp (-0.5*dn*dn)); - wn[i] = (dn / m1); - } - - return; -} - -double gaussZiggurat(double mean, double variance) { - hz=SHR3; - iz=hz&127; - return abs(hz)<kn[iz]? hz*wn[iz] : nfix(); -} diff --git a/radio/rfsimulator/rfsimulator.h b/radio/rfsimulator/rfsimulator.h index e69d41fa6ce..068250a149f 100644 --- a/radio/rfsimulator/rfsimulator.h +++ b/radio/rfsimulator/rfsimulator.h @@ -23,8 +23,6 @@ #ifndef __RFSIMULATOR_H #define __RFSIMULATOR_H -double gaussZiggurat(double mean, double variance); -void tableNor(unsigned long seed); void rxAddInput( const c16_t *input_sig, c16_t *after_channel_sig, int rxAnt, -- GitLab