private int[] findErrorMagnitudes(GenericGFPoly errorEvaluator, int[] errorLocations) { // 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 denominator = 1; for (int j = 0; j < s; j++) { if (i != j) { //denominator = field.multiply(denominator, // GenericGF.addOrSubtract(1, field.multiply(errorLocations[j], xiInverse))); // Above should work but fails on some Apple and Linux JDKs due to a Hotspot bug. // Below is a funny-looking workaround from Steven Parkes int term = field.multiply(errorLocations[j], xiInverse); int termPlus1 = (term & 0x1) == 0 ? term | 1 : term & ~1; denominator = field.multiply(denominator, termPlus1); } } result[i] = field.multiply(errorEvaluator.evaluateAt(xiInverse), field.inverse(denominator)); if (field.getGeneratorBase() != 0) { result[i] = field.multiply(result[i], xiInverse); } } return result; }
private int[] findErrorMagnitudes(GenericGFPoly errorEvaluator, int[] errorLocations) { // 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 denominator = 1; for (int j = 0; j < s; j++) { if (i != j) { //denominator = field.multiply(denominator, // GenericGF.addOrSubtract(1, field.multiply(errorLocations[j], xiInverse))); // Above should work but fails on some Apple and Linux JDKs due to a Hotspot bug. // Below is a funny-looking workaround from Steven Parkes int term = field.multiply(errorLocations[j], xiInverse); int termPlus1 = (term & 0x1) == 0 ? term | 1 : term & ~1; denominator = field.multiply(denominator, termPlus1); } } result[i] = field.multiply(errorEvaluator.evaluateAt(xiInverse), field.inverse(denominator)); if (field.getGeneratorBase() != 0) { result[i] = field.multiply(result[i], xiInverse); } } return result; }
GenericGFPoly multiplyByMonomial(int degree, int coefficient) { if (degree < 0) { throw new IllegalArgumentException(); } if (coefficient == 0) { return field.getZero(); } int size = coefficients.length; int[] product = new int[size + degree]; for (int i = 0; i < size; i++) { product[i] = field.multiply(coefficients[i], coefficient); } return new GenericGFPoly(field, product); }
GenericGFPoly multiplyByMonomial(int degree, int coefficient) { if (degree < 0) { throw new IllegalArgumentException(); } if (coefficient == 0) { return field.getZero(); } int size = coefficients.length; int[] product = new int[size + degree]; for (int i = 0; i < size; i++) { product[i] = field.multiply(coefficients[i], coefficient); } return new GenericGFPoly(field, product); }
GenericGFPoly multiply(int scalar) { if (scalar == 0) { return field.getZero(); } if (scalar == 1) { return this; } int size = coefficients.length; int[] product = new int[size]; for (int i = 0; i < size; i++) { product[i] = field.multiply(coefficients[i], scalar); } return new GenericGFPoly(field, product); }
GenericGFPoly multiply(int scalar) { if (scalar == 0) { return field.getZero(); } if (scalar == 1) { return this; } int size = coefficients.length; int[] product = new int[size]; for (int i = 0; i < size; i++) { product[i] = field.multiply(coefficients[i], scalar); } return new GenericGFPoly(field, product); }
GenericGFPoly multiply(GenericGFPoly other) { if (!field.equals(other.field)) { throw new IllegalArgumentException("GenericGFPolys do not have same GenericGF field"); } if (isZero() || other.isZero()) { return field.getZero(); } int[] aCoefficients = this.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); }
/** * @return evaluation of this polynomial at a given point */ int evaluateAt(int a) { if (a == 0) { // Just return the x^0 coefficient return getCoefficient(0); } if (a == 1) { // Just the sum of the coefficients int result = 0; for (int coefficient : coefficients) { result = GenericGF.addOrSubtract(result, coefficient); } return result; } int result = coefficients[0]; int size = coefficients.length; for (int i = 1; i < size; i++) { result = GenericGF.addOrSubtract(field.multiply(a, result), coefficients[i]); } return result; }
/** * @return evaluation of this polynomial at a given point */ int evaluateAt(int a) { if (a == 0) { // Just return the x^0 coefficient return getCoefficient(0); } if (a == 1) { // Just the sum of the coefficients int result = 0; for (int coefficient : coefficients) { result = GenericGF.addOrSubtract(result, coefficient); } return result; } int result = coefficients[0]; int size = coefficients.length; for (int i = 1; i < size; i++) { result = GenericGF.addOrSubtract(field.multiply(a, result), coefficients[i]); } return result; }
GenericGFPoly multiply(GenericGFPoly other) { if (!field.equals(other.field)) { throw new IllegalArgumentException("GenericGFPolys do not have same GenericGF field"); } if (isZero() || other.isZero()) { return field.getZero(); } int[] aCoefficients = this.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); }
GenericGFPoly[] divide(GenericGFPoly other) { if (!field.equals(other.field)) { throw new IllegalArgumentException("GenericGFPolys do not have same GenericGF field"); } if (other.isZero()) { throw new IllegalArgumentException("Divide by 0"); } GenericGFPoly quotient = field.getZero(); GenericGFPoly remainder = this; int denominatorLeadingTerm = other.getCoefficient(other.getDegree()); int inverseDenominatorLeadingTerm = field.inverse(denominatorLeadingTerm); while (remainder.getDegree() >= other.getDegree() && !remainder.isZero()) { int degreeDifference = remainder.getDegree() - other.getDegree(); int scale = field.multiply(remainder.getCoefficient(remainder.getDegree()), inverseDenominatorLeadingTerm); GenericGFPoly term = other.multiplyByMonomial(degreeDifference, scale); GenericGFPoly iterationQuotient = field.buildMonomial(degreeDifference, scale); quotient = quotient.addOrSubtract(iterationQuotient); remainder = remainder.addOrSubtract(term); } return new GenericGFPoly[] { quotient, remainder }; }
GenericGFPoly[] divide(GenericGFPoly other) { if (!field.equals(other.field)) { throw new IllegalArgumentException("GenericGFPolys do not have same GenericGF field"); } if (other.isZero()) { throw new IllegalArgumentException("Divide by 0"); } GenericGFPoly quotient = field.getZero(); GenericGFPoly remainder = this; int denominatorLeadingTerm = other.getCoefficient(other.getDegree()); int inverseDenominatorLeadingTerm = field.inverse(denominatorLeadingTerm); while (remainder.getDegree() >= other.getDegree() && !remainder.isZero()) { int degreeDifference = remainder.getDegree() - other.getDegree(); int scale = field.multiply(remainder.getCoefficient(remainder.getDegree()), inverseDenominatorLeadingTerm); GenericGFPoly term = other.multiplyByMonomial(degreeDifference, scale); GenericGFPoly iterationQuotient = field.buildMonomial(degreeDifference, scale); quotient = quotient.addOrSubtract(iterationQuotient); remainder = remainder.addOrSubtract(term); } return new GenericGFPoly[] { quotient, remainder }; }
while (r.getDegree() >= rLast.getDegree() && !r.isZero()) { int degreeDiff = r.getDegree() - rLast.getDegree(); int scale = field.multiply(r.getCoefficient(r.getDegree()), dltInverse); q = q.addOrSubtract(field.buildMonomial(degreeDiff, scale)); r = r.addOrSubtract(rLast.multiplyByMonomial(degreeDiff, scale));
while (r.getDegree() >= rLast.getDegree() && !r.isZero()) { int degreeDiff = r.getDegree() - rLast.getDegree(); int scale = field.multiply(r.getCoefficient(r.getDegree()), dltInverse); q = q.addOrSubtract(field.buildMonomial(degreeDiff, scale)); r = r.addOrSubtract(rLast.multiplyByMonomial(degreeDiff, scale));