421 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			421 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								/* DEC.C - Decoding procedures. */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* Copyright (c) 1995-2012 by Radford M. Neal.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Permission is granted for anyone to copy, use, modify, and distribute
							 | 
						||
| 
								 | 
							
								 * these programs and accompanying documents for any purpose, provided
							 | 
						||
| 
								 | 
							
								 * this copyright notice is retained and prominently displayed, and note
							 | 
						||
| 
								 | 
							
								 * is made of any changes made to these programs.  These programs and
							 | 
						||
| 
								 | 
							
								 * documents are distributed without any warranty, express or implied.
							 | 
						||
| 
								 | 
							
								 * As the programs were written for research purposes only, they have not
							 | 
						||
| 
								 | 
							
								 * been tested to the degree that would be advisable in any important
							 | 
						||
| 
								 | 
							
								 * application.  All use of these programs is entirely at the user's own
							 | 
						||
| 
								 | 
							
								 * risk.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* NOTE:  See decoding.html for general documentation on the decoding methods */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <stdio.h>
							 | 
						||
| 
								 | 
							
								#include <stdlib.h>
							 | 
						||
| 
								 | 
							
								#include <math.h>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "alloc.h"
							 | 
						||
| 
								 | 
							
								#include "mod2sparse.h"
							 | 
						||
| 
								 | 
							
								#include "mod2dense.h"
							 | 
						||
| 
								 | 
							
								#include "mod2convert.h"
							 | 
						||
| 
								 | 
							
								/*#include "rand.h"*/
							 | 
						||
| 
								 | 
							
								#include "rcode.h"
							 | 
						||
| 
								 | 
							
								#include "check.h"
							 | 
						||
| 
								 | 
							
								#include "dec.h"
							 | 
						||
| 
								 | 
							
								#include "enc.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* GLOBAL VARIABLES.  Declared in dec.h. */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								decoding_method dec_method;	/* Decoding method to use */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int ldpc_table;	/* Trace option, 2 for a table of decoding details */
							 | 
						||
| 
								 | 
							
								int block_no;	/* Number of current block, from zero */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int max_iter;	/* Maximum number of iteratons of decoding to do */
							 | 
						||
| 
								 | 
							
								char *gen_file;	/* Generator file for Enum_block and Enum_bit */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* DECODE BY EXHAUSTIVE ENUMERATION.  Decodes by trying all possible source
							 | 
						||
| 
								 | 
							
								   messages (and hence all possible codewords, unless the parity check matrix
							 | 
						||
| 
								 | 
							
								   was redundant).  If the last argument is 1, it sets dblk to the most likely
							 | 
						||
| 
								 | 
							
								   entire block; if this argument is 0, each bit of dblk is set to the most
							 | 
						||
| 
								 | 
							
								   likely value for that bit.  The marginal probabilities of each bit being 1
							 | 
						||
| 
								 | 
							
								   are returned in bitpr.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   The function value returned is the total number of codewords tried (which 
							 | 
						||
| 
								 | 
							
								   will be the same for all blocks).  The return valued is "unsigned" because
							 | 
						||
| 
								 | 
							
								   it might conceivably be as big as 2^31.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   The parity check matrix and other data are taken from the global variables
							 | 
						||
| 
								 | 
							
								   declared in rcode.h.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   The number of message bits should not be greater than 31 for this procedure.
							 | 
						||
| 
								 | 
							
								   The setup procedure immediately below checks this, reads the generator file,
							 | 
						||
| 
								 | 
							
								   and outputs headers for the detailed trace file, if required.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void enum_decode_setup(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  read_gen(gen_file,0,0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (N-M>31)
							 | 
						||
| 
								 | 
							
								  { fprintf(stderr,
							 | 
						||
| 
								 | 
							
								"Trying to decode messages with %d bits by exhaustive enumeration is absurd!\n",
							 | 
						||
| 
								 | 
							
								      N-M);
							 | 
						||
| 
								 | 
							
								    exit(1);  
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (ldpc_table==2)
							 | 
						||
| 
								 | 
							
								  { printf("  block   decoding  likelihood\n");
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								unsigned enum_decode
							 | 
						||
| 
								 | 
							
								( double *lratio,	/* Likelihood ratios for bits */
							 | 
						||
| 
								 | 
							
								  char *dblk, 		/* Place to stored decoded message */
							 | 
						||
| 
								 | 
							
								  double *bitpr,	/* Place to store marginal bit probabilities */
							 | 
						||
| 
								 | 
							
								  int max_block		/* Maximize probability of whole block being correct? */
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  mod2dense *u, *v;
							 | 
						||
| 
								 | 
							
								  double lk, maxlk, tpr;
							 | 
						||
| 
								 | 
							
								  double *bpr, *lk0, *lk1;
							 | 
						||
| 
								 | 
							
								  char sblk[31];
							 | 
						||
| 
								 | 
							
								  char *cblk;
							 | 
						||
| 
								 | 
							
								  unsigned d;
							 | 
						||
| 
								 | 
							
								  int i, j;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (N-M>31) abort();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* Allocate needed space. */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  bpr = bitpr;
							 | 
						||
| 
								 | 
							
								  if (bpr==0 && max_block==0)
							 | 
						||
| 
								 | 
							
								  { bpr = chk_alloc (N, sizeof *bpr);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  cblk = chk_alloc (N, sizeof *cblk);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (type=='d')
							 | 
						||
| 
								 | 
							
								  { u = mod2dense_allocate(N-M,1);
							 | 
						||
| 
								 | 
							
								    v = mod2dense_allocate(M,1);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (type=='m')
							 | 
						||
| 
								 | 
							
								  { u = mod2dense_allocate(M,1);
							 | 
						||
| 
								 | 
							
								    v = mod2dense_allocate(M,1);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  lk0 = chk_alloc (N, sizeof *lk0);
							 | 
						||
| 
								 | 
							
								  lk1 = chk_alloc (N, sizeof *lk1);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* Pre-compute likelihoods for bits. */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for (j = 0; j<N; j++)
							 | 
						||
| 
								 | 
							
								  { lk0[j] = 1/(1+lratio[j]);
							 | 
						||
| 
								 | 
							
								    lk1[j] = 1 - lk0[j];
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* Initialize marginal bit probabilities. */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (bpr)
							 | 
						||
| 
								 | 
							
								  { for (j = 0; j<N; j++) bpr[j] = 0.0;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* Exhaustively try all possible decoded messages. */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  tpr = 0.0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for (d = 0; d<=(1<<(N-M))-1; d++)
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    /* Unpack message into source block. */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    for (i = N-M-1; i>=0; i--)
							 | 
						||
| 
								 | 
							
								    { sblk[i] = (d>>i)&1;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* Find full codeword for this message. */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    switch (type)
							 | 
						||
| 
								 | 
							
								    { case 's':
							 | 
						||
| 
								 | 
							
								      { sparse_encode (sblk, cblk);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      case 'd':
							 | 
						||
| 
								 | 
							
								      { dense_encode (sblk, cblk, u, v);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      case 'm':
							 | 
						||
| 
								 | 
							
								      { mixed_encode (sblk, cblk, u, v);
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* Compute likelihood for this decoding. */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    lk = 1;
							 | 
						||
| 
								 | 
							
								    for (j = 0; j<N; j++)
							 | 
						||
| 
								 | 
							
								    { lk *= cblk[j]==0 ? lk0[j] : lk1[j];
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* Update maximum likelihood decoding. */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (max_block)
							 | 
						||
| 
								 | 
							
								    { if (d==0 || lk>maxlk)
							 | 
						||
| 
								 | 
							
								      { for (j = 0; j<N; j++)
							 | 
						||
| 
								 | 
							
								        { dblk[j] = cblk[j];
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        maxlk = lk;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* Update bit probabilities. */
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								    if (bpr)
							 | 
						||
| 
								 | 
							
								    { for (j = 0; j<N; j++) 
							 | 
						||
| 
								 | 
							
								      { if (cblk[j]==1) 
							 | 
						||
| 
								 | 
							
								        { bpr[j] += lk;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      tpr += lk;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* Output data to trace file. */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (ldpc_table==2)
							 | 
						||
| 
								 | 
							
								    { printf("%7d %10x  %10.4e\n",block_no,d,lk);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* Normalize bit probabilities. */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (bpr)
							 | 
						||
| 
								 | 
							
								  { for (j = 0; j<N; j++) bpr[j] /= tpr;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* Decoding to maximize bit-by-bit success, if that's what's wanted. 
							 | 
						||
| 
								 | 
							
								     In case of a tie, decode to a 1. */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (!max_block)
							 | 
						||
| 
								 | 
							
								  { for (j = 0; j<N; j++) 
							 | 
						||
| 
								 | 
							
								    { dblk[j] = bpr[j]>=0.5;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* Free space. */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (bpr!=0 && bpr!=bitpr) free(bpr);
							 | 
						||
| 
								 | 
							
								  free(cblk);
							 | 
						||
| 
								 | 
							
								  free(lk0);
							 | 
						||
| 
								 | 
							
								  free(lk1);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return 1<<(N-M);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* DECODE USING PROBABILITY PROPAGATION.  Tries to find the most probable 
							 | 
						||
| 
								 | 
							
								   values for the bits of the codeword, given a parity check matrix (H), and
							 | 
						||
| 
								 | 
							
								   likelihood ratios (lratio) for each bit.  If max_iter is positive, up to 
							 | 
						||
| 
								 | 
							
								   that many iterations of probability propagation are done, stopping before 
							 | 
						||
| 
								 | 
							
								   then if the tentative decoding is a valid codeword.  If max_iter is 
							 | 
						||
| 
								 | 
							
								   negative, abs(max_iter) iterations are done, regardless of whether a 
							 | 
						||
| 
								 | 
							
								   codeword was found earlier.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   Returns the number of iterations done (as an "unsigned" for consistency
							 | 
						||
| 
								 | 
							
								   with enum_decode).  Regardless of whether or not a valid codeword was 
							 | 
						||
| 
								 | 
							
								   reached, the bit vector from thresholding the bit-by-bit probabilities is 
							 | 
						||
| 
								 | 
							
								   stored in dblk, and the resulting parity checks are stored in pchk (all 
							 | 
						||
| 
								 | 
							
								   will be zero if the codeword is valid).  The final probabilities for each 
							 | 
						||
| 
								 | 
							
								   bit being a 1 are stored in bprb.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   The setup procedure immediately below outputs headers for the detailed trace
							 | 
						||
| 
								 | 
							
								   file, if required.
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void prprp_decode_setup (void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  if (ldpc_table==2)
							 | 
						||
| 
								 | 
							
								  { printf(
							 | 
						||
| 
								 | 
							
								     "  block  iter  changed  perrs    loglik   Eperrs   Eloglik  entropy\n");
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								unsigned prprp_decode
							 | 
						||
| 
								 | 
							
								( mod2sparse *H,	/* Parity check matrix */
							 | 
						||
| 
								 | 
							
								  double *lratio,	/* Likelihood ratios for bits */
							 | 
						||
| 
								 | 
							
								  char *dblk,		/* Place to store decoding */
							 | 
						||
| 
								 | 
							
								  char *pchk,		/* Place to store parity checks */
							 | 
						||
| 
								 | 
							
								  double *bprb		/* Place to store bit probabilities */
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								{ 
							 | 
						||
| 
								 | 
							
								  int N, n, c;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  N = mod2sparse_cols(H);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* Initialize probability and likelihood ratios, and find initial guess. */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  initprp(H,lratio,dblk,bprb);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* Do up to abs(max_iter) iterations of probability propagation, stopping
							 | 
						||
| 
								 | 
							
								     early if a codeword is found, unless max_iter is negative. */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for (n = 0; ; n++)
							 | 
						||
| 
								 | 
							
								  { 
							 | 
						||
| 
								 | 
							
								    c = check(H,dblk,pchk);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (ldpc_table==2)
							 | 
						||
| 
								 | 
							
								    { printf("%7d %5d %8.1f %6d %+9.2f %8.1f %+9.2f  %7.1f\n",
							 | 
						||
| 
								 | 
							
								       block_no, n, changed(lratio,dblk,N), c, loglikelihood(lratio,dblk,N), 
							 | 
						||
| 
								 | 
							
								       expected_parity_errors(H,bprb), expected_loglikelihood(lratio,bprb,N),
							 | 
						||
| 
								 | 
							
								       entropy(bprb,N));
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								   
							 | 
						||
| 
								 | 
							
								    if (n==max_iter || n==-max_iter || (max_iter>0 && c==0))
							 | 
						||
| 
								 | 
							
								    { break; 
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    iterprp(H,lratio,dblk,bprb);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return n;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* INITIALIZE PROBABILITY PROPAGATION.  Stores initial ratios, probabilities,
							 | 
						||
| 
								 | 
							
								   and guess at decoding. */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void initprp
							 | 
						||
| 
								 | 
							
								( mod2sparse *H,	/* Parity check matrix */
							 | 
						||
| 
								 | 
							
								  double *lratio,	/* Likelihood ratios for bits */
							 | 
						||
| 
								 | 
							
								  char *dblk,		/* Place to store decoding */
							 | 
						||
| 
								 | 
							
								  double *bprb		/* Place to store bit probabilities, 0 if not wanted */
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								{ 
							 | 
						||
| 
								 | 
							
								  mod2entry *e;
							 | 
						||
| 
								 | 
							
								  int N;
							 | 
						||
| 
								 | 
							
								  int j;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  N = mod2sparse_cols(H);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for (j = 0; j<N; j++)
							 | 
						||
| 
								 | 
							
								  { for (e = mod2sparse_first_in_col(H,j);
							 | 
						||
| 
								 | 
							
								         !mod2sparse_at_end(e);
							 | 
						||
| 
								 | 
							
								         e = mod2sparse_next_in_col(e))
							 | 
						||
| 
								 | 
							
								    { e->pr = lratio[j];
							 | 
						||
| 
								 | 
							
								      e->lr = 1;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (bprb) bprb[j] = 1 - 1/(1+lratio[j]);
							 | 
						||
| 
								 | 
							
								    dblk[j] = lratio[j]>=1;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* DO ONE ITERATION OF PROBABILITY PROPAGATION. */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void iterprp
							 | 
						||
| 
								 | 
							
								( mod2sparse *H,	/* Parity check matrix */
							 | 
						||
| 
								 | 
							
								  double *lratio,	/* Likelihood ratios for bits */
							 | 
						||
| 
								 | 
							
								  char *dblk,		/* Place to store decoding */
							 | 
						||
| 
								 | 
							
								  double *bprb		/* Place to store bit probabilities, 0 if not wanted */
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  double pr, dl, t;
							 | 
						||
| 
								 | 
							
								  mod2entry *e;
							 | 
						||
| 
								 | 
							
								  int N, M;
							 | 
						||
| 
								 | 
							
								  int i, j;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  M = mod2sparse_rows(H);
							 | 
						||
| 
								 | 
							
								  N = mod2sparse_cols(H);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* Recompute likelihood ratios. */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for (i = 0; i<M; i++)
							 | 
						||
| 
								 | 
							
								  { dl = 1;
							 | 
						||
| 
								 | 
							
								    for (e = mod2sparse_first_in_row(H,i);
							 | 
						||
| 
								 | 
							
								         !mod2sparse_at_end(e);
							 | 
						||
| 
								 | 
							
								         e = mod2sparse_next_in_row(e))
							 | 
						||
| 
								 | 
							
								    { e->lr = dl;
							 | 
						||
| 
								 | 
							
								      dl *= 2/(1+e->pr) - 1;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    dl = 1;
							 | 
						||
| 
								 | 
							
								    for (e = mod2sparse_last_in_row(H,i);
							 | 
						||
| 
								 | 
							
								         !mod2sparse_at_end(e);
							 | 
						||
| 
								 | 
							
								         e = mod2sparse_prev_in_row(e))
							 | 
						||
| 
								 | 
							
								    { t = e->lr * dl;
							 | 
						||
| 
								 | 
							
								      e->lr = (1-t)/(1+t);
							 | 
						||
| 
								 | 
							
								      dl *= 2/(1+e->pr) - 1;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* Recompute probability ratios.  Also find the next guess based on the
							 | 
						||
| 
								 | 
							
								     individually most likely values. */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for (j = 0; j<N; j++)
							 | 
						||
| 
								 | 
							
								  { pr = lratio[j];
							 | 
						||
| 
								 | 
							
								    for (e = mod2sparse_first_in_col(H,j);
							 | 
						||
| 
								 | 
							
								         !mod2sparse_at_end(e);
							 | 
						||
| 
								 | 
							
								         e = mod2sparse_next_in_col(e))
							 | 
						||
| 
								 | 
							
								    { e->pr = pr;
							 | 
						||
| 
								 | 
							
								      pr *= e->lr;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (isnan(pr))
							 | 
						||
| 
								 | 
							
								    { pr = 1;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (bprb) bprb[j] = 1 - 1/(1+pr);
							 | 
						||
| 
								 | 
							
								    dblk[j] = pr>=1;
							 | 
						||
| 
								 | 
							
								    pr = 1;
							 | 
						||
| 
								 | 
							
								    for (e = mod2sparse_last_in_col(H,j);
							 | 
						||
| 
								 | 
							
								         !mod2sparse_at_end(e);
							 | 
						||
| 
								 | 
							
								         e = mod2sparse_prev_in_col(e))
							 | 
						||
| 
								 | 
							
								    { e->pr *= pr;
							 | 
						||
| 
								 | 
							
								      if (isnan(e->pr)) 
							 | 
						||
| 
								 | 
							
								      { e->pr = 1;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      pr *= e->lr;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void ldpc_decode_ ( double lratio[], char decoded[], int *max_iterations, int *niterations, int *max_dither, int *ndither)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  int i, j, itry, valid;
							 | 
						||
| 
								 | 
							
								  char dblk[N],pchk[M];
							 | 
						||
| 
								 | 
							
								  double bprb[N],lr[N];
							 | 
						||
| 
								 | 
							
								  float fac;
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								  max_iter=*max_iterations;
							 | 
						||
| 
								 | 
							
								  srand(-1);
							 | 
						||
| 
								 | 
							
								  for (itry=0; itry< *max_dither; itry++) {
							 | 
						||
| 
								 | 
							
								    for (i=0; i<N; i++) {
							 | 
						||
| 
								 | 
							
								       if( itry == 0 ) {
							 | 
						||
| 
								 | 
							
								         fac=0.0;
							 | 
						||
| 
								 | 
							
								       } else { 
							 | 
						||
| 
								 | 
							
								         fac=(rand()%1024-512)/512.0;
							 | 
						||
| 
								 | 
							
								       } 
							 | 
						||
| 
								 | 
							
								       lr[i]=lratio[i]*exp(fac); 
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    *niterations = prprp_decode ( H, lr, dblk, pchk, bprb );
							 | 
						||
| 
								 | 
							
								    valid = check( H, dblk, pchk )==0;
							 | 
						||
| 
								 | 
							
								    if( !valid ) {
							 | 
						||
| 
								 | 
							
								       *niterations=-1;
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								      j=0;
							 | 
						||
| 
								 | 
							
								      for( i=M; i<N; i++ ) {
							 | 
						||
| 
								 | 
							
								        decoded[j]=dblk[cols[i]];
							 | 
						||
| 
								 | 
							
								        j=j+1;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      *ndither=itry;
							 | 
						||
| 
								 | 
							
								//      printf("ldpc_decode %d %d \n",*niterations, *ndither);
							 | 
						||
| 
								 | 
							
								      return;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								} 
							 |