Example #1
0
        /// <summary>
        /// Finds the error magnitudes by directly applying Forney's Formula
        /// </summary>
        /// <returns>The error magnitudes.</returns>
        /// <param name="errorEvaluator">Error evaluator.</param>
        /// <param name="errorLocator">Error locator.</param>
        /// <param name="errorLocations">Error locations.</param>
        private int[] findErrorMagnitudes(ModulusPoly errorEvaluator,
                                          ModulusPoly errorLocator,
                                          int[] errorLocations)
        {
            int errorLocatorDegree = errorLocator.Degree;

            if (errorLocatorDegree < 1)
            {
                return(new int[0]);
            }
            int[] formalDerivativeCoefficients = new int[errorLocatorDegree];
            for (int i = 1; i <= errorLocatorDegree; i++)
            {
                formalDerivativeCoefficients[errorLocatorDegree - i] =
                    field.multiply(i, errorLocator.getCoefficient(i));
            }
            ModulusPoly formalDerivative = new ModulusPoly(field, formalDerivativeCoefficients);

            // This is directly applying Forney's Formula
            int s = errorLocations.Length;

            int[] result = new int[s];
            for (int i = 0; i < s; i++)
            {
                int xiInverse   = field.inverse(errorLocations[i]);
                int numerator   = field.subtract(0, errorEvaluator.evaluateAt(xiInverse));
                int denominator = field.inverse(formalDerivative.evaluateAt(xiInverse));
                result[i] = field.multiply(numerator, denominator);
            }
            return(result);
        }
Example #2
0
      /// <summary>
      /// Decodes the specified received.
      /// </summary>
      /// <param name="received">The received.</param>
      /// <param name="numECCodewords">The num EC codewords.</param>
      /// <param name="erasures">The erasures.</param>
      /// <returns></returns>
      public bool decode(int[] received, int numECCodewords, int[] erasures)
      {
         ModulusPoly poly = new ModulusPoly(field, received);
         int[] S = new int[numECCodewords];
         bool error = false;
         for (int i = numECCodewords; i > 0; i--)
         {
            int eval = poly.evaluateAt(field.exp(i));
            S[numECCodewords - i] = eval;
            if (eval != 0)
            {
               error = true;
            }
         }
         if (error)
         {
            ModulusPoly knownErrors = field.getOne();
            foreach (int erasure in erasures)
            {
               int b = field.exp(received.Length - 1 - erasure);
               // Add (1 - bx) term:
               ModulusPoly term = new ModulusPoly(field, new int[] { field.subtract(0, b), 1 });
               knownErrors = knownErrors.multiply(term);
            }

            ModulusPoly syndrome = new ModulusPoly(field, S);
            //syndrome = syndrome.multiply(knownErrors);

            ModulusPoly[] sigmaOmega =
                runEuclideanAlgorithm(field.buildMonomial(numECCodewords, 1), syndrome, numECCodewords);
            if (sigmaOmega == null)
               return false;
            ModulusPoly sigma = sigmaOmega[0];
            ModulusPoly omega = sigmaOmega[1];

            //sigma = sigma.multiply(knownErrors);

            int[] errorLocations = findErrorLocations(sigma);
            if (errorLocations == null)
               return false;
            int[] errorMagnitudes = findErrorMagnitudes(omega, sigma, errorLocations);
            if (errorMagnitudes == null)
               return false;

            for (int i = 0; i < errorLocations.Length; i++)
            {
               int position = received.Length - 1 - field.log(errorLocations[i]);
               if (position < 0)
               {
                  return false;
               }
               received[position] = field.subtract(received[position], errorMagnitudes[i]);
            }
         }

         return true;
      }
Example #3
0
        /// <summary>
        /// Finds the error locations as a direct application of Chien's search
        /// </summary>
        /// <returns>The error locations.</returns>
        /// <param name="errorLocator">Error locator.</param>
        private int[] findErrorLocations(ModulusPoly errorLocator)
        {
            // This is a direct application of Chien's search
            int numErrors = errorLocator.Degree;

            int[] result = new int[numErrors];
            int   e      = 0;

            for (int i = 1; i < field.Size && e < numErrors; i++)
            {
                if (errorLocator.evaluateAt(i) == 0)
                {
                    result[e] = field.inverse(i);
                    e++;
                }
            }
            if (e != numErrors)
            {
                return(null);
            }
            return(result);
        }
Example #4
0
        /// <summary>
        /// Decodes the specified received.
        /// </summary>
        /// <param name="received">received codewords</param>
        /// <param name="numECCodewords">number of those codewords used for EC</param>
        /// <param name="erasures">location of erasures</param>
        /// <param name="errorLocationsCount">The error locations count.</param>
        /// <returns></returns>
        public bool decode(int[] received, int numECCodewords, int[] erasures, out int errorLocationsCount)
        {
            ModulusPoly poly = new ModulusPoly(field, received);

            int[] S     = new int[numECCodewords];
            bool  error = false;

            errorLocationsCount = 0;
            for (int i = numECCodewords; i > 0; i--)
            {
                int eval = poly.evaluateAt(field.exp(i));
                S[numECCodewords - i] = eval;
                if (eval != 0)
                {
                    error = true;
                }
            }

            if (!error)
            {
                return(true);
            }

            ModulusPoly knownErrors = field.One;

            if (erasures != null)
            {
                foreach (int erasure in erasures)
                {
                    int b = field.exp(received.Length - 1 - erasure);
                    // Add (1 - bx) term:
                    ModulusPoly term = new ModulusPoly(field, new int[] { field.subtract(0, b), 1 });
                    knownErrors = knownErrors.multiply(term);
                }
            }

            ModulusPoly syndrome = new ModulusPoly(field, S);

            //syndrome = syndrome.multiply(knownErrors);

            ModulusPoly[] sigmaOmega = runEuclideanAlgorithm(field.buildMonomial(numECCodewords, 1), syndrome, numECCodewords);

            if (sigmaOmega == null)
            {
                return(false);
            }

            ModulusPoly sigma = sigmaOmega[0];
            ModulusPoly omega = sigmaOmega[1];

            if (sigma == null || omega == null)
            {
                return(false);
            }

            //sigma = sigma.multiply(knownErrors);

            int[] errorLocations = findErrorLocations(sigma);

            if (errorLocations == null)
            {
                return(false);
            }

            int[] errorMagnitudes = findErrorMagnitudes(omega, sigma, errorLocations);

            for (int i = 0; i < errorLocations.Length; i++)
            {
                int position = received.Length - 1 - field.log(errorLocations[i]);
                if (position < 0)
                {
                    return(false);
                }
                received[position] = field.subtract(received[position], errorMagnitudes[i]);
            }
            errorLocationsCount = errorLocations.Length;
            return(true);
        }
Example #5
0
      /// <summary>
      /// Finds the error magnitudes by directly applying Forney's Formula
      /// </summary>
      /// <returns>The error magnitudes.</returns>
      /// <param name="errorEvaluator">Error evaluator.</param>
      /// <param name="errorLocator">Error locator.</param>
      /// <param name="errorLocations">Error locations.</param>
      private int[] findErrorMagnitudes(ModulusPoly errorEvaluator,
                                        ModulusPoly errorLocator,
                                        int[] errorLocations)
      {
         int errorLocatorDegree = errorLocator.Degree;
         int[] formalDerivativeCoefficients = new int[errorLocatorDegree];
         for (int i = 1; i <= errorLocatorDegree; i++)
         {
            formalDerivativeCoefficients[errorLocatorDegree - i] =
                field.multiply(i, errorLocator.getCoefficient(i));
         }
         ModulusPoly formalDerivative = new ModulusPoly(field, formalDerivativeCoefficients);

         // This is directly applying Forney's Formula
         int s = errorLocations.Length;
         int[] result = new int[s];
         for (int i = 0; i < s; i++)
         {
            int xiInverse = field.inverse(errorLocations[i]);
            int numerator = field.subtract(0, errorEvaluator.evaluateAt(xiInverse));
            int denominator = field.inverse(formalDerivative.evaluateAt(xiInverse));
            result[i] = field.multiply(numerator, denominator);
         }
         return result;
      }
Example #6
0
 /// <summary>
 /// Finds the error locations as a direct application of Chien's search
 /// </summary>
 /// <returns>The error locations.</returns>
 /// <param name="errorLocator">Error locator.</param>
 private int[] findErrorLocations(ModulusPoly errorLocator)
 {
    // This is a direct application of Chien's search
    int numErrors = errorLocator.Degree;
    int[] result = new int[numErrors];
    int e = 0;
    for (int i = 1; i < field.Size && e < numErrors; i++)
    {
       if (errorLocator.evaluateAt(i) == 0)
       {
          result[e] = field.inverse(i);
          e++;
       }
    }
    if (e != numErrors)
    {
       return null;
    }
    return result;
 }