⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rs_de.c

📁 一份比较有价值的有关RS编码的文章 欢迎下载
💻 C
字号:
/***************************************************************************
* File:     	RSDeCode.c
* Title:    	Decoder for RS codes in C
* Authors:  	lzg
* Date:     	2003.4
* Input:	mm,kk,b0,Generate the GF(2^mm) and conversion table
*		recd,received data that is Waiting for been decoded
*
* Return:	recd,data that has been decoded
*		return value 
*			0:no error,so correct decode codewords
*			1:correct decode codewords
*			2:cann't find root,so cann't correct decode codewords
*			3:error number > tt ,so dismissed for correcting decode codewords
* Note:		two ways for decodeing
*****************************************************************************/
/*===========================================================================
*Fuction:
*	decode_rs()	performs errors-only decoding of RS codes
*	
*
============================================================================*/

#include <math.h>
#include <stdio.h>
#include <time.h>
//#include <conio.h>
#include <stdlib.h>
#include <string.h>

#ifndef Gen_GF
#define Gen_GF
//#include "Gen_GF.c"
#endif

#ifndef GFMM_KK_B0
#define GFMM_KK_B0
#define mm		8
#define nn		255
#define kk		243
#define tt		6
#define b0		120
#define nn_short	31
#define kk_short	19
#endif

/* Performs ERRORS-ONLY decoding of RS codes. If decoding is successful,
 writes the codeword into recd[] itself. Otherwise recd[] is unaltered. 
 If channel caused no more than "tt" errors, the tranmitted codeword will
 be recovered.
*/ 

int decode_rs(int *recd)
 {
   register int i,j,u,q ;
   int elp[nn-kk+2][nn-kk], d[nn-kk+2], l[nn-kk+2], u_lu[nn-kk+2], s[nn-kk+1] ;
   int count=0, syn_error=0, root[tt], loc[tt], z[tt+1], err[nn], reg[tt+1] ;

   int *Alpha_to,*Index_of,*gg;
//   FILE *fp_out;
   /*
   int tt;
   tt=(nn-kk)/2;
   */
   /*nn=pow(2,mm) - 1;*/
   Alpha_to = (int *) calloc((nn + 1),sizeof(int));
   Index_of = (int *) calloc((nn + 1),sizeof(int));
   gg = (int *) calloc((nn - kk),sizeof(int));

   /*generate GF(2^mm) and conversion table for RS encode*/
   gen_gf(Alpha_to,Index_of,gg);


   /* recd[] is in polynomial form, convert to index form */
   for (i=0;i < nn;i++) recd[i] = Index_of[recd[i]];


   /********************************计算伴随式S************************************/
   /* first form the syndromes; i.e., evaluate recd(x) at roots of g(x) namely
    		@**(b0+i), i = 0, ... ,(2*tt-1) */
   for (i=1; i <= nn-kk; i++)
    { s[i] = 0 ;
      for (j=0; j < nn; j++)
        if (recd[j] != -1)
          s[i] ^= Alpha_to[(recd[j]+(long)(b0+i-1)*j)%nn] ;      /* recd[j] in index form */
      /* convert syndrome from polynomial form to index form  */
      if (s[i] != 0)  syn_error = 1 ;   /* set flag if non-zero syndrome => error */
      s[i] = Index_of[s[i]] ;
    };

  /***********************************伴随式计算结束*****************************/



   if (syn_error)       /* if errors, try and correct */
    {

/* compute the error location polynomial via the Berlekamp iterative algorithm,
   following the terminology of Lin and Costello :   d[u] is the 'mu'th
   discrepancy, where u = 'mu'+ 1 and 'mu' (the Greek letter!) is the step number
   ranging from -1 to 2*tt (see L&C),  l[u] is the
   degree of the elp at that step, and u_l[u] is the difference between the
   step number and the degree of the elp.
  
   The notation is the same as that in Lin and Costello's book; pages 155-156 and 175. */


/*********************************BM叠代法计算错误位置多项式elp******************************/
      /* initialise table entries */
      d[0] = 0 ;           	/* index form elp差值d*/
      d[1] = s[1] ;        	/* index form */
      elp[0][0] = 0 ;      	/* index form 错误位置多项式*/
      elp[1][0] = 1 ;      	/* polynomial form */
      for (i=1; i<nn-kk; i++)
        { 
          elp[0][i] = -1 ;   	/* index form */
          elp[1][i] = 0 ;   	/* polynomial form */
        }
      l[0] = 0 ;		/*elp的度数D*/
      l[1] = 0 ;
      u_lu[0] = -1 ;		/*i-D*/
      u_lu[1] = 0 ;
      u = 0 ;			/*叠代次数*/

      do
      {
        u++ ;
        if (d[u]==-1)		/*差值d为0*/
          { 
            l[u+1] = l[u] ;
            for (i=0; i<=l[u]; i++)
             {  
             	elp[u+1][i] = elp[u][i] ;
                elp[u][i] = Index_of[elp[u][i]] ;
             }
          }
        else
	/* search for words with greatest u_lu[q] for which d[q]!=0 */
          {
	/*************************查找满足i-D最大的q值********************************/ 
            q = u-1 ;
            while ((d[q]==-1) && (q>0)) q-- ;
	/* have found first non-zero d[q]  */
            if (q>0)
             { 
               j=q ;
               do
               { 
               	 j-- ;
                 if ((d[j]!=-1) && (u_lu[q]<u_lu[j])) q = j ;
               }while (j>0) ;
             } ;
	/********************查找满足i-D最大的q值结束********************************/ 


	/* have now found q such that d[u]!=0 and u_lu[q] is maximum */
	/* store degree of new elp polynomial */
	/*****************************计算D***************************************/
            if (l[u]>l[q]+u-q)  l[u+1] = l[u] ;
            else  l[u+1] = l[q]+u-q ;
	/*************************计算D结束***************************************/


	/* form new elp(x) */
	/******************************计算elp*****************************************/
            for (i=0; i<nn-kk; i++)    elp[u+1][i] = 0 ;
            for (i=0; i<=l[q]; i++)
              {
              	if (elp[q][i]!=-1)
                	elp[u+1][i+u-q] = Alpha_to[(d[u]+nn-d[q]+elp[q][i])%nn] ;
              }
            for (i=0; i<=l[u]; i++)
              { 
              	elp[u+1][i] ^= elp[u][i] ;
                elp[u][i] = Index_of[elp[u][i]] ;  /*convert old elp value to index*/
              }
          }
        u_lu[u+1] = u-l[u+1] ;
	/*******************************计算elp结束****************************************/


	/* form (u+1)th discrepancy */
	/********************************计算差值d*****************************************/
        if (u<nn-kk)    /* no discrepancy computed on last iteration */
          {
            if (s[u+1]!=-1)
                d[u+1] = Alpha_to[s[u+1]] ;
            else
              	d[u+1] = 0 ;
            for (i=1; i<=l[u+1]; i++)
            {
              if ((s[u+1-i]!=-1) && (elp[u+1][i]!=0))
                d[u+1] ^= Alpha_to[(s[u+1-i]+Index_of[elp[u+1][i]])%nn] ;
            }
            d[u+1] = Index_of[d[u+1]] ;    /* put d[u+1] into index form */
          }
	/********************************计算差值d结束***********************************/

      } while ((u < nn-kk) && l[u+1] <= tt);
/****************************************叠代结束************************************************/
	
      u++ ;
 
      if (l[u] <= tt)         /* can correct error */
       {

	/* put elp into index form */
         for (i=0; i<=l[u]; i++)   elp[u][i] = Index_of[elp[u][i]] ;

	/*****************************钱搜索计算错误位置**************************************/
	/* find roots of the error location polynomial */
         for (i=1; i <= l[u]; i++)
           reg[i] = elp[u][i] ;
         count = 0 ;
         for (i=1; i <= nn; i++)
          {  q = 1 ;
             for (j=1; j<=l[u]; j++)
              if (reg[j]!=-1)
                { reg[j] = (reg[j]+j)%nn ;
                  q ^= Alpha_to[reg[j]] ;
                } ;
             if (!q)        /* store root and error location number indices */
              { 
              	root[count] = i;	/*错误位置多项式的根*/
                loc[count] = nn-i ;	/*错误位置*/
                count++ ;
              };
          } ;
	/*****************************钱搜索计算错误位置结束***********************************/
      
         if (count == l[u])    /* no. roots = degree of elp hence <= tt errors */
          {
		/* form polynomial z(x) */
           /**************************计算错误值*******************************/
           for (i=1; i <= l[u]; i++)        /* Z[0] = 1 always - do not need */
            { 
              if ((s[i]!=-1) && (elp[u][i]!=-1))
              	z[i] = Alpha_to[s[i]] ^ Alpha_to[elp[u][i]] ;
              else if ((s[i]!=-1) && (elp[u][i]==-1))
                z[i] = Alpha_to[s[i]] ;
              else if ((s[i]==-1) && (elp[u][i]!=-1))
                z[i] = Alpha_to[elp[u][i]] ;
              else
                z[i] = 0 ;
              for (j=1; j<i; j++)
                if ((s[j]!=-1) && (elp[u][i-j]!=-1))
                   z[i] ^= Alpha_to[(elp[u][i-j] + s[j])%nn] ;
              z[i] = Index_of[z[i]] ;         /* put into index form */
            } ;
            
  	/* evaluate errors at locations given by error location numbers loc[i] */
           for (i=0; i<nn; i++)
             { 
               err[i] = 0 ;
               if (recd[i]!=-1)        /* convert recd[] to polynomial form */
                 recd[i] = Alpha_to[recd[i]] ;
               else  recd[i] = 0 ;
             }
           for (i=0; i < l[u]; i++)    /* compute numerator of error term first */
            { 
              err[loc[i]] = 1;       /* accounts for z[0] */
              for (j=1; j<=l[u]; j++)
              {
                if (z[j]!=-1)
                  err[loc[i]] ^= Alpha_to[(z[j]+j*root[i])%nn] ;
	      } /* z(x) evaluated at X(l)**(-1) */
              if (err[loc[i]] != 0) /* term X(l)**(1-b0) */
		 err[loc[i]] = Alpha_to[(Index_of[err[loc[i]]]+(long)root[i]*(b0+nn-1))%nn];
              if (err[loc[i]]!=0)
               {
		 err[loc[i]] = Index_of[err[loc[i]]] ;
                 q = 0 ;     /* form denominator of error term */
                 for (j=0; j<l[u]; j++)
                   if (j!=i)
                     q += Index_of[1^Alpha_to[(loc[j]+root[i])%nn]] ;
                 q = q % nn ;
                 err[loc[i]] = Alpha_to[(err[loc[i]]-q+nn)%nn] ;
                 recd[loc[i]] ^= err[loc[i]] ;  /*recd[i] must be in polynomial form */
               }
            /***************************计算错误值结束******************************/
            }
	    free(Alpha_to);
   	    free(Index_of);
   	    free(gg);
	    return(1);
          }
          else		/* no. roots != degree of elp => >tt errors and cannot solve */
          {    
           	for (i=0; i<nn; i++)
           	{        /* could return error flag if desired */
               	   if (recd[i]!=-1)        /* convert recd[] to polynomial form */
                 	recd[i] = Alpha_to[recd[i]] ;
                   else  
			recd[i] = 0 ;     /* just output received word as is */
		}
		free(Alpha_to);
   	    	free(Index_of);
   	    	free(gg);
		return(2);
	  }
       }
      else{         /* elp has degree has degree >tt hence cannot solve */
       	for (i=0; i<nn; i++){       /* could return error flag if desired */
            if (recd[i]!=-1)        /* convert recd[] to polynomial form */
                recd[i] = Alpha_to[recd[i]] ;
            else  
		recd[i] = 0 ;     /* just output received word as is */
	}
	free(Alpha_to);
   	free(Index_of);
   	free(gg);
	return(3);
      }
   }
   else{       /* no non-zero syndromes => no errors: output received codeword */

       	for (i=0; i < nn; i++)
       	{
       	   if (recd[i] != -1)        /* convert recd[] to polynomial form */
         	recd[i] = Alpha_to[recd[i]] ;
           else  
	 	recd[i] = 0 ;
 	}
 	free(Alpha_to);
   	free(Index_of);
   	free(gg);
	return(0);
   }
 }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -