public void Divide() { //System.Diagnostics.Debugger.Launch(); GaloisField field = new GaloisField(285, 256, 0); GaloisPolynomial divident = new GaloisPolynomial(field, new int[] {32, 49, 205, 69, 42, 20, 0, 236, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}); GaloisPolynomial divider = new GaloisPolynomial(field, new int[] {1, 119, 66, 83, 120, 119, 22, 197, 83, 249, 41, 143, 134, 85, 53, 125, 99, 79}); GaloisPolynomial quotient, remainder; divident.Divide(divider, out quotient, out remainder); int[] expectedQuotientCoefficients = new int[] { 32, 119, 212, 254, 109, 212, 30, 95, 117}; int[] expectedRemainderCoefficients = new int[] { 3, 130, 179, 194, 0, 55, 211, 110, 79, 98, 72, 170, 96, 211, 137, 213}; Assert.AreEqual(expectedQuotientCoefficients.Length, quotient.Coefficients.Length); Assert.AreEqual(expectedRemainderCoefficients.Length, remainder.Coefficients.Length); for (int i = 0; i < quotient.Coefficients.Length; i++) Assert.AreEqual(expectedQuotientCoefficients[i], quotient.Coefficients[i]); for (int i = 0; i < remainder.Coefficients.Length; i++) Assert.AreEqual(expectedRemainderCoefficients[i], remainder.Coefficients[i]); }
public GaloisPolynomial Multiply(GaloisPolynomial factorPolynomial) { if (!m_Field.Equals(factorPolynomial.m_Field)) { throw new NFXException(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)); }
public void Divide(GaloisPolynomial divider, out GaloisPolynomial quotient, out GaloisPolynomial remainder) { if (!m_Field.Equals(divider.m_Field)) { throw new NFXException(StringConsts.ARGUMENT_ERROR + GetType().Name + ".Div(divider: different field)"); } if (divider.IsPolynomial0) { throw new NFXException(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); } }
private void initialize() { m_ExpTable = new int[m_Size]; m_LogTable = new int[m_Size]; int x = 1; for (int i = 0; i < m_Size; i++) { m_ExpTable[i] = x; x <<= 1; if (x >= m_Size) { x ^= m_Primitive; x &= m_Size - 1; } } for (int i = 0; i < m_Size - 1; i++) { m_LogTable[m_ExpTable[i]] = i; } m_Polynomial0 = new GaloisPolynomial(this, new int[] { 0 }); m_Polynomial1 = new GaloisPolynomial(this, new int[] { 1 }); m_Initialized = true; }
public void Encode(int[] src, int errorCorrectionLength) { if (errorCorrectionLength <= 0) throw new NFXException(StringConsts.ARGUMENT_ERROR + GetType().Name + ".Encode(errorCorrectionLength)"); int dataLength = src.Length - errorCorrectionLength; if (dataLength <= 0) throw new NFXException(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); }
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 NFXException(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 GaloisPolynomial GenerateMonomial(int degree, int coefficient) { ensureInitialized(); if (coefficient == 0) { return(m_Polynomial0); } int[] coefficients = new int[degree + 1]; coefficients[0] = coefficient; GaloisPolynomial polynomial = new GaloisPolynomial(this, coefficients); return(polynomial); }
public void Encode(int[] src, int errorCorrectionLength) { if (errorCorrectionLength <= 0) { throw new NFXException(StringConsts.ARGUMENT_ERROR + GetType().Name + ".Encode(errorCorrectionLength)"); } int dataLength = src.Length - errorCorrectionLength; if (dataLength <= 0) { throw new NFXException(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); }
private void initialize() { m_ExpTable = new int[m_Size]; m_LogTable = new int[m_Size]; int x = 1; for (int i = 0; i < m_Size; i++) { m_ExpTable[i] = x; x <<= 1; if (x >= m_Size) { x ^= m_Primitive; x &= m_Size - 1; } } for (int i = 0; i < m_Size-1; i++) { m_LogTable[m_ExpTable[i]] = i; } m_Polynomial0 = new GaloisPolynomial(this, new int[] { 0 }); m_Polynomial1 = new GaloisPolynomial(this, new int[] { 1 }); m_Initialized = true; }
public GaloisPolynomial GenerateMonomial( int degree, int coefficient) { ensureInitialized(); if (coefficient == 0) return m_Polynomial0; int[] coefficients = new int[degree + 1]; coefficients[0] = coefficient; GaloisPolynomial polynomial = new GaloisPolynomial(this, coefficients); return polynomial; }
public GaloisPolynomial Add(GaloisPolynomial summand) { if (!m_Field.Equals(summand.m_Field)) throw new NFXException(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 GaloisPolynomial Multiply(GaloisPolynomial factorPolynomial) { if (!m_Field.Equals(factorPolynomial.m_Field)) throw new NFXException(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); }
public void Divide(GaloisPolynomial divider, out GaloisPolynomial quotient, out GaloisPolynomial remainder) { if (!m_Field.Equals(divider.m_Field)) throw new NFXException(StringConsts.ARGUMENT_ERROR + GetType().Name + ".Div(divider: different field)"); if (divider.IsPolynomial0) throw new NFXException(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); } }