diff options
author | Johnathan Corgan <johnathan@corganlabs.com> | 2015-12-07 16:15:31 -0800 |
---|---|---|
committer | Johnathan Corgan <johnathan@corganlabs.com> | 2015-12-07 16:15:31 -0800 |
commit | 422271f1e025bd1835e4a7ee68e2a60e23167b45 (patch) | |
tree | f49812df4a01de3d40af40e80ee9b6d62db6064c | |
parent | a96c1dd97ecb6ca9a40522d297df27bbdeca5d7f (diff) | |
parent | 9ac7203fffb37fd456b82b737a71d4c7a1607b06 (diff) |
Merge remote-tracking branch 'jdemel/polar-systematic'
21 files changed, 926 insertions, 577 deletions
diff --git a/gr-fec/examples/tpc_ber_curve_gen.py b/gr-fec/examples/tpc_ber_curve_gen.py deleted file mode 100755 index 004f9f8988..0000000000 --- a/gr-fec/examples/tpc_ber_curve_gen.py +++ /dev/null @@ -1,457 +0,0 @@ -#!/usr/bin/env python2 -################################################## -# GNU Radio Python Flow Graph -# Title: Tpc Ber Curve Gen -# Generated: Thu Jul 23 09:27:33 2015 -################################################## - -if __name__ == '__main__': - import ctypes - import sys - if sys.platform.startswith('linux'): - try: - x11 = ctypes.cdll.LoadLibrary('libX11.so') - x11.XInitThreads() - except: - print "Warning: failed to XInitThreads()" - -from PyQt4 import Qt -from gnuradio import eng_notation -from gnuradio import fec -from gnuradio import gr -from gnuradio import qtgui -from gnuradio.eng_option import eng_option -from gnuradio.filter import firdes -from optparse import OptionParser -import numpy -import sip -import sys - -from distutils.version import StrictVersion -class tpc_ber_curve_gen(gr.top_block, Qt.QWidget): - - def __init__(self): - gr.top_block.__init__(self, "Tpc Ber Curve Gen") - Qt.QWidget.__init__(self) - self.setWindowTitle("Tpc Ber Curve Gen") - try: - self.setWindowIcon(Qt.QIcon.fromTheme('gnuradio-grc')) - except: - pass - self.top_scroll_layout = Qt.QVBoxLayout() - self.setLayout(self.top_scroll_layout) - self.top_scroll = Qt.QScrollArea() - self.top_scroll.setFrameStyle(Qt.QFrame.NoFrame) - self.top_scroll_layout.addWidget(self.top_scroll) - self.top_scroll.setWidgetResizable(True) - self.top_widget = Qt.QWidget() - self.top_scroll.setWidget(self.top_widget) - self.top_layout = Qt.QVBoxLayout(self.top_widget) - self.top_grid_layout = Qt.QGridLayout() - self.top_layout.addLayout(self.top_grid_layout) - - self.settings = Qt.QSettings("GNU Radio", "tpc_ber_curve_gen") - self.restoreGeometry(self.settings.value("geometry").toByteArray()) - - - ################################################## - # Variables - ################################################## - self.esno_0 = esno_0 = numpy.arange(0, 8, .5) - self.samp_rate_0 = samp_rate_0 = 35000000 - self.rate = rate = 2 - self.polys = polys = [79, 109] - self.k = k = 7 - self.framebits = framebits = 4096 - - self.enc_tpc_4 = enc_tpc_4 = map( (lambda b: map( ( lambda a: fec.tpc_encoder_make(([3]), ([43]), 26, 6, 9, 3)), range(0,1) ) ), range(0,len(esno_0))); - - self.enc_tpc_3 = enc_tpc_3 = map( (lambda b: map( ( lambda a: fec.tpc_encoder_make(([3]), ([43]), 26, 6, 9, 3)), range(0,1) ) ), range(0,len(esno_0))); - - self.enc_tpc_2 = enc_tpc_2 = map( (lambda b: map( ( lambda a: fec.tpc_encoder_make(([3]), ([43]), 26, 6, 9, 3)), range(0,1) ) ), range(0,len(esno_0))); - - self.enc_tpc_1 = enc_tpc_1 = map( (lambda b: map( ( lambda a: fec.tpc_encoder_make(([3]), ([43]), 26, 6, 9, 3)), range(0,1) ) ), range(0,len(esno_0))); - - self.enc_tpc_0 = enc_tpc_0 = map( (lambda b: map( ( lambda a: fec.tpc_encoder_make(([3]), ([43]), 26, 6, 9, 3)), range(0,1) ) ), range(0,len(esno_0))); - - self.dec_tpc_4 = dec_tpc_4 = map( (lambda b: map( ( lambda a: fec.tpc_decoder_make(([3]), ([43]), 26, 6, 9, 3, 6, 4)), range(0,1) ) ), range(0,len(esno_0))); - - self.dec_tpc_3 = dec_tpc_3 = map( (lambda b: map( ( lambda a: fec.tpc_decoder_make(([3]), ([43]), 26, 6, 9, 3, 6, 3)), range(0,1) ) ), range(0,len(esno_0))); - - self.dec_tpc_2 = dec_tpc_2 = map( (lambda b: map( ( lambda a: fec.tpc_decoder_make(([3]), ([43]), 26, 6, 9, 3, 6, 2)), range(0,1) ) ), range(0,len(esno_0))); - - self.dec_tpc_1 = dec_tpc_1 = map( (lambda b: map( ( lambda a: fec.tpc_decoder_make(([3]), ([43]), 26, 6, 9, 3, 6, 1)), range(0,1) ) ), range(0,len(esno_0))); - - self.dec_tpc_0 = dec_tpc_0 = map( (lambda b: map( ( lambda a: fec.tpc_decoder_make(([3]), ([43]), 26, 6, 9, 3, 6, 0)), range(0,1) ) ), range(0,len(esno_0))); - - ################################################## - # Blocks - ################################################## - self.qtgui_bercurve_sink_0 = qtgui.ber_sink_b( - esno_0, #range of esnos - 5, #number of curves - 1000, #ensure at least - -10, #cutoff - [], #indiv. curve names - ) - self.qtgui_bercurve_sink_0.set_update_time(0.10) - self.qtgui_bercurve_sink_0.set_y_axis(-10, 0) - self.qtgui_bercurve_sink_0.set_x_axis(esno_0[0], esno_0[-1]) - - labels = ["Linear LOG-MAP", "MAX LOG-MAP", "Constant LOG-MAP", "LOG-MAP (LUT)", "LOG-MAP (C Correction)", - "", "", "", "", ""] - widths = [2, 2, 2, 2, 2, - 1, 1, 1, 1, 1] - colors = ["blue", "red", "magenta", "dark red", "Dark Blue", - "red", "red", "red", "red", "red"] - styles = [1, 2, 5, 5, 4, - 0, 0, 0, 0, 0] - markers = [0, 1, 0, 0, 0, - 0, 0, 0, 0, 0] - alphas = [1, 1, 1, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0] - for i in xrange(5): - if len(labels[i]) == 0: - self.qtgui_bercurve_sink_0.set_line_label(i, "Data {0}".format(i)) - else: - self.qtgui_bercurve_sink_0.set_line_label(i, labels[i]) - self.qtgui_bercurve_sink_0.set_line_width(i, widths[i]) - self.qtgui_bercurve_sink_0.set_line_color(i, colors[i]) - self.qtgui_bercurve_sink_0.set_line_style(i, styles[i]) - self.qtgui_bercurve_sink_0.set_line_marker(i, markers[i]) - self.qtgui_bercurve_sink_0.set_line_alpha(i, alphas[i]) - - self._qtgui_bercurve_sink_0_win = sip.wrapinstance(self.qtgui_bercurve_sink_0.pyqwidget(), Qt.QWidget) - self.top_layout.addWidget(self._qtgui_bercurve_sink_0_win) - self.fec_bercurve_generator_0_1_0 = fec.bercurve_generator( - enc_tpc_4, #size - dec_tpc_4, #name - esno_0, #range of esnos - samp_rate_0, #throttle - "capillary", #threading mode - '11', #puncture pattern - -100 # noise gen. seed - ) - - self.fec_bercurve_generator_0_1 = fec.bercurve_generator( - enc_tpc_3, #size - dec_tpc_3, #name - esno_0, #range of esnos - samp_rate_0, #throttle - "capillary", #threading mode - '11', #puncture pattern - -100 # noise gen. seed - ) - - self.fec_bercurve_generator_0_0_0 = fec.bercurve_generator( - enc_tpc_0, #size - dec_tpc_0, #name - esno_0, #range of esnos - samp_rate_0, #throttle - "capillary", #threading mode - '11', #puncture pattern - -100 # noise gen. seed - ) - - self.fec_bercurve_generator_0_0 = fec.bercurve_generator( - enc_tpc_1, #size - dec_tpc_1, #name - esno_0, #range of esnos - samp_rate_0, #throttle - "capillary", #threading mode - '11', #puncture pattern - -100 # noise gen. seed - ) - - self.fec_bercurve_generator_0 = fec.bercurve_generator( - enc_tpc_2, #size - dec_tpc_2, #name - esno_0, #range of esnos - samp_rate_0, #throttle - "capillary", #threading mode - '11', #puncture pattern - -100 # noise gen. seed - ) - - - ################################################## - # Connections - ################################################## - self.connect((self.fec_bercurve_generator_0, 0), (self.qtgui_bercurve_sink_0, 64)) - self.connect((self.fec_bercurve_generator_0, 1), (self.qtgui_bercurve_sink_0, 65)) - self.connect((self.fec_bercurve_generator_0, 2), (self.qtgui_bercurve_sink_0, 66)) - self.connect((self.fec_bercurve_generator_0, 3), (self.qtgui_bercurve_sink_0, 67)) - self.connect((self.fec_bercurve_generator_0, 4), (self.qtgui_bercurve_sink_0, 68)) - self.connect((self.fec_bercurve_generator_0, 5), (self.qtgui_bercurve_sink_0, 69)) - self.connect((self.fec_bercurve_generator_0, 6), (self.qtgui_bercurve_sink_0, 70)) - self.connect((self.fec_bercurve_generator_0, 7), (self.qtgui_bercurve_sink_0, 71)) - self.connect((self.fec_bercurve_generator_0, 8), (self.qtgui_bercurve_sink_0, 72)) - self.connect((self.fec_bercurve_generator_0, 9), (self.qtgui_bercurve_sink_0, 73)) - self.connect((self.fec_bercurve_generator_0, 10), (self.qtgui_bercurve_sink_0, 74)) - self.connect((self.fec_bercurve_generator_0, 11), (self.qtgui_bercurve_sink_0, 75)) - self.connect((self.fec_bercurve_generator_0, 12), (self.qtgui_bercurve_sink_0, 76)) - self.connect((self.fec_bercurve_generator_0, 13), (self.qtgui_bercurve_sink_0, 77)) - self.connect((self.fec_bercurve_generator_0, 14), (self.qtgui_bercurve_sink_0, 78)) - self.connect((self.fec_bercurve_generator_0, 15), (self.qtgui_bercurve_sink_0, 79)) - self.connect((self.fec_bercurve_generator_0, 16), (self.qtgui_bercurve_sink_0, 80)) - self.connect((self.fec_bercurve_generator_0, 17), (self.qtgui_bercurve_sink_0, 81)) - self.connect((self.fec_bercurve_generator_0, 18), (self.qtgui_bercurve_sink_0, 82)) - self.connect((self.fec_bercurve_generator_0, 19), (self.qtgui_bercurve_sink_0, 83)) - self.connect((self.fec_bercurve_generator_0, 20), (self.qtgui_bercurve_sink_0, 84)) - self.connect((self.fec_bercurve_generator_0, 21), (self.qtgui_bercurve_sink_0, 85)) - self.connect((self.fec_bercurve_generator_0, 22), (self.qtgui_bercurve_sink_0, 86)) - self.connect((self.fec_bercurve_generator_0, 23), (self.qtgui_bercurve_sink_0, 87)) - self.connect((self.fec_bercurve_generator_0, 24), (self.qtgui_bercurve_sink_0, 88)) - self.connect((self.fec_bercurve_generator_0, 25), (self.qtgui_bercurve_sink_0, 89)) - self.connect((self.fec_bercurve_generator_0, 26), (self.qtgui_bercurve_sink_0, 90)) - self.connect((self.fec_bercurve_generator_0, 27), (self.qtgui_bercurve_sink_0, 91)) - self.connect((self.fec_bercurve_generator_0, 28), (self.qtgui_bercurve_sink_0, 92)) - self.connect((self.fec_bercurve_generator_0, 29), (self.qtgui_bercurve_sink_0, 93)) - self.connect((self.fec_bercurve_generator_0, 30), (self.qtgui_bercurve_sink_0, 94)) - self.connect((self.fec_bercurve_generator_0, 31), (self.qtgui_bercurve_sink_0, 95)) - self.connect((self.fec_bercurve_generator_0_0, 0), (self.qtgui_bercurve_sink_0, 32)) - self.connect((self.fec_bercurve_generator_0_0, 1), (self.qtgui_bercurve_sink_0, 33)) - self.connect((self.fec_bercurve_generator_0_0, 2), (self.qtgui_bercurve_sink_0, 34)) - self.connect((self.fec_bercurve_generator_0_0, 3), (self.qtgui_bercurve_sink_0, 35)) - self.connect((self.fec_bercurve_generator_0_0, 4), (self.qtgui_bercurve_sink_0, 36)) - self.connect((self.fec_bercurve_generator_0_0, 5), (self.qtgui_bercurve_sink_0, 37)) - self.connect((self.fec_bercurve_generator_0_0, 6), (self.qtgui_bercurve_sink_0, 38)) - self.connect((self.fec_bercurve_generator_0_0, 7), (self.qtgui_bercurve_sink_0, 39)) - self.connect((self.fec_bercurve_generator_0_0, 8), (self.qtgui_bercurve_sink_0, 40)) - self.connect((self.fec_bercurve_generator_0_0, 9), (self.qtgui_bercurve_sink_0, 41)) - self.connect((self.fec_bercurve_generator_0_0, 10), (self.qtgui_bercurve_sink_0, 42)) - self.connect((self.fec_bercurve_generator_0_0, 11), (self.qtgui_bercurve_sink_0, 43)) - self.connect((self.fec_bercurve_generator_0_0, 12), (self.qtgui_bercurve_sink_0, 44)) - self.connect((self.fec_bercurve_generator_0_0, 13), (self.qtgui_bercurve_sink_0, 45)) - self.connect((self.fec_bercurve_generator_0_0, 14), (self.qtgui_bercurve_sink_0, 46)) - self.connect((self.fec_bercurve_generator_0_0, 15), (self.qtgui_bercurve_sink_0, 47)) - self.connect((self.fec_bercurve_generator_0_0, 16), (self.qtgui_bercurve_sink_0, 48)) - self.connect((self.fec_bercurve_generator_0_0, 17), (self.qtgui_bercurve_sink_0, 49)) - self.connect((self.fec_bercurve_generator_0_0, 18), (self.qtgui_bercurve_sink_0, 50)) - self.connect((self.fec_bercurve_generator_0_0, 19), (self.qtgui_bercurve_sink_0, 51)) - self.connect((self.fec_bercurve_generator_0_0, 20), (self.qtgui_bercurve_sink_0, 52)) - self.connect((self.fec_bercurve_generator_0_0, 21), (self.qtgui_bercurve_sink_0, 53)) - self.connect((self.fec_bercurve_generator_0_0, 22), (self.qtgui_bercurve_sink_0, 54)) - self.connect((self.fec_bercurve_generator_0_0, 23), (self.qtgui_bercurve_sink_0, 55)) - self.connect((self.fec_bercurve_generator_0_0, 24), (self.qtgui_bercurve_sink_0, 56)) - self.connect((self.fec_bercurve_generator_0_0, 25), (self.qtgui_bercurve_sink_0, 57)) - self.connect((self.fec_bercurve_generator_0_0, 26), (self.qtgui_bercurve_sink_0, 58)) - self.connect((self.fec_bercurve_generator_0_0, 27), (self.qtgui_bercurve_sink_0, 59)) - self.connect((self.fec_bercurve_generator_0_0, 28), (self.qtgui_bercurve_sink_0, 60)) - self.connect((self.fec_bercurve_generator_0_0, 29), (self.qtgui_bercurve_sink_0, 61)) - self.connect((self.fec_bercurve_generator_0_0, 30), (self.qtgui_bercurve_sink_0, 62)) - self.connect((self.fec_bercurve_generator_0_0, 31), (self.qtgui_bercurve_sink_0, 63)) - self.connect((self.fec_bercurve_generator_0_0_0, 0), (self.qtgui_bercurve_sink_0, 0)) - self.connect((self.fec_bercurve_generator_0_0_0, 1), (self.qtgui_bercurve_sink_0, 1)) - self.connect((self.fec_bercurve_generator_0_0_0, 2), (self.qtgui_bercurve_sink_0, 2)) - self.connect((self.fec_bercurve_generator_0_0_0, 3), (self.qtgui_bercurve_sink_0, 3)) - self.connect((self.fec_bercurve_generator_0_0_0, 4), (self.qtgui_bercurve_sink_0, 4)) - self.connect((self.fec_bercurve_generator_0_0_0, 5), (self.qtgui_bercurve_sink_0, 5)) - self.connect((self.fec_bercurve_generator_0_0_0, 6), (self.qtgui_bercurve_sink_0, 6)) - self.connect((self.fec_bercurve_generator_0_0_0, 7), (self.qtgui_bercurve_sink_0, 7)) - self.connect((self.fec_bercurve_generator_0_0_0, 8), (self.qtgui_bercurve_sink_0, 8)) - self.connect((self.fec_bercurve_generator_0_0_0, 9), (self.qtgui_bercurve_sink_0, 9)) - self.connect((self.fec_bercurve_generator_0_0_0, 10), (self.qtgui_bercurve_sink_0, 10)) - self.connect((self.fec_bercurve_generator_0_0_0, 11), (self.qtgui_bercurve_sink_0, 11)) - self.connect((self.fec_bercurve_generator_0_0_0, 12), (self.qtgui_bercurve_sink_0, 12)) - self.connect((self.fec_bercurve_generator_0_0_0, 13), (self.qtgui_bercurve_sink_0, 13)) - self.connect((self.fec_bercurve_generator_0_0_0, 14), (self.qtgui_bercurve_sink_0, 14)) - self.connect((self.fec_bercurve_generator_0_0_0, 15), (self.qtgui_bercurve_sink_0, 15)) - self.connect((self.fec_bercurve_generator_0_0_0, 16), (self.qtgui_bercurve_sink_0, 16)) - self.connect((self.fec_bercurve_generator_0_0_0, 17), (self.qtgui_bercurve_sink_0, 17)) - self.connect((self.fec_bercurve_generator_0_0_0, 18), (self.qtgui_bercurve_sink_0, 18)) - self.connect((self.fec_bercurve_generator_0_0_0, 19), (self.qtgui_bercurve_sink_0, 19)) - self.connect((self.fec_bercurve_generator_0_0_0, 20), (self.qtgui_bercurve_sink_0, 20)) - self.connect((self.fec_bercurve_generator_0_0_0, 21), (self.qtgui_bercurve_sink_0, 21)) - self.connect((self.fec_bercurve_generator_0_0_0, 22), (self.qtgui_bercurve_sink_0, 22)) - self.connect((self.fec_bercurve_generator_0_0_0, 23), (self.qtgui_bercurve_sink_0, 23)) - self.connect((self.fec_bercurve_generator_0_0_0, 24), (self.qtgui_bercurve_sink_0, 24)) - self.connect((self.fec_bercurve_generator_0_0_0, 25), (self.qtgui_bercurve_sink_0, 25)) - self.connect((self.fec_bercurve_generator_0_0_0, 26), (self.qtgui_bercurve_sink_0, 26)) - self.connect((self.fec_bercurve_generator_0_0_0, 27), (self.qtgui_bercurve_sink_0, 27)) - self.connect((self.fec_bercurve_generator_0_0_0, 28), (self.qtgui_bercurve_sink_0, 28)) - self.connect((self.fec_bercurve_generator_0_0_0, 29), (self.qtgui_bercurve_sink_0, 29)) - self.connect((self.fec_bercurve_generator_0_0_0, 30), (self.qtgui_bercurve_sink_0, 30)) - self.connect((self.fec_bercurve_generator_0_0_0, 31), (self.qtgui_bercurve_sink_0, 31)) - self.connect((self.fec_bercurve_generator_0_1, 0), (self.qtgui_bercurve_sink_0, 96)) - self.connect((self.fec_bercurve_generator_0_1, 1), (self.qtgui_bercurve_sink_0, 97)) - self.connect((self.fec_bercurve_generator_0_1, 2), (self.qtgui_bercurve_sink_0, 98)) - self.connect((self.fec_bercurve_generator_0_1, 3), (self.qtgui_bercurve_sink_0, 99)) - self.connect((self.fec_bercurve_generator_0_1, 4), (self.qtgui_bercurve_sink_0, 100)) - self.connect((self.fec_bercurve_generator_0_1, 5), (self.qtgui_bercurve_sink_0, 101)) - self.connect((self.fec_bercurve_generator_0_1, 6), (self.qtgui_bercurve_sink_0, 102)) - self.connect((self.fec_bercurve_generator_0_1, 7), (self.qtgui_bercurve_sink_0, 103)) - self.connect((self.fec_bercurve_generator_0_1, 8), (self.qtgui_bercurve_sink_0, 104)) - self.connect((self.fec_bercurve_generator_0_1, 9), (self.qtgui_bercurve_sink_0, 105)) - self.connect((self.fec_bercurve_generator_0_1, 10), (self.qtgui_bercurve_sink_0, 106)) - self.connect((self.fec_bercurve_generator_0_1, 11), (self.qtgui_bercurve_sink_0, 107)) - self.connect((self.fec_bercurve_generator_0_1, 12), (self.qtgui_bercurve_sink_0, 108)) - self.connect((self.fec_bercurve_generator_0_1, 13), (self.qtgui_bercurve_sink_0, 109)) - self.connect((self.fec_bercurve_generator_0_1, 14), (self.qtgui_bercurve_sink_0, 110)) - self.connect((self.fec_bercurve_generator_0_1, 15), (self.qtgui_bercurve_sink_0, 111)) - self.connect((self.fec_bercurve_generator_0_1, 16), (self.qtgui_bercurve_sink_0, 112)) - self.connect((self.fec_bercurve_generator_0_1, 17), (self.qtgui_bercurve_sink_0, 113)) - self.connect((self.fec_bercurve_generator_0_1, 18), (self.qtgui_bercurve_sink_0, 114)) - self.connect((self.fec_bercurve_generator_0_1, 19), (self.qtgui_bercurve_sink_0, 115)) - self.connect((self.fec_bercurve_generator_0_1, 20), (self.qtgui_bercurve_sink_0, 116)) - self.connect((self.fec_bercurve_generator_0_1, 21), (self.qtgui_bercurve_sink_0, 117)) - self.connect((self.fec_bercurve_generator_0_1, 22), (self.qtgui_bercurve_sink_0, 118)) - self.connect((self.fec_bercurve_generator_0_1, 23), (self.qtgui_bercurve_sink_0, 119)) - self.connect((self.fec_bercurve_generator_0_1, 24), (self.qtgui_bercurve_sink_0, 120)) - self.connect((self.fec_bercurve_generator_0_1, 25), (self.qtgui_bercurve_sink_0, 121)) - self.connect((self.fec_bercurve_generator_0_1, 26), (self.qtgui_bercurve_sink_0, 122)) - self.connect((self.fec_bercurve_generator_0_1, 27), (self.qtgui_bercurve_sink_0, 123)) - self.connect((self.fec_bercurve_generator_0_1, 28), (self.qtgui_bercurve_sink_0, 124)) - self.connect((self.fec_bercurve_generator_0_1, 29), (self.qtgui_bercurve_sink_0, 125)) - self.connect((self.fec_bercurve_generator_0_1, 30), (self.qtgui_bercurve_sink_0, 126)) - self.connect((self.fec_bercurve_generator_0_1, 31), (self.qtgui_bercurve_sink_0, 127)) - self.connect((self.fec_bercurve_generator_0_1_0, 0), (self.qtgui_bercurve_sink_0, 128)) - self.connect((self.fec_bercurve_generator_0_1_0, 1), (self.qtgui_bercurve_sink_0, 129)) - self.connect((self.fec_bercurve_generator_0_1_0, 2), (self.qtgui_bercurve_sink_0, 130)) - self.connect((self.fec_bercurve_generator_0_1_0, 3), (self.qtgui_bercurve_sink_0, 131)) - self.connect((self.fec_bercurve_generator_0_1_0, 4), (self.qtgui_bercurve_sink_0, 132)) - self.connect((self.fec_bercurve_generator_0_1_0, 5), (self.qtgui_bercurve_sink_0, 133)) - self.connect((self.fec_bercurve_generator_0_1_0, 6), (self.qtgui_bercurve_sink_0, 134)) - self.connect((self.fec_bercurve_generator_0_1_0, 7), (self.qtgui_bercurve_sink_0, 135)) - self.connect((self.fec_bercurve_generator_0_1_0, 8), (self.qtgui_bercurve_sink_0, 136)) - self.connect((self.fec_bercurve_generator_0_1_0, 9), (self.qtgui_bercurve_sink_0, 137)) - self.connect((self.fec_bercurve_generator_0_1_0, 10), (self.qtgui_bercurve_sink_0, 138)) - self.connect((self.fec_bercurve_generator_0_1_0, 11), (self.qtgui_bercurve_sink_0, 139)) - self.connect((self.fec_bercurve_generator_0_1_0, 12), (self.qtgui_bercurve_sink_0, 140)) - self.connect((self.fec_bercurve_generator_0_1_0, 13), (self.qtgui_bercurve_sink_0, 141)) - self.connect((self.fec_bercurve_generator_0_1_0, 14), (self.qtgui_bercurve_sink_0, 142)) - self.connect((self.fec_bercurve_generator_0_1_0, 15), (self.qtgui_bercurve_sink_0, 143)) - self.connect((self.fec_bercurve_generator_0_1_0, 16), (self.qtgui_bercurve_sink_0, 144)) - self.connect((self.fec_bercurve_generator_0_1_0, 17), (self.qtgui_bercurve_sink_0, 145)) - self.connect((self.fec_bercurve_generator_0_1_0, 18), (self.qtgui_bercurve_sink_0, 146)) - self.connect((self.fec_bercurve_generator_0_1_0, 19), (self.qtgui_bercurve_sink_0, 147)) - self.connect((self.fec_bercurve_generator_0_1_0, 20), (self.qtgui_bercurve_sink_0, 148)) - self.connect((self.fec_bercurve_generator_0_1_0, 21), (self.qtgui_bercurve_sink_0, 149)) - self.connect((self.fec_bercurve_generator_0_1_0, 22), (self.qtgui_bercurve_sink_0, 150)) - self.connect((self.fec_bercurve_generator_0_1_0, 23), (self.qtgui_bercurve_sink_0, 151)) - self.connect((self.fec_bercurve_generator_0_1_0, 24), (self.qtgui_bercurve_sink_0, 152)) - self.connect((self.fec_bercurve_generator_0_1_0, 25), (self.qtgui_bercurve_sink_0, 153)) - self.connect((self.fec_bercurve_generator_0_1_0, 26), (self.qtgui_bercurve_sink_0, 154)) - self.connect((self.fec_bercurve_generator_0_1_0, 27), (self.qtgui_bercurve_sink_0, 155)) - self.connect((self.fec_bercurve_generator_0_1_0, 28), (self.qtgui_bercurve_sink_0, 156)) - self.connect((self.fec_bercurve_generator_0_1_0, 29), (self.qtgui_bercurve_sink_0, 157)) - self.connect((self.fec_bercurve_generator_0_1_0, 30), (self.qtgui_bercurve_sink_0, 158)) - self.connect((self.fec_bercurve_generator_0_1_0, 31), (self.qtgui_bercurve_sink_0, 159)) - - def closeEvent(self, event): - self.settings = Qt.QSettings("GNU Radio", "tpc_ber_curve_gen") - self.settings.setValue("geometry", self.saveGeometry()) - event.accept() - - def get_esno_0(self): - return self.esno_0 - - def set_esno_0(self, esno_0): - self.esno_0 = esno_0 - - def get_samp_rate_0(self): - return self.samp_rate_0 - - def set_samp_rate_0(self, samp_rate_0): - self.samp_rate_0 = samp_rate_0 - - def get_rate(self): - return self.rate - - def set_rate(self, rate): - self.rate = rate - - def get_polys(self): - return self.polys - - def set_polys(self, polys): - self.polys = polys - - def get_k(self): - return self.k - - def set_k(self, k): - self.k = k - - def get_framebits(self): - return self.framebits - - def set_framebits(self, framebits): - self.framebits = framebits - - def get_enc_tpc_4(self): - return self.enc_tpc_4 - - def set_enc_tpc_4(self, enc_tpc_4): - self.enc_tpc_4 = enc_tpc_4 - - def get_enc_tpc_3(self): - return self.enc_tpc_3 - - def set_enc_tpc_3(self, enc_tpc_3): - self.enc_tpc_3 = enc_tpc_3 - - def get_enc_tpc_2(self): - return self.enc_tpc_2 - - def set_enc_tpc_2(self, enc_tpc_2): - self.enc_tpc_2 = enc_tpc_2 - - def get_enc_tpc_1(self): - return self.enc_tpc_1 - - def set_enc_tpc_1(self, enc_tpc_1): - self.enc_tpc_1 = enc_tpc_1 - - def get_enc_tpc_0(self): - return self.enc_tpc_0 - - def set_enc_tpc_0(self, enc_tpc_0): - self.enc_tpc_0 = enc_tpc_0 - - def get_dec_tpc_4(self): - return self.dec_tpc_4 - - def set_dec_tpc_4(self, dec_tpc_4): - self.dec_tpc_4 = dec_tpc_4 - - def get_dec_tpc_3(self): - return self.dec_tpc_3 - - def set_dec_tpc_3(self, dec_tpc_3): - self.dec_tpc_3 = dec_tpc_3 - - def get_dec_tpc_2(self): - return self.dec_tpc_2 - - def set_dec_tpc_2(self, dec_tpc_2): - self.dec_tpc_2 = dec_tpc_2 - - def get_dec_tpc_1(self): - return self.dec_tpc_1 - - def set_dec_tpc_1(self, dec_tpc_1): - self.dec_tpc_1 = dec_tpc_1 - - def get_dec_tpc_0(self): - return self.dec_tpc_0 - - def set_dec_tpc_0(self, dec_tpc_0): - self.dec_tpc_0 = dec_tpc_0 - - -if __name__ == '__main__': - parser = OptionParser(option_class=eng_option, usage="%prog: [options]") - (options, args) = parser.parse_args() - if(StrictVersion(Qt.qVersion()) >= StrictVersion("4.5.0")): - Qt.QApplication.setGraphicsSystem(gr.prefs().get_string('qtgui','style','raster')) - qapp = Qt.QApplication(sys.argv) - tb = tpc_ber_curve_gen() - tb.start() - tb.show() - def quitting(): - tb.stop() - tb.wait() - qapp.connect(qapp, Qt.SIGNAL("aboutToQuit()"), quitting) - qapp.exec_() - tb = None #to clean up Qt widgets diff --git a/gr-fec/grc/fec_block_tree.xml b/gr-fec/grc/fec_block_tree.xml index f7ddb3a3ce..5efc144cbd 100644 --- a/gr-fec/grc/fec_block_tree.xml +++ b/gr-fec/grc/fec_block_tree.xml @@ -15,9 +15,10 @@ <block>variable_ldpc_decoder_def</block> <block>variable_ldpc_bit_flip_decoder_def</block> <block>variable_tpc_decoder_def</block> + <block>variable_dummy_decoder_def</block> <block>variable_polar_decoder_sc_def</block> <block>variable_polar_decoder_sc_list_def</block> - <block>variable_dummy_decoder_def</block> + <block>variable_polar_decoder_sc_systematic_def</block> </cat> <cat> <name>Encoders</name> @@ -29,7 +30,8 @@ <block>variable_ldpc_encoder_G_def</block> <block>variable_ldpc_encoder_H_def</block> <block>variable_polar_encoder_def</block> - <block>variable_dummy_encoder_def</block> + <block>variable_polar_encoder_systematic_def</block> + <block>variable_dummy_encoder_def</block> </cat> <block>fec_extended_encoder</block> <block>fec_extended_async_encoder</block> diff --git a/gr-fec/grc/variable_polar_decoder_sc_systematic.xml b/gr-fec/grc/variable_polar_decoder_sc_systematic.xml new file mode 100644 index 0000000000..cefc7e237d --- /dev/null +++ b/gr-fec/grc/variable_polar_decoder_sc_systematic.xml @@ -0,0 +1,68 @@ +<?xml version="1.0"?> +<block> + <name>systematic POLAR Decoder SC Definition</name> + <key>variable_polar_decoder_sc_systematic_def</key> + <import>from gnuradio import fec</import> + <var_make>#if int($ndim())==0 # +self.$(id) = $(id) = fec.polar_decoder_sc_systematic.make($block_size, $num_info_bits, $frozen_bit_positions) #slurp +#else if int($ndim())==1 # +self.$(id) = $(id) = map((lambda a: fec.polar_decoder_sc_systematic.make($block_size, $num_info_bits, $frozen_bit_positions)), range(0, $dim1) ) #slurp +#else +self.$(id) = $(id) = map((lambda b: map((lambda a: fec.polar_decoder_sc_systematic.make($block_size, $num_info_bits, $frozen_bit_positions)), range(0, $dim2))), range(0, $dim1)) #slurp +#end if</var_make> + <var_value>fec.polar_decoder_sc_systematic.make($block_size, $num_info_bits, $frozen_bit_positions)</var_value> + <make></make> + + <param> + <name>Parallelism</name> + <key>ndim</key> + <value>0</value> + <type>enum</type> + <option> + <name>0</name> + <key>0</key> + </option> + <option> + <name>1</name> + <key>1</key> + </option> + <option> + <name>2</name> + <key>2</key> + </option> + </param> + + <param> + <name>Dimension 1</name> + <key>dim1</key> + <value>1</value> + <type>int</type> + <hide>#if (int($ndim()) >= 1) then 'none' else 'all' #</hide> + </param> + + <param> + <name>Dimension 2</name> + <key>dim2</key> + <value>4</value> + <type>int</type> + <hide>#if (int($ndim()) >= 2) then 'none' else 'all' #</hide> + </param> + + <param> + <name>Block size (N)</name> + <key>block_size</key> + <type>int</type> + </param> + + <param> + <name>#Info Bits (K)</name> + <key>num_info_bits</key> + <type>int</type> + </param> + + <param> + <name>Frozen Bit Positions</name> + <key>frozen_bit_positions</key> + <type>int_vector</type> + </param> +</block> diff --git a/gr-fec/grc/variable_polar_encoder_systematic.xml b/gr-fec/grc/variable_polar_encoder_systematic.xml new file mode 100644 index 0000000000..0d9bcd96ab --- /dev/null +++ b/gr-fec/grc/variable_polar_encoder_systematic.xml @@ -0,0 +1,68 @@ +<?xml version="1.0"?> +<block> + <name>systematic POLAR Encoder Definition</name> + <key>variable_polar_encoder_systematic_def</key> + <import>from gnuradio import fec</import> + <var_make>#if int($ndim())==0 # +self.$(id) = $(id) = fec.polar_encoder_systematic.make($block_size, $num_info_bits, $frozen_bit_positions) #slurp +#else if int($ndim())==1 # +self.$(id) = $(id) = map((lambda a: fec.polar_encoder_systematic.make($block_size, $num_info_bits, $frozen_bit_positions)), range(0, $dim1)) #slurp +#else +self.$(id) = $(id) = map((lambda b: map((lambda a: fec.polar_encoder_systematic.make($block_size, $num_info_bits, $frozen_bit_positions)), range(0, $dim2))), range(0, $dim1)) #slurp +#end if</var_make> + <var_value>fec.polar_encoder_systematic.make($block_size, $num_info_bits, $frozen_bit_positions)</var_value> + <make></make> + + <param> + <name>Parallelism</name> + <key>ndim</key> + <value>0</value> + <type>enum</type> + <option> + <name>0</name> + <key>0</key> + </option> + <option> + <name>1</name> + <key>1</key> + </option> + <option> + <name>2</name> + <key>2</key> + </option> + </param> + + <param> + <name>Dimension 1</name> + <key>dim1</key> + <value>1</value> + <type>int</type> + <hide>#if (int($ndim()) >= 1) then 'none' else 'all' #</hide> + </param> + + <param> + <name>Dimension 2</name> + <key>dim2</key> + <value>4</value> + <type>int</type> + <hide>#if (int($ndim()) >= 2) then 'none' else 'all' #</hide> + </param> + + <param> + <name>Block size (N)</name> + <key>block_size</key> + <type>int</type> + </param> + + <param> + <name>#Info Bits (K)</name> + <key>num_info_bits</key> + <type>int</type> + </param> + + <param> + <name>Frozen Bit Positions</name> + <key>frozen_bit_positions</key> + <type>int_vector</type> + </param> +</block> diff --git a/gr-fec/include/gnuradio/fec/CMakeLists.txt b/gr-fec/include/gnuradio/fec/CMakeLists.txt index c108c7c29c..aca8c8da84 100644 --- a/gr-fec/include/gnuradio/fec/CMakeLists.txt +++ b/gr-fec/include/gnuradio/fec/CMakeLists.txt @@ -54,7 +54,8 @@ install(FILES polar_common.h polar_decoder_sc_list.h polar_decoder_common.h - DESTINATION ${GR_INCLUDE_DIR}/gnuradio/fec + polar_encoder_systematic.h + polar_decoder_sc_systematic.h DESTINATION ${GR_INCLUDE_DIR}/gnuradio/fec COMPONENT "fec_devel" ) diff --git a/gr-fec/include/gnuradio/fec/polar_common.h b/gr-fec/include/gnuradio/fec/polar_common.h index 7ef3e59b77..99c7d84e55 100644 --- a/gr-fec/include/gnuradio/fec/polar_common.h +++ b/gr-fec/include/gnuradio/fec/polar_common.h @@ -88,6 +88,18 @@ namespace gr { std::vector<int> d_frozen_bit_positions; std::vector<char> d_frozen_bit_values; std::vector<int> d_info_bit_positions; + std::vector<int> d_info_bit_positions_reversed; + void setup_info_bit_positions_reversed(); +// std::vector<int> d_info_bit_positions_reversed; + + + // VOLK methods + void setup_volk_vectors(); + void volk_encode(unsigned char* out_buf, const unsigned char* in_buf); + void volk_encode_block(unsigned char* out_buf, unsigned char* in_buf); + unsigned char* d_volk_temp; + unsigned char* d_volk_frozen_bit_mask; + unsigned char* d_volk_frozen_bits; private: int d_block_size; // depending on paper called 'N' or 'm' diff --git a/gr-fec/include/gnuradio/fec/polar_decoder_sc_systematic.h b/gr-fec/include/gnuradio/fec/polar_decoder_sc_systematic.h new file mode 100644 index 0000000000..36a0dc6ec4 --- /dev/null +++ b/gr-fec/include/gnuradio/fec/polar_decoder_sc_systematic.h @@ -0,0 +1,82 @@ +/* -*- c++ -*- */ +/* + * 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. + */ + + +#ifndef INCLUDED_FEC_POLAR_DECODER_SC_SYSTEMATIC_H +#define INCLUDED_FEC_POLAR_DECODER_SC_SYSTEMATIC_H + +#include <gnuradio/fec/api.h> +#include <gnuradio/fec/polar_decoder_common.h> + +namespace gr { + namespace fec { + namespace code { + + /*! + * \brief Standard systematic successive cancellation (SC) decoder for POLAR codes + * + * \details + * It expects float input with bits mapped 1 --> 1, 0 --> -1 + * Or: f = 2.0 * bit - 1.0 + * + * Systematic encoding indicates that the info bit values are present in the codeword. + * 'info_bit_positions' may be obtained by ordering all non frozen_bit_positions in increasing order. + * One may extract them at their positions after a bit reversal operation. + * encoder -> decoder chain would need additional bit-reversal after encoding + before decoding. + * This is unnecessary. + */ + class FEC_API polar_decoder_sc_systematic : public polar_decoder_common + { + public: + /*! + * \param block_size codeword size. MUST be a power of 2. + * \param num_info_bits represents the number of information + * bits in a block. Also called frame_size. <= block_size + * \param frozen_bit_positions is an integer vector which + * defines the position of all frozen bits in a block. + * Its size MUST be equal to block_size - num_info_bits. + * Also it must be sorted and every position must only + * occur once. + */ + static generic_decoder::sptr make(int block_size, int num_info_bits, + std::vector<int> frozen_bit_positions); + + ~polar_decoder_sc_systematic(); + + // FECAPI + void generic_work(void *in_buffer, void *out_buffer); + private: + polar_decoder_sc_systematic(int block_size, int num_info_bits, std::vector<int> frozen_bit_positions); + float* d_llr_vec; + unsigned char* d_u_hat_vec; + unsigned char* d_frame_vec; + unsigned char retrieve_bit_from_llr(float llr, const int pos); + void sc_decode(float* llrs, unsigned char* u); + void extract_info_bits_reversed(unsigned char* outbuf, const unsigned char* inbuf); + }; + + } /* namespace code */ + } // namespace fec +} // namespace gr + +#endif /* INCLUDED_FEC_POLAR_DECODER_SC_SYSTEMATIC_H */ + diff --git a/gr-fec/include/gnuradio/fec/polar_encoder.h b/gr-fec/include/gnuradio/fec/polar_encoder.h index f9541a203d..f7d036e849 100644 --- a/gr-fec/include/gnuradio/fec/polar_encoder.h +++ b/gr-fec/include/gnuradio/fec/polar_encoder.h @@ -81,7 +81,6 @@ namespace gr { polar_encoder(int block_size, int num_info_bits, std::vector<int>& frozen_bit_positions, std::vector<char>& frozen_bit_values, bool is_packed); - std::vector<int> d_info_bit_reversed_positions; bool d_is_packed; // c'tor method for packed algorithm setup. @@ -104,13 +103,6 @@ namespace gr { void encode_vector_packed_subbyte(unsigned char* target) const; void encode_packed_byte(unsigned char* target) const; void encode_vector_packed_interbyte(unsigned char* target) const; - - // VOLK methods - void setup_volk_vectors(); - void volk_encode(unsigned char* out_buf, const unsigned char* in_buf); - unsigned char* d_temp; - unsigned char* d_frozen_bit_mask; - unsigned char* d_frozen_bits; }; } // namespace code diff --git a/gr-fec/include/gnuradio/fec/polar_encoder_systematic.h b/gr-fec/include/gnuradio/fec/polar_encoder_systematic.h new file mode 100644 index 0000000000..8dd734df71 --- /dev/null +++ b/gr-fec/include/gnuradio/fec/polar_encoder_systematic.h @@ -0,0 +1,111 @@ +/* -*- c++ -*- */ +/* + * 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. + */ + + +#ifndef INCLUDED_FEC_POLAR_ENCODER_SYSTEMATIC_H +#define INCLUDED_FEC_POLAR_ENCODER_SYSTEMATIC_H + +#include <gnuradio/fec/api.h> +#include <gnuradio/fec/generic_encoder.h> +#include <gnuradio/fec/polar_common.h> + +namespace gr { + namespace fec { + namespace code { + + /*! + * \brief systematic POLAR encoder + * for basic details see 'polar_common' class. + * \ingroup error_coding_blk + * + * \details + * expects values with MSB first. It needs a full information word and encodes it in one pass. + * Output is a codeword of block_size. + * + * Systematic encoding indicates that the info bit values are present in the codeword. + * 'info_bit_positions' may be obtained by ordering all non frozen_bit_positions in increasing order. + * One may extract them at their positions after a bit reversal operation. + * encoder -> decoder chain would need additional bit-reversal after encoding + before decoding. + * This is unnecessary. + */ + class FEC_API polar_encoder_systematic: public generic_encoder, public polar_common + { + public: + /*! + * Factory for a polar code encoder object. + * + * \param block_size defines the codeword size. It MUST be a + * power of 2. + * \param num_info_bits represents the number of information + * bits in a block. Also called frame_size. + * \param frozen_bit_positions is an integer vector which + * defines the position of all frozen bits in a block. + * Its size MUST be equal to block_size - num_info_bits. + * Also it must be sorted and every position must only + * occur once. Frozen bit values will be set to ZERO! + */ + static generic_encoder::sptr + make(int block_size, int num_info_bits, std::vector<int> frozen_bit_positions); + + // FECAPI + void + generic_work(void *in_buffer, void *out_buffer); + double + rate() + { + return (1.0 * get_input_size() / get_output_size()); + } + ; + int + get_input_size() + { + return num_info_bits(); + } + ; + int + get_output_size() + { + return block_size(); + } + ; + bool + set_frame_size(unsigned int frame_size) + { + return false; + } + ; + + ~polar_encoder_systematic(); + private: + polar_encoder_systematic(int block_size, int num_info_bits, + std::vector<int> frozen_bit_positions); + + void bit_reverse_and_reset_frozen_bits(unsigned char *outbuf, const unsigned char *inbuf); + unsigned char* d_volk_syst_intermediate; + }; + + } // namespace code + } // namespace fec +} // namespace gr + +#endif /* INCLUDED_FEC_POLAR_ENCODER_SYSTEMATIC_H */ + diff --git a/gr-fec/lib/CMakeLists.txt b/gr-fec/lib/CMakeLists.txt index 8234d6a27a..bda98016b0 100644 --- a/gr-fec/lib/CMakeLists.txt +++ b/gr-fec/lib/CMakeLists.txt @@ -87,6 +87,8 @@ list(APPEND gnuradio_fec_sources polar_decoder_sc_list.cc polar_decoder_common.cc scl_list.cc + polar_encoder_systematic.cc + polar_decoder_sc_systematic.cc ) #Add Windows DLL resource file if using MSVC diff --git a/gr-fec/lib/polar_common.cc b/gr-fec/lib/polar_common.cc index ff78d3428e..c04ec5a15c 100644 --- a/gr-fec/lib/polar_common.cc +++ b/gr-fec/lib/polar_common.cc @@ -26,6 +26,7 @@ #include <gnuradio/io_signature.h> #include <gnuradio/fec/polar_common.h> +#include <volk/volk.h> #include <gnuradio/blocks/pack_k_bits.h> #include <gnuradio/blocks/unpack_k_bits.h> @@ -61,6 +62,8 @@ namespace gr { d_frozen_bit_values.push_back(0); } initialize_info_bit_position_vector(); + setup_volk_vectors(); + setup_info_bit_positions_reversed(); d_unpacker = new gr::blocks::kernel::unpack_k_bits(8); } @@ -86,9 +89,59 @@ namespace gr { } } + void + polar_common::setup_info_bit_positions_reversed() + { + for(unsigned int i = 0; i < d_info_bit_positions.size(); i++){ + d_info_bit_positions_reversed.push_back((int) bit_reverse((long) d_info_bit_positions.at(i), block_power())); + } + + if((int) d_info_bit_positions_reversed.size() != num_info_bits()) { + throw std::runtime_error("polar_encoder: number of info bit positions MUST equal num_info_bits (K)!"); + } + } + + void + polar_common::setup_volk_vectors() + { + int nfrozen = block_size() - num_info_bits(); + d_volk_temp = (unsigned char*) volk_malloc(sizeof(unsigned char) * block_size(), volk_get_alignment()); + d_volk_frozen_bit_mask = (unsigned char*) volk_malloc(sizeof(unsigned char) * block_size(), volk_get_alignment()); + d_volk_frozen_bits = (unsigned char*) volk_malloc(sizeof(unsigned char) * nfrozen, volk_get_alignment()); + for(int i = 0; i < nfrozen; i++){ + d_volk_frozen_bits[i] = d_frozen_bit_values[i]; + } + + int nfbit = 0; + for(int i = 0; i < block_size(); i++){ + unsigned char m = 0x00; + if(d_frozen_bit_positions[nfbit] == i){ + m = 0xFF; + nfbit++; + } + d_volk_frozen_bit_mask[i] = m; + } + } + + void + polar_common::volk_encode(unsigned char* out_buf, const unsigned char* in_buf) + { + volk_8u_x3_encodepolar_8u_x2(out_buf, d_volk_temp, d_volk_frozen_bit_mask, d_volk_frozen_bits, in_buf, block_size()); + } + + void + polar_common::volk_encode_block(unsigned char* out_buf, unsigned char* in_buf) + { + volk_8u_x2_encodeframepolar_8u(out_buf, in_buf, block_size()); + } + polar_common::~polar_common() { delete d_unpacker; + + volk_free(d_volk_temp); + volk_free(d_volk_frozen_bit_mask); + volk_free(d_volk_frozen_bits); } long diff --git a/gr-fec/lib/polar_decoder_sc_systematic.cc b/gr-fec/lib/polar_decoder_sc_systematic.cc new file mode 100644 index 0000000000..c65c80f7aa --- /dev/null +++ b/gr-fec/lib/polar_decoder_sc_systematic.cc @@ -0,0 +1,101 @@ +/* -*- c++ -*- */ +/* + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gnuradio/io_signature.h> +#include <gnuradio/fec/polar_decoder_sc_systematic.h> +#include <volk/volk.h> + +namespace gr { + namespace fec { + namespace code { + + generic_decoder::sptr + polar_decoder_sc_systematic::make(int block_size, int num_info_bits, + std::vector<int> frozen_bit_positions) + { + return generic_decoder::sptr( + new polar_decoder_sc_systematic(block_size, num_info_bits, frozen_bit_positions)); + } + + polar_decoder_sc_systematic::polar_decoder_sc_systematic( + int block_size, int num_info_bits, std::vector<int> frozen_bit_positions) : + polar_decoder_common(block_size, num_info_bits, frozen_bit_positions, std::vector<char>()) + { + d_llr_vec = (float*) volk_malloc(sizeof(float) * block_size * (block_power() + 1), volk_get_alignment()); + memset(d_llr_vec, 0, sizeof(float) * block_size * (block_power() + 1)); + d_u_hat_vec = (unsigned char*) volk_malloc(block_size * (block_power() + 1), volk_get_alignment()); + memset(d_u_hat_vec, 0, sizeof(unsigned char) * block_size * (block_power() + 1)); + d_frame_vec = (unsigned char*) volk_malloc(block_size, volk_get_alignment()); + memset(d_frame_vec, 0, sizeof(unsigned char) * block_size); + } + + polar_decoder_sc_systematic::~polar_decoder_sc_systematic() + { + } + + void + polar_decoder_sc_systematic::generic_work(void* in_buffer, void* out_buffer) + { + const float *in = (const float*) in_buffer; + unsigned char *out = (unsigned char*) out_buffer; + + initialize_decoder(d_u_hat_vec, d_llr_vec, in); + sc_decode(d_llr_vec, d_u_hat_vec); + volk_encode_block(d_frame_vec, d_u_hat_vec); + extract_info_bits_reversed(out, d_frame_vec); + } + + void + polar_decoder_sc_systematic::sc_decode(float* llrs, unsigned char* u) + { + for(int i = 0; i < block_size(); i++){ + butterfly(llrs, u, 0, i, i); + u[i] = retrieve_bit_from_llr(llrs[i], i); + } + } + + unsigned char + polar_decoder_sc_systematic::retrieve_bit_from_llr(float llr, const int pos) + { + if(is_frozen_bit(pos)){ + return next_frozen_bit(); + } + return llr_bit_decision(llr); + } + + void + polar_decoder_sc_systematic::extract_info_bits_reversed(unsigned char* outbuf, + const unsigned char* inbuf) + { + for(int i = 0; i < num_info_bits(); i++){ + *outbuf++ = inbuf[d_info_bit_positions_reversed[i]]; + } + } + + } // namespace code + } /* namespace fec */ +} /* namespace gr */ + diff --git a/gr-fec/lib/polar_encoder.cc b/gr-fec/lib/polar_encoder.cc index 350f490487..d587793f4a 100644 --- a/gr-fec/lib/polar_encoder.cc +++ b/gr-fec/lib/polar_encoder.cc @@ -56,7 +56,6 @@ namespace gr { d_is_packed(is_packed) { setup_frozen_bit_inserter(); - setup_volk_vectors(); } void @@ -72,45 +71,11 @@ namespace gr { insert_unpacked_bit_into_packed_array_at_position(d_frozen_bit_prototype, frozen_bit, rev_pos); } - - for(unsigned int i = 0; i < d_info_bit_positions.size(); i++){ - d_info_bit_reversed_positions.push_back((int) bit_reverse((long) d_info_bit_positions.at(i), block_power())); - } - - if((int) d_info_bit_reversed_positions.size() != num_info_bits()) { - throw std::runtime_error("polar_encoder: number of info bit positions MUST equal num_info_bits (K)!"); - } - } - - void - polar_encoder::setup_volk_vectors() - { - int nfrozen = block_size() - num_info_bits(); - d_temp = (unsigned char*) volk_malloc(sizeof(unsigned char) * block_size(), volk_get_alignment()); - d_frozen_bit_mask = (unsigned char*) volk_malloc(sizeof(unsigned char) * block_size(), volk_get_alignment()); - d_frozen_bits = (unsigned char*) volk_malloc(sizeof(unsigned char) * nfrozen, volk_get_alignment()); - for(int i = 0; i < nfrozen; i++){ - d_frozen_bits[i] = d_frozen_bit_values[i]; - } - - int nfbit = 0; - for(int i = 0; i < block_size(); i++){ - unsigned char m = 0x00; - if(d_frozen_bit_positions[nfbit] == i){ - m = 0xFF; - nfbit++; - } - d_frozen_bit_mask[i] = m; - } } polar_encoder::~polar_encoder() { volk_free(d_frozen_bit_prototype); - - volk_free(d_temp); - volk_free(d_frozen_bit_mask); - volk_free(d_frozen_bits); } void @@ -129,12 +94,6 @@ namespace gr { } void - polar_encoder::volk_encode(unsigned char* out_buf, const unsigned char* in_buf) - { - volk_8u_x3_encodepolar_8u_x2(out_buf, d_temp, d_frozen_bit_mask, d_frozen_bits, in_buf, block_size()); - } - - void polar_encoder::encode_vector_packed(unsigned char* target) const { encode_vector_packed_subbyte(target); @@ -194,7 +153,7 @@ namespace gr { const unsigned char* input) const { memcpy(target, d_frozen_bit_prototype, block_size() >> 3); - const int* info_bit_reversed_positions_ptr = &d_info_bit_reversed_positions[0]; + const int* info_bit_reversed_positions_ptr = &d_info_bit_positions_reversed[0]; int bit_num = 0; unsigned char byte = *input; int bit_pos; diff --git a/gr-fec/lib/polar_encoder_systematic.cc b/gr-fec/lib/polar_encoder_systematic.cc new file mode 100644 index 0000000000..80bfa1ca0c --- /dev/null +++ b/gr-fec/lib/polar_encoder_systematic.cc @@ -0,0 +1,79 @@ +/* -*- c++ -*- */ +/* + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gnuradio/io_signature.h> +#include <gnuradio/fec/polar_encoder_systematic.h> +#include <volk/volk.h> + +namespace gr { + namespace fec { + namespace code { + + generic_encoder::sptr + polar_encoder_systematic::make(int block_size, int num_info_bits, + std::vector<int> frozen_bit_positions) + { + return generic_encoder::sptr( + new polar_encoder_systematic(block_size, num_info_bits, frozen_bit_positions)); + } + + polar_encoder_systematic::polar_encoder_systematic(int block_size, int num_info_bits, + std::vector<int> frozen_bit_positions) : + polar_common(block_size, num_info_bits, frozen_bit_positions, std::vector<char>()) + { + d_volk_syst_intermediate = (unsigned char*) volk_malloc(sizeof(unsigned char) * block_size, volk_get_alignment()); + } + + polar_encoder_systematic::~polar_encoder_systematic() + { + volk_free(d_volk_syst_intermediate); + } + + void + polar_encoder_systematic::generic_work(void* in_buffer, void* out_buffer) + { + const unsigned char *in = (const unsigned char*) in_buffer; + unsigned char *out = (unsigned char*) out_buffer; + + volk_encode(out, in); + bit_reverse_and_reset_frozen_bits(d_volk_syst_intermediate, out); + volk_encode_block(out, d_volk_syst_intermediate); + } + + void + polar_encoder_systematic::bit_reverse_and_reset_frozen_bits(unsigned char* outbuf, + const unsigned char* inbuf) + { + memset(outbuf, 0, sizeof(unsigned char) * block_size()); + for(int i = 0; i < num_info_bits(); i++){ + outbuf[d_info_bit_positions[i]] = inbuf[d_info_bit_positions_reversed[i]]; + } + } + + } /* namespace code */ + } /* namespace fec */ +} /* namespace gr */ + diff --git a/gr-fec/python/fec/polar/common.py b/gr-fec/python/fec/polar/common.py index b4b152de61..fa5987b6d2 100644 --- a/gr-fec/python/fec/polar/common.py +++ b/gr-fec/python/fec/polar/common.py @@ -65,5 +65,20 @@ class PolarCommon: def _vector_bit_reversed(self, vec, n): return bit_reverse_vector(vec, n) + def _encode_efficient(self, vec): + n_stages = self.power + pos = np.arange(self.N, dtype=int) + for i in range(n_stages): + splitted = np.reshape(pos, (2 ** (i + 1), -1)) + upper_branch = splitted[0::2].flatten() + lower_branch = splitted[1::2].flatten() + vec[upper_branch] = (vec[upper_branch] + vec[lower_branch]) % 2 + return vec + + def _encode_natural_order(self, vec): + # use this function. It reflects the encoding process implemented in VOLK. + vec = vec[self.bit_reverse_positions] + return self._encode_efficient(vec) + def info_print(self): print "POLAR code ({0}, {1})".format(self.N, self.K) diff --git a/gr-fec/python/fec/polar/decoder.py b/gr-fec/python/fec/polar/decoder.py index ae62943275..8748d284f7 100644 --- a/gr-fec/python/fec/polar/decoder.py +++ b/gr-fec/python/fec/polar/decoder.py @@ -202,6 +202,33 @@ class PolarDecoder(PolarCommon): data = np.packbits(data) return data + def _extract_info_bits_reversed(self, y): + info_bit_positions_reversed = self._vector_bit_reversed(self.info_bit_position, self.power) + return y[info_bit_positions_reversed] + + def decode_systematic(self, data): + if not len(data) == self.N: + raise ValueError("len(data)={0} is not equal to n={1}!".format(len(data), self.N)) + # data = self._reverse_bits(data) + data = self._lr_sc_decoder_efficient(data) + data = self._encode_natural_order(data) + data = self._extract_info_bits_reversed(data) + return data + + +def test_systematic_decoder(): + ntests = 1000 + n = 16 + k = 8 + frozenbitposition = np.array((0, 1, 2, 3, 4, 5, 8, 9), dtype=int) + encoder = PolarEncoder(n, k, frozenbitposition) + decoder = PolarDecoder(n, k, frozenbitposition) + for i in range(ntests): + bits = np.random.randint(2, size=k) + y = encoder.encode_systematic(bits) + u_hat = decoder.decode_systematic(y) + assert (bits == u_hat).all() + def test_reverse_enc_dec(): n = 16 @@ -240,29 +267,31 @@ def compare_decoder_impls(): def main(): - power = 3 - n = 2 ** power - k = 4 - frozenbits = np.zeros(n - k, dtype=int) - frozenbitposition = np.array((0, 1, 2, 4), dtype=int) - frozenbitposition4 = np.array((0, 1), dtype=int) - - - encoder = PolarEncoder(n, k, frozenbitposition, frozenbits) - decoder = PolarDecoder(n, k, frozenbitposition, frozenbits) - - bits = np.ones(k, dtype=int) - print "bits: ", bits - evec = encoder.encode(bits) - print "froz: ", encoder._insert_frozen_bits(bits) - print "evec: ", evec - - evec[1] = 0 - deced = decoder._lr_sc_decoder(evec) - print 'SC decoded:', deced - - test_reverse_enc_dec() - compare_decoder_impls() + # power = 3 + # n = 2 ** power + # k = 4 + # frozenbits = np.zeros(n - k, dtype=int) + # frozenbitposition = np.array((0, 1, 2, 4), dtype=int) + # frozenbitposition4 = np.array((0, 1), dtype=int) + # + # + # encoder = PolarEncoder(n, k, frozenbitposition, frozenbits) + # decoder = PolarDecoder(n, k, frozenbitposition, frozenbits) + # + # bits = np.ones(k, dtype=int) + # print "bits: ", bits + # evec = encoder.encode(bits) + # print "froz: ", encoder._insert_frozen_bits(bits) + # print "evec: ", evec + # + # evec[1] = 0 + # deced = decoder._lr_sc_decoder(evec) + # print 'SC decoded:', deced + # + # test_reverse_enc_dec() + # compare_decoder_impls() + + test_systematic_decoder() if __name__ == '__main__': diff --git a/gr-fec/python/fec/polar/encoder.py b/gr-fec/python/fec/polar/encoder.py index 3b5eea2a94..cc8fda2d1b 100644 --- a/gr-fec/python/fec/polar/encoder.py +++ b/gr-fec/python/fec/polar/encoder.py @@ -41,16 +41,6 @@ class PolarEncoder(PolarCommon): data = data.astype(dtype=int) return data - def _encode_efficient(self, vec): - n_stages = int(np.log2(self.N)) - pos = np.arange(self.N, dtype=int) - for i in range(n_stages): - splitted = np.reshape(pos, (2 ** (i + 1), -1)) - upper_branch = splitted[0::2].flatten() - lower_branch = splitted[1::2].flatten() - vec[upper_branch] = (vec[upper_branch] + vec[lower_branch]) % 2 - return vec - def encode(self, data, is_packed=False): if not len(data) == self.K: raise ValueError("len(data)={0} is not equal to k={1}!".format(len(data), self.K)) @@ -64,6 +54,31 @@ class PolarEncoder(PolarCommon): data = np.packbits(data) return data + def encode_systematic(self, data): + if not len(data) == self.K: + raise ValueError("len(data)={0} is not equal to k={1}!".format(len(data), self.K)) + if np.max(data) > 1 or np.min(data) < 0: + raise ValueError("can only encode bits!") + + d = self._insert_frozen_bits(data) + d = self._encode_natural_order(d) + d = self._reverse_bits(d) + d[self.frozen_bit_position] = 0 + d = self._encode_natural_order(d) + # d = self._reverse_bits(d) # for more accuracy, do another bit-reversal. or don't for computational simplicity. + return d + + +def test_systematic_encoder(encoder, ntests, k): + for n in range(ntests): + bits = np.random.randint(2, size=k) + x = encoder.encode_systematic(bits) + x = encoder._reverse_bits(x) + u_hat = encoder._extract_info_bits(x) + + assert (bits == u_hat).all() + # print((bits == u_hat).all()) + def compare_results(encoder, ntests, k): for n in range(ntests): @@ -95,15 +110,16 @@ def test_encoder_impls(): ntests = 1000 n = 16 k = 8 - frozenbits = np.zeros(n - k) + # frozenbits = np.zeros(n - k) # frozenbitposition8 = np.array((0, 1, 2, 4), dtype=int) # keep it! frozenbitposition = np.array((0, 1, 2, 3, 4, 5, 8, 9), dtype=int) - encoder = PolarEncoder(n, k, frozenbitposition, frozenbits) + encoder = PolarEncoder(n, k, frozenbitposition) #, frozenbits) print 'result:', compare_results(encoder, ntests, k) print('Test rate-1 encoder/decoder chain results') r1_test = test_pseudo_rate_1_encoder(encoder, ntests, k) print 'Test rate-1 encoder/decoder:', r1_test + test_systematic_encoder(encoder, ntests, k) def main(): diff --git a/gr-fec/python/fec/polar/testbed.py b/gr-fec/python/fec/polar/testbed.py index d60c83e776..3f8e814e4f 100755 --- a/gr-fec/python/fec/polar/testbed.py +++ b/gr-fec/python/fec/polar/testbed.py @@ -305,17 +305,19 @@ def find_decoder_subframes(frozen_mask): print('{0:4} lock {1:4} value: {2} in sub {3}'.format(i, 2 ** (l + 1), v, t)) -def load_file(filename): - z_params = [] - with open(filename, 'r') as f: - for line in f: - if 'Bhattacharyya:' in line: - l = line.split(' ') - l = l[10:-2] - l = l[0][:-1] - l = float(l) - z_params.append(l) - return np.array(z_params) +def systematic_encoder_decoder_chain_test(): + print('systematic encoder decoder chain test') + block_size = int(2 ** 8) + info_bit_size = block_size // 2 + ntests = 100 + frozenbitposition = cc.get_frozen_bit_indices_from_z_parameters(cc.bhattacharyya_bounds(0.0, block_size), block_size - info_bit_size) + encoder = PolarEncoder(block_size, info_bit_size, frozenbitposition) + decoder = PolarDecoder(block_size, info_bit_size, frozenbitposition) + for i in range(ntests): + bits = np.random.randint(2, size=info_bit_size) + y = encoder.encode_systematic(bits) + u_hat = decoder.decode_systematic(y) + assert (bits == u_hat).all() def main(): @@ -334,27 +336,12 @@ def main(): # test_1024_rate_1_code() # channel_analysis() - frozen_indices = cc.get_bec_frozen_indices(m, n_frozen, 0.11) - frozen_mask = cc.get_frozen_bit_mask(frozen_indices, m) - find_decoder_subframes(frozen_mask) - - frozen_mask = np.zeros(m, dtype=int) - frozen_mask[frozen_indices] = 1 + # frozen_indices = cc.get_bec_frozen_indices(m, n_frozen, 0.11) + # frozen_mask = cc.get_frozen_bit_mask(frozen_indices, m) + # find_decoder_subframes(frozen_mask) - # filename = 'channel_z-parameters.txt' - # ido = load_file(filename) - # ido_frozen = cc.get_frozen_bit_indices_from_z_parameters(ido, k) - # ido_mask = np.zeros(m, dtype=int) - # ido_mask[ido_frozen] = 1 - # - # - # plt.plot(ido_mask) - # plt.plot(frozen_mask) - # for i in range(m): - # if not ido_mask[i] == frozen_mask[i]: - # plt.axvline(i, color='r') - # plt.show() + systematic_encoder_decoder_chain_test() if __name__ == '__main__': - main()
\ No newline at end of file + main() diff --git a/gr-fec/python/fec/qa_polar_decoder_sc_systematic.py b/gr-fec/python/fec/qa_polar_decoder_sc_systematic.py new file mode 100644 index 0000000000..fb2381e069 --- /dev/null +++ b/gr-fec/python/fec/qa_polar_decoder_sc_systematic.py @@ -0,0 +1,117 @@ +#!/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, gr_unittest, blocks +import fec_swig as fec + +import numpy as np +from extended_decoder import extended_decoder +from polar.encoder import PolarEncoder +import polar.channel_construction as cc + +# import os +# print('PID:', os.getpid()) +# raw_input('tell me smth') + + +class test_polar_decoder_sc_systematic(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_001_setup(self): + block_size = 16 + num_info_bits = 8 + frozen_bit_positions = np.arange(block_size - num_info_bits) + + polar_decoder = fec.polar_decoder_sc_systematic.make(block_size, num_info_bits, frozen_bit_positions) + + self.assertEqual(num_info_bits, polar_decoder.get_output_size()) + self.assertEqual(block_size, polar_decoder.get_input_size()) + self.assertFloatTuplesAlmostEqual((float(num_info_bits) / block_size, ), (polar_decoder.rate(), )) + self.assertFalse(polar_decoder.set_frame_size(10)) + + def test_002_one_vector(self): + block_power = 4 + block_size = 2 ** block_power + num_info_bits = block_size // 2 + frozen_bit_positions = cc.frozen_bit_positions(block_size, num_info_bits, 0.0) + + bits, gr_data = self.generate_test_data(block_size, num_info_bits, frozen_bit_positions, 1, False) + + polar_decoder = fec.polar_decoder_sc_systematic.make(block_size, num_info_bits, frozen_bit_positions) + src = blocks.vector_source_f(gr_data, False) + dec_block = extended_decoder(polar_decoder, None) + snk = blocks.vector_sink_b(1) + + self.tb.connect(src, dec_block) + self.tb.connect(dec_block, snk) + self.tb.run() + + res = np.array(snk.data()).astype(dtype=int) + self.assertTupleEqual(tuple(res), tuple(bits)) + + def test_003_stream(self): + nframes = 3 + block_power = 8 + block_size = 2 ** block_power + num_info_bits = block_size // 2 + frozen_bit_positions = cc.frozen_bit_positions(block_size, num_info_bits, 0.0) + + bits, gr_data = self.generate_test_data(block_size, num_info_bits, frozen_bit_positions, nframes, False) + + polar_decoder = fec.polar_decoder_sc_systematic.make(block_size, num_info_bits, frozen_bit_positions) + src = blocks.vector_source_f(gr_data, False) + dec_block = extended_decoder(polar_decoder, None) + snk = blocks.vector_sink_b(1) + + self.tb.connect(src, dec_block) + self.tb.connect(dec_block, snk) + self.tb.run() + + res = np.array(snk.data()).astype(dtype=int) + self.assertTupleEqual(tuple(res), tuple(bits)) + + def generate_test_data(self, block_size, num_info_bits, frozen_bit_positions, nframes, onlyones): + frozen_bit_values = np.zeros(block_size - num_info_bits, dtype=int) + encoder = PolarEncoder(block_size, num_info_bits, frozen_bit_positions, frozen_bit_values) + bits = np.array([], dtype=int) + data = np.array([], dtype=int) + for n in range(nframes): + if onlyones: + b = np.ones(num_info_bits, dtype=int) + else: + b = np.random.randint(2, size=num_info_bits) + d = encoder.encode_systematic(b) + bits = np.append(bits, b) + data = np.append(data, d) + gr_data = 2.0 * data - 1.0 + return bits, gr_data + + +if __name__ == '__main__': + gr_unittest.run(test_polar_decoder_sc_systematic) + + diff --git a/gr-fec/python/fec/qa_polar_encoder_systematic.py b/gr-fec/python/fec/qa_polar_encoder_systematic.py new file mode 100644 index 0000000000..015a31b3cb --- /dev/null +++ b/gr-fec/python/fec/qa_polar_encoder_systematic.py @@ -0,0 +1,107 @@ +#!/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, gr_unittest, blocks +import fec_swig as fec +import numpy as np + +from extended_encoder import extended_encoder +from polar.encoder import PolarEncoder +import polar.channel_construction as cc + +# import os +# print('PID:', os.getpid()) +# raw_input('tell me smth') + + +class test_polar_encoder_systematic(gr_unittest.TestCase): + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_001_setup(self): + block_size = 16 + num_info_bits = 8 + frozen_bit_positions = cc.frozen_bit_positions(block_size, num_info_bits, 0.0) + + polar_encoder = fec.polar_encoder_systematic.make(block_size, num_info_bits, frozen_bit_positions) + + self.assertEqual(block_size, polar_encoder.get_output_size()) + self.assertEqual(num_info_bits, polar_encoder.get_input_size()) + self.assertFloatTuplesAlmostEqual((float(num_info_bits) / block_size, ), (polar_encoder.rate(), )) + self.assertFalse(polar_encoder.set_frame_size(10)) + + def test_002_work_function_packed(self): + block_size = 256 + num_info_bits = block_size // 2 + + data, ref, polar_encoder = self.get_test_data(block_size, num_info_bits, 1) + src = blocks.vector_source_b(data, False) + enc_block = extended_encoder(polar_encoder, None, '11') + snk = blocks.vector_sink_b(1) + + self.tb.connect(src, enc_block, snk) + self.tb.run() + + res = np.array(snk.data()).astype(dtype=int) + self.assertTupleEqual(tuple(res), tuple(ref)) + + def test_004_big_input(self): + num_blocks = 30 + block_size = 1024 + num_info_bits = block_size // 8 + + data, ref, polar_encoder = self.get_test_data(block_size, num_info_bits, num_blocks) + src = blocks.vector_source_b(data, False) + enc_block = extended_encoder(polar_encoder, None, '11') + snk = blocks.vector_sink_b(1) + + self.tb.connect(src, enc_block, snk) + self.tb.run() + + res = np.array(snk.data()).astype(dtype=int) + self.assertTupleEqual(tuple(res), tuple(ref)) + + def get_test_data(self, block_size, num_info_bits, num_blocks): + # helper function to set up test data and together with encoder object. + num_frozen_bits = block_size - num_info_bits + frozen_bit_positions = cc.frozen_bit_positions(block_size, num_info_bits, 0.0) + frozen_bit_values = np.array([0] * num_frozen_bits,) + python_encoder = PolarEncoder(block_size, num_info_bits, frozen_bit_positions, frozen_bit_values) + + data = np.array([], dtype=int) + ref = np.array([], dtype=int) + for i in range(num_blocks): + d = np.random.randint(2, size=num_info_bits) + data = np.append(data, d) + ref = np.append(ref, python_encoder.encode_systematic(d)) + polar_encoder = fec.polar_encoder_systematic.make(block_size, num_info_bits, frozen_bit_positions) + return data, ref, polar_encoder + + +if __name__ == '__main__': + gr_unittest.run(test_polar_encoder_systematic) + + diff --git a/gr-fec/swig/fec_swig.i b/gr-fec/swig/fec_swig.i index 41aca1476e..2641931cda 100644 --- a/gr-fec/swig/fec_swig.i +++ b/gr-fec/swig/fec_swig.i @@ -58,6 +58,8 @@ #include "gnuradio/fec/puncture_bb.h" #include "gnuradio/fec/puncture_ff.h" #include "gnuradio/fec/depuncture_bb.h" +#include "gnuradio/fec/ldpc_encoder.h" +#include "gnuradio/fec/ldpc_decoder.h" #include "gnuradio/fec/tpc_encoder.h" #include "gnuradio/fec/tpc_decoder.h" #include "gnuradio/fec/polar_encoder.h" @@ -65,7 +67,8 @@ #include "gnuradio/fec/polar_common.h" #include "gnuradio/fec/polar_decoder_sc_list.h" #include "gnuradio/fec/polar_decoder_common.h" -#include "gnuradio/fec/ldpc_encoder.h" +#include "gnuradio/fec/polar_encoder_systematic.h" +#include "gnuradio/fec/polar_decoder_sc_systematic.h" %} %include "gnuradio/fec/generic_decoder.h" @@ -97,6 +100,8 @@ %include "gnuradio/fec/polar_common.h" %include "gnuradio/fec/polar_decoder_sc_list.h" %include "gnuradio/fec/polar_decoder_common.h" +%include "gnuradio/fec/polar_encoder_systematic.h" +%include "gnuradio/fec/polar_decoder_sc_systematic.h" %include "gnuradio/fec/ldpc_encoder.h" |