From 81588300d0530576e6180d54aba32a7d2840d5fc Mon Sep 17 00:00:00 2001 From: Marcus Müller <marcus.mueller@ettus.com> Date: Sat, 27 Jan 2018 20:10:46 +0100 Subject: added unit testing for statistical properties of fastnoise source. --- gr-analog/python/analog/qa_fastnoise.py | 64 ++++++++++++++++++++++++++------- 1 file changed, 51 insertions(+), 13 deletions(-) (limited to 'gr-analog/python/analog/qa_fastnoise.py') diff --git a/gr-analog/python/analog/qa_fastnoise.py b/gr-analog/python/analog/qa_fastnoise.py index 91e1cb87b7..605a0552ac 100644 --- a/gr-analog/python/analog/qa_fastnoise.py +++ b/gr-analog/python/analog/qa_fastnoise.py @@ -20,7 +20,8 @@ # Boston, MA 02110-1301, USA. # -from gnuradio import gr, gr_unittest, analog +from gnuradio import gr, gr_unittest, analog, blocks +import numpy class test_fastnoise_source(gr_unittest.TestCase): @@ -30,21 +31,58 @@ class test_fastnoise_source(gr_unittest.TestCase): def tearDown (self): self.tb = None - def test_001(self): - # Just confirm that we can instantiate a noise source - op = analog.fastnoise_source_f(analog.GR_GAUSSIAN, 10, 10) + def test_001_test_moments(self): + tb = self.tb - def test_002(self): - # Test get methods - set_type = analog.GR_GAUSSIAN - set_ampl = 10 - op = analog.fastnoise_source_f(set_type, set_ampl, 10) - get_type = op.type() - get_ampl = op.amplitude() + NUM = 2**22 + NUM_ITEMS = 10**6 + DEFAULTARGS = {"samples": NUM, "seed": 43, "ampl": 1} + self.uni_real_src = analog.fastnoise_source_f(type = analog.GR_UNIFORM, **DEFAULTARGS) + self.uni_cplx_src = analog.fastnoise_source_c(type = analog.GR_UNIFORM, **DEFAULTARGS) - self.assertEqual(get_type, set_type) - self.assertEqual(get_ampl, set_ampl) + self.norm_real_src = analog.fastnoise_source_f(type = analog.GR_GAUSSIAN, **DEFAULTARGS) + self.norm_cplx_src = analog.fastnoise_source_c(type = analog.GR_GAUSSIAN, **DEFAULTARGS) + self.lapl_real_src = analog.fastnoise_source_f(type = analog.GR_LAPLACIAN, **DEFAULTARGS) + + types = { + self.uni_real_src: "uniform", self.uni_cplx_src: "uniform", + self.norm_cplx_src: "norm", self.norm_cplx_src: "norm", + self.lapl_real_src: "laplace" + } + + real_srcs = [self.uni_real_src, self.norm_real_src, self.lapl_real_src] + cplx_srcs = [self.uni_cplx_src, self.norm_cplx_src] + + paths = {} + for src in real_srcs: + head = blocks.head(nitems=NUM_ITEMS, sizeof_stream_item=gr.sizeof_float) + sink = blocks.vector_sink_f() + paths[src] = (src, head, sink) + + for src in cplx_srcs: + head = blocks.head(nitems=NUM_ITEMS, sizeof_stream_item=gr.sizeof_gr_complex) + sink = blocks.vector_sink_c() + paths[src] = (src, head, sink) + for path in paths.itervalues(): + tb.connect(*path) + + tb.run() + self.data = {src: path[2].data() for src, path in paths.iteritems()} + data = self.data + # min, max + self.assertAlmostEqual(min(data[self.uni_real_src]), -1, places=4) + self.assertAlmostEqual(max(data[self.uni_real_src]), 1, places=4) + # mean, variance + data = numpy.array(data[self.uni_real_src]) + self.assertAlmostEqual(data.mean(), 0, places = 2) + self.assertAlmostEqual(data.var(), (1-(-1))**2./12, places = 3) + data = numpy.array(self.data[self.norm_real_src]) + self.assertAlmostEqual(data.mean(), 0, places=2) + self.assertAlmostEqual(data.var(), 1, places=2) + data = numpy.array(self.data[self.lapl_real_src]) + self.assertAlmostEqual(data.mean(), 0, places=2) + self.assertAlmostEqual(data.var(), 2, places=2) if __name__ == '__main__': gr_unittest.run(test_fastnoise_source, "test_fastnoise_source.xml") -- cgit v1.2.3 From 663caa10de2a1320763d503207e98e8f3944b0a4 Mon Sep 17 00:00:00 2001 From: Andrej Rode <mail@andrejro.de> Date: Thu, 15 Mar 2018 17:17:40 +0100 Subject: analog: rework qa_fastnoise, add reproducibility test --- gr-analog/python/analog/qa_fastnoise.py | 115 ++++++++++++++++++++------------ 1 file changed, 72 insertions(+), 43 deletions(-) (limited to 'gr-analog/python/analog/qa_fastnoise.py') diff --git a/gr-analog/python/analog/qa_fastnoise.py b/gr-analog/python/analog/qa_fastnoise.py index 605a0552ac..848b045b9a 100644 --- a/gr-analog/python/analog/qa_fastnoise.py +++ b/gr-analog/python/analog/qa_fastnoise.py @@ -23,67 +23,96 @@ from gnuradio import gr, gr_unittest, analog, blocks import numpy + class test_fastnoise_source(gr_unittest.TestCase): def setUp (self): - self.tb = gr.top_block () - def tearDown (self): - self.tb = None + self.num = 2**22 + self.num_items = 10**6 + self.default_args = {"samples": self.num, "seed": 43, "ampl": 1} - def test_001_test_moments(self): - tb = self.tb + def tearDown (self): + pass - NUM = 2**22 - NUM_ITEMS = 10**6 - DEFAULTARGS = {"samples": NUM, "seed": 43, "ampl": 1} - self.uni_real_src = analog.fastnoise_source_f(type = analog.GR_UNIFORM, **DEFAULTARGS) - self.uni_cplx_src = analog.fastnoise_source_c(type = analog.GR_UNIFORM, **DEFAULTARGS) + def run_test_real(self, form): + """ Run test case with float input/output + """ + tb = gr.top_block() + src = analog.fastnoise_source_f(type=form, **self.default_args) + head = blocks.head(nitems=self.num_items, sizeof_stream_item=gr.sizeof_float) + sink = blocks.vector_sink_f() + tb.connect(src, head, sink) + tb.run() + return numpy.array(sink.data()) - self.norm_real_src = analog.fastnoise_source_f(type = analog.GR_GAUSSIAN, **DEFAULTARGS) - self.norm_cplx_src = analog.fastnoise_source_c(type = analog.GR_GAUSSIAN, **DEFAULTARGS) + def run_test_complex(self, form): + """ Run test case with complex input/output + """ + tb = gr.top_block() + src = analog.fastnoise_source_c(type=form, **self.default_args) + head = blocks.head(nitems=self.num_items, sizeof_stream_item=gr.sizeof_gr_complex) + sink = blocks.vector_sink_c() + tb.connect(src, head, sink) + tb.run() + return numpy.array(sink.data()) - self.lapl_real_src = analog.fastnoise_source_f(type = analog.GR_LAPLACIAN, **DEFAULTARGS) + def test_001_real_uniform_moments(self): - types = { - self.uni_real_src: "uniform", self.uni_cplx_src: "uniform", - self.norm_cplx_src: "norm", self.norm_cplx_src: "norm", - self.lapl_real_src: "laplace" - } + data = self.run_test_real(analog.GR_UNIFORM) - real_srcs = [self.uni_real_src, self.norm_real_src, self.lapl_real_src] - cplx_srcs = [self.uni_cplx_src, self.norm_cplx_src] + self.assertAlmostEqual(min(data), -1, places=4) + self.assertAlmostEqual(max(data), 1, places=4) - paths = {} - for src in real_srcs: - head = blocks.head(nitems=NUM_ITEMS, sizeof_stream_item=gr.sizeof_float) - sink = blocks.vector_sink_f() - paths[src] = (src, head, sink) + # mean, variance + self.assertAlmostEqual(data.mean(), 0, places=2) + self.assertAlmostEqual(data.var(), (1-(-1))**2./12, places=3) - for src in cplx_srcs: - head = blocks.head(nitems=NUM_ITEMS, sizeof_stream_item=gr.sizeof_gr_complex) - sink = blocks.vector_sink_c() - paths[src] = (src, head, sink) - for path in paths.itervalues(): - tb.connect(*path) + def test_001_real_gaussian_moments(self): + data = self.run_test_real(analog.GR_GAUSSIAN) - tb.run() - self.data = {src: path[2].data() for src, path in paths.iteritems()} - data = self.data - # min, max - self.assertAlmostEqual(min(data[self.uni_real_src]), -1, places=4) - self.assertAlmostEqual(max(data[self.uni_real_src]), 1, places=4) # mean, variance - data = numpy.array(data[self.uni_real_src]) - self.assertAlmostEqual(data.mean(), 0, places = 2) - self.assertAlmostEqual(data.var(), (1-(-1))**2./12, places = 3) - data = numpy.array(self.data[self.norm_real_src]) self.assertAlmostEqual(data.mean(), 0, places=2) self.assertAlmostEqual(data.var(), 1, places=2) - data = numpy.array(self.data[self.lapl_real_src]) + + def test_001_real_laplacian_moments(self): + data = self.run_test_real(analog.GR_LAPLACIAN) + + # mean, variance self.assertAlmostEqual(data.mean(), 0, places=2) self.assertAlmostEqual(data.var(), 2, places=2) + def test_001_complex_uniform_moments(self): + data = self.run_test_complex(analog.GR_UNIFORM) + + # mean, variance + self.assertAlmostEqual(data.real.mean(), 0, places=2) + self.assertAlmostEqual(data.real.var(), 0.5*(1-(-1))**2./12, places=3) + + self.assertAlmostEqual(data.imag.mean(), 0, places=2) + self.assertAlmostEqual(data.imag.var(), 0.5*(1-(-1))**2./12, places=3) + + def test_001_complex_gaussian_moments(self): + data = self.run_test_complex(analog.GR_GAUSSIAN) + + # mean, variance + self.assertAlmostEqual(data.real.mean(), 0, places=2) + self.assertAlmostEqual(data.real.var(), 0.5, places=2) + + self.assertAlmostEqual(data.imag.mean(), 0, places=2) + self.assertAlmostEqual(data.imag.var(), 0.5, places=2) + + def test_002_reproducibility(self): + data1 = self.run_test_real(analog.GR_UNIFORM) + data2 = self.run_test_real(analog.GR_UNIFORM) + + # It's pseudoramdo thus must be equal + self.assertTrue(numpy.array_equal(data1, data2)) + + data1 = self.run_test_real(analog.GR_GAUSSIAN) + data2 = self.run_test_real(analog.GR_GAUSSIAN) + + self.assertTrue(numpy.array_equal(data1, data2)) + if __name__ == '__main__': gr_unittest.run(test_fastnoise_source, "test_fastnoise_source.xml") - -- cgit v1.2.3 From 8ca68d846ba9e07ec1c43f106ebcedfdbeb46c91 Mon Sep 17 00:00:00 2001 From: Andrej Rode <mail@andrejro.de> Date: Thu, 15 Mar 2018 17:36:31 +0100 Subject: split reproducibility into types --- gr-analog/python/analog/qa_fastnoise.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'gr-analog/python/analog/qa_fastnoise.py') diff --git a/gr-analog/python/analog/qa_fastnoise.py b/gr-analog/python/analog/qa_fastnoise.py index 848b045b9a..a7730ffcb1 100644 --- a/gr-analog/python/analog/qa_fastnoise.py +++ b/gr-analog/python/analog/qa_fastnoise.py @@ -30,7 +30,7 @@ class test_fastnoise_source(gr_unittest.TestCase): self.num = 2**22 self.num_items = 10**6 - self.default_args = {"samples": self.num, "seed": 43, "ampl": 1} + self.default_args = {"samples": self.num, "seed": int(43), "ampl": 1} def tearDown (self): pass @@ -102,13 +102,14 @@ class test_fastnoise_source(gr_unittest.TestCase): self.assertAlmostEqual(data.imag.mean(), 0, places=2) self.assertAlmostEqual(data.imag.var(), 0.5, places=2) - def test_002_reproducibility(self): + def test_002_real_uniform_reproducibility(self): data1 = self.run_test_real(analog.GR_UNIFORM) data2 = self.run_test_real(analog.GR_UNIFORM) # It's pseudoramdo thus must be equal self.assertTrue(numpy.array_equal(data1, data2)) + def test_002_real_gaussian_reproducibility(self): data1 = self.run_test_real(analog.GR_GAUSSIAN) data2 = self.run_test_real(analog.GR_GAUSSIAN) -- cgit v1.2.3 From 57a92af4e9f4b5eba42a00749b0936d06a2779b4 Mon Sep 17 00:00:00 2001 From: Andrej Rode <mail@andrejro.de> Date: Mon, 19 Mar 2018 23:32:52 +0100 Subject: analog: improve fastnoise qa --- .../include/gnuradio/analog/fastnoise_source_X.h.t | 3 +++ gr-analog/lib/fastnoise_source_X_impl.cc.t | 4 ++++ gr-analog/lib/fastnoise_source_X_impl.h.t | 1 + gr-analog/python/analog/qa_fastnoise.py | 22 +++++++++++++++++++++- 4 files changed, 29 insertions(+), 1 deletion(-) (limited to 'gr-analog/python/analog/qa_fastnoise.py') diff --git a/gr-analog/include/gnuradio/analog/fastnoise_source_X.h.t b/gr-analog/include/gnuradio/analog/fastnoise_source_X.h.t index 850633979c..f588299604 100644 --- a/gr-analog/include/gnuradio/analog/fastnoise_source_X.h.t +++ b/gr-analog/include/gnuradio/analog/fastnoise_source_X.h.t @@ -29,6 +29,8 @@ #include <gnuradio/analog/noise_type.h> #include <gnuradio/sync_block.h> +#include <vector> + namespace gr { namespace analog { @@ -62,6 +64,7 @@ namespace gr { long seed = 0, long samples=1024*16); virtual @TYPE@ sample() = 0; virtual @TYPE@ sample_unbiased() = 0; + virtual const std::vector<@TYPE@>& samples() const = 0; /*! * Set the noise type. Nominally from the diff --git a/gr-analog/lib/fastnoise_source_X_impl.cc.t b/gr-analog/lib/fastnoise_source_X_impl.cc.t index 9283f11733..72c6cb0582 100644 --- a/gr-analog/lib/fastnoise_source_X_impl.cc.t +++ b/gr-analog/lib/fastnoise_source_X_impl.cc.t @@ -163,5 +163,9 @@ namespace gr { #endif } + const std::vector<@TYPE@>& @IMPL_NAME@::samples() const + { + return d_samples; + } } /* namespace analog */ } /* namespace gr */ diff --git a/gr-analog/lib/fastnoise_source_X_impl.h.t b/gr-analog/lib/fastnoise_source_X_impl.h.t index 5bea010e62..ef0465729d 100644 --- a/gr-analog/lib/fastnoise_source_X_impl.h.t +++ b/gr-analog/lib/fastnoise_source_X_impl.h.t @@ -50,6 +50,7 @@ namespace gr { void set_type(noise_type_t type); void set_amplitude(float ampl); void generate(); + const std::vector<@TYPE@>& samples() const; noise_type_t type() const { return d_type; } float amplitude() const { return d_ampl; } diff --git a/gr-analog/python/analog/qa_fastnoise.py b/gr-analog/python/analog/qa_fastnoise.py index a7730ffcb1..f712d66ca7 100644 --- a/gr-analog/python/analog/qa_fastnoise.py +++ b/gr-analog/python/analog/qa_fastnoise.py @@ -30,7 +30,7 @@ class test_fastnoise_source(gr_unittest.TestCase): self.num = 2**22 self.num_items = 10**6 - self.default_args = {"samples": self.num, "seed": int(43), "ampl": 1} + self.default_args = {"samples": self.num, "seed": 43, "ampl": 1} def tearDown (self): pass @@ -115,5 +115,25 @@ class test_fastnoise_source(gr_unittest.TestCase): self.assertTrue(numpy.array_equal(data1, data2)) + def test_003_real_uniform_pool(self): + src = analog.fastnoise_source_f(type=analog.GR_UNIFORM, **self.default_args) + src2 = analog.fastnoise_source_f(type=analog.GR_UNIFORM, **self.default_args) + self.assertTrue(numpy.array_equal(numpy.array(src.samples()), numpy.array(src2.samples()))) + def test_003_real_gaussian_pool(self): + src = analog.fastnoise_source_f(type=analog.GR_GAUSSIAN, **self.default_args) + src2 = analog.fastnoise_source_f(type=analog.GR_GAUSSIAN, **self.default_args) + self.assertTrue(numpy.array_equal(numpy.array(src.samples()), numpy.array(src2.samples()))) + def test_003_cmplx_gaussian_pool(self): + src = analog.fastnoise_source_c(type=analog.GR_GAUSSIAN, **self.default_args) + src2 = analog.fastnoise_source_c(type=analog.GR_GAUSSIAN, **self.default_args) + self.assertTrue(numpy.array_equal(numpy.array(src.samples()), numpy.array(src2.samples()))) + def test_003_cmplx_uniform_pool(self): + src = analog.fastnoise_source_c(type=analog.GR_UNIFORM, **self.default_args) + src2 = analog.fastnoise_source_c(type=analog.GR_UNIFORM, **self.default_args) + self.assertTrue(numpy.array_equal(numpy.array(src.samples()), numpy.array(src2.samples()))) + def test_003_real_laplacian_pool(self): + src = analog.fastnoise_source_f(type=analog.GR_LAPLACIAN, **self.default_args) + src2 = analog.fastnoise_source_f(type=analog.GR_LAPLACIAN, **self.default_args) + self.assertTrue(numpy.array_equal(numpy.array(src.samples()), numpy.array(src2.samples()))) if __name__ == '__main__': gr_unittest.run(test_fastnoise_source, "test_fastnoise_source.xml") -- cgit v1.2.3