public void Divide(GaloisPolynomial divider, out GaloisPolynomial quotient, out GaloisPolynomial remainder) { if (!m_Field.Equals(divider.m_Field)) { throw new AzosException(StringConsts.ARGUMENT_ERROR + GetType().Name + ".Div(divider: different field)"); } if (divider.IsPolynomial0) { throw new AzosException(StringConsts.ARGUMENT_ERROR + GetType().Name + ".Div(divider: div zero is undefined)"); } quotient = m_Field.Polynomial0; remainder = this; int dividerLeadingCoefficient = divider.coefficientAt(divider.Degree);//divider.Coefficients.Last(); int inversedDividerLeadingCoefficient = m_Field.Inverse(dividerLeadingCoefficient); while (remainder.Degree >= divider.Degree && !remainder.IsPolynomial0) { int deltaDegree = remainder.Degree - divider.Degree; int scale = m_Field.Multiply(remainder.coefficientAt(remainder.Degree), inversedDividerLeadingCoefficient); GaloisPolynomial term = divider.Multiply(deltaDegree, scale); GaloisPolynomial iterationQuotient = m_Field.GenerateMonomial(deltaDegree, scale); quotient = quotient.Add(iterationQuotient); remainder = remainder.Add(term); } }
public GaloisPolynomial Multiply(GaloisPolynomial factorPolynomial) { if (!m_Field.Equals(factorPolynomial.m_Field)) { throw new AzosException(StringConsts.ARGUMENT_ERROR + GetType().Name + ".Mult(factor: different field)"); } if (IsPolynomial0 || factorPolynomial.IsPolynomial0) { return(m_Field.Polynomial0); } int[] multiplicand = m_Coefficients; int[] factor = factorPolynomial.m_Coefficients; int[] product = new int[m_Coefficients.Length + factorPolynomial.m_Coefficients.Length - 1]; for (int i = 0; i < multiplicand.Length; i++) { int multiplicandCoefficient = multiplicand[i]; for (int j = 0; j < factor.Length; j++) { product[i + j] = GaloisField.Add(product[i + j], m_Field.Multiply(multiplicandCoefficient, factor[j])); } } return(new GaloisPolynomial(m_Field, product)); }
private GaloisPolynomial getPolySet(int degree) { if (degree >= m_PolySet.Count) { GaloisPolynomial lastPoly = m_PolySet.Last(); for (int i = m_PolySet.Count; i <= degree; i++) { GaloisPolynomial newPoly = lastPoly.Multiply(new GaloisPolynomial(m_Field, new int[] { 1, m_Field.Exp(i - 1 + m_Field.GeneratorBase) })); m_PolySet.Add(newPoly); lastPoly = newPoly; } } return(m_PolySet[degree]); }
public GaloisPolynomial Add(GaloisPolynomial summand) { if (!m_Field.Equals(summand.m_Field)) { throw new AzosException(StringConsts.ARGUMENT_ERROR + GetType().Name + ".Add(summand: different field)"); } if (IsPolynomial0) { return(summand); } if (summand.IsPolynomial0) { return(this); } int[] shorterPolynomialCoefficients; int[] longerPolynomialCoefficients; if (m_Coefficients.Length < summand.m_Coefficients.Length) { shorterPolynomialCoefficients = m_Coefficients; longerPolynomialCoefficients = summand.m_Coefficients; } else { shorterPolynomialCoefficients = summand.m_Coefficients; longerPolynomialCoefficients = m_Coefficients; } int[] resultCoefficients = new int[longerPolynomialCoefficients.Length]; int deltaLength = (int)(longerPolynomialCoefficients.Length - shorterPolynomialCoefficients.Length); for (int i = 0; i < longerPolynomialCoefficients.Length; i++) { if (i < deltaLength) { resultCoefficients[i] = longerPolynomialCoefficients[i]; } else { resultCoefficients[i] = GaloisField.Add(longerPolynomialCoefficients[i], shorterPolynomialCoefficients[i - deltaLength]); } } return(new GaloisPolynomial(m_Field, resultCoefficients)); }
public void Encode(int[] src, int errorCorrectionLength) { if (errorCorrectionLength <= 0) { throw new AzosException(StringConsts.ARGUMENT_ERROR + GetType().Name + ".Encode(errorCorrectionLength)"); } int dataLength = src.Length - errorCorrectionLength; if (dataLength <= 0) { throw new AzosException(StringConsts.ARGUMENT_ERROR + GetType().Name + ".Encode: No data bytes provided"); } GaloisPolynomial generationPoly = getPolySet(errorCorrectionLength); int[] infoCoefficients = new int[dataLength]; Array.Copy(src, 0, infoCoefficients, 0, dataLength); GaloisPolynomial infoPoly = new GaloisPolynomial(m_Field, infoCoefficients); infoPoly = infoPoly.Multiply(errorCorrectionLength, 1); GaloisPolynomial remainder, quotient; infoPoly.Divide(generationPoly, out quotient, out remainder); int[] coefficients = remainder.Coefficients; int numZeroCoefficients = errorCorrectionLength - coefficients.Length; for (var i = 0; i < numZeroCoefficients; i++) { src[dataLength + i] = 0; } Array.Copy(coefficients, 0, src, dataLength + numZeroCoefficients, coefficients.Length); }