[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Commit-gnuradio] [gnuradio] 03/25: polar: SC and SC List decoder implem
From: |
git |
Subject: |
[Commit-gnuradio] [gnuradio] 03/25: polar: SC and SC List decoder implemented in C++ |
Date: |
Wed, 23 Sep 2015 14:51:36 +0000 (UTC) |
This is an automated email from the git hooks/post-receive script.
jcorgan pushed a commit to branch master
in repository gnuradio.
commit 13592802e792a417b1db511dbb1d0445ff4955c8
Author: Johannes Demel <address@hidden>
Date: Thu Jun 18 12:14:32 2015 +0200
polar: SC and SC List decoder implemented in C++
---
gr-fec/examples/polar_encoder_decoder_chain.grc | 350 ++++++++++-----------
gr-fec/grc/fec_block_tree.xml | 2 +
gr-fec/grc/fec_polar_decoder_sc.xml | 50 +++
gr-fec/grc/fec_polar_decoder_sc_list.xml | 57 ++++
gr-fec/include/gnuradio/fec/CMakeLists.txt | 6 +-
gr-fec/include/gnuradio/fec/polar_common.h | 83 +++++
gr-fec/include/gnuradio/fec/polar_decoder_common.h | 87 +++++
gr-fec/include/gnuradio/fec/polar_decoder_sc.h | 65 ++++
.../include/gnuradio/fec/polar_decoder_sc_list.h | 69 ++++
gr-fec/include/gnuradio/fec/polar_encoder.h | 31 +-
gr-fec/lib/CMakeLists.txt | 7 +-
gr-fec/lib/polar_common.cc | 139 ++++++++
gr-fec/lib/polar_decoder_common.cc | 209 ++++++++++++
gr-fec/lib/polar_decoder_sc.cc | 99 ++++++
gr-fec/lib/polar_decoder_sc_list.cc | 123 ++++++++
gr-fec/lib/polar_encoder.cc | 162 ++++------
gr-fec/lib/scl_list.cc | 191 +++++++++++
gr-fec/lib/scl_list.h | 83 +++++
.../python/fec/polar/channel_construction_bec.py | 6 +
.../python/fec/polar/channel_construction_bsc.py | 17 -
gr-fec/python/fec/polar/decoder.py | 15 +-
gr-fec/python/fec/polar/helper_functions.py | 6 +-
gr-fec/python/fec/polar/testbed.py | 23 +-
gr-fec/python/fec/qa_polar_decoder_sc.py | 152 +++++++++
gr-fec/python/fec/qa_polar_decoder_sc_list.py | 157 +++++++++
gr-fec/python/fec/qa_polar_encoder.py | 23 +-
gr-fec/swig/fec_swig.i | 8 +
27 files changed, 1865 insertions(+), 355 deletions(-)
diff --git a/gr-fec/examples/polar_encoder_decoder_chain.grc
b/gr-fec/examples/polar_encoder_decoder_chain.grc
index c648aea..7cab62d 100644
--- a/gr-fec/examples/polar_encoder_decoder_chain.grc
+++ b/gr-fec/examples/polar_encoder_decoder_chain.grc
@@ -18,7 +18,17 @@
</param>
<param>
<key>comment</key>
- <value></value>
+ <value># for rough throughput measurements.
+
+ tb = polar_encoder_decoder_chain()
+ start_time = time.time()
+ tb.start()
+ tb.wait()
+ stop_time = time.time()
+ samps = 2 ** 22
+ diff = stop_time - start_time
+ throughput = tb.head_samps / diff
+ print("exe time:", diff, ", with ", tb.head_samps, "samps, throughput: ",
throughput)</value>
</param>
<param>
<key>description</key>
@@ -74,42 +84,18 @@
</param>
</block>
<block>
- <key>variable_cc_decoder_def</key>
- <param>
- <key>padding</key>
- <value>False</value>
- </param>
+ <key>variable</key>
<param>
<key>comment</key>
<value></value>
</param>
<param>
- <key>k</key>
- <value>7</value>
- </param>
- <param>
- <key>dim1</key>
- <value>1</value>
- </param>
- <param>
- <key>dim2</key>
- <value>1</value>
- </param>
- <param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
- <key>state_end</key>
- <value>-1</value>
- </param>
- <param>
- <key>framebits</key>
- <value>2048</value>
- </param>
- <param>
<key>_coordinate</key>
- <value>(640, 35)</value>
+ <value>(360, 11)</value>
</param>
<param>
<key>_rotation</key>
@@ -117,66 +103,42 @@
</param>
<param>
<key>id</key>
- <value>cc_decoder</value>
+ <value>head_samps</value>
</param>
<param>
<key>value</key>
- <value>"ok"</value>
- </param>
- <param>
- <key>ndim</key>
- <value>0</value>
- </param>
- <param>
- <key>polys</key>
- <value>[79,109]</value>
- </param>
- <param>
- <key>rate</key>
- <value>2</value>
- </param>
- <param>
- <key>state_start</key>
- <value>0</value>
- </param>
- <param>
- <key>mode</key>
- <value>fec.CC_STREAMING</value>
+ <value>2 ** 22</value>
</param>
</block>
<block>
- <key>variable_cc_encoder_def</key>
+ <key>variable_polar_decoder_sc_def</key>
<param>
- <key>padding</key>
- <value>False</value>
- </param>
- <param>
- <key>comment</key>
- <value></value>
+ <key>num_info_bits</key>
+ <value>128</value>
</param>
<param>
- <key>k</key>
- <value>7</value>
+ <key>block_size</key>
+ <value>256</value>
</param>
<param>
- <key>dim1</key>
- <value>1</value>
+ <key>comment</key>
+ <value></value>
</param>
<param>
- <key>dim2</key>
- <value>1</value>
+ <key>_enabled</key>
+ <value>True</value>
</param>
<param>
- <key>_enabled</key>
- <value>False</value>
+ <key>frozen_bit_positions</key>
+ <value>range(128)</value>
</param>
<param>
- <key>framebits</key>
- <value>2048</value>
+ <key>frozen_bit_values</key>
+ <value>[0] * 128</value>
</param>
<param>
<key>_coordinate</key>
- <value>(304, 43)</value>
+ <value>(864, 555)</value>
</param>
<param>
<key>_rotation</key>
@@ -184,27 +146,11 @@
</param>
<param>
<key>id</key>
- <value>cc_encoder</value>
- </param>
- <param>
- <key>ndim</key>
- <value>0</value>
- </param>
- <param>
- <key>polys</key>
- <value>[79,109]</value>
- </param>
- <param>
- <key>rate</key>
- <value>2</value>
- </param>
- <param>
- <key>state_start</key>
- <value>0</value>
+ <value>polar_decoder</value>
</param>
<param>
- <key>mode</key>
- <value>fec.CC_STREAMING</value>
+ <key>is_packed</key>
+ <value>False</value>
</param>
</block>
<block>
@@ -235,7 +181,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(576, 307)</value>
+ <value>(192, 451)</value>
</param>
<param>
<key>_rotation</key>
@@ -251,7 +197,15 @@
</param>
</block>
<block>
- <key>variable</key>
+ <key>variable_polar_decoder_sc_list_def</key>
+ <param>
+ <key>num_info_bits</key>
+ <value>128</value>
+ </param>
+ <param>
+ <key>block_size</key>
+ <value>256</value>
+ </param>
<param>
<key>comment</key>
<value></value>
@@ -261,8 +215,16 @@
<value>True</value>
</param>
<param>
+ <key>frozen_bit_positions</key>
+ <value>range(128)</value>
+ </param>
+ <param>
+ <key>frozen_bit_values</key>
+ <value>[0,] * 128</value>
+ </param>
+ <param>
<key>_coordinate</key>
- <value>(10, 170)</value>
+ <value>(608, 539)</value>
</param>
<param>
<key>_rotation</key>
@@ -270,11 +232,15 @@
</param>
<param>
<key>id</key>
- <value>samp_rate</value>
+ <value>polar_scld</value>
</param>
<param>
- <key>value</key>
- <value>32000</value>
+ <key>max_list_size</key>
+ <value>8</value>
+ </param>
+ <param>
+ <key>is_packed</key>
+ <value>False</value>
</param>
</block>
<block>
@@ -297,7 +263,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(136, 227)</value>
+ <value>(0, 323)</value>
</param>
<param>
<key>_rotation</key>
@@ -325,7 +291,7 @@
</param>
<param>
<key>num_samps</key>
- <value>2 ** 10</value>
+ <value>2 ** 10 </value>
</param>
<param>
<key>type</key>
@@ -337,7 +303,7 @@
</param>
</block>
<block>
- <key>blocks_char_to_float</key>
+ <key>blocks_add_const_vxx</key>
<param>
<key>alias</key>
<value></value>
@@ -347,16 +313,20 @@
<value></value>
</param>
<param>
+ <key>const</key>
+ <value>1.0</value>
+ </param>
+ <param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
- <value>False</value>
+ <value>True</value>
</param>
<param>
<key>_coordinate</key>
- <value>(1272, 251)</value>
+ <value>(752, 347)</value>
</param>
<param>
<key>_rotation</key>
@@ -364,7 +334,11 @@
</param>
<param>
<key>id</key>
- <value>blocks_char_to_float_0</value>
+ <value>blocks_add_const_vxx_0</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>float</value>
</param>
<param>
<key>maxoutbuf</key>
@@ -375,16 +349,12 @@
<value>0</value>
</param>
<param>
- <key>scale</key>
- <value>10</value>
- </param>
- <param>
<key>vlen</key>
<value>1</value>
</param>
</block>
<block>
- <key>blocks_head</key>
+ <key>blocks_char_to_float</key>
<param>
<key>alias</key>
<value></value>
@@ -399,11 +369,11 @@
</param>
<param>
<key>_enabled</key>
- <value>True</value>
+ <value>False</value>
</param>
<param>
<key>_coordinate</key>
- <value>(1080, 363)</value>
+ <value>(1112, 347)</value>
</param>
<param>
<key>_rotation</key>
@@ -411,7 +381,7 @@
</param>
<param>
<key>id</key>
- <value>blocks_head_0</value>
+ <value>blocks_char_to_float_0</value>
</param>
<param>
<key>maxoutbuf</key>
@@ -422,12 +392,8 @@
<value>0</value>
</param>
<param>
- <key>num_items</key>
- <value>2 ** 32</value>
- </param>
- <param>
- <key>type</key>
- <value>byte</value>
+ <key>scale</key>
+ <value>1.0</value>
</param>
<param>
<key>vlen</key>
@@ -435,16 +401,12 @@
</param>
</block>
<block>
- <key>blocks_null_sink</key>
+ <key>blocks_char_to_float</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
- <key>bus_conns</key>
- <value>[[0,],]</value>
- </param>
- <param>
<key>comment</key>
<value></value>
</param>
@@ -458,7 +420,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(1256, 368)</value>
+ <value>(616, 347)</value>
</param>
<param>
<key>_rotation</key>
@@ -466,15 +428,19 @@
</param>
<param>
<key>id</key>
- <value>blocks_null_sink_0</value>
+ <value>blocks_char_to_float_0_0</value>
</param>
<param>
- <key>type</key>
- <value>byte</value>
+ <key>maxoutbuf</key>
+ <value>0</value>
</param>
<param>
- <key>num_inputs</key>
- <value>1</value>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>scale</key>
+ <value>-0.5</value>
</param>
<param>
<key>vlen</key>
@@ -482,7 +448,7 @@
</param>
</block>
<block>
- <key>blocks_pack_k_bits_bb</key>
+ <key>blocks_head</key>
<param>
<key>alias</key>
<value></value>
@@ -501,7 +467,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(408, 251)</value>
+ <value>(944, 459)</value>
</param>
<param>
<key>_rotation</key>
@@ -509,11 +475,7 @@
</param>
<param>
<key>id</key>
- <value>blocks_pack_k_bits_bb_0</value>
- </param>
- <param>
- <key>k</key>
- <value>8</value>
+ <value>blocks_head_0</value>
</param>
<param>
<key>maxoutbuf</key>
@@ -523,14 +485,30 @@
<key>minoutbuf</key>
<value>0</value>
</param>
+ <param>
+ <key>num_items</key>
+ <value>head_samps</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>byte</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
</block>
<block>
- <key>blocks_unpack_k_bits_bb</key>
+ <key>blocks_null_sink</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
+ <key>bus_conns</key>
+ <value>[[0,],]</value>
+ </param>
+ <param>
<key>comment</key>
<value></value>
</param>
@@ -544,7 +522,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(904, 363)</value>
+ <value>(1160, 464)</value>
</param>
<param>
<key>_rotation</key>
@@ -552,23 +530,27 @@
</param>
<param>
<key>id</key>
- <value>blocks_unpack_k_bits_bb_0</value>
+ <value>blocks_null_sink_0</value>
</param>
<param>
- <key>k</key>
- <value>8</value>
+ <key>type</key>
+ <value>byte</value>
</param>
<param>
- <key>maxoutbuf</key>
- <value>0</value>
+ <key>num_inputs</key>
+ <value>1</value>
</param>
<param>
- <key>minoutbuf</key>
- <value>0</value>
+ <key>vlen</key>
+ <value>1</value>
</param>
</block>
<block>
- <key>fec_generic_decoder</key>
+ <key>fec_extended_decoder</key>
+ <param>
+ <key>ann</key>
+ <value>None</value>
+ </param>
<param>
<key>alias</key>
<value></value>
@@ -582,16 +564,16 @@
<value></value>
</param>
<param>
- <key>decoder</key>
- <value>cc_decoder</value>
+ <key>decoder_list</key>
+ <value>polar_scld</value>
</param>
<param>
<key>_enabled</key>
- <value>False</value>
+ <value>True</value>
</param>
<param>
<key>_coordinate</key>
- <value>(1040, 251)</value>
+ <value>(872, 323)</value>
</param>
<param>
<key>_rotation</key>
@@ -599,11 +581,7 @@
</param>
<param>
<key>id</key>
- <value>fec_generic_decoder_0</value>
- </param>
- <param>
- <key>itype</key>
- <value>byte</value>
+ <value>fec_extended_decoder_0</value>
</param>
<param>
<key>maxoutbuf</key>
@@ -614,12 +592,20 @@
<value>0</value>
</param>
<param>
- <key>otype</key>
- <value>byte</value>
+ <key>puncpat</key>
+ <value>'11'</value>
+ </param>
+ <param>
+ <key>threadtype</key>
+ <value>none</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>fec_extended_decoder</value>
</param>
</block>
<block>
- <key>fec_generic_encoder</key>
+ <key>fec_extended_encoder</key>
<param>
<key>alias</key>
<value></value>
@@ -629,20 +615,20 @@
<value></value>
</param>
<param>
- <key>encoder</key>
- <value>polar_encoder</value>
- </param>
- <param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
- <value>True</value>
+ <value>False</value>
+ </param>
+ <param>
+ <key>encoder_list</key>
+ <value>polar_encoder</value>
</param>
<param>
<key>_coordinate</key>
- <value>(576, 251)</value>
+ <value>(192, 331)</value>
</param>
<param>
<key>_rotation</key>
@@ -650,11 +636,7 @@
</param>
<param>
<key>id</key>
- <value>fec_generic_encoder_0</value>
- </param>
- <param>
- <key>itype</key>
- <value>byte</value>
+ <value>fec_extended_encoder_0</value>
</param>
<param>
<key>maxoutbuf</key>
@@ -665,8 +647,12 @@
<value>0</value>
</param>
<param>
- <key>otype</key>
- <value>byte</value>
+ <key>puncpat</key>
+ <value>'11'</value>
+ </param>
+ <param>
+ <key>threadtype</key>
+ <value>none</value>
</param>
</block>
<block>
@@ -732,7 +718,7 @@
</param>
<param>
<key>_coordinate</key>
- <value>(1432, 235)</value>
+ <value>(1256, 331)</value>
</param>
<param>
<key>gui_hint</key>
@@ -1061,55 +1047,55 @@
</block>
<connection>
<source_block_id>analog_random_source_x_0</source_block_id>
- <sink_block_id>blocks_pack_k_bits_bb_0</sink_block_id>
+ <sink_block_id>blocks_char_to_float_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_char_to_float_0</source_block_id>
- <sink_block_id>qtgui_time_sink_x_0</sink_block_id>
+ <source_block_id>analog_random_source_x_0</source_block_id>
+ <sink_block_id>fec_extended_encoder_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_head_0</source_block_id>
- <sink_block_id>blocks_null_sink_0</sink_block_id>
+ <source_block_id>blocks_add_const_vxx_0</source_block_id>
+ <sink_block_id>fec_extended_decoder_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_pack_k_bits_bb_0</source_block_id>
- <sink_block_id>fec_generic_encoder_0</sink_block_id>
+ <source_block_id>blocks_char_to_float_0</source_block_id>
+ <sink_block_id>qtgui_time_sink_x_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>blocks_unpack_k_bits_bb_0</source_block_id>
- <sink_block_id>blocks_head_0</sink_block_id>
+ <source_block_id>blocks_char_to_float_0_0</source_block_id>
+ <sink_block_id>blocks_add_const_vxx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>fec_generic_decoder_0</source_block_id>
- <sink_block_id>blocks_char_to_float_0</sink_block_id>
+ <source_block_id>blocks_head_0</source_block_id>
+ <sink_block_id>blocks_null_sink_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>fec_generic_encoder_0</source_block_id>
+ <source_block_id>fec_extended_decoder_0</source_block_id>
<sink_block_id>blocks_char_to_float_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>fec_generic_encoder_0</source_block_id>
- <sink_block_id>blocks_unpack_k_bits_bb_0</sink_block_id>
+ <source_block_id>fec_extended_decoder_0</source_block_id>
+ <sink_block_id>blocks_head_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
- <source_block_id>fec_generic_encoder_0</source_block_id>
- <sink_block_id>fec_generic_decoder_0</sink_block_id>
+ <source_block_id>fec_extended_encoder_0</source_block_id>
+ <sink_block_id>blocks_char_to_float_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
diff --git a/gr-fec/grc/fec_block_tree.xml b/gr-fec/grc/fec_block_tree.xml
index f2f2c5b..d15ef26 100644
--- a/gr-fec/grc/fec_block_tree.xml
+++ b/gr-fec/grc/fec_block_tree.xml
@@ -15,6 +15,8 @@
<block>variable_ldpc_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>
</cat>
<cat>
<name>Encoders</name>
diff --git a/gr-fec/grc/fec_polar_decoder_sc.xml
b/gr-fec/grc/fec_polar_decoder_sc.xml
new file mode 100644
index 0000000..e7cb1ea
--- /dev/null
+++ b/gr-fec/grc/fec_polar_decoder_sc.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0"?>
+<block>
+ <name>POLAR Decoder SC Definition</name>
+ <key>variable_polar_decoder_sc_def</key>
+ <import>from gnuradio import fec</import>
+ <var_make>
+self.$(id) = $(id) = fec.polar_decoder_sc.make($block_size, $num_info_bits,
$frozen_bit_positions, $frozen_bit_values, $is_packed)
+ </var_make>
+ <var_value>fec.polar_decoder_sc.make($block_size, $num_info_bits,
$frozen_bit_positions, $frozen_bit_values, $is_packed)</var_value>
+ <make></make>
+
+ <param>
+ <name>Packed Bits</name>
+ <key>is_packed</key>
+ <value>False</value>
+ <type>enum</type>
+ <option>
+ <name>No</name>
+ <key>False</key>
+ </option>
+ <option>
+ <name>Yes</name>
+ <key>True</key>
+ </option>
+ </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>
+
+ <param>
+ <name>Frozen Bit Values</name>
+ <key>frozen_bit_values</key>
+ <type>int_vector</type>
+ </param>
+</block>
diff --git a/gr-fec/grc/fec_polar_decoder_sc_list.xml
b/gr-fec/grc/fec_polar_decoder_sc_list.xml
new file mode 100644
index 0000000..fa8208f
--- /dev/null
+++ b/gr-fec/grc/fec_polar_decoder_sc_list.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0"?>
+<block>
+ <name>POLAR Decoder SC List Definition</name>
+ <key>variable_polar_decoder_sc_list_def</key>
+ <import>from gnuradio import fec</import>
+ <var_make>
+self.$(id) = $(id) = fec.polar_decoder_sc_list.make($max_list_size,
$block_size, $num_info_bits, $frozen_bit_positions, $frozen_bit_values,
$is_packed)
+ </var_make>
+ <var_value>fec.polar_decoder_sc_list.make($max_list_size, $block_size,
$num_info_bits, $frozen_bit_positions, $frozen_bit_values,
$is_packed)</var_value>
+ <make></make>
+
+
+ <param>
+ <name>Packed Bits</name>
+ <key>is_packed</key>
+ <value>False</value>
+ <type>enum</type>
+ <option>
+ <name>No</name>
+ <key>False</key>
+ </option>
+ <option>
+ <name>Yes</name>
+ <key>True</key>
+ </option>
+ </param>
+
+ <param>
+ <name>Maximum List Size (L)</name>
+ <key>max_list_size</key>
+ <type>int</type>
+ </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>
+
+ <param>
+ <name>Frozen Bit Values</name>
+ <key>frozen_bit_values</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 0b3a5a3..1078225 100644
--- a/gr-fec/include/gnuradio/fec/CMakeLists.txt
+++ b/gr-fec/include/gnuradio/fec/CMakeLists.txt
@@ -47,6 +47,10 @@ install(FILES
puncture_bb.h
puncture_ff.h
depuncture_bb.h
- polar_encoder.h DESTINATION ${GR_INCLUDE_DIR}/gnuradio/fec
+ polar_encoder.h
+ polar_decoder_sc.h
+ polar_common.h
+ polar_decoder_sc_list.h
+ polar_decoder_common.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
new file mode 100644
index 0000000..59e0ad3
--- /dev/null
+++ b/gr-fec/include/gnuradio/fec/polar_common.h
@@ -0,0 +1,83 @@
+/* -*- 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_COMMON_H
+#define INCLUDED_FEC_POLAR_COMMON_H
+
+#include <gnuradio/fec/api.h>
+
+// Forward declaration for those objects. SWIG doesn't like them to be
#include'd.
+namespace gr {
+ namespace blocks {
+ namespace kernel {
+ class pack_k_bits;
+ class unpack_k_bits;
+ }
+ }
+}
+
+namespace gr {
+ namespace fec {
+
+ /*!
+ * \brief POLAR code common operations and attributes
+ * Erdal Arikan "Channel Polarization: A Method for Contructing
Capacity-Achieving Codes for Symmetric Binary-Input Memoryless Channels", 2009
+ */
+ class FEC_API polar_common
+ {
+ public:
+ polar_common(int block_size, int num_info_bits, std::vector<int>
frozen_bit_positions, std::vector<char> frozen_bit_values, bool is_packed =
false);
+ ~polar_common();
+
+ protected:
+ const int block_size()const {return d_block_size;};
+ const int block_power()const {return d_block_power;};
+ const int num_info_bits() const {return d_num_info_bits;};
+ const bool is_packed() const {return d_is_packed;};
+
+ // helper functions
+ long bit_reverse(long value, int active_bits) const;
+ void print_packed_bit_array(const unsigned char* printed_array, const
int num_bytes) const;
+ void print_unpacked_bit_array(const unsigned char* bits, const unsigned
int num_bytes) const;
+ const gr::blocks::kernel::unpack_k_bits* unpacker() const {return
d_unpacker;};
+ std::vector<int> info_bit_position_vector();
+
+ private:
+ int d_block_size; // depending on paper called 'N' or 'm'
+ int d_block_power;
+ int d_num_info_bits; // mostly abbreviated by 'K'
+ bool d_is_packed;
+ std::vector<int> d_frozen_bit_positions;
+ std::vector<int> d_info_bit_positions;
+ std::vector<char> d_frozen_bit_values;
+ void initialize_info_bit_position_vector();
+
+ gr::blocks::kernel::pack_k_bits *d_packer;
+ gr::blocks::kernel::unpack_k_bits *d_unpacker;
+ };
+
+ } // namespace fec
+} // namespace gr
+
+#endif /* INCLUDED_FEC_POLAR_COMMON_H */
+
diff --git a/gr-fec/include/gnuradio/fec/polar_decoder_common.h
b/gr-fec/include/gnuradio/fec/polar_decoder_common.h
new file mode 100644
index 0000000..50003b6
--- /dev/null
+++ b/gr-fec/include/gnuradio/fec/polar_decoder_common.h
@@ -0,0 +1,87 @@
+/* -*- 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_COMMON_H
+#define INCLUDED_FEC_POLAR_DECODER_COMMON_H
+
+#include <gnuradio/fec/api.h>
+#include <gnuradio/fec/generic_decoder.h>
+#include <gnuradio/fec/polar_common.h>
+
+namespace gr {
+ namespace fec {
+
+ /*!
+ * \brief Class holds common methods and attributes for different decoder
implementations
+ *
+ */
+ class FEC_API polar_decoder_common : public generic_decoder, public
polar_common
+ {
+ public:
+ polar_decoder_common(int block_size, int num_info_bits, std::vector<int>
frozen_bit_positions, std::vector<char> frozen_bit_values, bool is_packed);
+ ~polar_decoder_common();
+
+ // FECAPI
+ double rate(){return (1.0 * get_input_size() / get_output_size());};
+ int get_input_size(){return block_size() / (is_packed() ? 8 : 1);};
+ int get_output_size(){return num_info_bits() / (is_packed() ? 8 : 1);};
+ bool set_frame_size(unsigned int frame_size){return false;};
+ const char* get_output_conversion() {return "none";};
+
+ private:
+ const float D_LLR_FACTOR;
+
+ protected:
+ // calculate LLRs for stage
+ float llr_odd(const float la, const float lb) const;
+ float llr_even(const float la, const float lb, const unsigned char f)
const;
+ unsigned char llr_bit_decision(const float llr) const {return (llr <
0.0f) ? 1 : 0;};
+
+ // preparation for decoding
+ void initialize_llr_vector(float* llrs, const float* input);
+ // basic algorithm methods
+ void butterfly(float* llrs, const int stage, unsigned char* u, const int
u_num);
+ void even_u_values(unsigned char* u_even, const unsigned char* u, const
int u_num);
+ void odd_xor_even_values(unsigned char* u_xor, const unsigned char* u,
const int u_num);
+ void demortonize_values(unsigned char* u);
+
+ void extract_info_bits(unsigned char* output, const unsigned char*
input) const;
+
+ static void insert_bit_at_pos(unsigned char* u, const unsigned char ui,
const unsigned int pos){u[pos >> 3] ^= ui << (7 - (pos % 8));};
+ static unsigned char fetch_bit_at_pos(const unsigned char* u, const
unsigned int pos){return (u[pos >> 3] >> (7 - (pos % 8))) & 0x01;};
+
+ // info shared among all implementations.
+ std::vector<int> d_frozen_bit_positions;
+ std::vector<int> d_info_bit_positions;
+ std::vector<char> d_frozen_bit_values;
+
+ // helper functions.
+ void print_pretty_llr_vector(const float* llr_vec) const;
+
+ };
+
+ } // namespace fec
+} // namespace gr
+
+#endif /* INCLUDED_FEC_POLAR_DECODER_COMMON_H */
+
diff --git a/gr-fec/include/gnuradio/fec/polar_decoder_sc.h
b/gr-fec/include/gnuradio/fec/polar_decoder_sc.h
new file mode 100644
index 0000000..d9aa959
--- /dev/null
+++ b/gr-fec/include/gnuradio/fec/polar_decoder_sc.h
@@ -0,0 +1,65 @@
+/* -*- 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_H
+#define INCLUDED_FEC_POLAR_DECODER_SC_H
+
+#include <gnuradio/fec/api.h>
+#include <gnuradio/fec/polar_decoder_common.h>
+
+
+namespace gr {
+ namespace fec {
+
+ /*!
+ * \brief Standard successive cancellation decoder for POLAR codes
+ * It expects float input with bits mapped 1 --> -1, 0 --> 1
+ * Or: f = 1.0 - 2.0 * bit
+ *
+ */
+ class FEC_API polar_decoder_sc : public polar_decoder_common
+ {
+ public:
+ static generic_decoder::sptr make(int block_size, int num_info_bits,
std::vector<int> frozen_bit_positions, std::vector<char> frozen_bit_values,
bool is_packed = false);
+ ~polar_decoder_sc();
+
+ // FECAPI
+ void generic_work(void *in_buffer, void *out_buffer);
+
+ private:
+ polar_decoder_sc(int block_size, int num_info_bits, std::vector<int>
frozen_bit_positions, std::vector<char> frozen_bit_values, bool is_packed);
+
+ unsigned int d_frozen_bit_counter;
+
+ float* d_llr_vec;
+ unsigned char* d_u_hat_vec;
+
+ unsigned char retrieve_bit_from_llr(float llr, const int pos);
+ void sc_decode(float* llrs, unsigned char* u);
+ };
+
+ } // namespace fec
+} // namespace gr
+
+#endif /* INCLUDED_FEC_POLAR_DECODER_SC_H */
+
diff --git a/gr-fec/include/gnuradio/fec/polar_decoder_sc_list.h
b/gr-fec/include/gnuradio/fec/polar_decoder_sc_list.h
new file mode 100644
index 0000000..001ef66
--- /dev/null
+++ b/gr-fec/include/gnuradio/fec/polar_decoder_sc_list.h
@@ -0,0 +1,69 @@
+/* -*- 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_POLAR_FEC_DECODER_SC_LIST_H
+#define INCLUDED_POLAR_FEC_DECODER_SC_LIST_H
+
+#include <gnuradio/fec/api.h>
+#include <gnuradio/fec/polar_decoder_common.h>
+
+namespace gr {
+ namespace fec {
+ namespace polar {
+ class scl_list;
+ class path;
+ }
+
+ /*!
+ * \brief implements a successive cancellation list decoder for polar codes
+ * decoder is based on Tal, Vardy "List Decoding of Polar Codes", 2012
+ * LLR version: Balatsoukas-Stimming, Parizi, Burg "LLR-based Successive
Cancellation List Decoding of Polar Codes", 2015
+ *
+ */
+ class FEC_API polar_decoder_sc_list : public polar_decoder_common
+ {
+ public:
+ static generic_decoder::sptr make(int max_list_size, int block_size, int
num_info_bits, std::vector<int> frozen_bit_positions, std::vector<char>
frozen_bit_values, bool is_packed = false);
+ ~polar_decoder_sc_list();
+
+ // FECAPI
+ void generic_work(void *in_buffer, void *out_buffer);
+
+ private:
+ polar_decoder_sc_list(int max_list_size, int block_size, int
num_info_bits, std::vector<int> frozen_bit_positions, std::vector<char>
frozen_bit_values, bool is_packed);
+
+ unsigned int d_max_list_size;
+ polar::scl_list* d_scl;
+ unsigned int d_frozen_bit_counter;
+
+ void decode_list();
+ void calculate_next_llr_in_paths(int u_num);
+ void calculate_next_llr(polar::path* current_path, int u_num);
+ void update_with_frozenbit(const int u_num);
+
+ };
+ } // namespace fec
+} // namespace gr
+
+#endif /* INCLUDED_POLAR_FEC_DECODER_SC_LIST_H */
+
diff --git a/gr-fec/include/gnuradio/fec/polar_encoder.h
b/gr-fec/include/gnuradio/fec/polar_encoder.h
index 9cd37b8..85208bf 100644
--- a/gr-fec/include/gnuradio/fec/polar_encoder.h
+++ b/gr-fec/include/gnuradio/fec/polar_encoder.h
@@ -26,16 +26,7 @@
#include <gnuradio/fec/api.h>
#include <gnuradio/fec/generic_encoder.h>
-
-// Forward declaration for those objects. SWIG doesn't like them to be
#include'd.
-namespace gr {
- namespace blocks {
- namespace kernel {
- class pack_k_bits;
- class unpack_k_bits;
- }
- }
-}
+#include <gnuradio/fec/polar_common.h>
namespace gr {
namespace fec {
@@ -44,7 +35,7 @@ namespace gr {
* \brief POLAR encoder
*
*/
- class FEC_API polar_encoder : public generic_encoder
+ class FEC_API polar_encoder : public generic_encoder, public polar_common
{
public:
static generic_encoder::sptr make(int block_size, int num_info_bits,
std::vector<int> frozen_bit_positions, std::vector<char> frozen_bit_values,
bool is_packed = false);
@@ -53,17 +44,14 @@ namespace gr {
// 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 d_input_size;};
- int get_output_size(){return d_output_size;};
+ int get_input_size(){return num_info_bits() / (is_packed() ? 8 : 1);};
+ int get_output_size(){return block_size() / (is_packed() ? 8 : 1);};
bool set_frame_size(unsigned int frame_size){return false;};
+ const char* get_input_conversion(){return is_packed() ? "pack" :
"none";};
+ const char* get_output_conversion(){return is_packed() ? "packed_bits" :
"none";};
private:
polar_encoder(int block_size, int num_info_bits, std::vector<int>
frozen_bit_positions, std::vector<char> frozen_bit_values, bool is_packed);
- int d_block_size; // depending on paper called 'N' or 'm'
- int d_block_power;
- int d_input_size, d_output_size;
- bool d_is_packed;
- int d_num_info_bits; // mostly abbreviated by 'K'
std::vector<int> d_frozen_bit_positions;
std::vector<int> d_info_bit_positions;
std::vector<char> d_frozen_bit_values;
@@ -90,13 +78,6 @@ namespace gr {
void encode_packed_byte(unsigned char* target) const;
void encode_vector_packed_interbyte(unsigned char* target) const;
- // helper functions
- long bit_reverse(long value, int active_bits) const;
- void print_packed_bit_array(const unsigned char* printed_array, const
int num_bytes) const;
-
- gr::blocks::kernel::pack_k_bits *d_packer;
- gr::blocks::kernel::unpack_k_bits *d_unpacker;
-
};
} // namespace fec
diff --git a/gr-fec/lib/CMakeLists.txt b/gr-fec/lib/CMakeLists.txt
index 00cb061..0343ce3 100644
--- a/gr-fec/lib/CMakeLists.txt
+++ b/gr-fec/lib/CMakeLists.txt
@@ -81,7 +81,12 @@ list(APPEND gnuradio_fec_sources
tpc_common.cc
tpc_decoder.cc
tpc_encoder.cc
- polar_encoder.cc
+ polar_encoder.cc
+ polar_decoder_sc.cc
+ polar_common.cc
+ polar_decoder_sc_list.cc
+ polar_decoder_common.cc
+ scl_list.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
new file mode 100644
index 0000000..c76f530
--- /dev/null
+++ b/gr-fec/lib/polar_common.cc
@@ -0,0 +1,139 @@
+/* -*- 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_common.h>
+
+#include <gnuradio/blocks/pack_k_bits.h>
+#include <gnuradio/blocks/unpack_k_bits.h>
+
+#include <cmath>
+#include <stdexcept>
+#include <iostream>
+#include <vector>
+
+namespace gr
+{
+ namespace fec
+ {
+
+ polar_common::polar_common(int block_size, int num_info_bits,
+ std::vector<int> frozen_bit_positions,
+ std::vector<char> frozen_bit_values, bool
is_packed) :
+ d_block_size(block_size), d_block_power((int)
log2(float(block_size))), d_num_info_bits(num_info_bits),
d_is_packed(is_packed),
+ d_frozen_bit_positions(frozen_bit_positions),
d_frozen_bit_values(frozen_bit_values)
+ {
+ if(pow(2, d_block_power) != d_block_size) {
+ throw std::runtime_error("block_size MUST be a power of 2!");
+ }
+
+ unsigned int num_frozen_bits = d_block_size - d_num_info_bits;
+ if(num_frozen_bits != d_frozen_bit_positions.size()) {
+ throw std::runtime_error(
+ "number of frozen bit positions must equal block_size -
num_info_bits");
+ }
+
+ // According to papers frozen bits default to '0'.
+ while(d_frozen_bit_values.size() < num_frozen_bits) {
+ d_frozen_bit_values.push_back(0);
+ }
+ initialize_info_bit_position_vector();
+
+ d_packer = new gr::blocks::kernel::pack_k_bits(8);
+ d_unpacker = new gr::blocks::kernel::unpack_k_bits(8);
+ }
+
+
+ std::vector<int>
+ polar_common::info_bit_position_vector()
+ {
+ return d_info_bit_positions;
+ }
+
+ void
+ polar_common::initialize_info_bit_position_vector()
+ {
+ int num_frozen_bit = 0;
+ for(int i = 0; i < block_size(); i++) {
+ int frozen_pos = d_frozen_bit_positions.at(num_frozen_bit);
+ if(i != frozen_pos) {
+ d_info_bit_positions.push_back((int) i);
+ }
+ else {
+ num_frozen_bit++;
+ num_frozen_bit = std::min(num_frozen_bit, (int)
(d_frozen_bit_positions.size() - 1));
+ }
+ }
+ }
+
+ polar_common::~polar_common()
+ {
+ delete d_packer;
+ delete d_unpacker;
+ }
+
+ long
+ polar_common::bit_reverse(long value, int active_bits) const
+ {
+ long r = 0;
+ for(int i = 0; i < active_bits; i++) {
+ r <<= 1;
+ r |= value & 1;
+ value >>= 1;
+ }
+ return r;
+ }
+
+ void
+ polar_common::print_packed_bit_array(const unsigned char* printed_array,
+ const int num_bytes) const
+ {
+ int num_bits = num_bytes << 3;
+ unsigned char* temp = new unsigned char[num_bits];
+ unpacker()->unpack(temp, printed_array, num_bytes);
+
+ std::cout << "[";
+ for(int i = 0; i < num_bits; i++) {
+ std::cout << (int) *(temp + i) << " ";
+ }
+ std::cout << "]" << std::endl;
+
+ delete [] temp;
+ }
+
+ void
+ polar_common::print_unpacked_bit_array(const unsigned char* bits,
+ const unsigned int
num_bytes) const
+ {
+ std::cout << "( ";
+ for(unsigned int i = 0; i < num_bytes; i++){
+ std::cout << (int) *bits++ << ", ";
+ }
+ std::cout << ")" << std::endl;
+ }
+
+ } /* namespace fec */
+} /* namespace gr */
diff --git a/gr-fec/lib/polar_decoder_common.cc
b/gr-fec/lib/polar_decoder_common.cc
new file mode 100644
index 0000000..0285641
--- /dev/null
+++ b/gr-fec/lib/polar_decoder_common.cc
@@ -0,0 +1,209 @@
+/* -*- 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_common.h>
+#include <volk/volk.h>
+
+#include <cstdio>
+
+#define INT_BIT_MASK 0x80000000
+
+namespace gr {
+ namespace fec {
+
+ polar_decoder_common::polar_decoder_common(int block_size, int
num_info_bits,
+ std::vector<int>
frozen_bit_positions,
+ std::vector<char>
frozen_bit_values, bool is_packed) :
+ polar_common(block_size, num_info_bits, frozen_bit_positions,
frozen_bit_values, is_packed),
+ D_LLR_FACTOR(2.19722458f),
+ d_frozen_bit_positions(frozen_bit_positions),
+ d_frozen_bit_values(frozen_bit_values)
+ {
+ }
+
+ polar_decoder_common::~polar_decoder_common()
+ {
+ }
+
+ void
+ polar_decoder_common::initialize_llr_vector(float* llrs, const float*
input)
+ {
+ volk_32f_s32f_multiply_32f(llrs + block_size() * block_power(), input,
D_LLR_FACTOR, block_size());
+ }
+
+ float
+ polar_decoder_common::llr_odd(const float la, const float lb) const
+ {
+ return copysignf(1.0f, la) * copysignf(1.0f, lb) * std::min(fabs(la),
fabs(lb));
+ }
+
+ float
+ polar_decoder_common::llr_even(const float la, const float lb, const
unsigned char f) const
+ {
+ switch(f){
+ case 0:
+ return lb + la;
+ default:
+ return lb - la;
+ }
+ }
+
+ void
+ polar_decoder_common::butterfly(float* llrs, const int stage, unsigned
char* u, const int u_num)
+ {
+// if(!(block_power() > stage)){
+// return;
+// }
+ const int next_stage = stage + 1;
+ const int stage_half_block_size = block_size() >> next_stage;
+
+// // this is a natural bit order impl
+ float* next_llrs = llrs + block_size(); // LLRs are stored in an
consecutive array.
+ float* call_row_llr = llrs + u_num;
+ const int upper_right = u_num >> 1; // floor divide by 2.
+ const float* upper_right_llr_ptr = next_llrs + upper_right;
+ const float* lower_right_llr_ptr = upper_right_llr_ptr +
stage_half_block_size;
+
+ if(u_num % 2){
+ const unsigned char f = u[u_num - 1];
+// const unsigned char f = fetch_bit_at_pos(u, u_num - 1);
+ *call_row_llr = llr_even(*upper_right_llr_ptr, *lower_right_llr_ptr,
f);
+ return;
+ }
+
+ if(block_power() > next_stage) {
+ unsigned char* u_half = u + block_size();
+ odd_xor_even_values(u_half, u, u_num);
+ butterfly(next_llrs, next_stage, u_half, upper_right);
+
+ even_u_values(u_half, u, u_num);
+ butterfly(next_llrs + stage_half_block_size, next_stage, u_half,
upper_right);
+ }
+
+ *call_row_llr = llr_odd(*upper_right_llr_ptr, *lower_right_llr_ptr);
+ }
+
+
+ void
+ polar_decoder_common::even_u_values(unsigned char* u_even, const unsigned
char* u,
+ const int u_num)
+ {
+ u++;
+ for(int i = 1; i < u_num; i += 2){
+ *u_even++ = *u;
+ u += 2;
+ }
+
+// short* target = (short*) u_even;
+// short* src = (short*) u;
+//
+// const int iterations = std::max(1, u_num >> 3);
+// for(int i = 0; i < iterations; i++){
+// *target = *src << 1;
+// demortonize_values((unsigned char*) target);
+// u_even++;
+// target = (short*) u_even;
+// src++;
+// }
+ }
+
+ void
+ polar_decoder_common::odd_xor_even_values(unsigned char* u_xor, const
unsigned char* u,
+ const int u_num)
+ {
+ for(int i = 1; i < u_num; i += 2){
+ *u_xor++ = *u ^ *(u + 1);
+ u += 2;
+ }
+
+// short* target = (short*) u_xor;
+// short* src = (short*) u;
+//
+// const int iterations = std::max(1, u_num >> 3);
+// for(int i = 0; i < iterations; i++){
+// *target = *src ^ (*src << 1);
+// demortonize_values((unsigned char*) target);
+// u_xor++;
+// target = (short*) u_xor;
+// src++;
+// }
+ }
+
+ void
+ polar_decoder_common::extract_info_bits(unsigned char* output, const
unsigned char* input) const
+ {
+ unsigned int frozenbit_num = 0;
+ for(int i = 0; i < block_size(); i++){
+ if(frozenbit_num < d_frozen_bit_positions.size() &&
d_frozen_bit_positions.at(frozenbit_num) == i){
+ frozenbit_num++;
+ }
+ else{
+ *output++ = *input;
+ }
+ input++;
+ }
+
+// unsigned int frozenbit_num = 0;
+// for(int i = 0; i < block_size(); i++){
+// if(frozenbit_num < d_frozen_bit_positions.size() &&
d_frozen_bit_positions.at(frozenbit_num) == i){
+// frozenbit_num++;
+// }
+// else{
+// *output++ = fetch_bit_at_pos(input, i); // *input;
+// }
+// }
+ }
+
+ void
+ polar_decoder_common::demortonize_values(unsigned char* u)
+ {
+ *u &= 0xaa; // b0d0f0h0
+ *u = (*u ^ (*u << 1)) & 0xcc; // bd00fh00
+ *u = (*u ^ (*u << 2)) & 0xf0; // bdfh0000
+
+ unsigned char* u2 = u + 1;
+ *u2 &= 0xaa; // b0d0f0h0
+ *u2 = (*u2 ^ (*u2 << 1)) & 0xcc; // bd00fh00
+ *u2 = (*u2 ^ (*u2 << 2)) & 0xf0; // bdfh0000
+ *u ^= (*u2 >> 4);
+ }
+
+ void
+ polar_decoder_common::print_pretty_llr_vector(const float* llr_vec) const
+ {
+ for(int row = 0; row < block_size(); row++) {
+ std::cout << row << "->" << int(bit_reverse(row, block_power())) <<
":\t";
+ for(int stage = 0; stage < block_power() + 1; stage++) {
+ printf("%+4.2f, ", llr_vec[(stage * block_size()) + row]);
+ }
+ std::cout << std::endl;
+ }
+ }
+
+ } /* namespace fec */
+} /* namespace gr */
+
diff --git a/gr-fec/lib/polar_decoder_sc.cc b/gr-fec/lib/polar_decoder_sc.cc
new file mode 100644
index 0000000..e4f64b5
--- /dev/null
+++ b/gr-fec/lib/polar_decoder_sc.cc
@@ -0,0 +1,99 @@
+/* -*- 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.h>
+#include <volk/volk.h>
+
+#include <cmath>
+#include <cstdio>
+
+namespace gr
+{
+ namespace fec
+ {
+
+ generic_decoder::sptr
+ polar_decoder_sc::make(int block_size, int num_info_bits, std::vector<int>
frozen_bit_positions,
+ std::vector<char> frozen_bit_values, bool is_packed)
+ {
+ return generic_decoder::sptr(
+ new polar_decoder_sc(block_size, num_info_bits,
frozen_bit_positions, frozen_bit_values,
+ is_packed));
+ }
+
+ polar_decoder_sc::polar_decoder_sc(int block_size, int num_info_bits,
+ std::vector<int> frozen_bit_positions,
+ std::vector<char> frozen_bit_values,
bool is_packed) :
+ polar_decoder_common(block_size, num_info_bits, frozen_bit_positions,
frozen_bit_values, is_packed),
+ d_frozen_bit_counter(0)
+ {
+ 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));
+ }
+
+ polar_decoder_sc::~polar_decoder_sc()
+ {
+ volk_free(d_llr_vec);
+ volk_free(d_u_hat_vec);
+ }
+
+ void
+ polar_decoder_sc::generic_work(void* in_buffer, void* out_buffer)
+ {
+ const float *in = (const float*) in_buffer;
+ unsigned char *out = (unsigned char*) out_buffer;
+
+ initialize_llr_vector(d_llr_vec, in);
+ sc_decode(d_llr_vec, d_u_hat_vec);
+ extract_info_bits(out, d_u_hat_vec);
+ }
+
+ void
+ polar_decoder_sc::sc_decode(float* llrs, unsigned char* u)
+ {
+ d_frozen_bit_counter = 0;
+ memset(u, 0, sizeof(unsigned char) * block_size() * block_power());
+ for(int i = 0; i < block_size(); i++){
+ butterfly(llrs, 0, u, i);
+ u[i] = retrieve_bit_from_llr(llrs[i], i);
+// const unsigned char bit = retrieve_bit_from_llr(llrs[i], i);
+// insert_bit_at_pos(u, bit, i);
+ }
+ }
+
+ unsigned char
+ polar_decoder_sc::retrieve_bit_from_llr(float llr, const int pos)
+ {
+ if(d_frozen_bit_counter < d_frozen_bit_positions.size() && pos ==
d_frozen_bit_positions.at(d_frozen_bit_counter)){
+ return d_frozen_bit_values.at(d_frozen_bit_counter++);
+ }
+ return llr_bit_decision(llr);
+ }
+ } /* namespace fec */
+} /* namespace gr */
diff --git a/gr-fec/lib/polar_decoder_sc_list.cc
b/gr-fec/lib/polar_decoder_sc_list.cc
new file mode 100644
index 0000000..9340e30
--- /dev/null
+++ b/gr-fec/lib/polar_decoder_sc_list.cc
@@ -0,0 +1,123 @@
+/* -*- 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_list.h>
+#include <volk/volk.h>
+#include <scl_list.h>
+
+#include <cmath>
+#include <algorithm>
+
+namespace gr
+{
+ namespace fec
+ {
+
+ generic_decoder::sptr
+ polar_decoder_sc_list::make(int max_list_size, int block_size, int
num_info_bits,
+ std::vector<int> frozen_bit_positions,
+ std::vector<char> frozen_bit_values, bool
is_packed)
+ {
+ return generic_decoder::sptr(
+ new polar_decoder_sc_list(max_list_size, block_size, num_info_bits,
frozen_bit_positions,
+ frozen_bit_values, is_packed));
+ }
+
+ polar_decoder_sc_list::polar_decoder_sc_list(int max_list_size, int
block_size,
+ int num_info_bits,
+ std::vector<int>
frozen_bit_positions,
+ std::vector<char>
frozen_bit_values,
+ bool is_packed) :
+ polar_decoder_common(block_size, num_info_bits,
frozen_bit_positions, frozen_bit_values,
+ is_packed), d_max_list_size(max_list_size),
d_frozen_bit_counter(0)
+ {
+ d_scl = new polar::scl_list(max_list_size, block_size, block_power());
+ }
+
+ polar_decoder_sc_list::~polar_decoder_sc_list()
+ {
+ delete d_scl;
+ }
+
+ void
+ polar_decoder_sc_list::generic_work(void* in_buffer, void* out_buffer)
+ {
+ const float *in = (const float*) in_buffer;
+ unsigned char *out = (unsigned char*) out_buffer;
+ polar::path* init_path = d_scl->initial_path();
+ initialize_llr_vector(init_path->llr_vec, in);
+ memset(init_path->u_vec, 0, sizeof(unsigned char) * block_size() *
(block_power() + 1));
+ decode_list();
+ const polar::path* temp = d_scl->optimal_path();
+ extract_info_bits(out, temp->u_vec);
+ }
+
+ void
+ polar_decoder_sc_list::decode_list()
+ {
+ d_frozen_bit_counter = 0;
+ for(int i = 0; i < block_size(); i++){
+ calculate_next_llr_in_paths(i);
+ }
+
+ }
+
+ void
+ polar_decoder_sc_list::calculate_next_llr_in_paths(int u_num)
+ {
+ for(unsigned int i = 0; i < d_scl->active_size(); i++){
+ polar::path* current_path = d_scl->next_active_path();
+ calculate_next_llr(current_path, u_num);
+ }
+
+ // 1. if frozen bit, update with known value
+ if(d_frozen_bit_counter < d_frozen_bit_positions.size() && u_num ==
d_frozen_bit_positions.at(d_frozen_bit_counter)){
+ update_with_frozenbit(u_num);
+ }
+ // 2. info bit
+ else{
+ d_scl->set_info_bit(u_num);
+ }
+ }
+
+ void
+ polar_decoder_sc_list::update_with_frozenbit(const int u_num)
+ {
+ unsigned char frozen_bit = d_frozen_bit_values[d_frozen_bit_counter];
+ d_scl->set_frozen_bit(frozen_bit, u_num);
+ d_frozen_bit_counter++;
+ }
+
+ void
+ polar_decoder_sc_list::calculate_next_llr(polar::path* current_path, int
u_num)
+ {
+ butterfly(current_path->llr_vec, 0, current_path->u_vec, u_num);
+ }
+ } /* namespace fec */
+} /* namespace gr */
+
+
diff --git a/gr-fec/lib/polar_encoder.cc b/gr-fec/lib/polar_encoder.cc
index 1214e80..7187ea6 100644
--- a/gr-fec/lib/polar_encoder.cc
+++ b/gr-fec/lib/polar_encoder.cc
@@ -33,83 +33,63 @@
#include <gnuradio/blocks/pack_k_bits.h>
#include <gnuradio/blocks/unpack_k_bits.h>
-namespace gr {
- namespace fec {
+namespace gr
+{
+ namespace fec
+ {
generic_encoder::sptr
polar_encoder::make(int block_size, int num_info_bits, std::vector<int>
frozen_bit_positions,
std::vector<char> frozen_bit_values, bool is_packed)
{
- return generic_encoder::sptr(new polar_encoder(block_size,
num_info_bits, frozen_bit_positions, frozen_bit_values, is_packed));
+ return generic_encoder::sptr(
+ new polar_encoder(block_size, num_info_bits, frozen_bit_positions,
frozen_bit_values,
+ is_packed));
}
- polar_encoder::polar_encoder(int block_size, int num_info_bits,
std::vector<int> frozen_bit_positions, std::vector<char> frozen_bit_values,
bool is_packed):
- d_block_size(block_size),
- d_input_size(num_info_bits / (is_packed ? 8 : 1)),
- d_output_size(block_size / (is_packed ? 8 : 1)),
- d_is_packed(is_packed),
- d_num_info_bits(num_info_bits),
- d_frozen_bit_positions(frozen_bit_positions),
- d_frozen_bit_values(frozen_bit_values)
+ polar_encoder::polar_encoder(int block_size, int num_info_bits,
+ std::vector<int> frozen_bit_positions,
+ std::vector<char> frozen_bit_values, bool
is_packed) :
+ polar_common(block_size, num_info_bits, frozen_bit_positions,
frozen_bit_values, is_packed),
+ d_frozen_bit_positions(frozen_bit_positions),
+ d_frozen_bit_values(frozen_bit_values)
{
- int n = (int) log2(float(block_size));
- d_block_power = n;
- if(pow(2, n) != block_size){
- throw std::runtime_error("block_size MUST be a power of 2!");
- }
-
- unsigned int num_frozen_bits = d_block_size - d_num_info_bits;
- if(num_frozen_bits != d_frozen_bit_positions.size()){
- throw std::runtime_error("number of frozen bit positions must equal
block_size - num_info_bits");
- }
+ unsigned int num_frozen_bits = block_size - num_info_bits;
- while(d_frozen_bit_values.size() < num_frozen_bits){
+ while(d_frozen_bit_values.size() < num_frozen_bits) {
d_frozen_bit_values.push_back(0);
}
- int k = 8;
- d_unpacker = new gr::blocks::kernel::unpack_k_bits(k);
- d_packer = new gr::blocks::kernel::pack_k_bits(k);
-
setup_frozen_bit_inserter();
}
void
polar_encoder::setup_frozen_bit_inserter()
{
- d_block_array = (unsigned char*) volk_malloc(d_block_size >> 3,
volk_get_alignment());
- d_frozen_bit_prototype = (unsigned char*) volk_malloc(d_block_size >> 3,
volk_get_alignment());
- memset(d_frozen_bit_prototype, 0, d_block_size >> 3);
+ d_block_array = (unsigned char*) volk_malloc(block_size() >> 3,
volk_get_alignment());
+ d_frozen_bit_prototype = (unsigned char*) volk_malloc(block_size() >> 3,
+
volk_get_alignment());
+ memset(d_frozen_bit_prototype, 0, block_size() >> 3);
- for(unsigned int i = 0; i < d_frozen_bit_positions.size(); i++){
- int rev_pos = (int) bit_reverse((long) d_frozen_bit_positions.at(i),
d_block_power);
+ for(unsigned int i = 0; i < d_frozen_bit_positions.size(); i++) {
+ int rev_pos = (int) bit_reverse((long) d_frozen_bit_positions.at(i),
block_power());
unsigned char frozen_bit = (unsigned char) d_frozen_bit_values.at(i);
-
insert_unpacked_bit_into_packed_array_at_position(d_frozen_bit_prototype,
frozen_bit, rev_pos);
+
insert_unpacked_bit_into_packed_array_at_position(d_frozen_bit_prototype,
frozen_bit,
+ rev_pos);
}
-// print_packed_bit_array(d_frozen_bit_prototype, d_block_size >> 3);
-
- int num_frozen_bit = 0;
- for(int i = 0; i < d_block_size; i++){
- int frozen_pos = d_frozen_bit_positions.at(num_frozen_bit);
- if(i != frozen_pos){
- d_info_bit_positions.push_back((int) bit_reverse((long) i,
d_block_power));
- }
- else{
- num_frozen_bit++;
- num_frozen_bit = std::min(num_frozen_bit, (int)
(d_frozen_bit_positions.size() - 1));
- }
+ std::vector<int> temp_vec = info_bit_position_vector();
+ for(unsigned int i = 0; i < temp_vec.size(); i++){
+ d_info_bit_positions.push_back((int) bit_reverse((long)
temp_vec.at(i), block_power()));
}
- if((int) d_info_bit_positions.size() != d_num_info_bits){
+
+ if((int) d_info_bit_positions.size() != num_info_bits()) {
throw std::runtime_error("number of info bit positions MUST equal
num_info_bits (K)!");
}
}
polar_encoder::~polar_encoder()
{
- delete d_unpacker;
- delete d_packer;
-
volk_free(d_block_array);
volk_free(d_frozen_bit_prototype);
}
@@ -120,14 +100,14 @@ namespace gr {
const unsigned char *in = (const unsigned char*) in_buffer;
unsigned char *out = (unsigned char*) out_buffer;
- if(d_is_packed){
+ if(is_packed()) {
insert_packed_frozen_bits_and_reverse(out, in);
encode_vector_packed(out);
}
- else{
+ else {
insert_unpacked_frozen_bits_and_reverse(d_block_array, in);
encode_vector_packed(d_block_array);
- d_unpacker->unpack(out, d_block_array, d_block_size >> 3);
+ unpacker()->unpack(out, d_block_array, block_size() >> 3);
}
// insert_frozen_bits(d_block_array, in);
@@ -145,8 +125,8 @@ namespace gr {
void
polar_encoder::encode_vector_packed_subbyte(unsigned char* target) const
{
- int num_bytes_per_block = d_block_size >> 3;
- while(num_bytes_per_block){
+ int num_bytes_per_block = block_size() >> 3;
+ while(num_bytes_per_block) {
encode_packed_byte(target);
++target;
--num_bytes_per_block;
@@ -168,15 +148,15 @@ namespace gr {
{
int branch_byte_size = 1;
unsigned char* pos;
- int n_branches = d_block_size >> 4;
+ int n_branches = block_size() >> 4;
int byte = 0;
- for(int stage = 3; stage < d_block_power; ++stage){
+ for(int stage = 3; stage < block_power(); ++stage) {
pos = target;
- for(int branch = 0; branch < n_branches; ++branch){
+ for(int branch = 0; branch < n_branches; ++branch) {
byte = 0;
- while(byte < branch_byte_size){
+ while(byte < branch_byte_size) {
*pos ^= *(pos + branch_byte_size);
++pos;
++byte;
@@ -194,12 +174,13 @@ namespace gr {
polar_encoder::insert_unpacked_frozen_bits_and_reverse(unsigned char*
target,
const unsigned
char* input) const
{
- memcpy(target, d_frozen_bit_prototype, d_block_size >> 3);
+ memcpy(target, d_frozen_bit_prototype, block_size() >> 3);
const int* info_bit_positions_ptr = &d_info_bit_positions[0];
- const unsigned char* end_input = input + d_num_info_bits;
+ const unsigned char* end_input = input + num_info_bits();
int bit_pos = 7;
- while(input < end_input){
- insert_packet_bit_into_packed_array_at_position(target, *input++,
*info_bit_positions_ptr++, bit_pos);
+ while(input < end_input) {
+ insert_packet_bit_into_packed_array_at_position(target, *input++,
*info_bit_positions_ptr++,
+ bit_pos);
}
}
@@ -207,16 +188,16 @@ namespace gr {
polar_encoder::insert_packed_frozen_bits_and_reverse(unsigned char* target,
const unsigned char*
input) const
{
- memcpy(target, d_frozen_bit_prototype, d_block_size >> 3);
+ memcpy(target, d_frozen_bit_prototype, block_size() >> 3);
const int* info_bit_positions_ptr = &d_info_bit_positions[0];
int bit_num = 0;
unsigned char byte = *input;
int bit_pos;
- while(bit_num < d_num_info_bits){
+ while(bit_num < num_info_bits()) {
bit_pos = *info_bit_positions_ptr++;
insert_packet_bit_into_packed_array_at_position(target, byte, bit_pos,
bit_num % 8);
++bit_num;
- if(bit_num % 8 == 0){
+ if(bit_num % 8 == 0) {
++input;
byte = *input;
}
@@ -239,38 +220,22 @@ namespace gr {
const int
target_pos,
const int
bit_pos) const
{
- insert_unpacked_bit_into_packed_array_at_position(target, (bit >> (7 -
bit_pos)) & 0x01, target_pos);
- }
-
- void
- polar_encoder::print_packed_bit_array(const unsigned char* printed_array,
const int num_bytes) const
- {
- int num_bits = num_bytes << 3;
- unsigned char* temp = (unsigned char*) volk_malloc(num_bits,
volk_get_alignment());
- d_unpacker->unpack(temp, printed_array, num_bytes);
-
-
- std::cout << "[";
- for(int i = 0; i < num_bits; i++){
- std::cout << (int) *(temp + i) << " ";
- }
- std::cout << "]" << std::endl;
-
- volk_free(temp);
+ insert_unpacked_bit_into_packed_array_at_position(target, (bit >> (7 -
bit_pos)) & 0x01,
+ target_pos);
}
void
polar_encoder::insert_frozen_bits(unsigned char* target, const unsigned
char* input)
{
int frozen_num = 0;
- int num_frozen_bits = d_block_size - d_num_info_bits;
+ int num_frozen_bits = block_size() - num_info_bits();
int info_num = 0;
- for(int i = 0; i < d_block_size; i++){
- if(frozen_num < num_frozen_bits &&
d_frozen_bit_positions.at(frozen_num) == i){
+ for(int i = 0; i < block_size(); i++) {
+ if(frozen_num < num_frozen_bits &&
d_frozen_bit_positions.at(frozen_num) == i) {
target[i] = d_frozen_bit_values.at(frozen_num);
frozen_num++;
}
- else{
+ else {
target[i] = input[info_num];
info_num++;
}
@@ -280,19 +245,19 @@ namespace gr {
void
polar_encoder::bit_reverse_vector(unsigned char* target, const unsigned
char* input)
{
- for(int i = 0; i < d_block_size; i++){
- target[bit_reverse(long(i), d_block_power)] = input[i];
+ for(int i = 0; i < block_size(); i++) {
+ target[bit_reverse(long(i), block_power())] = input[i];
}
}
void
polar_encoder::encode_vector(unsigned char* target)
{
- for(int stage = 0; stage < d_block_power; stage++){
+ for(int stage = 0; stage < block_power(); stage++) {
int n_branches = pow(2, stage);
- int branch_elements = d_block_size / (2 * n_branches);
- for(int branch = 0; branch < n_branches; branch++){
- for(int e = 0; e < branch_elements; e++){
+ int branch_elements = block_size() / (2 * n_branches);
+ for(int branch = 0; branch < n_branches; branch++) {
+ for(int e = 0; e < branch_elements; e++) {
int pos = branch * branch_elements * 2 + e;
target[pos] ^= target[pos + branch_elements];
}
@@ -300,19 +265,6 @@ namespace gr {
}
}
- long
- polar_encoder::bit_reverse(long value, int active_bits) const
- {
- long r = 0;
- for(int i = 0; i < active_bits; i++){
- r <<= 1;
- r |= value & 1;
- value >>= 1;
- }
- return r;
- }
-
} /* namespace fec */
} /* namespace gr */
-
diff --git a/gr-fec/lib/scl_list.cc b/gr-fec/lib/scl_list.cc
new file mode 100644
index 0000000..6942bfb
--- /dev/null
+++ b/gr-fec/lib/scl_list.cc
@@ -0,0 +1,191 @@
+/* -*- 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.
+ */
+
+#include <scl_list.h>
+#include <cstring>
+#include <iostream>
+#include <algorithm>
+#include <volk/volk.h>
+
+namespace gr {
+ namespace fec {
+ namespace polar {
+
+ scl_list::scl_list(const unsigned int size, const unsigned int
block_size, const unsigned int block_power):
+ d_list_size(size), d_block_size(block_size),
d_block_power(block_power), d_num_buff_elements(block_size * (block_power + 1))
+ {
+ for(unsigned int i = 0; i < 2 * size; i++){
+ d_path_list.push_back(new path());
+ }
+
+ for(unsigned int i = 0; i < size; i++){
+ d_path_list[i]->llr_vec = (float*) volk_malloc(sizeof(float) *
d_num_buff_elements, volk_get_alignment());
+ memset(d_path_list[i]->llr_vec, 0, sizeof(float) *
d_num_buff_elements);
+ d_path_list[i]->u_vec = (unsigned char*) volk_malloc(sizeof(unsigned
char) * d_num_buff_elements, volk_get_alignment());
+ memset(d_path_list[i]->u_vec, 0, sizeof(unsigned char) *
d_num_buff_elements);
+ d_path_list[i]->owns_vectors = true;
+ }
+
+ d_path_list[0]->is_active = true;
+ d_active_path_counter = 1;
+ d_active_pos = 0;
+ }
+
+ scl_list::~scl_list()
+ {
+ for(unsigned int i = 0; i < d_path_list.size(); i++){
+ delete d_path_list[i];
+ }
+ }
+
+
+ const path*
+ scl_list::optimal_path()
+ {
+ const path* temp = *std::min_element(d_path_list.begin(),
d_path_list.begin() + d_active_path_counter, path_compare);
+ reset();
+ return temp;
+ }
+
+ void
+ scl_list::reset()
+ {
+ // leave 0th element active for next iteration
+ d_path_list[0]->path_metric = 0.0f;
+ for(unsigned int i = 1; i < d_path_list.size(); i++){
+ d_path_list[i]->is_active = false;
+ d_path_list[i]->path_metric = 0.0f;
+ }
+ d_active_path_counter = 1;
+ d_active_pos = 0;
+ }
+
+ void
+ scl_list::set_info_bit(const int bit_pos)
+ {
+ if(d_active_path_counter < d_list_size) {
+ const int offset = d_active_path_counter;
+ for(int i = 0; i < offset; i++) {
+ duplicate_path(d_path_list[i + offset], d_path_list[i]);
+ d_path_list[i]->path_metric =
update_path_metric(d_path_list[i]->path_metric,
+
d_path_list[i]->llr_vec[bit_pos], 0);
+ d_path_list[i + offset]->path_metric = update_path_metric(
+ d_path_list[i + offset]->path_metric, d_path_list[i +
offset]->llr_vec[bit_pos], 1);
+ d_path_list[i]->u_vec[bit_pos] = 0;
+// insert_bit_at_pos(d_path_list[i]->u_vec, 0, bit_pos);
+ d_path_list[i + offset]->u_vec[bit_pos] = 1;
+// insert_bit_at_pos(d_path_list[i + offset]->u_vec, 1, bit_pos);
+ }
+ }
+ else {
+
+ for(unsigned int i = 0; i < d_list_size; i++) {
+ branch_paths(d_path_list[i + d_list_size], d_path_list[i],
d_path_list[i]->llr_vec[bit_pos]);
+ }
+ std::sort(d_path_list.begin(), d_path_list.end(), path_compare);
+
+ for(unsigned int i = 0; i < d_list_size; i++) {
+ if(!d_path_list[i]->owns_vectors) {
+ int t_pos = d_list_size;
+ while(!d_path_list[t_pos]->owns_vectors) {
+ t_pos++;
+ }
+ steal_vector_ownership(d_path_list[i], d_path_list[t_pos]);
+ d_path_list[i]->u_vec[bit_pos] = 1;
+// insert_bit_at_pos(d_path_list[i]->u_vec, 1, bit_pos);
+ }
+ else{
+ d_path_list[i]->u_vec[bit_pos] = 0;
+// insert_bit_at_pos(d_path_list[i]->u_vec, 0, bit_pos);
+ }
+ }
+ }
+ d_active_pos = 0;
+ }
+
+ void
+ scl_list::branch_paths(path* target, path* original, const float llr)
+ {
+ target->path_metric = update_path_metric(original->path_metric, llr,
1);
+ original->path_metric = update_path_metric(original->path_metric, llr,
0);
+ target->llr_vec = original->llr_vec;
+ target->u_vec = original->u_vec;
+ }
+
+ void
+ scl_list::steal_vector_ownership(path* target, path* original)
+ {
+ memcpy(original->llr_vec, target->llr_vec, sizeof(float) *
d_num_buff_elements);
+ memcpy(original->u_vec, target->u_vec, sizeof(unsigned char) *
d_num_buff_elements);
+ target->llr_vec = original->llr_vec;
+ target->u_vec = original->u_vec;
+ target->owns_vectors = true;
+ original->owns_vectors = false;
+ }
+
+ void
+ scl_list::duplicate_path(path* target, const path* original)
+ {
+ memcpy(target->llr_vec, original->llr_vec, sizeof(float) *
d_num_buff_elements);
+ memcpy(target->u_vec, original->u_vec, sizeof(unsigned char) *
d_num_buff_elements);
+ target->path_metric = original->path_metric;
+ d_active_path_counter++;
+ target->is_active = true;
+ }
+
+ float
+ scl_list::update_path_metric(const float last_pm, const float llr,
+ const float ui) const
+ {
+ if((ui == 0 && llr > 0.0f) || (ui == 1 && llr < 0.0f)){
+// if(ui == (unsigned char) (0.5 * 1 - copysignf(1.0f, llr))){
+ return last_pm;
+ }
+ return last_pm + fabs(llr);
+ }
+
+ void
+ scl_list::set_frozen_bit(const unsigned char frozen_bit, const int
bit_pos)
+ {
+ for(unsigned int i = 0; i < d_active_path_counter; i++){
+// insert_bit_at_pos(d_path_list[i]->u_vec, frozen_bit, bit_pos);
+ d_path_list[i]->u_vec[bit_pos] = frozen_bit;
+ d_path_list[i]->path_metric =
update_path_metric(d_path_list[i]->path_metric,
d_path_list[i]->llr_vec[bit_pos], frozen_bit);
+ }
+ d_active_pos = 0;
+ }
+
+ path::path():
+ path_metric(0.0f), owns_vectors(false), is_active(false),
llr_vec(NULL), u_vec(NULL)
+ {
+ }
+
+ path::~path(){
+ if(owns_vectors){
+ volk_free(llr_vec);
+ volk_free(u_vec);
+ }
+ }
+
+ } /* namespace polar */
+ } /* namespace fec */
+} /* namespace gr */
diff --git a/gr-fec/lib/scl_list.h b/gr-fec/lib/scl_list.h
new file mode 100644
index 0000000..8f09198
--- /dev/null
+++ b/gr-fec/lib/scl_list.h
@@ -0,0 +1,83 @@
+/* -*- 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_SCL_LIST_H
+#define INCLUDED_FEC_SCL_LIST_H
+
+#include <vector>
+
+namespace gr {
+ namespace fec {
+ namespace polar {
+ struct path {
+ path();
+ ~path();
+ float path_metric;
+ bool owns_vectors;
+ bool is_active;
+ float* llr_vec;
+ unsigned char* u_vec;
+ };
+
+ /*!
+ * \brief List implementation for Successive Cancellation List decoders
+ *
+ */
+ class scl_list{
+ const unsigned int d_list_size;
+ const unsigned int d_block_size;
+ const unsigned int d_block_power;
+ const unsigned int d_num_buff_elements;
+ std::vector<path*> d_path_list;
+ unsigned int d_active_path_counter;
+ unsigned int d_active_pos;
+
+ float update_path_metric(const float last_pm, const float llr, const
float ui) const;
+ void duplicate_path(path* target, const path* original);
+ void branch_paths(path* target, path* original, const float llr);
+ void steal_vector_ownership(path* target, path* original);
+
+ static void insert_bit_at_pos(unsigned char* u, const unsigned char
ui, const unsigned int pos){u[pos >> 3] ^= ui << (7 - (pos % 8));};
+
+ // comparator for std::sort
+ static bool path_compare(path* first, path* second){return
first->path_metric < second->path_metric;};
+
+ public:
+ scl_list(const unsigned int list_size, const unsigned int block_size,
const unsigned int block_power);
+ virtual
+ ~scl_list();
+ const unsigned int size() const {return d_list_size;};
+ const unsigned int active_size() const {return d_active_path_counter;};
+
+ path* initial_path() const {return d_path_list[0];};
+ path* next_active_path(){return d_path_list[d_active_pos++];};
+ void set_frozen_bit(const unsigned char frozen_bit, const int bit_pos);
+ void set_info_bit(const int bit_pos);
+ const path* optimal_path();
+ void reset();
+ };
+
+ } /* namespace polar */
+ } /* namespace fec */
+} /* namespace gr */
+
+#endif /* INCLUDED_FEC_SCL_LIST_H */
diff --git a/gr-fec/python/fec/polar/channel_construction_bec.py
b/gr-fec/python/fec/polar/channel_construction_bec.py
index cd61f46..4d3654d 100644
--- a/gr-fec/python/fec/polar/channel_construction_bec.py
+++ b/gr-fec/python/fec/polar/channel_construction_bec.py
@@ -87,6 +87,12 @@ def get_frozen_bit_indices_from_capacities(chan_caps,
nfrozen):
return np.sort(indexes)
+def get_bec_frozen_indices(nblock, kfrozen, eta):
+ bec_caps = calculate_bec_channel_capacities(eta, nblock)
+ positions = get_frozen_bit_indices_from_capacities(bec_caps, kfrozen)
+ return positions
+
+
def bec_channel_contruction_tests():
n = 2 ** 10
k = n // 2
diff --git a/gr-fec/python/fec/polar/channel_construction_bsc.py
b/gr-fec/python/fec/polar/channel_construction_bsc.py
index 8cee7ce..2263bf0 100755
--- a/gr-fec/python/fec/polar/channel_construction_bsc.py
+++ b/gr-fec/python/fec/polar/channel_construction_bsc.py
@@ -23,23 +23,6 @@ from helper_functions import *
import matplotlib.pyplot as plt
-# def bit_reverse(value, n):
-# # is this really missing in NumPy???
-# bits = np.zeros(n, type(value))
-# for index in range(n):
-# mask = 1
-# mask = np.left_shift(mask, index)
-# bit = np.bitwise_and(value, mask)
-# bit = np.right_shift(bit, index)
-# bits[index] = bit
-# bits = bits[::-1]
-# result = 0
-# for index, bit in enumerate(bits):
-# bit = np.left_shift(bit, index)
-# result += bit
-# return result
-
-
def get_Bn(n):
# this is a bit reversal matrix.
lw = int(np.log2(n)) # number of used bits
diff --git a/gr-fec/python/fec/polar/decoder.py
b/gr-fec/python/fec/polar/decoder.py
index d74f1f9..ef7d700 100644
--- a/gr-fec/python/fec/polar/decoder.py
+++ b/gr-fec/python/fec/polar/decoder.py
@@ -122,16 +122,27 @@ class PolarDecoder(PolarCommon):
u = np.append(u, ui)
return u
+ def _llr_retrieve_bit(self, llr, pos):
+ f_index = np.where(self.frozen_bit_position == pos)[0]
+ if not f_index.size == 0:
+ ui = self.frozenbits[f_index][0]
+ else:
+ ui = self._llr_bit_decision(llr)
+ return ui
+
def _butterfly_decode_bits(self, pos, graph, u):
+ bit_num = u.size
llr = graph[pos][0]
- ui = self._llr_bit_decision(llr)
+ ui = self._llr_retrieve_bit(llr, bit_num)
+ # ui = self._llr_bit_decision(llr)
u = np.append(u, ui)
lower_right = pos + (self.N // 2)
la = graph[pos][1]
lb = graph[lower_right][1]
graph[lower_right][0] = self._llr_even(la, lb, ui)
llr = graph[lower_right][0]
- ui = self._llr_bit_decision(llr)
+ # ui = self._llr_bit_decision(llr)
+ ui = self._llr_retrieve_bit(llr, u.size)
u = np.append(u, ui)
return graph, u
diff --git a/gr-fec/python/fec/polar/helper_functions.py
b/gr-fec/python/fec/polar/helper_functions.py
index ffa4fc1..213f3cb 100644
--- a/gr-fec/python/fec/polar/helper_functions.py
+++ b/gr-fec/python/fec/polar/helper_functions.py
@@ -19,6 +19,7 @@
#
import numpy as np
+from channel_construction_bec import get_bec_frozen_indices
def is_power_of_two(num):
@@ -72,7 +73,8 @@ def pack_byte(bits):
def get_frozen_bit_positions(directory, n, k, p):
import glob, os
- os.chdir(directory)
+ if not os.getcwd().endswith(directory):
+ os.chdir(directory)
prefix = 'frozen_bit_positions_'
prefix_len = len(prefix)
for file in glob.glob("*.npy"):
@@ -90,7 +92,7 @@ def get_frozen_bit_positions(directory, n, k, p):
pstr = float(pstr[0][1:])
if n == nstr and k == kstr:
return np.load(filename)
- return np.arange(k)
+ return get_bec_frozen_indices(n, k, p)
def main():
diff --git a/gr-fec/python/fec/polar/testbed.py
b/gr-fec/python/fec/polar/testbed.py
index 4ace91e..bdf9ae4 100755
--- a/gr-fec/python/fec/polar/testbed.py
+++ b/gr-fec/python/fec/polar/testbed.py
@@ -67,6 +67,24 @@ def approx_value(la, lb):
return np.sign(la) * np.sign(lb) * np.minimum(np.abs(la), np.abs(lb))
+def path_metric_exact(last_pm, llr, ui):
+ return last_pm + np.log(1 + np.exp(-1. * llr * (1 - 2 * ui)))
+
+
+def path_metric_approx(last_pm, llr, ui):
+ if ui == int(.5 * (1 - np.sign(llr))):
+ return last_pm
+ return last_pm + np.abs(llr)
+
+
+def calculate_path_metric_vector(metric, llrs, us):
+ res = np.zeros(llrs.size)
+ res[0] = metric(0, llrs[0], us[0])
+ for i in range(1, llrs.size):
+ res[i] = metric(res[i - 1], llrs[i], us[i])
+ return res
+
+
def test_1024_rate_1_code():
# effectively a Monte-Carlo simulation for channel polarization.
ntests = 10000
@@ -135,11 +153,12 @@ def main():
# frozenbitposition = np.array((0, 1, 2, 3, 4, 5, 8, 9), dtype=int)
# print frozenbitposition
- test_enc_dec_chain()
+ # test_enc_dec_chain()
# test_1024_rate_1_code()
- # channel_analysis()
+ channel_analysis()
+
if __name__ == '__main__':
main()
\ No newline at end of file
diff --git a/gr-fec/python/fec/qa_polar_decoder_sc.py
b/gr-fec/python/fec/qa_polar_decoder_sc.py
new file mode 100644
index 0000000..f26bf9a
--- /dev/null
+++ b/gr-fec/python/fec/qa_polar_decoder_sc.py
@@ -0,0 +1,152 @@
+#!/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 Crypto.Cipher._AES import block_size
+
+from gnuradio import gr, gr_unittest, blocks
+import fec_swig as fec
+from _qa_helper import _qa_helper
+import numpy as np
+import os
+
+from extended_encoder import extended_encoder
+from extended_decoder import extended_decoder
+from polar.encoder import PolarEncoder
+from polar.decoder import PolarDecoder
+from polar.helper_functions import get_frozen_bit_positions
+# from polar.helper_functions import bit_reverse_vector
+
+# print('PID:', os.getpid())
+# raw_input('tell me smth')
+
+class test_polar_decoder_sc(gr_unittest.TestCase):
+
+ def setUp(self):
+ self.tb = gr.top_block()
+
+ def tearDown(self):
+ self.tb = None
+
+ def test_001_setup(self):
+ is_packed = False
+ block_size = 16
+ num_info_bits = 8
+ frozen_bit_positions = np.arange(block_size - num_info_bits)
+ frozen_bit_values = np.array([],)
+
+ polar_decoder = fec.polar_decoder_sc.make(block_size, num_info_bits,
frozen_bit_positions, frozen_bit_values, is_packed)
+
+ self.assertEqual(num_info_bits, polar_decoder.get_output_size())
+ self.assertEqual(block_size, polar_decoder.get_input_size())
+ self.assertFloatTuplesAlmostEqual((float(block_size) / num_info_bits,
), (polar_decoder.rate(), ))
+ self.assertFalse(polar_decoder.set_frame_size(10))
+
+ def test_002_one_vector(self):
+ print "test_002_one_vector"
+ is_packed = False
+ block_power = 8
+ block_size = 2 ** block_power
+ num_info_bits = 2 ** (block_power - 1)
+ num_frozen_bits = block_size - num_info_bits
+ frozen_bit_positions = get_frozen_bit_positions('polar', block_size,
num_frozen_bits, 0.11)
+ frozen_bit_values = np.array([0] * num_frozen_bits,)
+ print frozen_bit_positions
+
+ python_decoder = PolarDecoder(block_size, num_info_bits,
frozen_bit_positions, frozen_bit_values)
+
+ bits = np.ones(num_info_bits, dtype=int)
+ # bits = np.random.randint(2, size=num_info_bits)
+ encoder = PolarEncoder(block_size, num_info_bits,
frozen_bit_positions, frozen_bit_values)
+ data = encoder.encode(bits)
+ # data = np.array([0, 1, 1, 0, 1, 0, 1, 0], dtype=int)
+ gr_data = -2.0 * data + 1.0
+
+ polar_decoder = fec.polar_decoder_sc.make(block_size, num_info_bits,
frozen_bit_positions, frozen_bit_values, is_packed)
+ 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)
+
+ ref = python_decoder.decode(data)
+
+ print("input:", data)
+ print("res :", res)
+ print("ref :", ref)
+
+ self.assertTupleEqual(tuple(res), tuple(ref))
+
+ def test_003_stream(self):
+ print "test_002_stream"
+ nframes = 3
+ is_packed = False
+ block_power = 8
+ block_size = 2 ** block_power
+ num_info_bits = 2 ** (block_power - 1)
+ num_frozen_bits = block_size - num_info_bits
+ frozen_bit_positions = get_frozen_bit_positions('polar', block_size,
num_frozen_bits, 0.11)
+ frozen_bit_values = np.array([0] * num_frozen_bits,)
+ print frozen_bit_positions
+
+ python_decoder = PolarDecoder(block_size, num_info_bits,
frozen_bit_positions, frozen_bit_values)
+ 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):
+ b = np.random.randint(2, size=num_info_bits)
+ d = encoder.encode(b)
+ bits = np.append(bits, b)
+ data = np.append(data, d)
+ # bits = np.ones(num_info_bits, dtype=int)
+ # bits = np.random.randint(2, size=num_info_bits)
+ # data = encoder.encode(bits)
+ # data = np.array([0, 1, 1, 0, 1, 0, 1, 0], dtype=int)
+ gr_data = -2.0 * data + 1.0
+
+ polar_decoder = fec.polar_decoder_sc.make(block_size, num_info_bits,
frozen_bit_positions, frozen_bit_values, is_packed)
+ 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)
+
+ # ref = python_decoder.decode(data)
+
+ print("input:", data)
+ print("res :", res)
+ # print("ref :", ref)
+
+ self.assertTupleEqual(tuple(res), tuple(bits))
+
+
+if __name__ == '__main__':
+ gr_unittest.run(test_polar_decoder_sc)
+
+
diff --git a/gr-fec/python/fec/qa_polar_decoder_sc_list.py
b/gr-fec/python/fec/qa_polar_decoder_sc_list.py
new file mode 100644
index 0000000..f698a4e
--- /dev/null
+++ b/gr-fec/python/fec/qa_polar_decoder_sc_list.py
@@ -0,0 +1,157 @@
+#!/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
+import os
+
+from extended_encoder import extended_encoder
+from extended_decoder import extended_decoder
+from polar.encoder import PolarEncoder
+from polar.decoder import PolarDecoder
+from polar.helper_functions import get_frozen_bit_positions
+# from polar.helper_functions import bit_reverse_vector
+#
+# print('PID:', os.getpid())
+# raw_input('tell me smth')
+
+class test_polar_decoder_sc_list(gr_unittest.TestCase):
+
+ def setUp(self):
+ self.tb = gr.top_block()
+
+ def tearDown(self):
+ self.tb = None
+
+ def test_001_setup(self):
+ is_packed = False
+ block_size = 16
+ num_info_bits = 8
+ max_list_size = 4
+ frozen_bit_positions = np.arange(block_size - num_info_bits)
+ frozen_bit_values = np.array([],)
+
+ polar_decoder = fec.polar_decoder_sc_list.make(max_list_size,
block_size, num_info_bits, frozen_bit_positions, frozen_bit_values, is_packed)
+
+ self.assertEqual(num_info_bits, polar_decoder.get_output_size())
+ self.assertEqual(block_size, polar_decoder.get_input_size())
+ self.assertFloatTuplesAlmostEqual((float(block_size) / num_info_bits,
), (polar_decoder.rate(), ))
+ self.assertFalse(polar_decoder.set_frame_size(10))
+
+ def test_002_one_vector(self):
+ print "test_002_one_vector"
+ is_packed = False
+ expo = 6
+ block_size = 2 ** expo
+ num_info_bits = 2 ** (expo - 1)
+ max_list_size = 2 ** (expo - 2)
+ num_frozen_bits = block_size - num_info_bits
+ frozen_bit_positions = get_frozen_bit_positions('polar', block_size,
num_frozen_bits, 0.11)
+ frozen_bit_values = np.array([0] * num_frozen_bits,)
+ print(frozen_bit_positions)
+
+ python_decoder = PolarDecoder(block_size, num_info_bits,
frozen_bit_positions, frozen_bit_values)
+
+ # data = np.ones(block_size, dtype=int)
+ bits = np.random.randint(2, size=num_info_bits)
+ # bits = np.ones(num_info_bits, dtype=int)
+ encoder = PolarEncoder(block_size, num_info_bits,
frozen_bit_positions, frozen_bit_values)
+ data = encoder.encode(bits)
+ # data = np.array([0, 1, 1, 0, 1, 0, 1, 0], dtype=int)
+ gr_data = -2.0 * data + 1.0
+
+ polar_decoder = fec.polar_decoder_sc_list.make(max_list_size,
block_size, num_info_bits, frozen_bit_positions, frozen_bit_values, is_packed)
+ 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)
+
+ ref = python_decoder.decode(data)
+
+ print("input:", data)
+ print("res :", res)
+ print("ref :", ref)
+ print("bits :", bits)
+
+ self.assertTupleEqual(tuple(res), tuple(ref))
+
+ def test_003_stream(self):
+ print "test_003_stream"
+ nframes = 5
+ is_packed = False
+ expo = 8
+ block_size = 2 ** expo
+ num_info_bits = 2 ** (expo - 1)
+ max_list_size = 2 ** (expo - 2)
+ num_frozen_bits = block_size - num_info_bits
+ frozen_bit_positions = get_frozen_bit_positions('polar', block_size,
num_frozen_bits, 0.11)
+ frozen_bit_values = np.array([0] * num_frozen_bits,)
+ print(frozen_bit_positions)
+
+ encoder = PolarEncoder(block_size, num_info_bits,
frozen_bit_positions, frozen_bit_values)
+
+ # data = np.ones(block_size, dtype=int)
+ ref = np.array([], dtype=int)
+ data = np.array([], dtype=int)
+ for i in range(nframes):
+ b = np.random.randint(2, size=num_info_bits)
+ d = encoder.encode(b)
+ data = np.append(data, d)
+ ref = np.append(ref, b)
+
+ # bits = np.ones(num_info_bits, dtype=int)
+ # data = encoder.encode(bits)
+ # data = np.array([0, 1, 1, 0, 1, 0, 1, 0], dtype=int)
+ gr_data = -2.0 * data + 1.0
+
+ polar_decoder = fec.polar_decoder_sc_list.make(max_list_size,
block_size, num_info_bits, frozen_bit_positions, frozen_bit_values, is_packed)
+ 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)
+
+
+ print("input:", data)
+ print("res :", res)
+ print("ref :", ref)
+
+ self.assertTupleEqual(tuple(res), tuple(ref))
+
+
+
+
+if __name__ == '__main__':
+ gr_unittest.run(test_polar_decoder_sc_list)
+
+
+
diff --git a/gr-fec/python/fec/qa_polar_encoder.py
b/gr-fec/python/fec/qa_polar_encoder.py
index 0362935..4af193e 100644
--- a/gr-fec/python/fec/qa_polar_encoder.py
+++ b/gr-fec/python/fec/qa_polar_encoder.py
@@ -22,14 +22,11 @@
from gnuradio import gr, gr_unittest, blocks
import fec_swig as fec
-from _qa_helper import _qa_helper
import numpy as np
from extended_encoder import extended_encoder
-from extended_decoder import extended_decoder
from polar.encoder import PolarEncoder
from polar.helper_functions import get_frozen_bit_positions
-from polar.helper_functions import bit_reverse_vector
class test_polar_encoder(gr_unittest.TestCase):
@@ -61,21 +58,17 @@ class test_polar_encoder(gr_unittest.TestCase):
frozen_bit_values = np.array([0] * num_frozen_bits,)
python_encoder = PolarEncoder(block_size, num_info_bits,
frozen_bit_positions, frozen_bit_values)
- is_packed = False
+ is_packed = True
polar_encoder = fec.polar_encoder.make(block_size, num_info_bits,
frozen_bit_positions, frozen_bit_values, is_packed)
data = np.ones(num_info_bits, dtype=int)
src = blocks.vector_source_b(data, False)
- packer = blocks.pack_k_bits_bb(8)
enc_block = extended_encoder(polar_encoder, None, '11')
- unpacker = blocks.unpack_k_bits_bb(8)
snk = blocks.vector_sink_b(1)
- if is_packed:
- self.tb.connect(src, packer, enc_block, unpacker, snk)
- else:
- self.tb.connect(src, enc_block, snk)
+ self.tb.connect(src, enc_block, snk)
self.tb.run()
+ print(self.tb.edge_list())
res = np.array(snk.data()).astype(dtype=int)
penc = python_encoder.encode(data)
@@ -85,7 +78,7 @@ class test_polar_encoder(gr_unittest.TestCase):
self.assertTupleEqual(tuple(res), tuple(penc))
def test_003_big_input(self):
- is_packed = False
+ is_packed = True
num_blocks = 30
block_size = 256
num_info_bits = 128
@@ -106,19 +99,13 @@ class test_polar_encoder(gr_unittest.TestCase):
src = blocks.vector_source_b(data, False)
- packer = blocks.pack_k_bits_bb(8)
enc_block = extended_encoder(polar_encoder, None, '11')
- unpacker = blocks.unpack_k_bits_bb(8)
snk = blocks.vector_sink_b(1)
- if is_packed:
- self.tb.connect(src, packer, enc_block, unpacker, snk)
- else:
- self.tb.connect(src, enc_block, snk)
+ self.tb.connect(src, enc_block, snk)
self.tb.run()
res = np.array(snk.data()).astype(dtype=int)
- # penc = python_encoder.encode(data)
print(res)
print(ref)
diff --git a/gr-fec/swig/fec_swig.i b/gr-fec/swig/fec_swig.i
index b5735aa..a33e8d1 100644
--- a/gr-fec/swig/fec_swig.i
+++ b/gr-fec/swig/fec_swig.i
@@ -63,6 +63,10 @@
#include "gnuradio/fec/tpc_encoder.h"
#include "gnuradio/fec/tpc_decoder.h"
#include "gnuradio/fec/polar_encoder.h"
+#include "gnuradio/fec/polar_decoder_sc.h"
+#include "gnuradio/fec/polar_common.h"
+#include "gnuradio/fec/polar_decoder_sc_list.h"
+#include "gnuradio/fec/polar_decoder_common.h"
%}
%include "gnuradio/fec/generic_decoder.h"
@@ -106,3 +110,7 @@ GR_SWIG_BLOCK_MAGIC2(fec, puncture_bb);
GR_SWIG_BLOCK_MAGIC2(fec, puncture_ff);
GR_SWIG_BLOCK_MAGIC2(fec, depuncture_bb);
%include "gnuradio/fec/polar_encoder.h"
+%include "gnuradio/fec/polar_decoder_sc.h"
+%include "gnuradio/fec/polar_common.h"
+%include "gnuradio/fec/polar_decoder_sc_list.h"
+%include "gnuradio/fec/polar_decoder_common.h"
- [Commit-gnuradio] [gnuradio] 22/25: Merge remote-tracking branch 'geiger/volkize_fft_fix', (continued)
- [Commit-gnuradio] [gnuradio] 22/25: Merge remote-tracking branch 'geiger/volkize_fft_fix', git, 2015/09/23
- [Commit-gnuradio] [gnuradio] 10/25: polar: rebased and fixed branch for merge again., git, 2015/09/23
- [Commit-gnuradio] [gnuradio] 19/25: polar: rearranged polar_code_example flowgraph, git, 2015/09/23
- [Commit-gnuradio] [gnuradio] 21/25: Merge branch 'maint', git, 2015/09/23
- [Commit-gnuradio] [gnuradio] 05/25: polar: VOLK kernel integration, git, 2015/09/23
- [Commit-gnuradio] [gnuradio] 24/25: Merge remote-tracking branch 'gnuradio-wg-grc/master_grcwg', git, 2015/09/23
- [Commit-gnuradio] [gnuradio] 07/25: polar: updated polar code example GRC, git, 2015/09/23
- [Commit-gnuradio] [gnuradio] 02/25: polar: encoder implemented in C++, git, 2015/09/23
- [Commit-gnuradio] [gnuradio] 25/25: Merge remote-tracking branch 'tom/socis/master', git, 2015/09/23
- [Commit-gnuradio] [gnuradio] 06/25: polar: refarctoring and clean-up, git, 2015/09/23
- [Commit-gnuradio] [gnuradio] 03/25: polar: SC and SC List decoder implemented in C++,
git <=
- [Commit-gnuradio] [gnuradio] 01/25: polar: Python test code for polar codes, git, 2015/09/23
- [Commit-gnuradio] [gnuradio] 04/25: polar: Python implementation for channel construction, git, 2015/09/23
- [Commit-gnuradio] [gnuradio] 13/25: polar: updated documentation and examples, git, 2015/09/23
- [Commit-gnuradio] [gnuradio] 15/25: fec: polar: moving polar codes into ::code:: namespace like the others., git, 2015/09/23
- [Commit-gnuradio] [gnuradio] 16/25: fec: polar: whitespace fixes/tabs to go along with namespace change from last commit., git, 2015/09/23
- [Commit-gnuradio] [gnuradio] 14/25: polar: updated documentation and examples, git, 2015/09/23