/// <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); }
/// <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; throw ReaderException.Instance; } return(result); }
/// <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 int 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) { return 0; } ModulusPoly knownErrors = field.One; 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) { throw ReaderException.Instance; } ModulusPoly sigma = sigmaOmega[0]; ModulusPoly omega = sigmaOmega[1]; if (sigma == null || omega == null) { throw ReaderException.Instance; } //sigma = sigma.multiply(knownErrors); int[] errorLocations = FindErrorLocations(sigma); if (errorLocations == null) { throw ReaderException.Instance; } 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) { throw ReaderException.Instance; // return -3; // don't throw } received[position] = field.Subtract(received[position], errorMagnitudes[i]); } return errorLocations.Length; }
/// <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; }
/// <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; throw ReaderException.Instance; } return result; }
/// <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 int 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) { return(0); } ModulusPoly knownErrors = field.One; 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) { throw ReaderException.Instance; } ModulusPoly sigma = sigmaOmega[0]; ModulusPoly omega = sigmaOmega[1]; if (sigma == null || omega == null) { throw ReaderException.Instance; } //sigma = sigma.multiply(knownErrors); int[] errorLocations = FindErrorLocations(sigma); if (errorLocations == null) { throw ReaderException.Instance; } 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) { throw ReaderException.Instance; // return -3; // don't throw } received[position] = field.Subtract(received[position], errorMagnitudes[i]); } return(errorLocations.Length); }