summaryrefslogtreecommitdiff
path: root/gr-fec/lib/ldpc_bit_flip_decoder_impl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gr-fec/lib/ldpc_bit_flip_decoder_impl.cc')
-rw-r--r--gr-fec/lib/ldpc_bit_flip_decoder_impl.cc151
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 */
-