internal GenericGFPoly Multiply(GenericGFPoly other) { if (field.Equals(other.field) == false) { throw new ArgumentException("GenericGFPolys do not have same GenericGF field"); } if (IsZero || other.IsZero) { return(field.Zero); } int[] aCoefficients = coefficients; int aLength = aCoefficients.Length; int[] bCoefficients = other.coefficients; int bLength = bCoefficients.Length; int[] product = new int[aLength + bLength - 1]; for (int i = 0; i < aLength; i++) { int aCoeff = aCoefficients[i]; for (int j = 0; j < bLength; j++) { product[i + j] = GenericGF.AddOrSubtract(product[i + j], field.Multiply(aCoeff, bCoefficients[j])); } } return(new GenericGFPoly(field, product)); }
/// <summary> /// evaluation of this polynomial at a given point /// </summary> /// <param name="a">A.</param> /// <returns>evaluation of this polynomial at a given point</returns> internal int EvaluateAt(int a) { int result = 0; if (a == 0) { // Just return the x^0 coefficient return(GetCoefficient(0)); } int size = coefficients.Length; if (a == 1) { // Just the sum of the coefficients foreach (var coefficient in coefficients) { result = GenericGF.AddOrSubtract(result, coefficient); } return(result); } result = coefficients[0]; for (int i = 1; i < size; i++) { result = GenericGF.AddOrSubtract(field.Multiply(a, result), coefficients[i]); } return(result); }
/// <summary> /// <p>Decodes given set of received codewords, which include both data and error-correction /// codewords. Really, this means it uses Reed-Solomon to detect and correct errors, in-place, /// in the input.</p> /// </summary> /// <param name="received">data and error-correction codewords</param> /// <param name="twoS">number of error-correction codewords available</param> /// <returns>false: decoding fails</returns> public bool Decode(int[] received, int twoS) { var poly = new GenericGFPoly(field, received); var syndromeCoefficients = new int[twoS]; var noError = true; for (var i = 0; i < twoS; i++) { int eval = poly.EvaluateAt(field.Exp(i + field.GeneratorBase)); syndromeCoefficients[syndromeCoefficients.Length - 1 - i] = eval; if (eval != 0) { noError = false; } } if (noError) { return(true); } var syndrome = new GenericGFPoly(field, syndromeCoefficients); GenericGFPoly[] sigmaOmega = RunEuclideanAlgorithm(field.BuildMonomial(twoS, 1), syndrome, twoS); if (sigmaOmega == null) { return(false); } GenericGFPoly sigma = sigmaOmega[0]; int[] errorLocations = FindErrorLocations(sigma); if (errorLocations == null) { return(false); } GenericGFPoly omega = sigmaOmega[1]; int[] errorMagnitudes = FindErrorMagnitudes(omega, errorLocations); for (int i = 0; i < errorLocations.Length; i++) { int position = received.Length - 1 - field.Log(errorLocations[i]); if (position < 0) { // throw new ReedSolomonException("Bad error location"); return(false); } received[position] = GenericGF.AddOrSubtract(received[position], errorMagnitudes[i]); } return(true); }
internal GenericGFPoly AddOrSubtract(GenericGFPoly other) { if (field.Equals(other.field) == false) { throw new ArgumentException("GenericGFPolys do not have same GenericGF field"); } if (IsZero) { return(other); } if (other.IsZero) { return(this); } int[] smallerCoefficients = coefficients; int[] largerCoefficients = other.coefficients; if (smallerCoefficients.Length > largerCoefficients.Length) { int[] temp = smallerCoefficients; smallerCoefficients = largerCoefficients; largerCoefficients = temp; } int[] sumDiff = new int[largerCoefficients.Length]; int lengthDiff = largerCoefficients.Length - smallerCoefficients.Length; // Copy high-order terms only found in higher-degree polynomial's coefficients Array.Copy(largerCoefficients, 0, sumDiff, 0, lengthDiff); for (int i = lengthDiff; i < largerCoefficients.Length; i++) { sumDiff[i] = GenericGF.AddOrSubtract(smallerCoefficients[i - lengthDiff], largerCoefficients[i]); } return(new GenericGFPoly(field, sumDiff)); }