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