Main Page | Class List | File List | Class Members | File Members

golay.c

Go to the documentation of this file.
00001 /* File:    golay.c
00002  * Title:   Encoder/decoder for a binary (23,12,7) Golay code
00003  * Author:  Max Luttrell (luttrell@icsl.ucla.edu),
00004  * Date:    October 1997
00005  *          
00006  * based on work done by:
00007  * Author:  Robert Morelos-Zaragoza (robert@spectra.eng.hawaii.edu)
00008  * Date:    August 1994
00009  *
00010  * The binary (23,12,7) Golay code is an example of a perfect code, that is,
00011  * the number of syndromes equals the number of correctable error patterns.
00012  * The minimum distance is 7, so all error patterns of Hamming weight up to
00013  * 3 can be corrected. The total number of these error patterns is:
00014  *
00015  *       Number of errors         Number of patterns
00016  *       ----------------         ------------------
00017  *              0                         1
00018  *              1                        23
00019  *              2                       253
00020  *              3                      1771
00021  *                                     ----
00022  *    Total number of error patterns = 2048 = 2^{11} = number of syndromes
00023  *                                               --
00024  *                number of redundant bits -------^
00025  *
00026  * Because of its relatively low length (23), dimension (12) and number of
00027  * redundant bits (11), the binary (23,12,7) Golay code can be encoded and
00028  * decoded simply by using look-up tables. The program below uses a 16K 
00029  * encoding table and an 8K decoding table.
00030  * 
00031  * For more information, suggestions, or other ideas on implementing error
00032  * correcting codes, please contact me at (I'm temporarily in Japan, but
00033  * below is my U.S. address):
00034  *
00035  *                    Robert Morelos-Zaragoza
00036  *                    770 S. Post Oak Ln. #200
00037  *                      Houston, Texas 77056
00038  *
00039  *             email: robert@spectra.eng.hawaii.edu
00040  *
00041  * NOTE: This program is free. You may modify it at will. However, please
00042  *       include the original file with any redistribution. The author is
00043  *       not responsible for any damage caused by the use of this program.
00044  *
00045  *       Homework: Add an overall parity-check bit to get the (24,12,8)
00046  *                 extended Golay code.
00047  *
00048  * ==   Copyright (c) 1994  Robert Morelos-Zaragoza. All rights reserved.   ==
00049  */
00050 
00051 #include <stdio.h>
00052 #define X22             0x00400000   /* vector representation of X^{22} */
00053 #define X11             0x00000800   /* vector representation of X^{11} */
00054 #define MASK12          0xfffff800   /* auxiliary vector for testing */
00055 #define GENPOL          0x00000c75   /* generator polinomial, g(x) */
00056 
00057 /* Global variables:
00058  *
00059  * pattern = error pattern, or information, or received vector
00060  * encoding_table[] = encoding table
00061  * decoding_table[] = decoding table
00062  * data = information bits, i(x)
00063  * codeword = code bits = x^{11}i(x) + (x^{11}i(x) mod g(x))
00064  * numerr = number of errors = Hamming weight of error polynomial e(x)
00065  * position[] = error positions in the vector representation of e(x)
00066  * recd = representation of corrupted received polynomial r(x) = c(x) + e(x)
00067  * decerror = number of decoding errors
00068  * a[] = auxiliary array to generate correctable error patterns
00069  */
00070 
00071 long pattern;
00072 long encoding_table[4096], decoding_table[2048];
00073 long data, codeword, recd;
00074 long position[23] = { 0x00000001, 0x00000002, 0x00000004, 0x00000008,
00075                       0x00000010, 0x00000020, 0x00000040, 0x00000080,
00076                       0x00000100, 0x00000200, 0x00000400, 0x00000800,
00077                       0x00001000, 0x00002000, 0x00004000, 0x00008000,
00078                       0x00010000, 0x00020000, 0x00040000, 0x00080000,
00079                       0x00100000, 0x00200000, 0x00400000 };
00080 long numerr, errpos[23], decerror = 0;
00081 int a[4];
00082 extern int debug;
00083 
00084 long arr2int(int* a,int r)
00085 /*
00086  * Convert a binary vector of Hamming weight r, and nonzero positions in
00087  * array a[1]...a[r], to a long integer \sum_{i=1}^r 2^{a[i]-1}.
00088  */
00089 {
00090    int i;
00091    long mul, result = 0, temp;
00092  
00093    for (i=1; i<=r; i++) {
00094       mul = 1;
00095       temp = a[i]-1;
00096       while (temp--)
00097          mul = mul << 1;
00098       result += mul;
00099       }
00100    return(result);
00101 }
00102 
00103 void nextcomb(int n, int r, int *a)
00104 /*
00105  * Calculate next r-combination of an n-set.
00106  */
00107 {
00108   int  i, j;
00109  
00110   a[r]++;
00111   if (a[r] <= n)
00112       return;
00113   j = r - 1;
00114   while (a[j] == n - r + j)
00115      j--;
00116   for (i = r; i >= j; i--)
00117       a[i] = a[j] + i - j + 1;
00118   return;
00119 }
00120 
00121 long get_syndrome(long pattern)
00122 /*
00123  * Compute the syndrome corresponding to the given pattern, i.e., the
00124  * remainder after dividing the pattern (when considering it as the vector
00125  * representation of a polynomial) by the generator polynomial, GENPOL.
00126  * In the program this pattern has several meanings: (1) pattern = infomation
00127  * bits, when constructing the encoding table; (2) pattern = error pattern,
00128  * when constructing the decoding table; and (3) pattern = received vector, to
00129  * obtain its syndrome in decoding.
00130  */
00131 {
00132     long aux = X22;
00133  
00134     if (pattern >= X11)
00135        while (pattern & MASK12) {
00136            while (!(aux & pattern))
00137               aux = aux >> 1;
00138            pattern ^= (aux/X11) * GENPOL;
00139            }
00140     return(pattern);
00141 }
00142 
00143 void gen_enc_table(void)
00144 {
00145    /*
00146     * ---------------------------------------------------------------------
00147     *                  Generate ENCODING TABLE
00148     *
00149     * An entry to the table is an information vector, a 32-bit integer,
00150     * whose 12 least significant positions are the information bits. The
00151     * resulting value is a codeword in the (23,12,7) Golay code: A 32-bit
00152     * integer whose 23 least significant bits are coded bits: Of these, the
00153     * 12 most significant bits are information bits and the 11 least
00154     * significant bits are redundant bits (systematic encoding).
00155     * --------------------------------------------------------------------- 
00156     */
00157    long temp;
00158    for (pattern = 0; pattern < 4096; pattern++) {
00159        temp = pattern << 11;          /* multiply information by X^{11} */
00160        encoding_table[pattern] = temp + get_syndrome(temp);/* add redundancy */
00161    }
00162 }
00163 
00164 void gen_dec_table(void)
00165 {
00166    /*
00167     * ---------------------------------------------------------------------
00168     *                  Generate DECODING TABLE
00169     *
00170     * An entry to the decoding table is a syndrome and the resulting value
00171     * is the most likely error pattern. First an error pattern is generated.
00172     * Then its syndrome is calculated and used as a pointer to the table
00173     * where the error pattern value is stored.
00174     * --------------------------------------------------------------------- 
00175     *            
00176     * (1) Error patterns of WEIGHT 1 (SINGLE ERRORS)
00177     */
00178     long temp;
00179     int i;
00180 
00181     decoding_table[0] = 0;
00182     decoding_table[1] = 1;
00183     temp = 1; 
00184     for (i=2; i<= 23; i++) {
00185         temp *= 2;
00186         decoding_table[get_syndrome(temp)] = temp;
00187         }
00188    /*            
00189     * (2) Error patterns of WEIGHT 2 (DOUBLE ERRORS)
00190     */
00191     a[1] = 1; a[2] = 2;
00192     temp = arr2int(a,2);
00193     decoding_table[get_syndrome(temp)] = temp;
00194     for (i=1; i<253; i++) {
00195         nextcomb(23,2,a);
00196         temp = arr2int(a,2);
00197         decoding_table[get_syndrome(temp)] = temp;
00198         }
00199    /*            
00200     * (3) Error patterns of WEIGHT 3 (TRIPLE ERRORS)
00201     */
00202     a[1] = 1; a[2] = 2; a[3] = 3;
00203     temp = arr2int(a,3);
00204     decoding_table[get_syndrome(temp)] = temp;
00205     for (i=1; i<1771; i++) {
00206         nextcomb(23,3,a);
00207         temp = arr2int(a,3);
00208         decoding_table[get_syndrome(temp)] = temp;
00209         }
00210 }
00211 
00212 
00213 long encode_golay(long data)
00214 {
00215 /*
00216  * encodes data and returns the codeword.  
00217  * data is assumed to contain 12 bits in the least significant bit positions
00218  * codeword contains the 23 bits in the LSB positions
00219  * 
00220  */
00221     static int initialized=0;
00222 
00223     if (!initialized) {
00224         gen_enc_table();
00225         initialized=1;
00226     }
00227     codeword = encoding_table[data];
00228     if (debug) printf("encode_golay() - codeword =        %#012x\n", codeword);
00229     return codeword;
00230 }
00231 
00232 long decode_golay(long codeword)
00233 {
00234 /*
00235  * decodes codeword and returns the dataword contained within.  
00236  * 
00237  * note: no detection is done here!
00238  * codeword is assumed to contain the 23 bits in the LSB positions
00239  * the returned bits contain the bits in the LSB positions
00240  * 
00241  * MSB will be ignored, since this is 23,12 code.
00242  */
00243    static int initialized=0;
00244 
00245    if (!initialized) {
00246        gen_dec_table();
00247        initialized=1;
00248    }
00249 
00250    if (debug) {
00251        printf("decode_golay() - codeword =  %#012x\n", codeword);
00252        printf("decode_golay() - syndrome =  %#012x\n", get_syndrome(codeword));
00253    }
00254 
00255    /*
00256     * Calculate the syndrome, look up the corresponding error pattern and
00257     * add it to the received vector.
00258     */
00259    codeword ^= decoding_table[get_syndrome(codeword)];
00260    
00261    if (debug) {
00262      printf("decoded vector =  %#012x\n", codeword);
00263      printf("recovered data =  %#012x\n", (codeword>>11));
00264    }
00265    return codeword >> 11;
00266 }
00267 
00268 #if(0)
00269 main()
00270 {
00271   long data,encoded,decoded;
00272   data = 0x0b;
00273   printf("data: %x \n",data);
00274   encoded = encode_golay(data);
00275   printf("encoded: %x \n",encoded);
00276   encoded ^= 0xE000;
00277   printf("error encoded: %x \n",encoded);
00278   decoded = decode_golay(encoded);
00279   printf("decoded: %x \n",decoded);
00280 
00281 }
00282 #endif
00283 

Generated on Sun Jul 16 16:27:45 2006 by  doxygen 1.3.9.1