diff options
author | Johannes Demel <ufcsy@student.kit.edu> | 2015-09-25 20:24:18 +0200 |
---|---|---|
committer | Johannes Demel <ufcsy@student.kit.edu> | 2015-09-28 14:48:21 +0200 |
commit | 44ef5e1c240b7d5aeac7ca6537c4b07f3cf606c5 (patch) | |
tree | 576ba8429c5192c256dd7060d66167383a97bb23 /gnuradio-runtime | |
parent | 222e0003f9797a1b92d64855bd2b93f0d9099f93 (diff) |
random-analog: added new uniform integer distribution source
Diffstat (limited to 'gnuradio-runtime')
-rw-r--r-- | gnuradio-runtime/include/gnuradio/random.h | 16 | ||||
-rw-r--r-- | gnuradio-runtime/lib/math/random.cc | 21 | ||||
-rw-r--r-- | gnuradio-runtime/python/gnuradio/gr/qa_random.py | 37 |
3 files changed, 61 insertions, 13 deletions
diff --git a/gnuradio-runtime/include/gnuradio/random.h b/gnuradio-runtime/include/gnuradio/random.h index e95f36d1c2..c5761d7359 100644 --- a/gnuradio-runtime/include/gnuradio/random.h +++ b/gnuradio-runtime/include/gnuradio/random.h @@ -45,10 +45,12 @@ namespace gr { boost::mt19937 *d_rng; // mersenne twister as random number generator boost::uniform_real<float> *d_uniform; // choose uniform distribution, default is [0,1) + boost::random::uniform_int_distribution<> *d_integer_dis; boost::variate_generator<boost::mt19937&, boost::uniform_real<float> > *d_generator; + boost::variate_generator<boost::mt19937&, boost::random::uniform_int_distribution<> > *d_integer_generator; public: - random(unsigned int seed=0); + random(unsigned int seed=0, int min_integer = 0, int max_integer = 2); ~random(); /*! @@ -57,6 +59,18 @@ namespace gr { void reseed(unsigned int seed); /*! + * set minimum and maximum for integer random number generator. + * Limits are [minimum, maximum) + * Default: [0, std::numeric_limits< IntType >::max)] + */ + void set_integer_limits(const int minimum, const int maximum); + + /*! + * Uniform random integers in the range set by 'set_integer_limits'. + */ + int ran_int(); + + /*! * \brief Uniform random numbers in the range [0.0, 1.0) */ float ran1(); diff --git a/gnuradio-runtime/lib/math/random.cc b/gnuradio-runtime/lib/math/random.cc index a2b2621307..b35dfa106e 100644 --- a/gnuradio-runtime/lib/math/random.cc +++ b/gnuradio-runtime/lib/math/random.cc @@ -44,7 +44,7 @@ namespace gr { - random::random(unsigned int seed) + random::random(unsigned int seed, int min_integer, int max_integer) { d_gauss_stored = false; // set gasdev (gauss distributed numbers) on calculation state @@ -52,14 +52,18 @@ namespace gr { d_rng = new boost::mt19937; reseed(seed); // set seed for random number generator d_uniform = new boost::uniform_real<float>; + d_integer_dis = new boost::random::uniform_int_distribution<>(min_integer, max_integer - 1); d_generator = new boost::variate_generator<boost::mt19937&, boost::uniform_real<float> > (*d_rng,*d_uniform); // create number generator in [0,1) from boost.random + d_integer_generator = new boost::variate_generator<boost::mt19937&, boost::random::uniform_int_distribution<> >(*d_rng, *d_integer_dis); } random::~random() { delete d_rng; delete d_uniform; + delete d_integer_dis; delete d_generator; + delete d_integer_generator; } /* @@ -68,11 +72,26 @@ namespace gr { void random::reseed(unsigned int seed) { + //FIXME: method without effect after c'tor. if(seed==0) d_seed = static_cast<unsigned int>(std::time(0)); else d_seed = seed; d_rng->seed(d_seed); } + void + random::set_integer_limits(const int minimum, const int maximum){ + // boost expects integer limits defined as [minimum, maximum] which is unintuitive. + boost::random::uniform_int_distribution<>::param_type dis_params(minimum, maximum - 1); + d_integer_dis->param(dis_params); + delete d_integer_generator; + d_integer_generator = new boost::variate_generator<boost::mt19937&, boost::random::uniform_int_distribution<> >(*d_rng, *d_integer_dis); + } + + int + random::ran_int(){ + return (*d_integer_generator)(); + } + /* * Returns uniformly distributed numbers in [0,1) taken from boost.random using a Mersenne twister */ diff --git a/gnuradio-runtime/python/gnuradio/gr/qa_random.py b/gnuradio-runtime/python/gnuradio/gr/qa_random.py index 83fee56181..6e321894b9 100644 --- a/gnuradio-runtime/python/gnuradio/gr/qa_random.py +++ b/gnuradio-runtime/python/gnuradio/gr/qa_random.py @@ -23,8 +23,8 @@ from gnuradio import gr, gr_unittest import numpy as np -class test_random(gr_unittest.TestCase): +class test_random(gr_unittest.TestCase): # NOTE: For tests on the output distribution of the random numbers, see gnuradio-runtime/apps/evaluation_random_numbers.py. # Check for range [0,1) of uniform distributed random numbers @@ -42,23 +42,38 @@ class test_random(gr_unittest.TestCase): def test_2(self): num = 5 - rndm0 = gr.random(42); # init with time - rndm1 = gr.random(42); # init with fix seed + rndm0 = gr.random(42) # init with time + rndm1 = gr.random(42) # init with fix seed for k in range(num): - x = rndm0.ran1(); - y = rndm1.ran1(); - self.assertEqual(x,y) + x = rndm0.ran1() + y = rndm1.ran1() + self.assertEqual(x, y) x = np.zeros(num) y = np.zeros(num) - rndm0 = gr.random(42); # init with fix seed 1 + rndm0 = gr.random(42) # init with fix seed 1 for k in range(num): - x[k] = rndm0.ran1(); - rndm1.reseed(43); # init with fix seed 2 + x[k] = rndm0.ran1() + rndm1.reseed(43) # init with fix seed 2 for k in range(num): - y[k] = rndm0.ran1(); + y[k] = rndm0.ran1() for k in range(num): - self.assertNotEqual(x[k],y[k]) + self.assertNotEqual(x[k], y[k]) + + def test_003_integer(self): + nitems = 100000 + minimum = 2 + maximum = 42 + + rng = gr.random(1, minimum, maximum) + + rnd_vals = np.zeros(nitems, dtype=int) + for i in range(nitems): + rnd_vals[i] = rng.ran_int() + + self.assertGreaterEqual(minimum, np.min(rnd_vals)) + self.assertLess(np.max(rnd_vals), maximum) + if __name__ == '__main__': gr_unittest.run(test_random, "test_random.xml") |