// ------------------------------------------------------------------------ // File: rm31_chase.c // // Simulation of RM(3,1), equivalent to the (8,4,4) extended Hamming code. // Soft-decision decoding performed by Chase type-II algorithm. // ------------------------------------------------------------------------ // 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 RATE 0.5 // Coding rate = 4/8 #define INIT_SNR 3.0 // Initial value of Eb/N0 #define FINAL_SNR 8.0 // Final value of Eb/N0 #define SNR_INCREMENT 1.0 // Increment in Eb/N0 #define NUMSIM 1000000 // Number of simulations (one per 4 bits) #define SWAP(a,b) itemp=(a); (a)=(b); (b)=itemp; #define n 8 #define k 4 #define nk 4 // n-k int L; // Generator matric in systematic form // Information positions: 1,2,3 and 4 (exchanged 4 and 5 in original) // int G[k][n] = { 1,0,0,0,1,1,1,0, 0,1,0,0,1,1,0,1, 0,0,1,0,1,0,1,1, 0,0,0,1,0,1,1,1 }; // Original: // int G[k][n] = { 1,0,0,1,0,1,1,0, // 0,1,0,1,0,1,0,1, // 0,0,1,1,0,0,1,1, // 0,0,0,0,1,1,1,1 }; int wh[16] = { 0, 1, 1, 2, 1, 2, 2, 3, /* Hamming weight function: */ 1, 2, 2, 3, 2, 3, 3, 4 }; /* wh[i] = weight of i */ double sim, block_error; double ber; double amp; double seed; int error; int data[k], codeword[n]; int data_int; float snr; float transmited[n]; float received[n]; int hard[n]; int decoded[n]; float reli[n]; float reli_ord[n+1]; // Indexed from 1 .. n int perm[n+1]; // Indexed from 1 .. n void initialize(void); void awgn(void); void encode(void); void bpsk_dec(void); void indexx(int ns, float arr[], int indx[]); void dec2bin(int test, int err[]); float metric(int vector[]); void gen_err(int count[], int patt[]); main() { int i,j; unsigned long value, test; int err[n], patt[n]; double max, temp; int count[n]; int got_one; printf("Enter the value of L: "); scanf("%d", &L); // Compute 2^L - 1 value = 1; for (i=0; i>10) & 0x01; /* convert data[] to integer for error computation purposes */ data_int = 0; for (i=0; i h bpsk_dec(); // ----------- Reliabilities of received symbols for (i=0; i max) { max = temp; for (i=0; i= 1); noise = u1 * sqrt( (-2.0*log(s))/s ); received[i] = transmited[i] + noise/amp; #ifdef NO_NOISE received[i] = transmited[i]; #endif } } void indexx(int ns, float arr[], int indx[]) { // Indexes an array arr[1..n]: Outputs indx[1..n] such that // arr[indx[j]] is in ascending order. Neither n nor arr are changed. // { int i, indxt, ir=ns, itemp, j,ks,l=1; int jstack = 0, istack[50]; float a; for (i=1; i <= ns; i++) indx[i] = i; for (;;) { if ( (ir-l) < 7) { for (j=l+1; j <= ir; j++) { indxt = indx[j]; a = arr[indxt]; for (i=j-1; i >= 1; i--) { if (arr[indx[i]] <= a) break; indx[i+1] = indx[i]; } indx[i+1] = indxt; } if (jstack == 0) break; ir = istack[jstack--]; l = istack[jstack--]; } else { ks = (l+ir) >> 1; SWAP(indx[ks],indx[l+1]); if (arr[indx[l]]>arr[indx[ir]]) { SWAP(indx[l],indx[ir]); } if (arr[indx[l+1]]>arr[indx[ir]]) { SWAP(indx[l+1],indx[ir]); } if (arr[indx[l]]>arr[indx[l+1]]) { SWAP(indx[l],indx[l+1]); } i = l+1; j = ir; indxt = indx[l+1]; a = arr[indxt]; for (;;) { do i++; while (arr[indx[i]] < a); do j--; while (arr[indx[j]] > a); if (j < i) break; SWAP(indx[i],indx[j]); } indx[l+1] = indx[j]; indx[j] = indxt; jstack += 2; if (jstack > 50) { printf("\nError in indxx\n"); exit(0); } if ((ir-i+1) >= j-1) { istack[jstack] = ir; istack[jstack-1] = i; ir = j-1; } else { istack[jstack] = j-1; istack[jstack-1] = l; l = i; } } } } } void initialize() { time(&seed); srandom(seed); amp = sqrt(2.0*RATE*pow(10.0,(snr/10.0))); block_error = 0.0; ber = 0.0; sim = 0.0; } int check(int patt[]) { // Compute syndromes int i,j; int syn[nk]; for (i=0; i