\r
#include "ldpc_code.h" \r
\r
-void run_ldpc_decoder(int DecodedBits[], int ParityCheckCount[], double input[]);\r
-\r
int main(int argc, char *argv[])\r
{ \r
int CodeLength, NumberParityBits, max_iter;\r
int i, j, r, num_ok, num_runs;\r
char out_char[CODELENGTH];\r
+ struct LDPC ldpc;\r
\r
/* derive some parameters */\r
\r
exit(0);\r
}\r
\r
+ /* set up LDPC code from include file constants */\r
+\r
+ ldpc.max_iter = MAX_ITER;\r
+ ldpc.dec_type = 0;\r
+ ldpc.q_scale_factor = 1;\r
+ ldpc.r_scale_factor = 1;\r
+ ldpc.CodeLength = CODELENGTH;\r
+ ldpc.NumberParityBits = NUMBERPARITYBITS;\r
+ ldpc.NumberRowsHcols = NUMBERROWSHCOLS;\r
+ ldpc.max_row_weight = MAX_ROW_WEIGHT;\r
+ ldpc.max_col_weight = MAX_COL_WEIGHT;\r
+ ldpc.H_rows = H_rows;\r
+ ldpc.H_cols = H_cols;\r
+\r
int *DecodedBits = calloc( max_iter*CodeLength, sizeof( int ) );\r
int *ParityCheckCount = calloc( max_iter, sizeof(int) );\r
\r
\r
for(r=0; r<num_runs; r++) {\r
\r
- run_ldpc_decoder(DecodedBits, ParityCheckCount, input);\r
+ run_ldpc_decoder(&ldpc, DecodedBits, ParityCheckCount, input);\r
\r
/* Check output by comparing every output iteration */\r
\r
sdinput = 1;\r
\r
double *input_double = calloc(CodeLength, sizeof(double));\r
- double sum, mean, sign, sumsq, estvar, estEsN0, x;\r
\r
while(fread(input_double, sizeof(double), CodeLength, fin) == CodeLength) {\r
if (sdinput) {\r
- /* convert SD samples to LLRs -------------------------------*/\r
-\r
- sum = 0.0;\r
- for(i=0; i<CodeLength; i++)\r
- sum += fabs(input_double[i]);\r
- mean = sum/CodeLength;\r
- \r
- /* scale by mean to map onto +/- 1 symbol position */\r
-\r
- for(i=0; i<CodeLength; i++) {\r
- input_double[i] /= mean;\r
- }\r
-\r
- /* find variance from +/-1 symbol position */\r
-\r
- sum = sumsq = 0.0; \r
- for(i=0; i<CodeLength; i++) {\r
- sign = (input_double[i] > 0.0) - (input_double[i] < 0.0);\r
- x = (input_double[i] - sign);\r
- sum += x;\r
- sumsq += x*x;\r
- }\r
- mean = sum/CodeLength;\r
- estvar = sumsq/CodeLength - mean*mean;\r
-\r
- estEsN0 = 1.0/(2.0 * estvar + 1E-3); \r
- for(i=0; i<CodeLength; i++)\r
- input_double[i] = 4.0 * estEsN0 * input_double[i]; \r
+ sd_to_llr(input_double, input_double, CodeLength);\r
}\r
\r
- run_ldpc_decoder(DecodedBits, ParityCheckCount, input_double);\r
+ run_ldpc_decoder(&ldpc, DecodedBits, ParityCheckCount, input_double);\r
\r
/* extract output bits from ouput iteration that solved all parity equations, or failing that\r
the last iteration. */\r
}\r
\r
\r
-void run_ldpc_decoder(int DecodedBits[], int ParityCheckCount[], double input[]) {\r
- int max_iter, dec_type;\r
- float q_scale_factor, r_scale_factor;\r
- int max_row_weight, max_col_weight;\r
- int CodeLength, NumberParityBits, NumberRowsHcols, shift, H1;\r
- int i;\r
- struct c_node *c_nodes;\r
- struct v_node *v_nodes;\r
- \r
- /* default values */\r
-\r
- max_iter = MAX_ITER;\r
- dec_type = 0;\r
- q_scale_factor = 1;\r
- r_scale_factor = 1;\r
-\r
- /* derive some parameters */\r
-\r
- CodeLength = CODELENGTH; /* length of entire codeword */\r
- NumberParityBits = NUMBERPARITYBITS;\r
- NumberRowsHcols = NUMBERROWSHCOLS;\r
-\r
- shift = (NumberParityBits + NumberRowsHcols) - CodeLength;\r
- if (NumberRowsHcols == CodeLength) {\r
- H1=0;\r
- shift=0;\r
- } else {\r
- H1=1;\r
- }\r
- \r
- max_row_weight = MAX_ROW_WEIGHT;\r
- max_col_weight = MAX_COL_WEIGHT;\r
- \r
- c_nodes = calloc( NumberParityBits, sizeof( struct c_node ) );\r
- v_nodes = calloc( CodeLength, sizeof( struct v_node));\r
- \r
- /* initialize c-node and v-node structures */\r
-\r
- c_nodes = calloc( NumberParityBits, sizeof( struct c_node ) );\r
- v_nodes = calloc( CodeLength, sizeof( struct v_node));\r
- \r
- init_c_v_nodes(c_nodes, shift, NumberParityBits, max_row_weight, H_rows, H1, CodeLength, \r
- v_nodes, NumberRowsHcols, H_cols, max_col_weight, dec_type, input);\r
-\r
- int DataLength = CodeLength - NumberParityBits;\r
- int *data_int = calloc( DataLength, sizeof(int) );\r
- \r
- /* need to clear these on each call */\r
-\r
- for(i=0; i<max_iter; i++)\r
- ParityCheckCount[i] = 0;\r
- for(i=0; i<max_iter*CodeLength; i++)\r
- DecodedBits[i] = 0;\r
-\r
- /* Call function to do the actual decoding */\r
-\r
- if ( dec_type == 1) {\r
- MinSum( ParityCheckCount, DecodedBits, c_nodes, v_nodes, CodeLength, \r
- NumberParityBits, max_iter, r_scale_factor, q_scale_factor, data_int );\r
- } else if ( dec_type == 2) {\r
- fprintf(stderr, "dec_type = 2 not currently supported");\r
- /* ApproximateMinStar( BitErrors, DecodedBits, c_nodes, v_nodes, \r
- CodeLength, NumberParityBits, max_iter, r_scale_factor, q_scale_factor );*/\r
- } else {\r
- SumProduct( ParityCheckCount, DecodedBits, c_nodes, v_nodes, CodeLength, \r
- NumberParityBits, max_iter, r_scale_factor, q_scale_factor, data_int ); \r
- }\r
\r
- /* Clean up memory */\r
\r
- free( data_int );\r
-\r
- /* Cleaning c-node elements */\r
-\r
- for (i=0;i<NumberParityBits;i++) {\r
- free( c_nodes[i].index );\r
- free( c_nodes[i].message );\r
- free( c_nodes[i].socket );\r
- }\r
- \r
- /* printf( "Cleaning c-nodes \n" ); */\r
- free( c_nodes );\r
- \r
- /* printf( "Cleaning v-node elements\n" ); */\r
- for (i=0;i<CodeLength;i++) {\r
- free( v_nodes[i].index);\r
- free( v_nodes[i].sign );\r
- free( v_nodes[i].message );\r
- free( v_nodes[i].socket );\r
- }\r
- \r
- /* printf( "Cleaning v-nodes \n" ); */\r
- free( v_nodes );\r
-}\r
#include <math.h>
#include <stdlib.h>
+#include <stdio.h>
#include "mpdecode_core.h"
/* Phi function */
}
// printf(" ssum is %d \n", ssum);
-
-
+}
+
+
+/* Convenience function to call LDPC decoder from C programs */
+
+void run_ldpc_decoder(struct LDPC *ldpc, int DecodedBits[], int ParityCheckCount[], double input[]) {
+ int max_iter, dec_type;
+ float q_scale_factor, r_scale_factor;
+ int max_row_weight, max_col_weight;
+ int CodeLength, NumberParityBits, NumberRowsHcols, shift, H1;
+ int i;
+ struct c_node *c_nodes;
+ struct v_node *v_nodes;
+ /* default values */
+
+ max_iter = ldpc->max_iter;
+ dec_type = ldpc->dec_type;
+ q_scale_factor = ldpc->q_scale_factor;
+ r_scale_factor = ldpc->r_scale_factor;
+
+ CodeLength = ldpc->CodeLength; /* length of entire codeword */
+ NumberParityBits = ldpc->NumberParityBits;
+ NumberRowsHcols = ldpc->NumberRowsHcols;
+
+ /* derive some parameters */
+
+ shift = (NumberParityBits + NumberRowsHcols) - CodeLength;
+ if (NumberRowsHcols == CodeLength) {
+ H1=0;
+ shift=0;
+ } else {
+ H1=1;
+ }
+
+ max_row_weight = ldpc->max_row_weight;
+ max_col_weight = ldpc->max_col_weight;
+
+ c_nodes = calloc( NumberParityBits, sizeof( struct c_node ) );
+ v_nodes = calloc( CodeLength, sizeof( struct v_node));
+
+ /* initialize c-node and v-node structures */
+
+ c_nodes = calloc( NumberParityBits, sizeof( struct c_node ) );
+ v_nodes = calloc( CodeLength, sizeof( struct v_node));
+
+ init_c_v_nodes(c_nodes, shift, NumberParityBits, max_row_weight, ldpc->H_rows, H1, CodeLength,
+ v_nodes, NumberRowsHcols, ldpc->H_cols, max_col_weight, dec_type, input);
+
+ int DataLength = CodeLength - NumberParityBits;
+ int *data_int = calloc( DataLength, sizeof(int) );
+
+ /* need to clear these on each call */
+
+ for(i=0; i<max_iter; i++)
+ ParityCheckCount[i] = 0;
+ for(i=0; i<max_iter*CodeLength; i++)
+ DecodedBits[i] = 0;
+
+ /* Call function to do the actual decoding */
+
+ if ( dec_type == 1) {
+ MinSum( ParityCheckCount, DecodedBits, c_nodes, v_nodes, CodeLength,
+ NumberParityBits, max_iter, r_scale_factor, q_scale_factor, data_int );
+ } else if ( dec_type == 2) {
+ fprintf(stderr, "dec_type = 2 not currently supported");
+ /* ApproximateMinStar( BitErrors, DecodedBits, c_nodes, v_nodes,
+ CodeLength, NumberParityBits, max_iter, r_scale_factor, q_scale_factor );*/
+ } else {
+ SumProduct( ParityCheckCount, DecodedBits, c_nodes, v_nodes, CodeLength,
+ NumberParityBits, max_iter, r_scale_factor, q_scale_factor, data_int );
+ }
+
+ /* Clean up memory */
+
+ free( data_int );
+
+ /* Cleaning c-node elements */
+
+ for (i=0;i<NumberParityBits;i++) {
+ free( c_nodes[i].index );
+ free( c_nodes[i].message );
+ free( c_nodes[i].socket );
+ }
+
+ /* printf( "Cleaning c-nodes \n" ); */
+ free( c_nodes );
+
+ /* printf( "Cleaning v-node elements\n" ); */
+ for (i=0;i<CodeLength;i++) {
+ free( v_nodes[i].index);
+ free( v_nodes[i].sign );
+ free( v_nodes[i].message );
+ free( v_nodes[i].socket );
+ }
+
+ /* printf( "Cleaning v-nodes \n" ); */
+ free( v_nodes );
}
+void sd_to_llr(double llr[], double sd[], int n) {
+ double sum, mean, sign, sumsq, estvar, estEsN0, x;
+ int i;
+
+ /* convert SD samples to LLRs -------------------------------*/
+
+ sum = 0.0;
+ for(i=0; i<n; i++)
+ sum += fabs(sd[i]);
+ mean = sum/n;
+
+ /* scale by mean to map onto +/- 1 symbol position */
+
+ for(i=0; i<n; i++) {
+ sd[i] /= mean;
+ }
+
+ /* find variance from +/-1 symbol position */
+
+ sum = sumsq = 0.0;
+ for(i=0; i<n; i++) {
+ sign = (sd[i] > 0.0) - (sd[i] < 0.0);
+ x = (sd[i] - sign);
+ sum += x;
+ sumsq += x*x;
+ }
+ mean = sum/n;
+ estvar = sumsq/n - mean*mean;
+
+ estEsN0 = 1.0/(2.0 * estvar + 1E-3);
+ for(i=0; i<n; i++)
+ llr[i] = 4.0 * estEsN0 * sd[i];
+}