diff options
author | Stefan <stefan.wunsch@student.kit.edu> | 2015-09-04 11:22:13 +0200 |
---|---|---|
committer | Stefan <stefan.wunsch@student.kit.edu> | 2015-09-04 11:22:13 +0200 |
commit | 44fb1cb0482fa778c8e652164551711818db5476 (patch) | |
tree | 7de348490303418f1212caebca3d68ef602f1a89 | |
parent | 190ebe6caa1b92172fba691285b1bdb684e6ae83 (diff) |
redo qa_random without print statements and scipy; add stand-alone evaluation script in gnuradio-runtime/apps
-rw-r--r-- | gnuradio-runtime/apps/evaluation_random_numbers.py | 139 | ||||
-rw-r--r-- | gnuradio-runtime/python/gnuradio/gr/qa_random.py | 109 |
2 files changed, 148 insertions, 100 deletions
diff --git a/gnuradio-runtime/apps/evaluation_random_numbers.py b/gnuradio-runtime/apps/evaluation_random_numbers.py new file mode 100644 index 0000000000..069493c73e --- /dev/null +++ b/gnuradio-runtime/apps/evaluation_random_numbers.py @@ -0,0 +1,139 @@ +#!/usr/bin/env python +# +# Copyright 2015 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr +import numpy as np +from scipy.stats import norm, laplace, rayleigh +from matplotlib import pyplot as plt + +# NOTE: scipy and matplotlib are optional packages and not included in the default gnuradio dependencies + +#*** SETUP ***# + +# Number of realisations per histogram +num_tests = 1000000 + +# Set number of bins in histograms +uniform_num_bins = 31 +gauss_num_bins = 31 +rayleigh_num_bins = 31 +laplace_num_bins = 31 + +rndm = gr.random() # instance of gnuradio random class (gr::random) + +print 'All histograms contain',num_tests,'realisations.' + +#*** GENERATE DATA ***# + +uniform_values = np.zeros(num_tests) +gauss_values = np.zeros(num_tests) +rayleigh_values = np.zeros(num_tests) +laplace_values = np.zeros(num_tests) + +for k in range(num_tests): + uniform_values[k] = rndm.ran1() + gauss_values[k] = rndm.gasdev() + rayleigh_values[k] = rndm.rayleigh() + laplace_values[k] = rndm.laplacian() + +#*** HISTOGRAM DATA AND CALCULATE EXPECTED COUNTS ***# + +uniform_bins = np.linspace(0,1,uniform_num_bins) +gauss_bins = np.linspace(-8,8,gauss_num_bins) +laplace_bins = np.linspace(-8,8,laplace_num_bins) +rayleigh_bins = np.linspace(0,10,rayleigh_num_bins) + +uniform_hist = np.histogram(uniform_values,uniform_bins) +gauss_hist = np.histogram(gauss_values,gauss_bins) +rayleigh_hist = np.histogram(rayleigh_values,rayleigh_bins) +laplace_hist = np.histogram(laplace_values,laplace_bins) + +uniform_expected = np.zeros(uniform_num_bins-1) +gauss_expected = np.zeros(gauss_num_bins-1) +rayleigh_expected = np.zeros(rayleigh_num_bins-1) +laplace_expected = np.zeros(laplace_num_bins-1) + +for k in range(len(uniform_hist[0])): + uniform_expected[k] = num_tests/float(uniform_num_bins-1) + +for k in range(len(gauss_hist[0])): + gauss_expected[k] = float(norm.cdf(gauss_hist[1][k+1])-norm.cdf(gauss_hist[1][k]))*num_tests + +for k in range(len(rayleigh_hist[0])): + rayleigh_expected[k] = float(rayleigh.cdf(rayleigh_hist[1][k+1])-rayleigh.cdf(rayleigh_hist[1][k]))*num_tests + +for k in range(len(laplace_hist[0])): + laplace_expected[k] = float(laplace.cdf(laplace_hist[1][k+1])-laplace.cdf(laplace_hist[1][k]))*num_tests + +#*** PLOT HISTOGRAMS AND EXPECTATIONS TAKEN FROM SCIPY ***# + +uniform_bins_center = uniform_bins[0:-1]+(uniform_bins[1]-uniform_bins[0])/2.0 +gauss_bins_center = gauss_bins[0:-1]+(gauss_bins[1]-gauss_bins[0])/2.0 +rayleigh_bins_center = rayleigh_bins[0:-1]+(rayleigh_bins[1]-rayleigh_bins[0])/2.0 +laplace_bins_center = laplace_bins[0:-1]+(laplace_bins[1]-laplace_bins[0])/2.0 + +plt.figure(1) + +plt.subplot(2,1,1) +plt.plot(uniform_bins_center,uniform_hist[0],'s--',uniform_bins_center,uniform_expected,'o:') +plt.xlabel('Bins'), plt.ylabel('Count'), plt.title('Uniform: Distribution') +plt.legend(['histogram gr::random','calculation scipy'],loc=1) + +plt.subplot(2,1,2) +plt.plot(uniform_bins_center,uniform_hist[0]/uniform_expected,'rs--') +plt.xlabel('Bins'), plt.ylabel('Relative deviation'), plt.title('Uniform: Relative deviation to scipy') + +plt.figure(2) + +plt.subplot(2,1,1) +plt.plot(gauss_bins_center,gauss_hist[0],'s--',gauss_bins_center,gauss_expected,'o:') +plt.xlabel('Bins'), plt.ylabel('Count'), plt.title('Gauss: Distribution') +plt.legend(['histogram gr::random','calculation scipy'],loc=1) + +plt.subplot(2,1,2) +plt.plot(gauss_bins_center,gauss_hist[0]/gauss_expected,'rs--') +plt.xlabel('Bins'), plt.ylabel('Relative deviation'), plt.title('Gauss: Relative deviation to scipy') + +plt.figure(3) + +plt.subplot(2,1,1) +plt.plot(rayleigh_bins_center,rayleigh_hist[0],'s--',rayleigh_bins_center,rayleigh_expected,'o:') +plt.xlabel('Bins'), plt.ylabel('Count'), plt.title('Rayleigh: Distribution') +plt.legend(['histogram gr::random','calculation scipy'],loc=1) + + +plt.subplot(2,1,2) +plt.plot(rayleigh_bins_center,rayleigh_hist[0]/rayleigh_expected,'rs--') +plt.xlabel('Bins'), plt.ylabel('Relative deviation'), plt.title('Rayleigh: Relative deviation to scipy') + +plt.figure(4) + +plt.subplot(2,1,1) +plt.plot(laplace_bins_center,laplace_hist[0],'s--',laplace_bins_center,laplace_expected,'o:') +plt.xlabel('Bins'), plt.ylabel('Count'), plt.title('Laplace: Distribution') +plt.legend(['histogram gr::random','calculation scipy'],loc=1) + +plt.subplot(2,1,2) +plt.plot(laplace_bins_center,laplace_hist[0]/laplace_expected,'rs--') +plt.xlabel('Bins'), plt.ylabel('Relative deviation'), plt.title('Laplace: Relative deviation to scipy') + +plt.show() diff --git a/gnuradio-runtime/python/gnuradio/gr/qa_random.py b/gnuradio-runtime/python/gnuradio/gr/qa_random.py index c0d9a7f34c..83fee56181 100644 --- a/gnuradio-runtime/python/gnuradio/gr/qa_random.py +++ b/gnuradio-runtime/python/gnuradio/gr/qa_random.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2006,2007,2010 Free Software Foundation, Inc. +# Copyright 2006,2007,2010,2015 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -22,133 +22,42 @@ from gnuradio import gr, gr_unittest import numpy as np -from scipy.stats import norm, laplace, rayleigh -#from time import sleep class test_random(gr_unittest.TestCase): - num_tests = 10000 + # NOTE: For tests on the output distribution of the random numbers, see gnuradio-runtime/apps/evaluation_random_numbers.py. - # Disclaimer - def test_0(self): - print 'NOTE: Following tests are not statistically significant!' - print 'Realisations per test:',self.num_tests - self.assertEqual(1,1) - - # Check for range [0,1) of uniform distributed random numbers and print minimal and maximal value + # Check for range [0,1) of uniform distributed random numbers def test_1(self): - print '# TEST 1' - print 'Uniform distributed numbers: Range' - values = np.zeros(self.num_tests) + num_tests = 10000 + values = np.zeros(num_tests) rndm = gr.random() - for k in range(self.num_tests): + for k in range(num_tests): values[k] = rndm.ran1() for value in values: self.assertLess(value, 1) self.assertGreaterEqual(value, 0) - print 'Uniform random numbers (num/min/max):', self.num_tests, min(values), max(values) - # Check uniformly distributed random numbers on uniformity (without assert, only printing) + # Check reseed method (init with time and seed as fix number) def test_2(self): - print '# TEST 2' - print 'Uniform random numbers: Distribution' - num_bins = 11 - values = np.zeros(self.num_tests) - rndm = gr.random() - for k in range(self.num_tests): - values[k] = rndm.ran1() - bins = np.linspace(0,1,num_bins) # These are the bin edges! - hist = np.histogram(values,bins) - print 'Lower edge bin / upper edge bin / count / expected' - for k in range(len(hist[0])): - print hist[1][k], hist[1][k+1], hist[0][k], float(self.num_tests)/(num_bins-1) - - # Check distribution of normally (gaussian, mean=0, variance=1) distributed random numbers (no assert) - def test_3(self): - print '# TEST 3' - print 'Normal random numbers: Distribution' - num_bins = 11 - hist_range = [-5,5] - values = np.zeros(self.num_tests) - rndm = gr.random() - for k in range(self.num_tests): - values[k] = rndm.gasdev() - bins = np.linspace(hist_range[0],hist_range[1],num_bins) - hist = np.histogram(values,bins) - print 'Lower edge bin / upper edge bin / count / expected' - for k in range(len(hist[0])): - print hist[1][k], hist[1][k+1], hist[0][k], float(norm.cdf(hist[1][k+1])-norm.cdf(hist[1][k]))*self.num_tests - - # Check distribution of laplacian (mean=0, variance=1) distributed random numbers (no assert) - def test_4(self): - print '# TEST 4' - print 'Laplacian random numbers: Distribution' - num_bins = 11 - hist_range = [-5,5] - values = np.zeros(self.num_tests) - rndm = gr.random() - for k in range(self.num_tests): - values[k] = rndm.laplacian() - bins = np.linspace(hist_range[0],hist_range[1],num_bins) - hist = np.histogram(values,bins) - print 'Lower edge bin / upper edge bin / count / expected' - for k in range(len(hist[0])): - print hist[1][k], hist[1][k+1], hist[0][k], float(laplace.cdf(hist[1][k+1])-laplace.cdf(hist[1][k]))*self.num_tests - - # Check distribution of laplacian (mean=0, variance=1) distributed random numbers (no assert) - def test_5(self): - print '# TEST 5' - print 'Rayleigh random numbers: Distribution' - num_bins = 11 - hist_range = [0,10] - values = np.zeros(self.num_tests) - rndm = gr.random() - for k in range(self.num_tests): - values[k] = rndm.rayleigh() - bins = np.linspace(hist_range[0],hist_range[1],num_bins) - hist = np.histogram(values,bins) - print 'Lower edge bin / upper edge bin / count / expected' - for k in range(len(hist[0])): - print hist[1][k], hist[1][k+1], hist[0][k], float(rayleigh.cdf(hist[1][k+1])-rayleigh.cdf(hist[1][k]))*self.num_tests - - # Check seeds (init with time and seed as fix number) - def test_6(self): - print '# TEST 6' num = 5 - print 'Some random numbers in [0,1), should change every run:' - rndm0 = gr.random(0); # init with time - # NOTE: the sleep increases the executiont time massively, remove assert for convenience - #sleep(1) - #rndm1 = gr.random(0); # init with fix seed - for k in range(num): - x = rndm0.ran1(); - print x, - # y = rndm1.ran1(); - # print x, '!=', y - # self.assertNotEqual(x,y) - print ' ' - - print 'Some random numbers in [0,1) (seed two instances), should be the same every run:' 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(); - print x, '=', y self.assertEqual(x,y) - print 'Some random numbers in [0,1) (reseed one instance), should be the same every run:' x = np.zeros(num) y = np.zeros(num) - rndm0 = gr.random(42); # init with time + 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 + rndm1.reseed(43); # init with fix seed 2 for k in range(num): y[k] = rndm0.ran1(); for k in range(num): - print x[k], '!=', y[k] self.assertNotEqual(x[k],y[k]) if __name__ == '__main__': |