Added safe and good quality random generator in phy/utils

master
Xavier Arteaga 6 years ago committed by Andre Puschmann
parent c42fbbe6a5
commit ed6b138cb2

@ -58,7 +58,7 @@ typedef struct {
cf_t* state; // Length fft_size/2
} srslte_channel_fading_t;
SRSLTE_API int srslte_channel_fading_init(srslte_channel_fading_t* q, double srate, const char* model);
SRSLTE_API int srslte_channel_fading_init(srslte_channel_fading_t* q, double srate, const char* model, uint32_t seed);
SRSLTE_API void srslte_channel_fading_free(srslte_channel_fading_t* q);

@ -0,0 +1,49 @@
/*
* Copyright 2013-2019 Software Radio Systems Limited
*
* This file is part of srsLTE.
*
* srsLTE is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* srsLTE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* A copy of the GNU Affero General Public License can be found in
* the LICENSE file in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/.
*
*/
#ifndef SRSLTE_RANDOM_H
#define SRSLTE_RANDOM_H
#include "srslte/config.h"
#include <inttypes.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef void* srslte_random_t;
SRSLTE_API srslte_random_t* srslte_random_init(uint32_t seed);
SRSLTE_API int srslte_random_uniform_int_dist(srslte_random_t* q, int min, int max);
SRSLTE_API float srslte_random_uniform_real_dist(srslte_random_t* q, float min, float max);
SRSLTE_API float srslte_random_gauss_dist(srslte_random_t* q, float std_dev);
SRSLTE_API void srslte_random_free(srslte_random_t* q);
#ifdef __cplusplus
}
#endif
#endif // SRSLTE_RANDOM_H

@ -20,6 +20,7 @@
*/
#include "srslte/phy/channel/fading.h"
#include "srslte/phy/utils/random.h"
#include "srslte/phy/utils/vector.h"
#include <complex.h>
@ -147,7 +148,7 @@ static void filter_segment(srslte_channel_fading_t* q, const cf_t* input, cf_t*
bzero(&q->state[q->N - nsamples], sizeof(cf_t) * nsamples);
}
int srslte_channel_fading_init(srslte_channel_fading_t* q, double srate, const char* model)
int srslte_channel_fading_init(srslte_channel_fading_t* q, double srate, const char* model, uint32_t seed)
{
int ret = SRSLTE_ERROR;
@ -166,12 +167,20 @@ int srslte_channel_fading_init(srslte_channel_fading_t* q, double srate, const c
round(log2(excess_tap_delay_ns[q->model][nof_taps[q->model] - 1] * 1e-9 * srate)) + 3),
64);
q->path_delay = q->N / 4;
// Initialise random number
srslte_random_t* random = srslte_random_init(seed);
// Initialise values
for (int i = 0; i < nof_taps[q->model]; i++) {
q->coeff_a[i] = (((double)rand() / (double)RAND_MAX) * (COEFF_A_MAX - COEFF_A_MIN)) + COEFF_A_MIN;
q->coeff_a[i] = srslte_random_uniform_real_dist(random, COEFF_A_MIN, COEFF_A_MAX);
q->coeff_w[i] = 2.0 * M_PI * q->doppler / q->coeff_a[i];
q->coeff_p[i] = ((double)rand() / (double)RAND_MAX) * M_PI / 2.0;
q->coeff_p[i] = srslte_random_uniform_real_dist(random, 0, (float)M_PI / 2.0f);
}
// Free random
srslte_random_free(random);
// Plan FFT
if (srslte_dft_plan_c(&q->fft, q->N, SRSLTE_DFT_FORWARD) != SRSLTE_SUCCESS) {
fprintf(stderr, "Error: planning fft\n");

@ -41,6 +41,7 @@ static char default_model[] = "epa5";
static uint32_t duration_ms = 1000;
static char* model = default_model;
static uint32_t srate = (uint32_t)30.72e6;
static uint32_t random_seed = 0x12345678; // Default seed, deterministic channel
#define INPUT_TYPE 0 /* 0: Dirac Delta; Otherwise: Random*/
@ -50,6 +51,7 @@ static void usage(char* prog)
printf("\t-m Channel model: epa5, eva70, etu300 [Default %s]\n", model);
printf("\t-t Simulation time in ms: [Default %d]\n", duration_ms);
printf("\t-s Sampling rate in Hz: [Default %d]\n", srate);
printf("\t-r Random generator seed: [Default %d]\n", random_seed);
#ifdef ENABLE_GUI
printf("\t-g Enable GUI: [Default %s]\n", enable_gui ? "enabled" : "disabled");
#endif /* ENABLE_GUI */
@ -58,7 +60,7 @@ static void usage(char* prog)
static void parse_args(int argc, char** argv)
{
int opt;
while ((opt = getopt(argc, argv, "mtsg")) != -1) {
while ((opt = getopt(argc, argv, "mtsrg")) != -1) {
switch (opt) {
case 'm':
model = argv[optind];
@ -69,6 +71,9 @@ static void parse_args(int argc, char** argv)
case 's':
srate = (uint32_t)atof(argv[optind]);
break;
case 'r':
random_seed = (uint32_t)atoi(argv[optind]);
break;
#ifdef ENABLE_GUI
case 'g':
enable_gui ^= true;
@ -146,7 +151,7 @@ int main(int argc, char** argv)
#endif /* ENABLE_GUI */
// Initialise channel
if (srslte_channel_fading_init(&channel_fading, srate, model)) {
if (srslte_channel_fading_init(&channel_fading, srate, model, 0x12345678)) {
fprintf(stderr, "Error: initialising fading channel. model=%s, srate=%d\n", model, srate);
goto clean_exit;
}

@ -18,7 +18,7 @@
# and at http://www.gnu.org/licenses/.
#
file(GLOB SOURCES "*.c")
file(GLOB SOURCES "*.c" "*.cpp")
add_library(srslte_utils OBJECT ${SOURCES})
if(VOLK_FOUND)

@ -0,0 +1,103 @@
/*
* Copyright 2013-2019 Software Radio Systems Limited
*
* This file is part of srsLTE.
*
* srsLTE is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* srsLTE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* A copy of the GNU Affero General Public License can be found in
* the LICENSE file in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/.
*
*/
#include "srslte/phy/utils/random.h"
#include <random>
class random_wrap
{
private:
std::mt19937* mt19937;
public:
explicit random_wrap(uint32_t seed) { mt19937 = new std::mt19937(seed); }
~random_wrap() { delete mt19937; }
float uniform_real_dist(float min, float max)
{
std::uniform_real_distribution<float> dist(min, max);
return dist(*mt19937);
}
int uniform_int_dist(int min, int max)
{
std::uniform_int_distribution<int> dist(min, max);
return dist(*mt19937);
}
float gauss_dist(float sigma)
{
std::normal_distribution<float> dist(sigma);
return dist(*mt19937);
}
};
extern "C" {
srslte_random_t* srslte_random_init(uint32_t seed)
{
return (srslte_random_t*)(new random_wrap(seed));
}
int srslte_random_uniform_int_dist(srslte_random_t* q, int min, int max)
{
int ret = 0;
if (q) {
auto* h = (random_wrap*)q;
ret = h->uniform_int_dist(min, max);
}
return ret;
}
float srslte_random_uniform_real_dist(srslte_random_t* q, float min, float max)
{
float ret = NAN;
if (q) {
auto* h = (random_wrap*)q;
ret = h->uniform_real_dist(min, max);
}
return ret;
}
float srslte_random_gauss_dist(srslte_random_t* q, float std_dev)
{
float ret = NAN;
if (q) {
auto* h = (random_wrap*)q;
ret = h->gauss_dist(std_dev);
}
return ret;
}
void srslte_random_free(srslte_random_t* q)
{
if (q) {
delete (random_wrap*)q;
}
}
}
Loading…
Cancel
Save