public GFPoly AddOrSubtract(GFPoly other) { if (IsZero()) { return(other); } if (other.IsZero()) { return(this); } int[] smallCoefficients = Coefficients; int[] largeCoefficients = other.Coefficients; if (smallCoefficients.Length > largeCoefficients.Length) { (largeCoefficients, smallCoefficients) = (smallCoefficients, largeCoefficients); } int[] sumDiff = new int[largeCoefficients.Length]; int lenDiff = largeCoefficients.Length - smallCoefficients.Length; Array.Copy(largeCoefficients, sumDiff, lenDiff); for (int i = lenDiff; i < largeCoefficients.Length; i++) { sumDiff[i] = GaloisField.AddOrSubtract(smallCoefficients[i - lenDiff], largeCoefficients[i]); } return(new GFPoly(GaloisField, sumDiff)); }
public int[] Encode(int[] data, int eccCount) { GFPoly generator = GetPolynomial(eccCount); GFPoly info = new GFPoly(GaloisField, data); info = info.MultiplyByMonominal(eccCount, 1); (_, GFPoly remainder) = info.Divide(generator); int[] result = new int[eccCount]; int numZero = eccCount - remainder.Coefficients.Length; Array.Copy(remainder.Coefficients, 0, result, numZero, remainder.Coefficients.Length); return(result); }
private GFPoly GetPolynomial(int degree) { lock (_syncRoot) { if (degree >= _polynomes.Count) { GFPoly last = _polynomes[_polynomes.Count - 1]; for (int d = _polynomes.Count; d <= degree; d++) { GFPoly next = last.Multiply(new GFPoly(GaloisField, new int[] { 1, GaloisField.ALogTable[d - 1 + GaloisField.Base] })); _polynomes.Add(next); last = next; } } return(_polynomes[degree]); } }
public (GFPoly Quotient, GFPoly Remainder) Divide(GFPoly other) { GFPoly quotient = Zero(GaloisField); GFPoly remainder = this; int denomLeadTerm = other.GetCoefficient(other.Degree()); int inversDenomLeadTerm = GaloisField.Inverse(denomLeadTerm); while (remainder.Degree() >= other.Degree() && !remainder.IsZero()) { int degreeDiff = remainder.Degree() - other.Degree(); int scale = GaloisField.Multiply(remainder.GetCoefficient(remainder.Degree()), inversDenomLeadTerm); GFPoly term = other.MultiplyByMonominal(degreeDiff, scale); GFPoly itQuot = MonominalPoly(GaloisField, degreeDiff, scale); quotient = quotient.AddOrSubtract(itQuot); remainder = remainder.AddOrSubtract(term); } return(quotient, remainder); }
public GFPoly Multiply(GFPoly other) { if (IsZero() || other.IsZero()) { return(Zero(GaloisField)); } int[] product = new int[Coefficients.Length + other.Coefficients.Length - 1]; for (int i = 0; i < Coefficients.Length; i++) { int ac = Coefficients[i]; for (int j = 0; j < other.Coefficients.Length; j++) { int bc = other.Coefficients[j]; product[i + j] = GaloisField.AddOrSubtract(product[i + j], GaloisField.Multiply(ac, bc)); } } return(new GFPoly(GaloisField, product)); }