summaryrefslogtreecommitdiff
path: root/gr-fec/lib/ldpc_H_matrix_impl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gr-fec/lib/ldpc_H_matrix_impl.cc')
-rw-r--r--gr-fec/lib/ldpc_H_matrix_impl.cc713
1 files changed, 346 insertions, 367 deletions
diff --git a/gr-fec/lib/ldpc_H_matrix_impl.cc b/gr-fec/lib/ldpc_H_matrix_impl.cc
index 4d37899ba6..6b1b17e0f9 100644
--- a/gr-fec/lib/ldpc_H_matrix_impl.cc
+++ b/gr-fec/lib/ldpc_H_matrix_impl.cc
@@ -30,416 +30,395 @@
#include <stdexcept>
namespace gr {
- namespace fec {
- namespace code {
-
- ldpc_H_matrix::sptr
- ldpc_H_matrix::make(const std::string filename, unsigned int gap)
- {
- return ldpc_H_matrix::sptr
- (new ldpc_H_matrix_impl(filename, gap));
- }
-
- ldpc_H_matrix_impl::ldpc_H_matrix_impl(const std::string filename, unsigned int gap)
- : fec_mtrx_impl()
- {
- matrix_sptr x = read_matrix_from_file(filename);
- d_num_cols = x->size2;
- d_num_rows = x->size1;
- d_gap = gap;
-
- // Make an actual copy so we guarantee that we're not sharing
- // memory with another class that reads the same alist file.
- gsl_matrix *temp_mtrx = gsl_matrix_alloc(d_num_rows, d_num_cols);
- gsl_matrix_memcpy(temp_mtrx, (gsl_matrix*)(x.get()));
- d_H_sptr = matrix_sptr((matrix*)temp_mtrx, matrix_free);
-
- // Length of codeword = # of columns
- d_n = d_num_cols;
-
- // Length of information word = (# of columns) - (# of rows)
- d_k = d_num_cols - d_num_rows;
-
- set_parameters_for_encoding();
-
- // The parity bits come first in this particular matrix
- // format (specifically required for the Richardson Urbanke
- // encoder)
- d_par_bits_last = false;
-
- } // Constructor
-
- const gsl_matrix*
- ldpc_H_matrix_impl::A() const
- {
- const gsl_matrix *A_ptr = &d_A_view.matrix;
- return A_ptr;
- }
-
- const gsl_matrix*
- ldpc_H_matrix_impl::B() const
- {
- const gsl_matrix *B_ptr = &d_B_view.matrix;
- return B_ptr;
- }
-
- const gsl_matrix*
- ldpc_H_matrix_impl::D() const
- {
- const gsl_matrix *D_ptr = &d_D_view.matrix;
- return D_ptr;
- }
-
- const gsl_matrix*
- ldpc_H_matrix_impl::E() const
- {
- const gsl_matrix *E_ptr = &d_E_view.matrix;
- return E_ptr;
- }
-
- const gsl_matrix*
- ldpc_H_matrix_impl::T() const
- {
- const gsl_matrix *T_ptr = &d_T_view.matrix;
- return T_ptr;
- }
-
- const gsl_matrix*
- ldpc_H_matrix_impl::phi_inverse() const
- {
- const gsl_matrix *phi_inverse_ptr = d_phi_inverse_ptr;
- return phi_inverse_ptr;
- }
-
- void
- ldpc_H_matrix_impl::set_parameters_for_encoding()
- {
-
- // This function defines all of the submatrices that will be
- // needed during encoding.
-
- unsigned int t = d_num_rows - d_gap;
-
- // T submatrix
- d_T_view = gsl_matrix_submatrix((gsl_matrix*)(d_H_sptr.get()),
- 0, 0, t, t);
-
- gsl_matrix *d_T_inverse_ptr;
+namespace fec {
+namespace code {
+
+ldpc_H_matrix::sptr ldpc_H_matrix::make(const std::string filename, unsigned int gap)
+{
+ return ldpc_H_matrix::sptr(new ldpc_H_matrix_impl(filename, gap));
+}
+
+ldpc_H_matrix_impl::ldpc_H_matrix_impl(const std::string filename, unsigned int gap)
+ : fec_mtrx_impl()
+{
+ matrix_sptr x = read_matrix_from_file(filename);
+ d_num_cols = x->size2;
+ d_num_rows = x->size1;
+ d_gap = gap;
+
+ // Make an actual copy so we guarantee that we're not sharing
+ // memory with another class that reads the same alist file.
+ gsl_matrix* temp_mtrx = gsl_matrix_alloc(d_num_rows, d_num_cols);
+ gsl_matrix_memcpy(temp_mtrx, (gsl_matrix*)(x.get()));
+ d_H_sptr = matrix_sptr((matrix*)temp_mtrx, matrix_free);
+
+ // Length of codeword = # of columns
+ d_n = d_num_cols;
+
+ // Length of information word = (# of columns) - (# of rows)
+ d_k = d_num_cols - d_num_rows;
+
+ set_parameters_for_encoding();
+
+ // The parity bits come first in this particular matrix
+ // format (specifically required for the Richardson Urbanke
+ // encoder)
+ d_par_bits_last = false;
+
+} // Constructor
+
+const gsl_matrix* ldpc_H_matrix_impl::A() const
+{
+ const gsl_matrix* A_ptr = &d_A_view.matrix;
+ return A_ptr;
+}
+
+const gsl_matrix* ldpc_H_matrix_impl::B() const
+{
+ const gsl_matrix* B_ptr = &d_B_view.matrix;
+ return B_ptr;
+}
+
+const gsl_matrix* ldpc_H_matrix_impl::D() const
+{
+ const gsl_matrix* D_ptr = &d_D_view.matrix;
+ return D_ptr;
+}
+
+const gsl_matrix* ldpc_H_matrix_impl::E() const
+{
+ const gsl_matrix* E_ptr = &d_E_view.matrix;
+ return E_ptr;
+}
+
+const gsl_matrix* ldpc_H_matrix_impl::T() const
+{
+ const gsl_matrix* T_ptr = &d_T_view.matrix;
+ return T_ptr;
+}
+
+const gsl_matrix* ldpc_H_matrix_impl::phi_inverse() const
+{
+ const gsl_matrix* phi_inverse_ptr = d_phi_inverse_ptr;
+ return phi_inverse_ptr;
+}
+
+void ldpc_H_matrix_impl::set_parameters_for_encoding()
+{
+
+ // This function defines all of the submatrices that will be
+ // needed during encoding.
+
+ unsigned int t = d_num_rows - d_gap;
+
+ // T submatrix
+ d_T_view = gsl_matrix_submatrix((gsl_matrix*)(d_H_sptr.get()), 0, 0, t, t);
+
+ gsl_matrix* d_T_inverse_ptr;
+ try {
+ d_T_inverse_ptr = calc_inverse_mod2(&d_T_view.matrix);
+ } catch (char const* exceptionString) {
+ std::cout << "Error in set_parameters_for_encoding while "
+ << "looking for inverse T matrix: " << exceptionString
+ << "Tip: verify that the correct gap is being "
+ << "specified for this alist file.\n";
+
+ throw std::runtime_error("set_parameters_for_encoding");
+ }
+
+ // E submatrix
+ d_E_view = gsl_matrix_submatrix(
+ (gsl_matrix*)(d_H_sptr.get()), t, 0, d_gap, d_n - d_k - d_gap);
+
+ // A submatrix
+ d_A_view = gsl_matrix_submatrix((gsl_matrix*)(d_H_sptr.get()), 0, t, t, d_gap);
+
+ // C submatrix (used to find phi but not during encoding)
+ gsl_matrix_view C_view =
+ gsl_matrix_submatrix((gsl_matrix*)(d_H_sptr.get()), t, t, d_gap, d_gap);
+
+ // These are just temporary matrices used to find phi.
+ gsl_matrix* temp1 = gsl_matrix_alloc(d_E_view.matrix.size1, d_T_inverse_ptr->size2);
+ mult_matrices_mod2(temp1, &d_E_view.matrix, d_T_inverse_ptr);
+
+ gsl_matrix* temp2 = gsl_matrix_alloc(temp1->size1, d_A_view.matrix.size2);
+ mult_matrices_mod2(temp2, temp1, &d_A_view.matrix);
+
+ // Solve for phi.
+ gsl_matrix* phi = gsl_matrix_alloc(C_view.matrix.size1, temp2->size2);
+ add_matrices_mod2(phi, &C_view.matrix, temp2);
+
+ // If phi has at least one nonzero entry, try for inverse.
+ if (gsl_matrix_max(phi)) {
try {
- d_T_inverse_ptr = calc_inverse_mod2(&d_T_view.matrix);
- }
- catch (char const *exceptionString) {
- std::cout << "Error in set_parameters_for_encoding while "
- << "looking for inverse T matrix: "
- << exceptionString
- << "Tip: verify that the correct gap is being "
- << "specified for this alist file.\n";
-
- throw std::runtime_error("set_parameters_for_encoding");
- }
-
- // E submatrix
- d_E_view = gsl_matrix_submatrix((gsl_matrix*)(d_H_sptr.get()),
- t, 0, d_gap, d_n-d_k-d_gap);
-
- // A submatrix
- d_A_view = gsl_matrix_submatrix((gsl_matrix*)(d_H_sptr.get()),
- 0, t, t, d_gap);
-
- // C submatrix (used to find phi but not during encoding)
- gsl_matrix_view C_view = gsl_matrix_submatrix((gsl_matrix*)(d_H_sptr.get()),
- t, t, d_gap, d_gap);
-
- // These are just temporary matrices used to find phi.
- gsl_matrix *temp1 = gsl_matrix_alloc(d_E_view.matrix.size1, d_T_inverse_ptr->size2);
- mult_matrices_mod2(temp1, &d_E_view.matrix, d_T_inverse_ptr);
-
- gsl_matrix *temp2 = gsl_matrix_alloc(temp1->size1, d_A_view.matrix.size2);
- mult_matrices_mod2(temp2, temp1, &d_A_view.matrix);
-
- // Solve for phi.
- gsl_matrix *phi = gsl_matrix_alloc(C_view.matrix.size1, temp2->size2);
- add_matrices_mod2(phi, &C_view.matrix, temp2);
-
- // If phi has at least one nonzero entry, try for inverse.
- if (gsl_matrix_max(phi)) {
- try {
- gsl_matrix *inverse_phi = calc_inverse_mod2(phi);
+ gsl_matrix* inverse_phi = calc_inverse_mod2(phi);
// At this point, an inverse was found.
d_phi_inverse_ptr = inverse_phi;
- }
- catch (char const *exceptionString) {
+ } catch (char const* exceptionString) {
std::cout << "Error in set_parameters_for_encoding while"
<< " finding inverse_phi: " << exceptionString
<< "Tip: verify that the correct gap is being "
<< "specified for this alist file.\n";
throw std::runtime_error("set_parameters_for_encoding");
- }
}
-
- // B submatrix
- d_B_view = gsl_matrix_submatrix((gsl_matrix*)(d_H_sptr.get()),
- 0, t + d_gap, t, d_n-d_gap-t);
-
- // D submatrix
- d_D_view = gsl_matrix_submatrix((gsl_matrix*)(d_H_sptr.get()),
- t, t + d_gap, d_gap, d_n-d_gap-t);
-
- // Free memory
- gsl_matrix_free(temp1);
- gsl_matrix_free(temp2);
- gsl_matrix_free(phi);
- gsl_matrix_free(d_T_inverse_ptr);
- }
-
- void
- ldpc_H_matrix_impl::back_solve_mod2(gsl_matrix *x,
- const gsl_matrix *U,
- const gsl_matrix *y) const
- {
- // Exploit the fact that the matrix T is upper triangular and
- // sparse. In the steps to find p1 and p2, back solve rather
- // than do matrix multiplication to reduce number of
- // operations required.
-
- // Form is Ux = y where U is upper triangular and y is column
- // vector. Solve for x.
-
- // Allocate memory for the result
- int num_rows = (*U).size1;
- int num_cols_U = (*U).size2;
-
- // Back solve
- for (int i = num_rows-1; i >= 0; i--) {
- // x[i] = y[i]
- gsl_matrix_set(x, i, 0, gsl_matrix_get(y, i, 0));
-
- int j;
- for (j = i+1; j < num_cols_U; j++) {
+ }
+
+ // B submatrix
+ d_B_view = gsl_matrix_submatrix(
+ (gsl_matrix*)(d_H_sptr.get()), 0, t + d_gap, t, d_n - d_gap - t);
+
+ // D submatrix
+ d_D_view = gsl_matrix_submatrix(
+ (gsl_matrix*)(d_H_sptr.get()), t, t + d_gap, d_gap, d_n - d_gap - t);
+
+ // Free memory
+ gsl_matrix_free(temp1);
+ gsl_matrix_free(temp2);
+ gsl_matrix_free(phi);
+ gsl_matrix_free(d_T_inverse_ptr);
+}
+
+void ldpc_H_matrix_impl::back_solve_mod2(gsl_matrix* x,
+ const gsl_matrix* U,
+ const gsl_matrix* y) const
+{
+ // Exploit the fact that the matrix T is upper triangular and
+ // sparse. In the steps to find p1 and p2, back solve rather
+ // than do matrix multiplication to reduce number of
+ // operations required.
+
+ // Form is Ux = y where U is upper triangular and y is column
+ // vector. Solve for x.
+
+ // Allocate memory for the result
+ int num_rows = (*U).size1;
+ int num_cols_U = (*U).size2;
+
+ // Back solve
+ for (int i = num_rows - 1; i >= 0; i--) {
+ // x[i] = y[i]
+ gsl_matrix_set(x, i, 0, gsl_matrix_get(y, i, 0));
+
+ int j;
+ for (j = i + 1; j < num_cols_U; j++) {
int U_i_j = gsl_matrix_get(U, i, j);
- int x_i = gsl_matrix_get(x, i, 0);
- int x_j = gsl_matrix_get(x, j, 0);
+ int x_i = gsl_matrix_get(x, i, 0);
+ int x_j = gsl_matrix_get(x, j, 0);
int temp1 = (U_i_j * x_j) % 2;
int temp2 = (x_i + temp1) % 2;
gsl_matrix_set(x, i, 0, temp2);
- }
- // Perform x[i] /= U[i,i], GF(2) operations
- int U_i_i = gsl_matrix_get(U, i, i);
- int x_i = gsl_matrix_get(x, i, 0);
- if(x_i==0 && U_i_i==1)
+ }
+ // Perform x[i] /= U[i,i], GF(2) operations
+ int U_i_i = gsl_matrix_get(U, i, i);
+ int x_i = gsl_matrix_get(x, i, 0);
+ if (x_i == 0 && U_i_i == 1)
gsl_matrix_set(x, i, 0, 0);
- else if (x_i==0 && U_i_i==0)
+ else if (x_i == 0 && U_i_i == 0)
gsl_matrix_set(x, i, 0, 0);
- else if (x_i==1 && U_i_i==1)
+ else if (x_i == 1 && U_i_i == 1)
gsl_matrix_set(x, i, 0, 1);
- else if (x_i==1 && U_i_i==0)
+ else if (x_i == 1 && U_i_i == 0)
std::cout << "Error in "
<< " ldpc_H_matrix_impl::back_solve_mod2,"
<< " division not defined.\n";
- else
+ else
std::cout << "Error in ldpc_H_matrix::back_solve_mod2\n";
- }
- }
-
-
- void
- ldpc_H_matrix_impl::encode(unsigned char *outbuffer,
- const unsigned char *inbuffer) const
- {
-
- // Temporary matrix for storing stages of encoding.
- gsl_matrix *s, *p1, *p2;
- gsl_matrix *temp1, *temp2, *temp3, *temp4, *temp5, *temp6, *temp7;
-
- unsigned int index, k = d_k;
- s = gsl_matrix_alloc(k, 1);
- for (index = 0; index < k; index++) {
- double value = static_cast<double>(inbuffer[index]);
- gsl_matrix_set(s, index, 0, value);
- }
-
- // Solve for p2 (parity part). By using back substitution,
- // the overall complexity of determining p2 is O(n + g^2).
- temp1 = gsl_matrix_alloc(B()->size1, s->size2);
- mult_matrices_mod2(temp1, B(), s);
-
- temp2 = gsl_matrix_alloc(T()->size1, 1);
- back_solve_mod2(temp2, T(), temp1);
-
- temp3 = gsl_matrix_alloc(E()->size1, temp2->size2);
- mult_matrices_mod2(temp3, E(), temp2);
-
- temp4 = gsl_matrix_alloc(D()->size1, s->size2);
- mult_matrices_mod2(temp4, D(), s);
-
- temp5 = gsl_matrix_alloc(temp4->size1, temp3->size2);
- add_matrices_mod2(temp5, temp4, temp3);
-
- p2 = gsl_matrix_alloc(phi_inverse()->size1, temp5->size2);
- mult_matrices_mod2(p2, phi_inverse(), temp5);
-
- // Solve for p1 (parity part). By using back substitution,
- // the overall complexity of determining p1 is O(n).
- temp6 = gsl_matrix_alloc(A()->size1, p2->size2);
- mult_matrices_mod2(temp6, A(), p2);
-
- temp7 = gsl_matrix_alloc(temp6->size1, temp1->size2);
- add_matrices_mod2(temp7, temp6, temp1);
-
- p1 = gsl_matrix_alloc(T()->size1, 1);
- back_solve_mod2(p1, T(), temp7);
-
- // Populate the codeword to be output
- unsigned int p1_length = (*p1).size1;
- unsigned int p2_length = (*p2).size1;
- for (index = 0; index < p1_length; index++) {
- int value = gsl_matrix_get(p1, index, 0);
- outbuffer[index] = value;
- }
- for (index = 0; index < p2_length; index++) {
- int value = gsl_matrix_get(p2, index, 0);
- outbuffer[p1_length+index] = value;
- }
- for (index = 0; index < k; index++) {
- int value = gsl_matrix_get(s, index, 0);
- outbuffer[p1_length+p2_length+index] = value;
- }
-
- // Free temporary matrices
- gsl_matrix_free(temp1);
- gsl_matrix_free(temp2);
- gsl_matrix_free(temp3);
- gsl_matrix_free(temp4);
- gsl_matrix_free(temp5);
- gsl_matrix_free(temp6);
- gsl_matrix_free(temp7);
- gsl_matrix_free(p1);
- gsl_matrix_free(p2);
- }
-
-
- void
- ldpc_H_matrix_impl::decode(unsigned char *outbuffer,
- const float *inbuffer,
- unsigned int frame_size,
- unsigned int max_iterations) const
- {
- unsigned int index, n = d_n;
- gsl_matrix *x = gsl_matrix_alloc(n, 1);
- for (index = 0; index < n; index++) {
- double value = inbuffer[index] > 0 ? 1.0 : 0.0;
- gsl_matrix_set(x, index, 0, value);
- }
-
- // Initialize counter
- unsigned int count = 0;
-
- // Calculate syndrome
- gsl_matrix *syndrome = gsl_matrix_alloc(H()->size1, x->size2);
- mult_matrices_mod2(syndrome, 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 < 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++) {
+ }
+}
+
+
+void ldpc_H_matrix_impl::encode(unsigned char* outbuffer,
+ const unsigned char* inbuffer) const
+{
+
+ // Temporary matrix for storing stages of encoding.
+ gsl_matrix *s, *p1, *p2;
+ gsl_matrix *temp1, *temp2, *temp3, *temp4, *temp5, *temp6, *temp7;
+
+ unsigned int index, k = d_k;
+ s = gsl_matrix_alloc(k, 1);
+ for (index = 0; index < k; index++) {
+ double value = static_cast<double>(inbuffer[index]);
+ gsl_matrix_set(s, index, 0, value);
+ }
+
+ // Solve for p2 (parity part). By using back substitution,
+ // the overall complexity of determining p2 is O(n + g^2).
+ temp1 = gsl_matrix_alloc(B()->size1, s->size2);
+ mult_matrices_mod2(temp1, B(), s);
+
+ temp2 = gsl_matrix_alloc(T()->size1, 1);
+ back_solve_mod2(temp2, T(), temp1);
+
+ temp3 = gsl_matrix_alloc(E()->size1, temp2->size2);
+ mult_matrices_mod2(temp3, E(), temp2);
+
+ temp4 = gsl_matrix_alloc(D()->size1, s->size2);
+ mult_matrices_mod2(temp4, D(), s);
+
+ temp5 = gsl_matrix_alloc(temp4->size1, temp3->size2);
+ add_matrices_mod2(temp5, temp4, temp3);
+
+ p2 = gsl_matrix_alloc(phi_inverse()->size1, temp5->size2);
+ mult_matrices_mod2(p2, phi_inverse(), temp5);
+
+ // Solve for p1 (parity part). By using back substitution,
+ // the overall complexity of determining p1 is O(n).
+ temp6 = gsl_matrix_alloc(A()->size1, p2->size2);
+ mult_matrices_mod2(temp6, A(), p2);
+
+ temp7 = gsl_matrix_alloc(temp6->size1, temp1->size2);
+ add_matrices_mod2(temp7, temp6, temp1);
+
+ p1 = gsl_matrix_alloc(T()->size1, 1);
+ back_solve_mod2(p1, T(), temp7);
+
+ // Populate the codeword to be output
+ unsigned int p1_length = (*p1).size1;
+ unsigned int p2_length = (*p2).size1;
+ for (index = 0; index < p1_length; index++) {
+ int value = gsl_matrix_get(p1, index, 0);
+ outbuffer[index] = value;
+ }
+ for (index = 0; index < p2_length; index++) {
+ int value = gsl_matrix_get(p2, index, 0);
+ outbuffer[p1_length + index] = value;
+ }
+ for (index = 0; index < k; index++) {
+ int value = gsl_matrix_get(s, index, 0);
+ outbuffer[p1_length + p2_length + index] = value;
+ }
+
+ // Free temporary matrices
+ gsl_matrix_free(temp1);
+ gsl_matrix_free(temp2);
+ gsl_matrix_free(temp3);
+ gsl_matrix_free(temp4);
+ gsl_matrix_free(temp5);
+ gsl_matrix_free(temp6);
+ gsl_matrix_free(temp7);
+ gsl_matrix_free(p1);
+ gsl_matrix_free(p2);
+}
+
+
+void ldpc_H_matrix_impl::decode(unsigned char* outbuffer,
+ const float* inbuffer,
+ unsigned int frame_size,
+ unsigned int max_iterations) const
+{
+ unsigned int index, n = d_n;
+ gsl_matrix* x = gsl_matrix_alloc(n, 1);
+ for (index = 0; index < n; index++) {
+ double value = inbuffer[index] > 0 ? 1.0 : 0.0;
+ gsl_matrix_set(x, index, 0, value);
+ }
+
+ // Initialize counter
+ unsigned int count = 0;
+
+ // Calculate syndrome
+ gsl_matrix* syndrome = gsl_matrix_alloc(H()->size1, x->size2);
+ mult_matrices_mod2(syndrome, 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 < 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);
+ 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_n;
- std::vector<int> counts(n,0);
- for (i = 0; i < rows_of_interest_in_H.size(); i++) {
+ }
+
+ // 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_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(H(),
- row_num,
- col_num);
- if (value > 0) {
- counts[col_num] = counts[col_num] + 1;
- }
+ double value = gsl_matrix_get(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++) {
+ // 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];
+ max = counts[index];
}
- }
+ }
- for (index = 0; index < n; 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);
+ 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
- mult_matrices_mod2(syndrome, H(), x);
- if (gsl_matrix_isnull(syndrome)) {
+ // Check the syndrome; see if valid codeword has been found
+ mult_matrices_mod2(syndrome, H(), x);
+ if (gsl_matrix_isnull(syndrome)) {
found_word = true;
break;
- }
- count++;
}
+ count++;
+ }
- // Extract the info word and assign to output. This will
- // happen regardless of if a valid codeword was found.
- if(parity_bits_come_last()) {
- for(index = 0; index < frame_size; index++) {
+ // Extract the info word and assign to output. This will
+ // happen regardless of if a valid codeword was found.
+ if (parity_bits_come_last()) {
+ for (index = 0; index < frame_size; index++) {
outbuffer[index] = gsl_matrix_get(x, index, 0);
- }
}
- else {
- for(index = 0; index < frame_size; index++) {
+ } else {
+ for (index = 0; index < frame_size; index++) {
unsigned int i = index + n - frame_size;
int value = gsl_matrix_get(x, i, 0);
outbuffer[index] = value;
- }
}
-
- // Free memory
- gsl_matrix_free(syndrome);
- gsl_matrix_free(x);
- }
-
- gr::fec::code::fec_mtrx_sptr
- ldpc_H_matrix_impl::get_base_sptr()
- {
- return shared_from_this();
- }
-
- ldpc_H_matrix_impl::~ldpc_H_matrix_impl()
- {
-
- // Call the gsl_matrix_free function to free memory.
- gsl_matrix_free (d_phi_inverse_ptr);
- }
- } /* namespace code */
- } /* namespace fec */
+ }
+
+ // Free memory
+ gsl_matrix_free(syndrome);
+ gsl_matrix_free(x);
+}
+
+gr::fec::code::fec_mtrx_sptr ldpc_H_matrix_impl::get_base_sptr()
+{
+ return shared_from_this();
+}
+
+ldpc_H_matrix_impl::~ldpc_H_matrix_impl()
+{
+
+ // Call the gsl_matrix_free function to free memory.
+ gsl_matrix_free(d_phi_inverse_ptr);
+}
+} /* namespace code */
+} /* namespace fec */
} /* namespace gr */