summaryrefslogtreecommitdiff
path: root/gr-digital/python/digital/test_soft_decisions.py
diff options
context:
space:
mode:
authorTom Rondeau <tom@trondeau.com>2013-09-04 15:44:20 -0400
committerTom Rondeau <tom@trondeau.com>2013-09-04 15:44:20 -0400
commit02fd90029a1ec465f7c8da4a0d97dcdb8b3f438f (patch)
tree9bc144a9cb5b0e877108302d13181e50bd885528 /gr-digital/python/digital/test_soft_decisions.py
parentedf2ac24c9c2f723eb80918de7addf6d299958c2 (diff)
digital: Python functions to support soft decision making and look-up table generation.
Diffstat (limited to 'gr-digital/python/digital/test_soft_decisions.py')
-rwxr-xr-xgr-digital/python/digital/test_soft_decisions.py135
1 files changed, 135 insertions, 0 deletions
diff --git a/gr-digital/python/digital/test_soft_decisions.py b/gr-digital/python/digital/test_soft_decisions.py
new file mode 100755
index 0000000000..78714100b7
--- /dev/null
+++ b/gr-digital/python/digital/test_soft_decisions.py
@@ -0,0 +1,135 @@
+#!/usr/bin/env python
+#
+# Copyright 2013 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.
+#
+
+import numpy, pylab, sys
+from gnuradio import digital
+from soft_dec_lut_gen import *
+from psk_constellations import *
+from qam_constellations import *
+
+def test_qpsk(i, sample, prec):
+ qpsk_const_list = [psk_4_0, psk_4_1, psk_4_2, psk_4_3,
+ psk_4_4, psk_4_5, psk_4_6, psk_4_7]
+ qpsk_lut_gen_list = [sd_psk_4_0, sd_psk_4_1, sd_psk_4_2, sd_psk_4_3,
+ sd_psk_4_4, sd_psk_4_5, sd_psk_4_6, sd_psk_4_7]
+
+ constel, code = qpsk_const_list[i]()
+ qpsk_lut_gen = qpsk_lut_gen_list[i]
+
+ rot_sym = 1
+ side = 2
+ width = 2
+ c = digital.constellation_rect(constel, code, rot_sym,
+ side, side, width, width)
+
+ # Get max energy/symbol in constellation
+ constel = c.points()
+ Es = max([numpy.sqrt(constel_i.real**2 + constel_i.imag**2) for constel_i in constel])
+
+ #table = soft_dec_table_generator(qpsk_lut_gen, prec, Es)
+ table = soft_dec_table(constel, code, prec)
+
+ c.gen_soft_dec_lut(prec)
+ #c.set_soft_dec_lut(table, prec)
+
+ y_python_gen_calc = qpsk_lut_gen(sample, Es)
+ y_python_table = calc_soft_dec_from_table(sample, table, prec, Es)
+ y_python_raw_calc = calc_soft_dec(sample, constel, code)
+ y_cpp_table = c.soft_decision_maker(sample)
+ y_cpp_raw_calc = c.calc_soft_dec(sample)
+
+ return (y_python_gen_calc, y_python_table, y_python_raw_calc,
+ y_cpp_table, y_cpp_raw_calc, constel, code, c)
+
+def test_qam16(i, sample, prec):
+ sample = sample/1
+ qam_const_list = [qam_16_0, ]
+ qam_lut_gen_list = [sd_qam_16_0, ]
+
+ constel, code = qam_const_list[i]()
+ qam_lut_gen = qam_lut_gen_list[i]
+
+ rot_sym = 4
+ side = 2
+ width = 2
+ c = digital.constellation_rect(constel, code, rot_sym,
+ side, side, width, width)
+
+ # Get max energy/symbol in constellation
+ constel = c.points()
+ Es = max([abs(constel_i) for constel_i in constel])
+
+ #table = soft_dec_table_generator(qam_lut_gen, prec, Es)
+ table = soft_dec_table(constel, code, prec, 1)
+
+ #c.gen_soft_dec_lut(prec)
+ c.set_soft_dec_lut(table, prec)
+
+ y_python_gen_calc = qam_lut_gen(sample, Es)
+ y_python_table = calc_soft_dec_from_table(sample, table, prec, Es)
+ y_python_raw_calc = calc_soft_dec(sample, constel, code, 1)
+ y_cpp_table = c.soft_decision_maker(sample)
+ y_cpp_raw_calc = c.calc_soft_dec(sample)
+
+ return (y_python_gen_calc, y_python_table, y_python_raw_calc,
+ y_cpp_table, y_cpp_raw_calc, constel, code, c)
+
+if __name__ == "__main__":
+
+ index = 0
+ prec = 8
+
+ x_re = 2*numpy.random.random()-1
+ x_im = 2*numpy.random.random()-1
+ x = x_re + x_im*1j
+ #x = -1 + -0.j
+
+ if 1:
+ y_python_gen_calc, y_python_table, y_python_raw_calc, \
+ y_cpp_table, y_cpp_raw_calc, constel, code, c \
+ = test_qpsk(index, x, prec)
+ else:
+ y_python_gen_calc, y_python_table, y_python_raw_calc, \
+ y_cpp_table, y_cpp_raw_calc, constel, code, c \
+ = test_qam16(index, x, prec)
+
+ k = numpy.log2(len(constel))
+
+ print "Sample: ", x
+ print "Python Generator Calculated: ", (y_python_gen_calc)
+ print "Python Generator Table: ", (y_python_table)
+ print "Python Raw calc: ", (y_python_raw_calc)
+ print "C++ Table calc: ", (y_cpp_table)
+ print "C++ Raw calc: ", (y_cpp_raw_calc)
+
+ fig = pylab.figure(1)
+ sp1 = fig.add_subplot(1,1,1)
+ sp1.plot([c.real for c in constel],
+ [c.imag for c in constel], 'bo')
+ sp1.plot(x.real, x.imag, 'ro')
+ sp1.set_xlim([-1.5, 1.5])
+ sp1.set_ylim([-1.5, 1.5])
+ fill = int(numpy.log2(len(constel)))
+ for i,c in enumerate(constel):
+ sp1.text(1.2*c.real, 1.2*c.imag, bin(code[i])[2:].zfill(fill),
+ ha='center', va='center', size=18)
+ pylab.show()