// ------------------------------------------------------------------------ // Name: llr_pearl.c // Created: February 21, 2000 // // Iterative probabilistic decoding of linear block codes // Based on Pearl's Belief Propagation in Bayesian Networks // This version utilizes object to define graph nodes and // LOG-LIKELIHOOD RATIOS // Much improved in terms of speed compared to log_pearl.c // It can use a look-up table to avoid exp() computations... // ------------------------------------------------------------------------ // This program is complementary material for the book: // // R.H. Morelos-Zaragoza, The Art of Error Correcting Coding, Wiley, 2002. // // ISBN 0471 49581 6 // // This and other programs are available at http://the-art-of-ecc.com // // You may use this program for academic and personal purposes only. // If this program is used to perform simulations whose results are // published in a journal or book, please refer to the book above. // // The use of this program in a commercial product requires explicit // written permission from the author. The author is not responsible or // liable for damage or loss that may be caused by the use of this program. // // Copyright (c) 2002. Robert H. Morelos-Zaragoza. All rights reserved. // ------------------------------------------------------------------------ #include #include #include #include #include #define MAX_RANDOM LONG_MAX // Maximum value of random() #define NODES 16384 // Maximum of number of code/check nodes #define J 17 // Maximum number of checks per code bit #define K 17 // Maximum number of code bits per check int max_size_M; int max_size_N; int n; // length int k; // dimension int nk; // redundancy float rate; // code rate int M,N; // Size of parity-check matrix // --------------- // NODE STRUCTURES // --------------- struct parent_node { int size; int index[J]; // indexes of children float pi1[J], pi0[J]; // messages "pi" to children }; struct child_node { int size; int index[K]; // indexes of parents float lambda1[K], lambda0[K]; // messages "lambda" to parents }; struct parent_node code_node[NODES]; struct child_node check_node[NODES]; double init_snr, final_snr, snr_increment; double sim, num_sim, ber, amp; long seed; int error; int data[NODES], codeword[NODES]; int data_int; double snr, snr_rms; float transmited[NODES], received[NODES]; int hard[NODES], decoded[NODES]; int i,j, iter, max_iter; char filename[40], name2[40]; FILE *fp, *fp2; void initialize(void); void awgn(void); void encode(void); void log_belprop(void); double F(double x); main(int argc, char *argv[]) { // Command line processing if (argc != 11) { printf("Usage: %s length(n) dimension(k) file_parity-check max_iter init_snr final_snr snr_inc num_sim output_file seed\n", argv[0]); exit(0); } sscanf(argv[1],"%d", &n); sscanf(argv[2],"%d", &k); sscanf(argv[3],"%s", filename); sscanf(argv[4],"%d", &max_iter); sscanf(argv[5],"%lf", &init_snr); sscanf(argv[6],"%lf", &final_snr); sscanf(argv[7],"%lf", &snr_increment); sscanf(argv[8],"%lf",&num_sim); sscanf(argv[9],"%s", name2); sscanf(argv[10],"%ld",&seed); nk = n-k; rate = (float) k / (float) n; printf("\nITERATIVE LOG-LIKELIHOOD DECODING OF LINEAR BLOCK CODES\n"); printf("Log-likelihood version of Pearl's algorithm\n"); printf("max_iter = %d\n", max_iter); printf("SNR from %lf to %lf in increments of %lf\n", init_snr, final_snr, snr_increment); printf("%.0f codewords transmitted per SNR\n", num_sim); printf("\nn=%d, k=%d, n-k=%d, and rate = %lf\n\n",n,k,nk,rate); if ((fp = fopen(filename,"r")) != NULL) { fscanf(fp, "%d %d", &N, &M); fscanf(fp, "%d %d", &max_size_N, &max_size_M); for (i=0; i +1, "1" --> -1 for (i=0; i i,j, pi1 = %d,%d %10.7lf\n", i,j,code_node[i].pi1[j]); #endif if (code_node[i].pi1[j] < -30.0) code_node[i].pi1[j] = -30.0; } // DECODING: // MacKay: At this step we also compute the (unconditional) pseudo- // posterior probalilities "q0, q1" to make tentative decisions for (i=0; i 30.0) interm = 0.0; else interm = log ( (exp(x)+1.0)/(exp(x)-1.0) ); return(interm); } void encode() // // Systematic encoding // { //int i,j; //for (j=0; j= 1); noise = u1 * sqrt( (-2.0*log(s))/s ); received[i] = transmited[i] + noise/amp; #ifdef NO_NOISE received[i] = transmited[i]; #endif } } void initialize() { amp = sqrt(2.0*rate*pow(10.0,(snr/10.0))); ber = 0.0; sim = 0.0; snr_rms = 2.0*sqrt(2.0*rate*(pow(10.0,(snr/10.0)))); // 2/sigma^2 }