diff options
28 files changed, 484 insertions, 710 deletions
diff --git a/gr-fec/examples/polar_ber_curve_gen.grc b/gr-fec/examples/polar_ber_curve_gen.grc index b4e2f879eb..5c3c5c90bb 100644 --- a/gr-fec/examples/polar_ber_curve_gen.grc +++ b/gr-fec/examples/polar_ber_curve_gen.grc @@ -1,5 +1,5 @@ <?xml version='1.0' encoding='utf-8'?> -<?grc format='1' created='3.7.8rc1'?> +<?grc format='1' created='3.7.8'?> <flow_graph> <timestamp>Fri Jul 17 15:23:09 2015</timestamp> <block> @@ -132,7 +132,7 @@ </param> <param> <key>framebits</key> - <value>block_size</value> + <value>frame_size</value> </param> <param> <key>_coordinate</key> @@ -199,7 +199,7 @@ </param> <param> <key>framebits</key> - <value>block_size</value> + <value>frame_size</value> </param> <param> <key>_coordinate</key> @@ -273,6 +273,33 @@ </param> <param> <key>_coordinate</key> + <value>(1440, 51)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + <param> + <key>id</key> + <value>frame_size</value> + </param> + <param> + <key>value</key> + <value>block_size / 2</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>comment</key> + <value></value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>_coordinate</key> <value>(1368, 115)</value> </param> <param> @@ -432,10 +459,6 @@ <value>polar_decoder</value> </param> <param> - <key>is_packed</key> - <value>False</value> - </param> - <param> <key>ndim</key> <value>2</value> </param> @@ -601,10 +624,6 @@ <value>list_size</value> </param> <param> - <key>is_packed</key> - <value>False</value> - </param> - <param> <key>ndim</key> <value>2</value> </param> diff --git a/gr-fec/examples/polar_code_example.grc b/gr-fec/examples/polar_code_example.grc index 729e8fe873..1e389a5837 100644 --- a/gr-fec/examples/polar_code_example.grc +++ b/gr-fec/examples/polar_code_example.grc @@ -13,6 +13,10 @@ <value></value> </param> <param> + <key>window_size</key> + <value>1280, 1024</value> + </param> + <param> <key>category</key> <value>Custom</value> </param> @@ -68,10 +72,6 @@ <key>title</key> <value>POLAR code example flowgraph</value> </param> - <param> - <key>window_size</key> - <value>1280, 1024</value> - </param> </block> <block> <key>variable</key> @@ -217,10 +217,6 @@ <value>polar_decoder</value> </param> <param> - <key>is_packed</key> - <value>False</value> - </param> - <param> <key>ndim</key> <value>0</value> </param> @@ -331,10 +327,6 @@ <value>8</value> </param> <param> - <key>is_packed</key> - <value>False</value> - </param> - <param> <key>ndim</key> <value>0</value> </param> @@ -598,7 +590,7 @@ </param> <param> <key>_coordinate</key> - <value>(728, 360)</value> + <value>(728, 361)</value> </param> <param> <key>_rotation</key> @@ -759,7 +751,7 @@ </param> <param> <key>_coordinate</key> - <value>(1008, 355)</value> + <value>(984, 355)</value> </param> <param> <key>gui_hint</key> diff --git a/gr-fec/examples/polar_encoder_decoder_chain.grc b/gr-fec/examples/polar_encoder_decoder_chain.grc index f2501b998c..481dd1dbfd 100644 --- a/gr-fec/examples/polar_encoder_decoder_chain.grc +++ b/gr-fec/examples/polar_encoder_decoder_chain.grc @@ -133,7 +133,7 @@ </param> <param> <key>value</key> - <value>2 ** 32# encoder: 32, decoder: 23</value> + <value>2 ** 23# encoder: 32, decoder: 23</value> </param> </block> <block> @@ -253,10 +253,6 @@ <value>polar_decoder</value> </param> <param> - <key>is_packed</key> - <value>False</value> - </param> - <param> <key>ndim</key> <value>0</value> </param> @@ -367,10 +363,6 @@ <value>8</value> </param> <param> - <key>is_packed</key> - <value>False</value> - </param> - <param> <key>ndim</key> <value>0</value> </param> @@ -454,7 +446,7 @@ </param> <param> <key>_enabled</key> - <value>0</value> + <value>1</value> </param> <param> <key>_coordinate</key> @@ -548,7 +540,7 @@ </param> <param> <key>_enabled</key> - <value>0</value> + <value>1</value> </param> <param> <key>_coordinate</key> @@ -701,7 +693,7 @@ </param> <param> <key>_enabled</key> - <value>0</value> + <value>1</value> </param> <param> <key>_coordinate</key> @@ -752,7 +744,7 @@ </param> <param> <key>_enabled</key> - <value>1</value> + <value>0</value> </param> <param> <key>encoder_list</key> diff --git a/gr-fec/grc/fec_polar_decoder_sc.xml b/gr-fec/grc/fec_polar_decoder_sc.xml index 8b04c3d6ec..4976afb4b6 100644 --- a/gr-fec/grc/fec_polar_decoder_sc.xml +++ b/gr-fec/grc/fec_polar_decoder_sc.xml @@ -4,31 +4,16 @@ <key>variable_polar_decoder_sc_def</key> <import>from gnuradio import fec</import> <var_make>#if int($ndim())==0 # -self.$(id) = $(id) = fec.polar_decoder_sc.make($block_size, $num_info_bits, $frozen_bit_positions, $frozen_bit_values, $is_packed) #slurp +self.$(id) = $(id) = fec.polar_decoder_sc.make($block_size, $num_info_bits, $frozen_bit_positions, $frozen_bit_values) #slurp #else if int($ndim())==1 # -self.$(id) = $(id) = map((lambda a: fec.polar_decoder_sc.make($block_size, $num_info_bits, $frozen_bit_positions, $frozen_bit_values, $is_packed)), range(0, $dim1) ) #slurp +self.$(id) = $(id) = map((lambda a: fec.polar_decoder_sc.make($block_size, $num_info_bits, $frozen_bit_positions, $frozen_bit_values)), range(0, $dim1) ) #slurp #else -self.$(id) = $(id) = map((lambda b: map((lambda a: fec.polar_decoder_sc.make($block_size, $num_info_bits, $frozen_bit_positions, $frozen_bit_values, $is_packed)), range(0, $dim2))), range(0, $dim1)) #slurp +self.$(id) = $(id) = map((lambda b: map((lambda a: fec.polar_decoder_sc.make($block_size, $num_info_bits, $frozen_bit_positions, $frozen_bit_values)), range(0, $dim2))), range(0, $dim1)) #slurp #end if</var_make> - <var_value>fec.polar_decoder_sc.make($block_size, $num_info_bits, $frozen_bit_positions, $frozen_bit_values, $is_packed)</var_value> + <var_value>fec.polar_decoder_sc.make($block_size, $num_info_bits, $frozen_bit_positions, $frozen_bit_values)</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>Parallelism</name> <key>ndim</key> <value>0</value> diff --git a/gr-fec/grc/fec_polar_decoder_sc_list.xml b/gr-fec/grc/fec_polar_decoder_sc_list.xml index f178664c83..2128110ad4 100644 --- a/gr-fec/grc/fec_polar_decoder_sc_list.xml +++ b/gr-fec/grc/fec_polar_decoder_sc_list.xml @@ -4,31 +4,16 @@ <key>variable_polar_decoder_sc_list_def</key> <import>from gnuradio import fec</import> <var_make>#if int($ndim())==0 # -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) #slurp +self.$(id) = $(id) = fec.polar_decoder_sc_list.make($max_list_size, $block_size, $num_info_bits, $frozen_bit_positions, $frozen_bit_values) #slurp #else if int($ndim())==1 # -self.$(id) = $(id) = map((lambda a: fec.polar_decoder_sc_list.make($max_list_size, $block_size, $num_info_bits, $frozen_bit_positions, $frozen_bit_values, $is_packed)), range(0, $dim1)) #slurp +self.$(id) = $(id) = map((lambda a: fec.polar_decoder_sc_list.make($max_list_size, $block_size, $num_info_bits, $frozen_bit_positions, $frozen_bit_values)), range(0, $dim1)) #slurp #else -self.$(id) = $(id) = map((lambda b: map((lambda a: fec.polar_decoder_sc_list.make($max_list_size, $block_size, $num_info_bits, $frozen_bit_positions, $frozen_bit_values, $is_packed)), range(0, $dim2))), range(0, $dim1)) #slurp +self.$(id) = $(id) = map((lambda b: map((lambda a: fec.polar_decoder_sc_list.make($max_list_size, $block_size, $num_info_bits, $frozen_bit_positions, $frozen_bit_values)), range(0, $dim2))), range(0, $dim1)) #slurp #end if</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> + <var_value>fec.polar_decoder_sc_list.make($max_list_size, $block_size, $num_info_bits, $frozen_bit_positions, $frozen_bit_values)</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>Parallelism</name> <key>ndim</key> <value>0</value> diff --git a/gr-fec/include/gnuradio/fec/polar_common.h b/gr-fec/include/gnuradio/fec/polar_common.h index 59e0ad38ba..8bf1a61cd8 100644 --- a/gr-fec/include/gnuradio/fec/polar_common.h +++ b/gr-fec/include/gnuradio/fec/polar_common.h @@ -30,7 +30,6 @@ namespace gr { namespace blocks { namespace kernel { - class pack_k_bits; class unpack_k_bits; } } @@ -42,38 +41,46 @@ namespace gr { /*! * \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 + * \ingroup error_coding_blk + * + * \details + * polar codes are based on this paper by Erdal Arikan + * "Channel Polarization: A Method for Contructing Capacity-Achieving Codes for Symmetric Binary-Input Memoryless Channels", 2009 + * + * class holds common info. It is common to all encoders and decoders. + * block_size: MUST be a power of 2. + * num_info_bits: any integer <= block_size + * frozen_bit_positions: elements specify position of frozen bits in each frame. size MUST be equal to block_size - num_info_bits + * frozen_bit_values: desired frozen bit values. '0' appended if smaller than frozen_bit_positions. */ 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(int block_size, int num_info_bits, std::vector<int> frozen_bit_positions, std::vector<char> frozen_bit_values); ~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(); + + std::vector<int> d_frozen_bit_positions; + std::vector<char> d_frozen_bit_values; + std::vector<int> d_info_bit_positions; 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; + gr::blocks::kernel::unpack_k_bits *d_unpacker; // convenience for 'print_packed_bit_array' function. }; } // namespace fec diff --git a/gr-fec/include/gnuradio/fec/polar_decoder_common.h b/gr-fec/include/gnuradio/fec/polar_decoder_common.h index 61a6564cc6..6f192e5fdd 100644 --- a/gr-fec/include/gnuradio/fec/polar_decoder_common.h +++ b/gr-fec/include/gnuradio/fec/polar_decoder_common.h @@ -38,18 +38,18 @@ namespace gr { 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(int block_size, int num_info_bits, std::vector<int> frozen_bit_positions, std::vector<char> frozen_bit_values); ~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);}; + int get_input_size(){return block_size();}; + int get_output_size(){return num_info_bits();}; bool set_frame_size(unsigned int frame_size){return false;}; - const char* get_output_conversion() {return "none";}; private: - const float D_LLR_FACTOR; + static const float D_LLR_FACTOR = -2.19722458f; + unsigned int d_frozen_bit_counter; protected: // calculate LLRs for stage @@ -57,26 +57,21 @@ namespace gr { 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;}; + // control retrieval of frozen bits. + const bool is_frozen_bit(const int u_num) const; + const unsigned char next_frozen_bit(); + // preparation for decoding - void initialize_llr_vector(float* llrs, const float* input); + void initialize_decoder(unsigned char* u, float* llrs, const float* input); + // basic algorithm methods void butterfly(float* llrs, unsigned char* u, const int stage, const int u_num, const int row); void butterfly_volk(float* llrs, unsigned char* u, const int stage, const int u_num, const int row); void butterfly_generic(float* llrs, unsigned char* u, const int stage, const int u_num, const int row); 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; diff --git a/gr-fec/include/gnuradio/fec/polar_decoder_sc.h b/gr-fec/include/gnuradio/fec/polar_decoder_sc.h index e9fa6a244d..35f22dde5b 100644 --- a/gr-fec/include/gnuradio/fec/polar_decoder_sc.h +++ b/gr-fec/include/gnuradio/fec/polar_decoder_sc.h @@ -32,7 +32,7 @@ namespace gr { namespace fec { /*! - * \brief Standard successive cancellation decoder for POLAR codes + * \brief Standard successive cancellation (SC) decoder for POLAR codes * It expects float input with bits mapped 1 --> 1, 0 --> -1 * Or: f = 2.0 * bit - 1.0 * @@ -40,16 +40,14 @@ namespace gr { 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); + static generic_decoder::sptr make(int block_size, int num_info_bits, std::vector<int> frozen_bit_positions, std::vector<char> frozen_bit_values); ~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; + polar_decoder_sc(int block_size, int num_info_bits, std::vector<int> frozen_bit_positions, std::vector<char> frozen_bit_values); float* d_llr_vec; unsigned char* d_u_hat_vec; diff --git a/gr-fec/include/gnuradio/fec/polar_decoder_sc_list.h b/gr-fec/include/gnuradio/fec/polar_decoder_sc_list.h index 001ef66b1c..5dbad0eefa 100644 --- a/gr-fec/include/gnuradio/fec/polar_decoder_sc_list.h +++ b/gr-fec/include/gnuradio/fec/polar_decoder_sc_list.h @@ -35,32 +35,36 @@ namespace gr { } /*! - * \brief implements a successive cancellation list decoder for polar codes + * \brief Successive cancellation list (SCL) 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 * + * \details + * max_list_size: specifies the maximum number of code paths to follow. + * + * Block expects float input with bits mapped 1 --> 1, 0 --> -1 + * Or: f = 2.0 * bit - 1.0 + * */ 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); + 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); ~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); + 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); - 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); + void initialize_list(const float* in_buf); + const unsigned char* decode_list(); + void decode_bit(const int u_num); + void calculate_llrs_for_list(const int u_num); + void set_bit_in_list(const int u_num); }; } // namespace fec } // namespace gr diff --git a/gr-fec/include/gnuradio/fec/polar_encoder.h b/gr-fec/include/gnuradio/fec/polar_encoder.h index 20ff5dc3b1..530a6ded40 100644 --- a/gr-fec/include/gnuradio/fec/polar_encoder.h +++ b/gr-fec/include/gnuradio/fec/polar_encoder.h @@ -33,6 +33,13 @@ namespace gr { /*! * \brief POLAR encoder + * for basic details see 'polar_common' class. + * \ingroup error_coding_blk + * + * \details + * Additional parameters + * is_packed: choose 1 active bit/byte or 8 active bit/byte. + * if false, VOLK polar encoder is used. * */ class FEC_API polar_encoder : public generic_encoder, public polar_common @@ -44,23 +51,21 @@ 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 num_info_bits() / (is_packed() ? 8 : 1);}; - int get_output_size(){return block_size() / (is_packed() ? 8 : 1);}; + int get_input_size(){return num_info_bits() / (d_is_packed ? 8 : 1);}; + int get_output_size(){return block_size() / (d_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";}; + const char* get_input_conversion(){return d_is_packed ? "pack" : "none";}; + const char* get_output_conversion(){return d_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); - std::vector<int> d_frozen_bit_positions; - std::vector<int> d_info_bit_positions; - std::vector<char> d_frozen_bit_values; + std::vector<int> d_info_bit_reversed_positions; + bool d_is_packed; // c'tor method for packed algorithm setup. void setup_frozen_bit_inserter(); // methods insert input bits and frozen bits into packed array for encoding - unsigned char* d_block_array; // use for encoding unsigned char* d_frozen_bit_prototype; // packed frozen bits are written onto it and later copies are used. void insert_packed_frozen_bits_and_reverse(unsigned char* target, const unsigned char* input) const; void insert_unpacked_bit_into_packed_array_at_position(unsigned char* target, const unsigned char bit, const int pos) const; diff --git a/gr-fec/lib/polar_common.cc b/gr-fec/lib/polar_common.cc index 19caedf00c..3138aa5088 100644 --- a/gr-fec/lib/polar_common.cc +++ b/gr-fec/lib/polar_common.cc @@ -42,43 +42,36 @@ namespace gr 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) + std::vector<char> frozen_bit_values) : + d_frozen_bit_positions(frozen_bit_positions), d_frozen_bit_values(frozen_bit_values), + d_block_size(block_size), d_block_power((int) log2(float(block_size))), + d_num_info_bits(num_info_bits) { - if(pow(2, d_block_power) != d_block_size) { + 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()) { + 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) { + 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; int frozen_pos = d_frozen_bit_positions.at(num_frozen_bit); - for(int i = 0; i < block_size(); i++) { + for(int i = 0; i < d_block_size; i++) { if(i != frozen_pos) { d_info_bit_positions.push_back((int) i); } @@ -96,7 +89,6 @@ namespace gr polar_common::~polar_common() { - delete d_packer; delete d_unpacker; } @@ -118,7 +110,7 @@ namespace gr { int num_bits = num_bytes << 3; unsigned char* temp = new unsigned char[num_bits]; - unpacker()->unpack(temp, printed_array, num_bytes); + d_unpacker->unpack(temp, printed_array, num_bytes); std::cout << "["; for(int i = 0; i < num_bits; i++) { diff --git a/gr-fec/lib/polar_decoder_common.cc b/gr-fec/lib/polar_decoder_common.cc index 2263795451..e9138aad59 100644 --- a/gr-fec/lib/polar_decoder_common.cc +++ b/gr-fec/lib/polar_decoder_common.cc @@ -35,11 +35,9 @@ namespace gr { 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) + std::vector<char> frozen_bit_values) : + polar_common(block_size, num_info_bits, frozen_bit_positions, frozen_bit_values), + d_frozen_bit_counter(0) { } @@ -48,9 +46,11 @@ namespace gr { } void - polar_decoder_common::initialize_llr_vector(float* llrs, const float* input) + polar_decoder_common::initialize_decoder(unsigned char* u, float* llrs, const float* input) { volk_32f_s32f_multiply_32f(llrs + block_size() * block_power(), input, D_LLR_FACTOR, block_size()); + memset(u, 0, sizeof(unsigned char) * block_size() * block_power()); + d_frozen_bit_counter = 0; } float @@ -135,18 +135,6 @@ namespace gr { *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 @@ -157,18 +145,19 @@ namespace gr { *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++; -// } + const bool + polar_decoder_common::is_frozen_bit(const int u_num) const + { + return d_frozen_bit_counter < d_frozen_bit_positions.size() && u_num == d_frozen_bit_positions.at(d_frozen_bit_counter); + } + + + const unsigned char + polar_decoder_common::next_frozen_bit() + { + return d_frozen_bit_values[d_frozen_bit_counter++]; } void @@ -184,30 +173,6 @@ namespace gr { } 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 @@ -224,4 +189,3 @@ namespace gr { } /* namespace fec */ } /* namespace gr */ - diff --git a/gr-fec/lib/polar_decoder_sc.cc b/gr-fec/lib/polar_decoder_sc.cc index 7a290a8563..1b872d0c2a 100644 --- a/gr-fec/lib/polar_decoder_sc.cc +++ b/gr-fec/lib/polar_decoder_sc.cc @@ -38,18 +38,16 @@ namespace gr 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) + std::vector<char> frozen_bit_values) { return generic_decoder::sptr( - new polar_decoder_sc(block_size, num_info_bits, frozen_bit_positions, frozen_bit_values, - is_packed)); + new polar_decoder_sc(block_size, num_info_bits, frozen_bit_positions, frozen_bit_values)); } 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) + std::vector<char> frozen_bit_values) : + polar_decoder_common(block_size, num_info_bits, frozen_bit_positions, frozen_bit_values) { 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)); @@ -69,7 +67,7 @@ namespace gr const float *in = (const float*) in_buffer; unsigned char *out = (unsigned char*) out_buffer; - initialize_llr_vector(d_llr_vec, in); + initialize_decoder(d_u_hat_vec, d_llr_vec, in); sc_decode(d_llr_vec, d_u_hat_vec); extract_info_bits(out, d_u_hat_vec); } @@ -77,8 +75,6 @@ namespace gr 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, u, 0, i, i); u[i] = retrieve_bit_from_llr(llrs[i], i); @@ -88,8 +84,8 @@ namespace gr 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++); + if(is_frozen_bit(pos)){ + return next_frozen_bit(); } return llr_bit_decision(llr); } diff --git a/gr-fec/lib/polar_decoder_sc_list.cc b/gr-fec/lib/polar_decoder_sc_list.cc index 67b20f216d..1095e9a743 100644 --- a/gr-fec/lib/polar_decoder_sc_list.cc +++ b/gr-fec/lib/polar_decoder_sc_list.cc @@ -40,20 +40,18 @@ namespace gr 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) + std::vector<char> frozen_bit_values) { 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)); + frozen_bit_values)); } 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) + std::vector<char> frozen_bit_values) : + polar_decoder_common(block_size, num_info_bits, frozen_bit_positions, frozen_bit_values) { d_scl = new polar::scl_list(max_list_size, block_size, block_power()); } @@ -68,54 +66,62 @@ namespace gr { 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); + + initialize_list(in); + const unsigned char* temp = decode_list(); + extract_info_bits(out, temp); } void + polar_decoder_sc_list::initialize_list(const float* in_buf) + { + polar::path* init_path = d_scl->initial_path(); + initialize_decoder(init_path->u_vec, init_path->llr_vec, in_buf); + } + + const unsigned char* 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); + for(int u_num = 0; u_num < block_size(); u_num++){ + decode_bit(u_num); } - + return d_scl->optimal_path()->u_vec; } void - polar_decoder_sc_list::calculate_next_llr_in_paths(int u_num) + polar_decoder_sc_list::decode_bit(const 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); + if(u_num % 2 && is_frozen_bit(u_num)){ // LLR value is obsolete. save some time. + const unsigned char frozen_bit = next_frozen_bit(); + d_scl->set_frozen_bit(frozen_bit, u_num); } - // 2. info bit else{ - d_scl->set_info_bit(u_num); + calculate_llrs_for_list(u_num); + set_bit_in_list(u_num); } } void - polar_decoder_sc_list::update_with_frozenbit(const int u_num) + polar_decoder_sc_list::calculate_llrs_for_list(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++; + for(unsigned int i = 0; i < d_scl->active_size(); i++){ + polar::path* current_path = d_scl->next_active_path(); + butterfly(current_path->llr_vec, current_path->u_vec, 0, u_num, u_num); + } } void - polar_decoder_sc_list::calculate_next_llr(polar::path* current_path, int u_num) + polar_decoder_sc_list::set_bit_in_list(const int u_num) { - butterfly(current_path->llr_vec, current_path->u_vec, 0, u_num, u_num); + // 1. if frozen bit, update with known value + if(is_frozen_bit(u_num)){ + const unsigned char frozen_bit = next_frozen_bit(); + d_scl->set_frozen_bit(frozen_bit, u_num); + } + // 2. info bit + else{ + d_scl->set_info_bit(u_num); + } } } /* namespace fec */ } /* namespace gr */ diff --git a/gr-fec/lib/polar_encoder.cc b/gr-fec/lib/polar_encoder.cc index 40ffb05484..eeb283e4b4 100644 --- a/gr-fec/lib/polar_encoder.cc +++ b/gr-fec/lib/polar_encoder.cc @@ -50,16 +50,9 @@ namespace gr 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) + polar_common(block_size, num_info_bits, frozen_bit_positions, frozen_bit_values), + d_is_packed(is_packed) { - unsigned int num_frozen_bits = block_size - num_info_bits; - - while(d_frozen_bit_values.size() < num_frozen_bits) { - d_frozen_bit_values.push_back(0); - } - setup_frozen_bit_inserter(); setup_volk_vectors(); } @@ -67,7 +60,6 @@ namespace gr void polar_encoder::setup_frozen_bit_inserter() { - 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); @@ -79,12 +71,11 @@ namespace gr rev_pos); } - 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())); + 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_positions.size() != num_info_bits()) { + 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)!"); } } @@ -113,7 +104,6 @@ namespace gr polar_encoder::~polar_encoder() { - volk_free(d_block_array); volk_free(d_frozen_bit_prototype); volk_free(d_temp); @@ -127,11 +117,11 @@ namespace gr const unsigned char *in = (const unsigned char*) in_buffer; unsigned char *out = (unsigned char*) out_buffer; - if(is_packed()) { + if(d_is_packed){ insert_packed_frozen_bits_and_reverse(out, in); encode_vector_packed(out); } - else { + else{ volk_encode(out, in); } } @@ -163,7 +153,7 @@ namespace gr void polar_encoder::encode_packed_byte(unsigned char* target) const { - // this method only produces correct results if d_block_size > 4. + // this method only produces correct results if block_size > 4. // this is assumed to be the case. *target ^= 0xaa & (*target << 1); *target ^= 0xcc & (*target << 2); @@ -202,12 +192,12 @@ namespace gr const unsigned char* input) const { memcpy(target, d_frozen_bit_prototype, block_size() >> 3); - const int* info_bit_positions_ptr = &d_info_bit_positions[0]; + const int* info_bit_reversed_positions_ptr = &d_info_bit_reversed_positions[0]; int bit_num = 0; unsigned char byte = *input; int bit_pos; while(bit_num < num_info_bits()) { - bit_pos = *info_bit_positions_ptr++; + bit_pos = *info_bit_reversed_positions_ptr++; insert_packet_bit_into_packed_array_at_position(target, byte, bit_pos, bit_num % 8); ++bit_num; if(bit_num % 8 == 0) { diff --git a/gr-fec/lib/scl_list.cc b/gr-fec/lib/scl_list.cc index 6942bfb275..f36c48f475 100644 --- a/gr-fec/lib/scl_list.cc +++ b/gr-fec/lib/scl_list.cc @@ -91,9 +91,7 @@ namespace gr { 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 { @@ -111,11 +109,9 @@ namespace gr { } 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); } } } @@ -167,7 +163,6 @@ namespace gr { 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); } diff --git a/gr-fec/lib/scl_list.h b/gr-fec/lib/scl_list.h index 8f09198157..5a93db2525 100644 --- a/gr-fec/lib/scl_list.h +++ b/gr-fec/lib/scl_list.h @@ -55,8 +55,7 @@ namespace gr { 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));}; + void reset(); // comparator for std::sort static bool path_compare(path* first, path* second){return first->path_metric < second->path_metric;}; @@ -73,7 +72,6 @@ namespace gr { 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 */ diff --git a/gr-fec/python/fec/polar/README.md b/gr-fec/python/fec/polar/README.md index 2bd00dc3de..d425e8650d 100644 --- a/gr-fec/python/fec/polar/README.md +++ b/gr-fec/python/fec/polar/README.md @@ -1,4 +1,9 @@ POLAR Code Python test functions module =========== -This folder contains all the necessary files for POLAR code testcode. It shall serve as a reference later on.
\ No newline at end of file +This directory contains all the necessary files for POLAR code testcode. +It serves as a reference for C++ implementations. + +'polar_channel_construction' exposes functionality to calculate polar channels for different sizes. +It may be used to calculate Bhattacharyya parameters once and store them in a file in '~/.gnuradio/polar'. +Frozen bit positions are recalculated on every run.
\ No newline at end of file diff --git a/gr-fec/python/fec/polar/channel_construction.py b/gr-fec/python/fec/polar/channel_construction.py index 9c38d3a7e6..bf3ff925d8 100644 --- a/gr-fec/python/fec/polar/channel_construction.py +++ b/gr-fec/python/fec/polar/channel_construction.py @@ -24,9 +24,9 @@ foundational paper for polar codes. ''' -import numpy as np from channel_construction_bec import calculate_bec_channel_capacities from channel_construction_bec import design_snr_to_bec_eta +from channel_construction_bec import bhattacharyya_bounds from channel_construction_bsc import tal_vardy_tpm_algorithm from helper_functions import * import matplotlib.pyplot as plt @@ -59,6 +59,12 @@ def get_bec_frozen_indices(nblock, kfrozen, eta): return positions +def get_frozen_bit_mask(frozen_indices, block_size): + frozen_mask = np.zeros(block_size, dtype=int) + frozen_mask[frozen_indices] = 1 + return frozen_mask + + def frozen_bit_positions(block_size, info_size, design_snr=0.0): if not design_snr > -1.5917: print('bad value for design_nsr, must be > -1.5917! default=0.0') @@ -110,201 +116,21 @@ def load_z_parameters(block_size, design_snr, mu): return z_params -def prepare_merger(frozen_mask): - mask = [] - for e in frozen_mask: - mask.append([e, ]) - return np.array(mask, dtype=int) - - -def merge_first_stage(init_mask): - merged_frozen_mask = [] - for e in range(0, len(init_mask), 2): - v = [init_mask[e]['value'][0], init_mask[e + 1]['value'][0]] - s = init_mask[e]['size'] * 2 - if init_mask[e]['type'] == init_mask[e + 1]['type']: - t = init_mask[e]['type'] - merged_frozen_mask.append({'value': v, 'type': t, 'size': s}) - else: - t = 'RPT' - merged_frozen_mask.append({'value': v, 'type': t, 'size': s}) - return merged_frozen_mask - - -def merge_second_stage(init_mask): - merged_frozen_mask = [] - for e in range(0, len(init_mask), 2): - if init_mask[e]['type'] == init_mask[e + 1]['type']: - t = init_mask[e]['type'] - v = init_mask[e]['value'] - v.extend(init_mask[e + 1]['value']) - s = init_mask[e]['size'] * 2 - merged_frozen_mask.append({'value': v, 'type': t, 'size': s}) - elif init_mask[e]['type'] == 'ZERO' and init_mask[e + 1]['type'] == 'RPT': - t = init_mask[e + 1]['type'] - v = init_mask[e]['value'] - v.extend(init_mask[e + 1]['value']) - s = init_mask[e]['size'] * 2 - merged_frozen_mask.append({'value': v, 'type': t, 'size': s}) - elif init_mask[e]['type'] == 'RPT' and init_mask[e + 1]['type'] == 'ONE': - t = 'SPC' - v = init_mask[e]['value'] - v.extend(init_mask[e + 1]['value']) - s = init_mask[e]['size'] * 2 - merged_frozen_mask.append({'value': v, 'type': t, 'size': s}) - else: - merged_frozen_mask.append(init_mask[e]) - merged_frozen_mask.append(init_mask[e + 1]) - return merged_frozen_mask - - -def merge_stage_n(init_mask): - merged_frozen_mask = [] - n_elems = len(init_mask) - (len(init_mask) % 2) - for e in range(0, n_elems, 2): - if init_mask[e]['size'] == init_mask[e + 1]['size']: - if (init_mask[e]['type'] == 'ZERO' or init_mask[e]['type'] == 'ONE') and init_mask[e]['type'] == init_mask[e + 1]['type']: - t = init_mask[e]['type'] - v = init_mask[e]['value'] - v.extend(init_mask[e + 1]['value']) - s = init_mask[e]['size'] * 2 - merged_frozen_mask.append({'value': v, 'type': t, 'size': s}) - elif init_mask[e]['type'] == 'ZERO' and init_mask[e + 1]['type'] == 'RPT': - t = init_mask[e + 1]['type'] - v = init_mask[e]['value'] - v.extend(init_mask[e + 1]['value']) - s = init_mask[e]['size'] * 2 - merged_frozen_mask.append({'value': v, 'type': t, 'size': s}) - elif init_mask[e]['type'] == 'SPC' and init_mask[e + 1]['type'] == 'ONE': - t = init_mask[e]['type'] - v = init_mask[e]['value'] - v.extend(init_mask[e + 1]['value']) - s = init_mask[e]['size'] * 2 - merged_frozen_mask.append({'value': v, 'type': t, 'size': s}) - else: - merged_frozen_mask.append(init_mask[e]) - merged_frozen_mask.append(init_mask[e + 1]) - else: - merged_frozen_mask.append(init_mask[e]) - merged_frozen_mask.append(init_mask[e + 1]) - if n_elems < len(init_mask): - merged_frozen_mask.append(init_mask[-1]) - return merged_frozen_mask - - -def print_decode_subframes(subframes): - for e in subframes: - print(e) - - -def find_decoder_subframes(frozen_mask): - stages = power_of_2_int(len(frozen_mask)) - frame_size = 2 ** stages - - lock_mask = np.zeros(frame_size, dtype=int) - sub_mask = [] - - for e in frozen_mask: - if e == 1: - sub_mask.append(0) - else: - sub_mask.append(1) - sub_mask = np.array(sub_mask, dtype=int) - - for s in range(0, stages): - stage_size = 2 ** s - mask = np.reshape(sub_mask, (-1, stage_size)) - lock = np.reshape(lock_mask, (-1, stage_size)) - for p in range(0, (frame_size // stage_size) - 1, 2): - l0 = lock[p] - l1 = lock[p + 1] - first = mask[p] - second = mask[p + 1] - print(l0, l1) - print(first, second) - if np.all(l0 == l1): - for eq in range(2): - if np.all(first == eq) and np.all(second == eq): - mask[p].fill(eq) - mask[p + 1].fill(eq) - lock[p].fill(s) - lock[p + 1].fill(s) - - if np.all(first == 0) and np.all(second == 2): - mask[p].fill(2) - mask[p + 1].fill(2) - lock[p].fill(s) - lock[p + 1].fill(s) - - if np.all(first == 3) and np.all(second == 1): - mask[p].fill(3) - mask[p + 1].fill(3) - lock[p].fill(s) - lock[p + 1].fill(s) - - if s == 0 and np.all(first == 0) and np.all(second == 1): - mask[p].fill(2) - mask[p + 1].fill(2) - lock[p].fill(s) - lock[p + 1].fill(s) - - if s == 1 and np.all(first == 2) and np.all(second == 1): - mask[p].fill(3) - mask[p + 1].fill(3) - lock[p].fill(s) - lock[p + 1].fill(s) - - sub_mask = mask.flatten() - lock_mask = lock.flatten() - - words = {0: 'ZERO', 1: 'ONE', 2: 'RPT', 3: 'SPC'} - ll = lock_mask[0] - sub_t = sub_mask[0] - for i in range(len(frozen_mask)): - v = frozen_mask[i] - t = words[sub_mask[i]] - l = lock_mask[i] - # if i % 8 == 0: - # print - if not l == ll or not sub_mask[i] == sub_t: - print('--------------------------') - ll = l - sub_t = sub_mask[i] - print('{0:4} lock {1:4} value: {2} in sub {3}'.format(i, 2 ** (l + 1), v, t)) - - - def main(): np.set_printoptions(precision=3, linewidth=150) print 'channel construction Bhattacharyya bounds by Arikan' n = 10 m = 2 ** n k = m // 2 - design_snr = -1.59 + design_snr = 0.0 mu = 32 z_params = load_z_parameters(m, design_snr, mu) - # plt.plot(z_params) - # plt.show() - frozen_indices = get_frozen_bit_indices_from_z_parameters(z_params, k) - - frozen_mask = np.zeros(m, dtype=int) - frozen_mask[frozen_indices] = 1 - # frozen_mask = np.reshape(frozen_mask, (-1, 32)) - # for p in frozen_mask: - # print(p) - # if np.all(p == 1): - # print("zero rate") - # elif np.all(p == 0): - # print("ONE rate") - # elif p[0] == 1 and np.all(p[1:] == 0): - # print("SPC code") - # elif np.all(p[0:-1] == 1) and p[-1] == 0: - # print("REPETITION code") - - find_decoder_subframes(frozen_mask) - - + z_bounds = bhattacharyya_bounds(design_snr, m) + print(z_params[-10:]) + plt.plot(z_params) + plt.plot(z_bounds) + plt.show() if __name__ == '__main__': diff --git a/gr-fec/python/fec/polar/channel_construction_bec.py b/gr-fec/python/fec/polar/channel_construction_bec.py index 341b290057..c57ca6517b 100644 --- a/gr-fec/python/fec/polar/channel_construction_bec.py +++ b/gr-fec/python/fec/polar/channel_construction_bec.py @@ -29,10 +29,10 @@ def bec_channel(eta): W(y|0) * W(y|1) = 0 or W(y|0) = W(y|1) transistions are 1 -> 1 or 0 -> 0 or {0, 1} -> ? (erased symbol) ''' - # looks like BSC but should be interpreted differently. - W = np.array((1 - eta, eta, 1 - eta), dtype=float) - return W + w = np.array((1 - eta, eta, 1 - eta), dtype=float) + return w + def odd_rec(iwn): return iwn ** 2 @@ -73,7 +73,7 @@ def calculate_z_parameters_one_recursion(z_params): def calculate_bec_channel_z_parameters(eta, block_size): # compare [0, Arikan] eq. 38 block_power = hf.power_of_2_int(block_size) - z_params = np.array([eta,], dtype=float) + z_params = np.array([eta, ], dtype=float) for block_size in range(block_power): z_params = calculate_z_parameters_one_recursion(z_params) return z_params @@ -110,5 +110,6 @@ def main(): print(calculate_bec_channel_z_parameters(eta, block_size)) print(calculate_bec_channel_capacities(eta, block_size)) + if __name__ == '__main__': main() diff --git a/gr-fec/python/fec/polar/channel_construction_bsc.py b/gr-fec/python/fec/polar/channel_construction_bsc.py index 69acea861d..e16813fcb7 100755 --- a/gr-fec/python/fec/polar/channel_construction_bsc.py +++ b/gr-fec/python/fec/polar/channel_construction_bsc.py @@ -53,56 +53,6 @@ def bsc_channel(p): return W -def get_Bn(n): - # this is a bit reversal matrix. - lw = int(np.log2(n)) # number of used bits - indexes = [bit_reverse(i, lw) for i in range(n)] - Bn = np.zeros((n, n), type(n)) - for i, index in enumerate(indexes): - Bn[i][index] = 1 - return Bn - - -def get_Fn(n): - # this matrix defines the actual channel combining. - if n == 1: - return np.array([1, ]) - F2 = np.array([[1, 0], [1, 1]], np.int) - nump = int(np.log2(n)) - 1 # number of Kronecker products to calculate - Fn = F2 - for i in range(nump): - Fn = np.kron(Fn, F2) - return Fn - -def get_Gn(n): - # this matrix is called generator matrix - if not is_power_of_two(n): - print "invalid input" - return None - if n == 1: - return np.array([1, ]) - Bn = get_Bn(n) - Fn = get_Fn(n) - Gn = np.dot(Bn, Fn) - return Gn - - -def mutual_information(w): - ''' - calculate mutual information I(W) - I(W) = sum over y e Y ( sum over x e X ( ... ) ) - .5 W(y|x) log frac { W(y|x) }{ .5 W(y|0) + .5 W(y|1) } - ''' - ydim, xdim = np.shape(w) - i = 0.0 - for y in range(ydim): - for x in range(xdim): - v = w[y][x] * np.log2(w[y][x] / (0.5 * w[y][0] + 0.5 * w[y][1])) - i += v - i /= 2.0 - return i - - def solver_equation(val, s): cw_lambda = codeword_lambda_callable(s) ic_lambda = instantanious_capacity_callable() @@ -315,27 +265,16 @@ def normalize_q(q, tpm): def main(): print 'channel construction BSC main' - n = 10 + n = 8 m = 2 ** n - k = m // 2 - design_snr = 0.5 - mu = 32 - + design_snr = 0.0 + mu = 16 z_params = tal_vardy_tpm_algorithm(m, design_snr, mu) print(z_params) plt.plot(z_params) plt.show() - # q = discretize_awgn(mu, design_snr) - - - # print('discretized:', np.sum(q)) - # qu = upper_convolve(q, mu) - # print('upper_convolve:', np.sum(qu)) - # q0 = lower_convolve(q, mu) - # print('lower_convolve:', np.sum(q0)) - if __name__ == '__main__': main() diff --git a/gr-fec/python/fec/polar/decoder.py b/gr-fec/python/fec/polar/decoder.py index ef7d70081f..10eef9b6ed 100644 --- a/gr-fec/python/fec/polar/decoder.py +++ b/gr-fec/python/fec/polar/decoder.py @@ -224,13 +224,9 @@ def compare_decoder_impls(): n = 8 k = 4 frozenbits = np.zeros(n - k) - # frozenbitposition = np.array((0, 1, 2, 3, 4, 5, 8, 9), dtype=int) + # frozenbitposition16 = np.array((0, 1, 2, 3, 4, 5, 8, 9), dtype=int) frozenbitposition = np.array((0, 1, 2, 4), dtype=int) - # bits = np.ones(k, dtype=int) bits = np.random.randint(2, size=k) - # bits = np.array([0, 1, 1, 1]) - # bits = np.array([0, 1, 1, 0]) - # bits = np.array([1, 0, 1, 0]) print 'bits:', bits encoder = PolarEncoder(n, k, frozenbitposition, frozenbits) decoder = PolarDecoder(n, k, frozenbitposition, frozenbits) @@ -243,7 +239,6 @@ def compare_decoder_impls(): print (rx_st == rx_eff).all() - def main(): power = 3 n = 2 ** power @@ -257,33 +252,18 @@ def main(): decoder = PolarDecoder(n, k, frozenbitposition, frozenbits) bits = np.ones(k, dtype=int) - # bits = np.array([1, 0, 1, 0], dtype=int) print "bits: ", bits evec = encoder.encode(bits) print "froz: ", encoder._insert_frozen_bits(bits) print "evec: ", evec - # dvec = decoder.decode(evec) - # print "dec: ", dvec - # llr = decoder._llr(4, evec, np.array([0, 0, 0])) - # print "llr=", llr evec[1] = 0 deced = decoder._lr_sc_decoder(evec) print 'SC decoded:', deced - - - - # test_reverse_enc_dec() + test_reverse_enc_dec() compare_decoder_impls() - # graph_decode() - - - - - - if __name__ == '__main__': - main()
\ No newline at end of file + main() diff --git a/gr-fec/python/fec/polar/encoder.py b/gr-fec/python/fec/polar/encoder.py index 6f87a22191..3b5eea2a94 100644 --- a/gr-fec/python/fec/polar/encoder.py +++ b/gr-fec/python/fec/polar/encoder.py @@ -20,30 +20,13 @@ import numpy as np from common import PolarCommon +import helper_functions as hf class PolarEncoder(PolarCommon): def __init__(self, n, k, frozen_bit_position, frozenbits=None): PolarCommon.__init__(self, n, k, frozen_bit_position, frozenbits) - self.G = self._gn(n) - - def _gn(self, n): - # this matrix is called generator matrix - if n == 1: - return np.array([1, ]) - f = self._fn(n) - return f - - def _fn(self, n): - # this matrix defines the actual channel combining. - if n == 1: - return np.array([1, ]) - f2 = np.array([[1, 0], [1, 1]], np.int) - nump = int(np.log2(n)) - 1 # number of Kronecker products to calculate - fn = f2 - for i in range(nump): - fn = np.kron(fn, f2) - return fn + self.G = hf.get_Fn(n) def get_gn(self): return self.G @@ -59,9 +42,9 @@ class PolarEncoder(PolarCommon): return data def _encode_efficient(self, vec): - nstages = int(np.log2(self.N)) + n_stages = int(np.log2(self.N)) pos = np.arange(self.N, dtype=int) - for i in range(nstages): + 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() @@ -108,7 +91,7 @@ def test_pseudo_rate_1_encoder(encoder, ntests, k): def test_encoder_impls(): - print('comparing encoder implementations, matrix vs. efficient') + print('Compare encoder implementations, matrix vs. efficient') ntests = 1000 n = 16 k = 8 @@ -120,16 +103,12 @@ def test_encoder_impls(): 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 - + print 'Test rate-1 encoder/decoder:', r1_test def main(): - print "main in encoder" test_encoder_impls() - - if __name__ == '__main__': - main()
\ No newline at end of file + main() diff --git a/gr-fec/python/fec/polar/helper_functions.py b/gr-fec/python/fec/polar/helper_functions.py index 72501beae3..ca66bf4a50 100644 --- a/gr-fec/python/fec/polar/helper_functions.py +++ b/gr-fec/python/fec/polar/helper_functions.py @@ -56,6 +56,41 @@ def bit_reverse_vector(vec, n): return np.array([bit_reverse(e, n) for e in vec], dtype=vec.dtype) +def get_Bn(n): + # this is a bit reversal matrix. + lw = power_of_2_int(n) # number of used bits + indexes = [bit_reverse(i, lw) for i in range(n)] + Bn = np.zeros((n, n), type(n)) + for i, index in enumerate(indexes): + Bn[i][index] = 1 + return Bn + + +def get_Fn(n): + # this matrix defines the actual channel combining. + if n == 1: + return np.array([1, ]) + nump = power_of_2_int(n) - 1 # number of Kronecker products to calculate + F2 = np.array([[1, 0], [1, 1]], np.int) + Fn = F2 + for i in range(nump): + Fn = np.kron(Fn, F2) + return Fn + + +def get_Gn(n): + # this matrix is called generator matrix + if not is_power_of_two(n): + print "invalid input" + return None + if n == 1: + return np.array([1, ]) + Bn = get_Bn(n) + Fn = get_Fn(n) + Gn = np.dot(Bn, Fn) + return Gn + + def unpack_byte(byte, nactive): if np.amin(byte) < 0 or np.amax(byte) > 255: return None @@ -118,74 +153,17 @@ def bhattacharyya_parameter(w): def main(): print 'helper functions' - for i in range(8): + for i in range(9): print(i, 'is power of 2: ', is_power_of_two(i)) n = 6 m = 2 ** n - k = m // 2 - eta = 0.3 + pos = np.arange(m) rev_pos = bit_reverse_vector(pos, n) print(pos) print(rev_pos) - bound = 16 - num_lanes = m // bound - - - lanes = np.zeros((num_lanes, bound), dtype=int) - for i in range(0, num_lanes): - p = i * bound - part = rev_pos[p: p + bound] - lanes[i] = part - - print('reved lanes') - print(lanes) - - # SHUFFLE! - shuffle_pos = bit_reverse_vector(np.arange(bound), 4) - for i in range(num_lanes): - lane = lanes[i] - lanes[i] = lanes[i, shuffle_pos] - print('\nshuffled lanes') - print(lanes) - - # SORT HALVES - hb = bound // 2 - for i in range(num_lanes // 2): - l0 = lanes[i] - l1 = lanes[i + (num_lanes // 2)] - l0p = copy.deepcopy(l0[hb:]) - l0[hb:] = l1[0:hb] - l1[0:hb] = l0p - lanes[i] =l0 - lanes[i + (num_lanes // 2)] = l1 - print('\nsort halves') - print(lanes) - - # 'MELT' SHUFFLE INTERLEAVE! - melt_pos = np.arange(bound, dtype=int) - melt_pos = np.reshape(melt_pos, (2, -1)).T.flatten() - for i in range(num_lanes): - lanes[i] = lanes[i, melt_pos] - print('\nmelt lanes') - print(lanes) - - - - for i in range(0, m, bound): - print("\nlook at this part") - part = pos[i: i + bound] - rev = bit_reverse_vector(part, n) - sorted_rev = np.sort(rev) - print(part) - print(rev) - print(sorted_rev) - sorted_part = rev[shuffle_pos] - print(sorted_part) - - if __name__ == '__main__': main() diff --git a/gr-fec/python/fec/polar/testbed.py b/gr-fec/python/fec/polar/testbed.py index c35b62099c..d60c83e776 100755 --- a/gr-fec/python/fec/polar/testbed.py +++ b/gr-fec/python/fec/polar/testbed.py @@ -18,9 +18,11 @@ # Boston, MA 02110-1301, USA. # -import numpy as np + from encoder import PolarEncoder from decoder import PolarDecoder +import channel_construction as cc +from helper_functions import * import matplotlib.pyplot as plt @@ -28,7 +30,9 @@ import matplotlib.pyplot as plt def get_frozen_bit_position(): # frozenbitposition = np.array((0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 16, 17, 18, 20, 24), dtype=int) # frozenbitposition = np.array((0, 1, 2, 3, 4, 5, 8, 9), dtype=int) - frozenbitposition = np.load('frozen_bit_positions_n256_k128_p0.11.npy').flatten() + m = 256 + n_frozen = m // 2 + frozenbitposition = cc.get_frozen_bit_indices_from_z_parameters(cc.bhattacharyya_bounds(0.0, m), n_frozen) print(frozenbitposition) return frozenbitposition @@ -140,12 +144,185 @@ def channel_analysis(): good_indices *= 2000 good_indices += 4000 - plt.plot(channel_counter) plt.plot(good_indices) plt.show() + +def merge_first_stage(init_mask): + merged_frozen_mask = [] + for e in range(0, len(init_mask), 2): + v = [init_mask[e]['value'][0], init_mask[e + 1]['value'][0]] + s = init_mask[e]['size'] * 2 + if init_mask[e]['type'] == init_mask[e + 1]['type']: + t = init_mask[e]['type'] + merged_frozen_mask.append({'value': v, 'type': t, 'size': s}) + else: + t = 'RPT' + merged_frozen_mask.append({'value': v, 'type': t, 'size': s}) + return merged_frozen_mask + + +def merge_second_stage(init_mask): + merged_frozen_mask = [] + for e in range(0, len(init_mask), 2): + if init_mask[e]['type'] == init_mask[e + 1]['type']: + t = init_mask[e]['type'] + v = init_mask[e]['value'] + v.extend(init_mask[e + 1]['value']) + s = init_mask[e]['size'] * 2 + merged_frozen_mask.append({'value': v, 'type': t, 'size': s}) + elif init_mask[e]['type'] == 'ZERO' and init_mask[e + 1]['type'] == 'RPT': + t = init_mask[e + 1]['type'] + v = init_mask[e]['value'] + v.extend(init_mask[e + 1]['value']) + s = init_mask[e]['size'] * 2 + merged_frozen_mask.append({'value': v, 'type': t, 'size': s}) + elif init_mask[e]['type'] == 'RPT' and init_mask[e + 1]['type'] == 'ONE': + t = 'SPC' + v = init_mask[e]['value'] + v.extend(init_mask[e + 1]['value']) + s = init_mask[e]['size'] * 2 + merged_frozen_mask.append({'value': v, 'type': t, 'size': s}) + else: + merged_frozen_mask.append(init_mask[e]) + merged_frozen_mask.append(init_mask[e + 1]) + return merged_frozen_mask + + +def merge_stage_n(init_mask): + merged_frozen_mask = [] + n_elems = len(init_mask) - (len(init_mask) % 2) + for e in range(0, n_elems, 2): + if init_mask[e]['size'] == init_mask[e + 1]['size']: + if (init_mask[e]['type'] == 'ZERO' or init_mask[e]['type'] == 'ONE') and init_mask[e]['type'] == init_mask[e + 1]['type']: + t = init_mask[e]['type'] + v = init_mask[e]['value'] + v.extend(init_mask[e + 1]['value']) + s = init_mask[e]['size'] * 2 + merged_frozen_mask.append({'value': v, 'type': t, 'size': s}) + elif init_mask[e]['type'] == 'ZERO' and init_mask[e + 1]['type'] == 'RPT': + t = init_mask[e + 1]['type'] + v = init_mask[e]['value'] + v.extend(init_mask[e + 1]['value']) + s = init_mask[e]['size'] * 2 + merged_frozen_mask.append({'value': v, 'type': t, 'size': s}) + elif init_mask[e]['type'] == 'SPC' and init_mask[e + 1]['type'] == 'ONE': + t = init_mask[e]['type'] + v = init_mask[e]['value'] + v.extend(init_mask[e + 1]['value']) + s = init_mask[e]['size'] * 2 + merged_frozen_mask.append({'value': v, 'type': t, 'size': s}) + else: + merged_frozen_mask.append(init_mask[e]) + merged_frozen_mask.append(init_mask[e + 1]) + else: + merged_frozen_mask.append(init_mask[e]) + merged_frozen_mask.append(init_mask[e + 1]) + if n_elems < len(init_mask): + merged_frozen_mask.append(init_mask[-1]) + return merged_frozen_mask + + +def print_decode_subframes(subframes): + for e in subframes: + print(e) + + +def find_decoder_subframes(frozen_mask): + stages = power_of_2_int(len(frozen_mask)) + block_size = 2 ** stages + + lock_mask = np.zeros(block_size, dtype=int) + sub_mask = [] + + for e in frozen_mask: + if e == 1: + sub_mask.append(0) + else: + sub_mask.append(1) + sub_mask = np.array(sub_mask, dtype=int) + + for s in range(0, stages): + stage_size = 2 ** s + mask = np.reshape(sub_mask, (-1, stage_size)) + lock = np.reshape(lock_mask, (-1, stage_size)) + for p in range(0, (block_size // stage_size) - 1, 2): + l0 = lock[p] + l1 = lock[p + 1] + first = mask[p] + second = mask[p + 1] + print(l0, l1) + print(first, second) + if np.all(l0 == l1): + for eq in range(2): + if np.all(first == eq) and np.all(second == eq): + mask[p].fill(eq) + mask[p + 1].fill(eq) + lock[p].fill(s) + lock[p + 1].fill(s) + + if np.all(first == 0) and np.all(second == 2): + mask[p].fill(2) + mask[p + 1].fill(2) + lock[p].fill(s) + lock[p + 1].fill(s) + + if np.all(first == 3) and np.all(second == 1): + mask[p].fill(3) + mask[p + 1].fill(3) + lock[p].fill(s) + lock[p + 1].fill(s) + + if s == 0 and np.all(first == 0) and np.all(second == 1): + mask[p].fill(2) + mask[p + 1].fill(2) + lock[p].fill(s) + lock[p + 1].fill(s) + + if s == 1 and np.all(first == 2) and np.all(second == 1): + mask[p].fill(3) + mask[p + 1].fill(3) + lock[p].fill(s) + lock[p + 1].fill(s) + + sub_mask = mask.flatten() + lock_mask = lock.flatten() + + words = {0: 'ZERO', 1: 'ONE', 2: 'RPT', 3: 'SPC'} + ll = lock_mask[0] + sub_t = sub_mask[0] + for i in range(len(frozen_mask)): + v = frozen_mask[i] + t = words[sub_mask[i]] + l = lock_mask[i] + # if i % 8 == 0: + # print + if not l == ll or not sub_mask[i] == sub_t: + print('--------------------------') + ll = l + sub_t = sub_mask[i] + 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 main(): + n = 8 + m = 2 ** n + k = m // 2 + n_frozen = n - k # n = 16 # k = 8 # frozenbits = np.zeros(n - k) @@ -153,12 +330,31 @@ 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() + 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 + + # 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() + 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 index 1e7cd25e26..030142d6a6 100644 --- a/gr-fec/python/fec/qa_polar_decoder_sc.py +++ b/gr-fec/python/fec/qa_polar_decoder_sc.py @@ -19,24 +19,20 @@ # 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 +import numpy as np from extended_decoder import extended_decoder from polar.encoder import PolarEncoder -from polar.decoder import PolarDecoder import polar.channel_construction as cc -from polar.helper_functions import bit_reverse_vector +# import os # print('PID:', os.getpid()) # raw_input('tell me smth') + class test_polar_decoder_sc(gr_unittest.TestCase): def setUp(self): @@ -46,13 +42,12 @@ class test_polar_decoder_sc(gr_unittest.TestCase): 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) + polar_decoder = fec.polar_decoder_sc.make(block_size, num_info_bits, frozen_bit_positions, frozen_bit_values) self.assertEqual(num_info_bits, polar_decoder.get_output_size()) self.assertEqual(block_size, polar_decoder.get_input_size()) @@ -60,8 +55,6 @@ class test_polar_decoder_sc(gr_unittest.TestCase): self.assertFalse(polar_decoder.set_frame_size(10)) def test_002_one_vector(self): - print "test_002_one_vector" - is_packed = False block_power = 10 block_size = 2 ** block_power num_info_bits = 2 ** (block_power - 1) @@ -71,7 +64,7 @@ class test_polar_decoder_sc(gr_unittest.TestCase): bits, gr_data = self.generate_test_data(block_size, num_info_bits, frozen_bit_positions, frozen_bit_values, 1, True) - polar_decoder = fec.polar_decoder_sc.make(block_size, num_info_bits, frozen_bit_positions, frozen_bit_values, is_packed) + polar_decoder = fec.polar_decoder_sc.make(block_size, num_info_bits, frozen_bit_positions, frozen_bit_values) src = blocks.vector_source_f(gr_data, False) dec_block = extended_decoder(polar_decoder, None) snk = blocks.vector_sink_b(1) @@ -81,17 +74,10 @@ class test_polar_decoder_sc(gr_unittest.TestCase): self.tb.run() res = np.array(snk.data()).astype(dtype=int) - - print("input:", gr_data.astype(dtype=int)) - print("ref :", bits) - print("res :", res) - self.assertTupleEqual(tuple(res), tuple(bits)) def test_003_stream(self): - print "test_003_stream" nframes = 3 - is_packed = False block_power = 8 block_size = 2 ** block_power num_info_bits = 2 ** (block_power - 1) @@ -101,7 +87,7 @@ class test_polar_decoder_sc(gr_unittest.TestCase): bits, gr_data = self.generate_test_data(block_size, num_info_bits, frozen_bit_positions, frozen_bit_values, nframes, False) - polar_decoder = fec.polar_decoder_sc.make(block_size, num_info_bits, frozen_bit_positions, frozen_bit_values, is_packed) + polar_decoder = fec.polar_decoder_sc.make(block_size, num_info_bits, frozen_bit_positions, frozen_bit_values) src = blocks.vector_source_f(gr_data, False) dec_block = extended_decoder(polar_decoder, None) snk = blocks.vector_sink_b(1) @@ -111,11 +97,6 @@ class test_polar_decoder_sc(gr_unittest.TestCase): self.tb.run() res = np.array(snk.data()).astype(dtype=int) - - print("input:", gr_data.astype(dtype=int)) - print("ref :", bits) - print("res :", res) - self.assertTupleEqual(tuple(res), tuple(bits)) def generate_test_data(self, block_size, num_info_bits, frozen_bit_positions, frozen_bit_values, nframes, onlyones): diff --git a/gr-fec/python/fec/qa_polar_decoder_sc_list.py b/gr-fec/python/fec/qa_polar_decoder_sc_list.py index 3aefd0f478..6b1fe3d431 100644 --- a/gr-fec/python/fec/qa_polar_decoder_sc_list.py +++ b/gr-fec/python/fec/qa_polar_decoder_sc_list.py @@ -23,15 +23,12 @@ 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 import polar.channel_construction as cc - +# import os # print('PID:', os.getpid()) # raw_input('tell me smth') @@ -45,14 +42,13 @@ class test_polar_decoder_sc_list(gr_unittest.TestCase): 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) + polar_decoder = fec.polar_decoder_sc_list.make(max_list_size, block_size, num_info_bits, frozen_bit_positions, frozen_bit_values) self.assertEqual(num_info_bits, polar_decoder.get_output_size()) self.assertEqual(block_size, polar_decoder.get_input_size()) @@ -61,7 +57,6 @@ class test_polar_decoder_sc_list(gr_unittest.TestCase): 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) @@ -69,19 +64,13 @@ class test_polar_decoder_sc_list(gr_unittest.TestCase): 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,) - 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) + polar_decoder = fec.polar_decoder_sc_list.make(max_list_size, block_size, num_info_bits, frozen_bit_positions, frozen_bit_values) src = blocks.vector_source_f(gr_data, False) dec_block = extended_decoder(polar_decoder, None) snk = blocks.vector_sink_b(1) @@ -92,19 +81,16 @@ class test_polar_decoder_sc_list(gr_unittest.TestCase): res = np.array(snk.data()).astype(dtype=int) - ref = python_decoder.decode(data) + print("\ninput -> result -> bits") + print(data) + print(res) + print(bits) - print("input:", data) - print("res :", res) - print("ref :", ref) - print("bits :", bits) - - self.assertTupleEqual(tuple(res), tuple(ref)) + self.assertTupleEqual(tuple(res), tuple(bits)) 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) @@ -112,11 +98,9 @@ class test_polar_decoder_sc_list(gr_unittest.TestCase): 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,) - 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): @@ -124,13 +108,9 @@ class test_polar_decoder_sc_list(gr_unittest.TestCase): 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) + polar_decoder = fec.polar_decoder_sc_list.make(max_list_size, block_size, num_info_bits, frozen_bit_positions, frozen_bit_values) src = blocks.vector_source_f(gr_data, False) dec_block = extended_decoder(polar_decoder, None) snk = blocks.vector_sink_b(1) @@ -140,17 +120,9 @@ class test_polar_decoder_sc_list(gr_unittest.TestCase): 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 90190cd719..22d9b11fae 100644 --- a/gr-fec/python/fec/qa_polar_encoder.py +++ b/gr-fec/python/fec/qa_polar_encoder.py @@ -101,12 +101,10 @@ class test_polar_encoder(gr_unittest.TestCase): self.tb.run() res = np.array(snk.data()).astype(dtype=int) - - print(res) - print(ref) self.assertTupleEqual(tuple(res), tuple(ref)) def get_test_data(self, block_size, num_info_bits, num_blocks, is_packed): + # 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,) @@ -122,10 +120,6 @@ class test_polar_encoder(gr_unittest.TestCase): return data, ref, polar_encoder - - - - if __name__ == '__main__': gr_unittest.run(test_polar_encoder) |