diff options
Diffstat (limited to 'gr-fec/lib/ldpc_bit_flip_decoder_impl.cc')
-rw-r--r-- | gr-fec/lib/ldpc_bit_flip_decoder_impl.cc | 151 |
1 files changed, 32 insertions, 119 deletions
diff --git a/gr-fec/lib/ldpc_bit_flip_decoder_impl.cc b/gr-fec/lib/ldpc_bit_flip_decoder_impl.cc index cb71394ed7..49fd241a06 100644 --- a/gr-fec/lib/ldpc_bit_flip_decoder_impl.cc +++ b/gr-fec/lib/ldpc_bit_flip_decoder_impl.cc @@ -1,17 +1,17 @@ /* -*- c++ -*- */ -/* +/* * Copyright 2015 Free Software Foundation, Inc. - * + * * This 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 + * 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. - * + * * This software 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 this software; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, @@ -42,12 +42,15 @@ namespace gr { (new ldpc_bit_flip_decoder_impl(mtrx_obj, max_iter)); } - ldpc_bit_flip_decoder_impl::ldpc_bit_flip_decoder_impl(const fec_mtrx *mtrx_obj, unsigned int max_iter) + ldpc_bit_flip_decoder_impl::ldpc_bit_flip_decoder_impl(const fec_mtrx *mtrx_obj, + unsigned int max_iter) : generic_decoder("ldpc_bit_flip_decoder") { // FEC matrix object to use for decoding d_mtrx = mtrx_obj; + d_rate = static_cast<double>(d_mtrx->k())/static_cast<double>(d_mtrx->n()); + // Set frame size to k, the # of bits in the information word // All buffers and settings will be based on this value. set_frame_size(d_mtrx->k()); @@ -62,32 +65,36 @@ namespace gr { int ldpc_bit_flip_decoder_impl::get_output_size() { - return d_frame_size; + return d_output_size; } - + int ldpc_bit_flip_decoder_impl::get_input_size() { - return int(d_mtrx->n()); + return d_input_size; } bool - ldpc_bit_flip_decoder_impl::set_frame_size( - unsigned int frame_size) + ldpc_bit_flip_decoder_impl::set_frame_size(unsigned int frame_size) { - bool ret = true; - // TODO add some bounds check here? The frame size is - // constant and specified by the size of the parity check - // matrix used for encoding. - d_frame_size = frame_size; + if(frame_size % d_mtrx->k() != 0) { + GR_LOG_ERROR(d_logger, boost::format("Frame size (%1% bits) must be a " + "multiple of the information word " + "size of the LDPC matrix, %2%") \ + % frame_size % (d_mtrx->k())); + throw std::runtime_error("ldpc_bit_flip_decoder: cannot use frame size."); + } - return ret; + d_output_size = frame_size; + d_input_size = static_cast<int>(round(frame_size / d_rate)); + + return true; } double ldpc_bit_flip_decoder_impl::rate() { - return static_cast<double>(d_frame_size)/(d_mtrx->n()); + return d_rate; } @@ -95,112 +102,18 @@ namespace gr { ldpc_bit_flip_decoder_impl::generic_work(void *inbuffer, void *outbuffer) { - // Populate the information word const float *in = (const float*)inbuffer; - - unsigned int index, n = d_mtrx->n(); - gsl_matrix *x = gsl_matrix_alloc(n, 1); - for (index = 0; index < n; index++) { - double value = in[index] > 0 ? 1.0 : 0.0; - gsl_matrix_set(x, index, 0, value); - } - - // Initialize counter - unsigned int count = 0; - - // Calculate syndrome - gsl_matrix *syndrome = d_mtrx->mult_matrices_mod2(d_mtrx->H(),x); - - // Flag for finding a valid codeword - bool found_word = false; - - // If the syndrome is all 0s, then codeword is valid and we - // don't need to loop; we're done. - if (gsl_matrix_isnull(syndrome)) { - found_word = true; - } - - // Loop until valid codeword is found, or max number of - // iterations is reached, whichever comes first - while ((count < d_max_iterations) && !found_word) { - // For each of the n bits in the codeword, determine how - // many of the unsatisfied parity checks involve that bit. - // To do this, first find the nonzero entries in the - // syndrome. The entry numbers correspond to the rows of - // interest in H. - std::vector<int> rows_of_interest_in_H; - for (index = 0; index < (*syndrome).size1; index++) { - if (gsl_matrix_get(syndrome, index, 0)) { - rows_of_interest_in_H.push_back(index); - } - } - - // Second, for each bit, determine how many of the - // unsatisfied parity checks involve this bit and store - // the count. - unsigned int i, col_num, n = d_mtrx->n(); - std::vector<int> counts(n,0); - for (i = 0; i < rows_of_interest_in_H.size(); i++) { - unsigned int row_num = rows_of_interest_in_H[i]; - for (col_num = 0; col_num < n; col_num++) { - double value = gsl_matrix_get(d_mtrx->H(), - row_num, - col_num); - if (value > 0) { - counts[col_num] = counts[col_num] + 1; - } - } - } - - // Next, determine which bit(s) is associated with the most - // unsatisfied parity checks, and flip it/them. - int max = 0; - for (index = 0; index < n; index++) { - if (counts[index] > max) { - max = counts[index]; - } - } - - for (index = 0; index < n; index++) { - if (counts[index] == max) { - unsigned int value = gsl_matrix_get(x, index, 0); - unsigned int new_value = value ^ 1; - gsl_matrix_set(x, index, 0, new_value); - } - } - - // Check the syndrome; see if valid codeword has been found - syndrome = d_mtrx->mult_matrices_mod2(d_mtrx->H(), x); - if (gsl_matrix_isnull(syndrome)) { - found_word = true; - break; - } - count++; - } - - // Extract the info word and assign to output. This will - // happen regardless of if a valid codeword was found. unsigned char *out = (unsigned char*) outbuffer; - if (d_mtrx->parity_bits_come_last()) { - for (index = 0; index < d_frame_size; index++) { - out[index] = gsl_matrix_get(x, index, 0); - } - } - else { - for (index = 0; index < d_frame_size; index++) { - unsigned int i = index + n - d_frame_size; - int value = gsl_matrix_get(x, i, 0); - out[index] = value; - } + + int j = 0; + for(int i = 0; i < d_input_size; i+=d_mtrx->n()) { + d_mtrx->decode(&out[j], &in[i], d_mtrx->k(), d_max_iterations); + j += d_mtrx->k(); } - // Free memory - gsl_matrix_free(syndrome); - gsl_matrix_free(x); + } /* ldpc_bit_flip_decoder_impl::generic_work() */ - } /* ldpc_bit_flip_decoder_impl::generic_work() */ } /* namespace code */ } /* namespace fec */ } /* namespace gr */ - |