summaryrefslogtreecommitdiff
path: root/gr-fec/lib/ldpc_G_matrix_impl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gr-fec/lib/ldpc_G_matrix_impl.cc')
-rw-r--r--gr-fec/lib/ldpc_G_matrix_impl.cc454
1 files changed, 222 insertions, 232 deletions
diff --git a/gr-fec/lib/ldpc_G_matrix_impl.cc b/gr-fec/lib/ldpc_G_matrix_impl.cc
index 0ea76f2ef4..a17c571ec9 100644
--- a/gr-fec/lib/ldpc_G_matrix_impl.cc
+++ b/gr-fec/lib/ldpc_G_matrix_impl.cc
@@ -29,270 +29,260 @@
#include <iostream>
namespace gr {
- namespace fec {
- namespace code {
-
- ldpc_G_matrix::sptr
- ldpc_G_matrix::make(const std::string filename)
- {
- return ldpc_G_matrix::sptr
- (new ldpc_G_matrix_impl(filename));
- }
-
- ldpc_G_matrix_impl::ldpc_G_matrix_impl(const std::string filename)
- : fec_mtrx_impl()
- {
- configure_default_loggers(d_logger, d_debug_logger, "ldpc_G_matrix");
-
- // Read the matrix from a file in alist format
- matrix_sptr x = read_matrix_from_file(filename);
- d_num_cols = x->size2;
- d_num_rows = x->size1;
-
- // Make an actual copy so we guarantee that we're not sharing
- // memory with another class that reads the same alist file.
- gsl_matrix *G = gsl_matrix_alloc(d_num_rows, d_num_cols);
- gsl_matrix_memcpy(G, (gsl_matrix*)(x.get()));
-
- unsigned int row_index, col_index;
-
- // First, check if we have a generator matrix G in systematic
- // form, G = [I P], where I is a k x k identity matrix and P
- // is the parity submatrix.
-
- // Length of codeword = # of columns of generator matrix
- d_n = d_num_cols;
- // Length of information word = # of rows of generator matrix
- d_k = d_num_rows;
-
- gsl_matrix *I_test = gsl_matrix_alloc(d_k, d_k);
- gsl_matrix *identity = gsl_matrix_alloc(d_k, d_k);
- gsl_matrix_set_identity(identity);
-
- for(row_index = 0; row_index < d_k; row_index++) {
- for(col_index = 0; col_index < d_k; col_index++) {
- int value = gsl_matrix_get(G, row_index, col_index);
- gsl_matrix_set(I_test, row_index, col_index, value);
- }
- }
+namespace fec {
+namespace code {
- // Check if the identity matrix exists in the right spot.
- //int test_if_equal = gsl_matrix_equal(identity, I_test);
- gsl_matrix_sub(identity, I_test); // should be null set if equal
- double test_if_not_equal = gsl_matrix_max(identity);
-
- // Free memory
- gsl_matrix_free(identity);
- gsl_matrix_free(I_test);
-
- //if(!test_if_equal) {
- if(test_if_not_equal > 0) {
- GR_LOG_ERROR(d_logger,
- "Error in ldpc_G_matrix_impl constructor. It appears "
- "that the given alist file did not contain either a "
- "valid parity check matrix of the form H = [P' I] or "
- "a generator matrix of the form G = [I P].\n");
- throw std::runtime_error("ldpc_G_matrix: Bad matrix definition");
- }
-
- // Our G matrix is verified as correct, now convert it to the
- // parity check matrix.
+ldpc_G_matrix::sptr ldpc_G_matrix::make(const std::string filename)
+{
+ return ldpc_G_matrix::sptr(new ldpc_G_matrix_impl(filename));
+}
- // Grab P matrix
- gsl_matrix *P = gsl_matrix_alloc(d_k, d_n-d_k);
- for(row_index = 0; row_index < d_k; row_index++) {
- for(col_index = 0; col_index < d_n-d_k; col_index++) {
- int value = gsl_matrix_get(G, row_index, col_index + d_k);
- gsl_matrix_set(P, row_index, col_index, value);
- }
- }
+ldpc_G_matrix_impl::ldpc_G_matrix_impl(const std::string filename) : fec_mtrx_impl()
+{
+ configure_default_loggers(d_logger, d_debug_logger, "ldpc_G_matrix");
- // Calculate P transpose
- gsl_matrix *P_transpose = gsl_matrix_alloc(d_n-d_k, d_k);
- gsl_matrix_transpose_memcpy(P_transpose, P);
+ // Read the matrix from a file in alist format
+ matrix_sptr x = read_matrix_from_file(filename);
+ d_num_cols = x->size2;
+ d_num_rows = x->size1;
- // Set H matrix. H = [-P' I] but since we are doing mod 2,
- // -P = P, so H = [P' I]
- gsl_matrix *H_ptr = gsl_matrix_alloc(d_n-d_k, d_n);
- gsl_matrix_set_zero(H_ptr);
- for(row_index = 0; row_index < d_n-d_k; row_index++) {
- for(col_index = 0; col_index < d_k; col_index++) {
- int value = gsl_matrix_get(P_transpose, row_index, col_index);
- gsl_matrix_set(H_ptr, row_index, col_index, value);
- }
- }
+ // Make an actual copy so we guarantee that we're not sharing
+ // memory with another class that reads the same alist file.
+ gsl_matrix* G = gsl_matrix_alloc(d_num_rows, d_num_cols);
+ gsl_matrix_memcpy(G, (gsl_matrix*)(x.get()));
- for(row_index = 0; row_index < (d_n-d_k); row_index++) {
- col_index = row_index + d_k;
- gsl_matrix_set(H_ptr, row_index, col_index, 1);
- }
+ unsigned int row_index, col_index;
- // Calculate G transpose (used for encoding)
- d_G_transp_ptr = gsl_matrix_alloc(d_n, d_k);
- gsl_matrix_transpose_memcpy(d_G_transp_ptr, G);
+ // First, check if we have a generator matrix G in systematic
+ // form, G = [I P], where I is a k x k identity matrix and P
+ // is the parity submatrix.
- d_H_sptr = matrix_sptr((matrix*)H_ptr);
+ // Length of codeword = # of columns of generator matrix
+ d_n = d_num_cols;
+ // Length of information word = # of rows of generator matrix
+ d_k = d_num_rows;
- // Free memory
- gsl_matrix_free(P);
- gsl_matrix_free(P_transpose);
- gsl_matrix_free(G);
- }
+ gsl_matrix* I_test = gsl_matrix_alloc(d_k, d_k);
+ gsl_matrix* identity = gsl_matrix_alloc(d_k, d_k);
+ gsl_matrix_set_identity(identity);
-
- const gsl_matrix*
- ldpc_G_matrix_impl::G_transpose() const
- {
- const gsl_matrix *G_trans_ptr = d_G_transp_ptr;
- return G_trans_ptr;
- }
-
- void
- ldpc_G_matrix_impl::encode(unsigned char *outbuffer,
- const unsigned char *inbuffer) const
- {
-
- unsigned int index, k = d_k, n = d_n;
- gsl_matrix *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);
- }
-
- // Simple matrix multiplication to get codeword
- gsl_matrix *codeword = gsl_matrix_alloc(G_transpose()->size1, s->size2);
- mult_matrices_mod2(codeword, G_transpose(), s);
-
- // Output
- for(index = 0; index < n; index++) {
- outbuffer[index] = gsl_matrix_get(codeword, index, 0);
+ for (row_index = 0; row_index < d_k; row_index++) {
+ for (col_index = 0; col_index < d_k; col_index++) {
+ int value = gsl_matrix_get(G, row_index, col_index);
+ gsl_matrix_set(I_test, row_index, col_index, value);
}
-
- // Free memory
- gsl_matrix_free(s);
- gsl_matrix_free(codeword);
- }
-
-
- void
- ldpc_G_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);
+ }
+
+ // Check if the identity matrix exists in the right spot.
+ // int test_if_equal = gsl_matrix_equal(identity, I_test);
+ gsl_matrix_sub(identity, I_test); // should be null set if equal
+ double test_if_not_equal = gsl_matrix_max(identity);
+
+ // Free memory
+ gsl_matrix_free(identity);
+ gsl_matrix_free(I_test);
+
+ // if(!test_if_equal) {
+ if (test_if_not_equal > 0) {
+ GR_LOG_ERROR(d_logger,
+ "Error in ldpc_G_matrix_impl constructor. It appears "
+ "that the given alist file did not contain either a "
+ "valid parity check matrix of the form H = [P' I] or "
+ "a generator matrix of the form G = [I P].\n");
+ throw std::runtime_error("ldpc_G_matrix: Bad matrix definition");
+ }
+
+ // Our G matrix is verified as correct, now convert it to the
+ // parity check matrix.
+
+ // Grab P matrix
+ gsl_matrix* P = gsl_matrix_alloc(d_k, d_n - d_k);
+ for (row_index = 0; row_index < d_k; row_index++) {
+ for (col_index = 0; col_index < d_n - d_k; col_index++) {
+ int value = gsl_matrix_get(G, row_index, col_index + d_k);
+ gsl_matrix_set(P, row_index, col_index, 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;
+ }
+
+ // Calculate P transpose
+ gsl_matrix* P_transpose = gsl_matrix_alloc(d_n - d_k, d_k);
+ gsl_matrix_transpose_memcpy(P_transpose, P);
+
+ // Set H matrix. H = [-P' I] but since we are doing mod 2,
+ // -P = P, so H = [P' I]
+ gsl_matrix* H_ptr = gsl_matrix_alloc(d_n - d_k, d_n);
+ gsl_matrix_set_zero(H_ptr);
+ for (row_index = 0; row_index < d_n - d_k; row_index++) {
+ for (col_index = 0; col_index < d_k; col_index++) {
+ int value = gsl_matrix_get(P_transpose, row_index, col_index);
+ gsl_matrix_set(H_ptr, row_index, col_index, value);
}
-
- // 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++) {
+ }
+
+ for (row_index = 0; row_index < (d_n - d_k); row_index++) {
+ col_index = row_index + d_k;
+ gsl_matrix_set(H_ptr, row_index, col_index, 1);
+ }
+
+ // Calculate G transpose (used for encoding)
+ d_G_transp_ptr = gsl_matrix_alloc(d_n, d_k);
+ gsl_matrix_transpose_memcpy(d_G_transp_ptr, G);
+
+ d_H_sptr = matrix_sptr((matrix*)H_ptr);
+
+ // Free memory
+ gsl_matrix_free(P);
+ gsl_matrix_free(P_transpose);
+ gsl_matrix_free(G);
+}
+
+
+const gsl_matrix* ldpc_G_matrix_impl::G_transpose() const
+{
+ const gsl_matrix* G_trans_ptr = d_G_transp_ptr;
+ return G_trans_ptr;
+}
+
+void ldpc_G_matrix_impl::encode(unsigned char* outbuffer,
+ const unsigned char* inbuffer) const
+{
+
+ unsigned int index, k = d_k, n = d_n;
+ gsl_matrix* 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);
+ }
+
+ // Simple matrix multiplication to get codeword
+ gsl_matrix* codeword = gsl_matrix_alloc(G_transpose()->size1, s->size2);
+ mult_matrices_mod2(codeword, G_transpose(), s);
+
+ // Output
+ for (index = 0; index < n; index++) {
+ outbuffer[index] = gsl_matrix_get(codeword, index, 0);
+ }
+
+ // Free memory
+ gsl_matrix_free(s);
+ gsl_matrix_free(codeword);
+}
+
+
+void ldpc_G_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_G_matrix_impl::get_base_sptr()
- {
- return shared_from_this();
- }
-
- ldpc_G_matrix_impl::~ldpc_G_matrix_impl()
- {
- // Call the gsl_matrix_free function to free memory.
- gsl_matrix_free(d_G_transp_ptr);
- gsl_matrix_free(d_H_obj);
- }
- } /* namespace code */
- } /* namespace fec */
+ }
+
+ // Free memory
+ gsl_matrix_free(syndrome);
+ gsl_matrix_free(x);
+}
+
+gr::fec::code::fec_mtrx_sptr ldpc_G_matrix_impl::get_base_sptr()
+{
+ return shared_from_this();
+}
+
+ldpc_G_matrix_impl::~ldpc_G_matrix_impl()
+{
+ // Call the gsl_matrix_free function to free memory.
+ gsl_matrix_free(d_G_transp_ptr);
+ gsl_matrix_free(d_H_obj);
+}
+} /* namespace code */
+} /* namespace fec */
} /* namespace gr */