/// <summary> /// Indexing property for obtain bivariate polynomial coefficient by variable power <paramref name="index"/> /// </summary> /// <param name="index">Variable power which coefficient is required</param> /// <returns>Polynomial coefficient</returns> public int this[int index] { get { if (index < 0 || index > Degree) { throw new IndexOutOfRangeException(); } return(_coefficients[index]); } set { if (index < 0 || index > Degree) { throw new IndexOutOfRangeException(); } if (Field.IsFieldElement(value) == false) { throw new ArgumentException(NameOfExtension.nameof(() => value)); } _coefficients[index] = value; } }
/// <summary> /// Method for finding irreducible polynomial degree <paramref name="degree"/> with coefficients from field with order <paramref name="fieldOrder"/> /// </summary> /// <param name="fieldOrder">Field order from which irreducible polynomials coefficients come</param> /// <param name="degree">Irreducible polynomial degree</param> /// <returns>Irreducible polynomial with specified properties</returns> public GFPolynoms.Polynomial Find(int fieldOrder, int degree) { if (degree < 2) { throw new ArgumentException(NameOfExtension.nameof(() => degree)); } var field = new PrimeOrderField(fieldOrder); var possibleDivisors = new List <GFPolynoms.Polynomial>(); for (var i = 1; i *i <= degree; i++) { var templatePolynomial = GenerateTemplatePolynomial(field, i); Generate(templatePolynomial, 0, x => { possibleDivisors.Add(new GFPolynoms.Polynomial(x)); return(false); }); } var result = GenerateTemplatePolynomial(field, degree); Generate(result, 0, x => possibleDivisors.All(d => (x % d).IsZero == false)); return(result); }
/// <summary> /// Method for performing list decoding of Reed-Solomon code codeword /// </summary> /// <param name="n">Codeword length</param> /// <param name="k">Information word length</param> /// <param name="decodedCodeword">Recived codeword for decoding</param> /// <param name="minCorrectValuesCount">Minimum number of valid values</param> /// <returns>Decoding result</returns> public Polynomial[] Decode(int n, int k, Tuple <FieldElement, FieldElement>[] decodedCodeword, int minCorrectValuesCount) { if (n <= 0) { throw new ArgumentException(NameOfExtension.nameof(() => n)); } if (k <= 0 || k >= n) { throw new ArithmeticException(NameOfExtension.nameof(() => k)); } if (minCorrectValuesCount <= 0 || minCorrectValuesCount * minCorrectValuesCount <= n * (k - 1)) { throw new ArgumentException(NameOfExtension.nameof(() => minCorrectValuesCount) + " is to small"); } if (decodedCodeword == null) { throw new ArgumentNullException(NameOfExtension.nameof(() => decodedCodeword)); } if (decodedCodeword.Length != n) { throw new AggregateException(NameOfExtension.nameof(() => decodedCodeword)); } var decrementedK = k - 1; var temp = minCorrectValuesCount * minCorrectValuesCount - n * decrementedK; var rootsMultiplicity = 1 + (int)Math.Floor((n * decrementedK + Math.Sqrt(n * n * decrementedK * decrementedK + 4d * temp)) / (2d * temp)); var maxWeightedDegree = rootsMultiplicity * minCorrectValuesCount - 1; var interpolationPolynomial = _interpolationPolynomialBuilder.Build(new Tuple <int, int>(1, decrementedK), maxWeightedDegree, decodedCodeword, rootsMultiplicity); var possibleInformationPolynomials = _interpolationPolynomialFactorizator.Factorize(interpolationPolynomial, decrementedK); return(SelectCorrectInformationPolynomials(possibleInformationPolynomials, decodedCodeword, minCorrectValuesCount)); }
/// <summary> /// Method for bivariate interpolation polynomial building /// </summary> /// <param name="degreeWeight">Weight of bivariate monomials degree</param> /// <param name="maxWeightedDegree">Maximum value of bivariate monomial degree</param> /// <param name="roots">Roots of the interpolation polynomial</param> /// <param name="rootsMultiplicity">Multiplicity of bivariate polynomial's roots</param> /// <returns>Builded interpolation polynomial</returns> public BiVariablePolynomial Build( Tuple <int, int> degreeWeight, int maxWeightedDegree, Tuple <FieldElement, FieldElement>[] roots, int rootsMultiplicity) { if (degreeWeight == null) { throw new ArgumentNullException(NameOfExtension.nameof(() => degreeWeight)); } if (roots == null) { throw new ArgumentNullException(NameOfExtension.nameof(() => roots)); } if (roots.Length == 0) { throw new ArgumentException(NameOfExtension.nameof(() => roots) + " is empty"); } var field = roots[0].Item1.Field; var variableIndexByMonomial = new Dictionary <Tuple <int, int>, int>(); var monomialByVariableIndex = new Dictionary <int, Tuple <int, int> >(); var equationsSystem = BuildEquationsSystem(field, degreeWeight, maxWeightedDegree, maxWeightedDegree / degreeWeight.Item1, roots, rootsMultiplicity, variableIndexByMonomial, monomialByVariableIndex); var systemSolution = SolveEquationsSystem(field, variableIndexByMonomial.Count, equationsSystem); return(ConstructInterpolationPolynomial(field, systemSolution, monomialByVariableIndex)); }
/// <summary> /// Method for subtracting bivariate polynomial <paramref name="other"/> multiplied by <paramref name="b"/> from current bivariate polynomial /// </summary> /// <param name="b">Subtrahend multiplier</param> /// <param name="other">Subtrahend</param> public BiVariablePolynomial Subtract(FieldElement b, BiVariablePolynomial other) { if (Field.Equals(b.Field) == false) { throw new ArgumentException(NameOfExtension.nameof(() => b)); } if (Field.Equals(other.Field) == false) { throw new ArgumentException(NameOfExtension.nameof(() => other)); } if (b.Representation == 0) { return(this); } foreach (var otherCoefficient in other._coefficients) { FieldElement coeficientValue; if (_coefficients.TryGetValue(otherCoefficient.Key, out coeficientValue) == false) { coeficientValue = Field.Zero(); _coefficients[otherCoefficient.Key] = coeficientValue; } coeficientValue.Subtract(b * otherCoefficient.Value); if (coeficientValue.Representation == 0) { _coefficients.Remove(otherCoefficient.Key); } } return(this); }
/// <summary> /// Method Calculating results of replacement bivariate polynomial <paramref name="polynomial"/> variable y by value <paramref name="yValue"/> /// </summary> /// <param name="polynomial">Modified polynomial</param> /// <param name="yValue">Value for y variable</param> /// <returns>Replacement results</returns> public static Polynomial EvaluateY(this BiVariablePolynomial polynomial, FieldElement yValue) { if (polynomial == null) { throw new ArgumentNullException(NameOfExtension.nameof(() => polynomial)); } if (yValue == null) { throw new ArgumentNullException(NameOfExtension.nameof(() => yValue)); } if (polynomial.Field.Equals(yValue.Field) == false) { throw new AggregateException(NameOfExtension.nameof(() => yValue)); } var field = polynomial.Field; var resultCoefficients = new int[polynomial.MaxXDegree + 1]; foreach (var coefficient in polynomial) { resultCoefficients[coefficient.Key.Item1] = field.Add(resultCoefficients[coefficient.Key.Item1], field.Multiply(coefficient.Value.Representation, field.Pow(yValue.Representation, coefficient.Key.Item2))); } return(new Polynomial(field, resultCoefficients)); }
/// <summary> /// Converts source polynomial <paramref name="polynomial"/> to form p(x) = p_e(x^2)+x*p_o(x^2) /// </summary> /// <param name="polynomial">Polynomial for processing</param> /// <returns>Pair (p_e(x), p_o(x))</returns> public static Tuple <Polynomial, Polynomial> GetPolyphaseComponents(this Polynomial polynomial) { if (polynomial == null) { throw new ArgumentNullException(NameOfExtension.nameof(() => polynomial)); } var evenDegreesCoefficients = new List <int>(); var oddDegreesCoefficients = new List <int>(); for (var i = 0; i <= polynomial.Degree; i++) { if (i % 2 == 0) { evenDegreesCoefficients.Add(polynomial[i]); } else { oddDegreesCoefficients.Add(polynomial[i]); } } return(new Tuple <Polynomial, Polynomial>(new Polynomial(polynomial.Field, evenDegreesCoefficients.ToArray()), new Polynomial(polynomial.Field, oddDegreesCoefficients.ToArray()))); }
/// <summary> /// Constructor for creating field with order <paramref name="order"/> and irreducible polynomial <paramref name="irreduciblePolynomial"/> /// </summary> /// <param name="order">Field order</param> /// <param name="irreduciblePolynomial">Field irreducible polynomial</param> public PrimePowerOrderField(int order, GFPolynoms.Polynomial irreduciblePolynomial) { var analysisResult = AnalyzeOrder(order); if (analysisResult.Count != 1) { throw new ArgumentException("Field order isn't a prime number power"); } if (analysisResult.First().Value == 1) { throw new ArgumentException("Field order is a prime number"); } if (irreduciblePolynomial == null) { throw new ArgumentNullException(NameOfExtension.nameof(() => irreduciblePolynomial)); } if (irreduciblePolynomial.Field.Order != analysisResult.First().Key) { throw new ArgumentException("Irreducible polynomial isn't declared over properly field"); } if (irreduciblePolynomial.Degree != analysisResult.First().Value) { throw new ArgumentException("Irreducible polynomial degree isn't correct"); } if (Enumerable.Range(0, analysisResult.First().Key).Any(x => irreduciblePolynomial.Evaluate(x) == 0)) { throw new ArgumentException(string.Format("Polynomial {0} isn't irreducible", irreduciblePolynomial)); } Initialize(order, analysisResult.First().Key); IrreduciblePolynomial = irreduciblePolynomial; InitializeAdditionalStructures(); }
/// <summary> /// Method for multiplying current polynomial by polynomial <paramref name="b"/> /// </summary> /// <param name="b">Factor</param> public Polynomial Multiply(Polynomial b) { if (Field.Equals(b.Field) == false) { throw new ArgumentException(NameOfExtension.nameof(() => b)); } if (Degree == 0 && _coefficients[0] == 0 || b.Degree == 0 && b[0] == 0) { _coefficients = new List <int> { 0 }; return(this); } var newCoefficients = new List <int>(Enumerable.Repeat(0, Degree + b.Degree + 1)); for (var i = 0; i <= Degree; i++) { for (var j = 0; j <= b.Degree; j++) { newCoefficients[i + j] = Field.Add(newCoefficients[i + j], Field.Multiply(_coefficients[i], b[j])); } } _coefficients = newCoefficients; return(Truncate()); }
/// <summary> /// Method for shifting current polynomial by <paramref name="degreeDelta"/> positions to the right /// </summary> /// <param name="degreeDelta">Positions count for shifting</param> public Polynomial RightShift(int degreeDelta) { if (degreeDelta < 0) { throw new ArgumentException(NameOfExtension.nameof(() => degreeDelta)); } if (degreeDelta == 0 || Degree == 0 && _coefficients[0] == 0) { return(this); } var oldDegree = Degree; Enlarge(oldDegree + degreeDelta); for (var i = oldDegree; i >= 0; i--) { _coefficients[i + degreeDelta] = _coefficients[i]; if (i < degreeDelta) { _coefficients[i] = 0; } } return(this); }
/// <summary> /// Constructor for initializing internal structures of the decoder /// </summary> /// <param name="rsStandardDecoder">Implementation of the Reed-Solomon code standard decoder</param> /// <param name="linearSystemSolver">Implementation of the linear equations system solver</param> public RsBasedDecoder(IStandardDecoder rsStandardDecoder, ILinearSystemSolver linearSystemSolver) : base(linearSystemSolver) { if (rsStandardDecoder == null) { throw new ArgumentNullException(NameOfExtension.nameof(() => rsStandardDecoder)); } _rsStandardDecoder = rsStandardDecoder; }
/// <summary> /// Constructor for creation instance of decoder /// </summary> /// <param name="linearSystemSolver">Implementation of linear equations system solver contract</param> public BerlekampWelchDecoder(ILinearSystemSolver linearSystemSolver) { if (linearSystemSolver == null) { throw new ArgumentNullException(NameOfExtension.nameof(() => linearSystemSolver)); } _linearSystemSolver = linearSystemSolver; }
/// <summary> /// Constructor for initialization of internal objects /// </summary> /// <param name="linearSystemSolver">Implementation of the linear equations system solver</param> protected FixedDistanceCodesDecoderBase(ILinearSystemSolver linearSystemSolver) { if (linearSystemSolver == null) { throw new ArgumentNullException(NameOfExtension.nameof(() => linearSystemSolver)); } _linearSystemSolver = linearSystemSolver; }
/// <summary> /// Constructor for creation instance of the implementation of the wavelet code list decoding contract based on Guruswami–Sudan algorithm /// </summary> /// <param name="rsListDecoder">Implementation of the Reed-Solomon code list decoding contract</param> /// <param name="linearSystemSolver">Implementation of the linear equations system solver</param> public GsBasedDecoder(RsCodesTools.ListDecoder.IListDecoder rsListDecoder, ILinearSystemSolver linearSystemSolver) : base(linearSystemSolver) { if (rsListDecoder == null) { throw new ArgumentNullException(NameOfExtension.nameof(() => rsListDecoder)); } _rsListDecoder = rsListDecoder; }
/// <summary> /// Constructor for creating bivariate monomials comparer with degree weights <paramref name="degreeWeight"/> /// </summary> /// <param name="degreeWeight">Weights of monomial variable's powers</param> public BiVariableMonomialsComparer(Tuple <int, int> degreeWeight) { if (degreeWeight == null) { throw new ArgumentNullException(NameOfExtension.nameof(() => degreeWeight)); } _degreeWeight = degreeWeight; }
/// <summary> /// Constructor for builder creation /// </summary> /// <param name="gcdFinder">Implementation of GCD algorithm contract</param> public GcdBasedBuilder(IPolynomialsGcdFinder gcdFinder) { if (gcdFinder == null) { throw new ArgumentNullException(NameOfExtension.nameof(() => gcdFinder)); } _gcdFinder = gcdFinder; }
/// <summary> /// Method for validation arguments of the algorithm /// </summary> /// <param name="a">First argument</param> /// <param name="b">Second argument</param> private static void ValidateArguments(Polynomial a, Polynomial b) { if (a == null) { throw new ArgumentNullException(NameOfExtension.nameof(() => a)); } if (b == null) { throw new ArgumentNullException(NameOfExtension.nameof(() => b)); } }
/// <summary> /// Constructor for creating copy of the bivariate polynomial <paramref name="polynomial"/> /// </summary> /// <param name="polynomial">Copied bivariate polynomial</param> public BiVariablePolynomial(BiVariablePolynomial polynomial) { if (polynomial == null) { throw new ArgumentNullException(NameOfExtension.nameof(() => polynomial)); } Field = polynomial.Field; _coefficients = polynomial._coefficients.ToDictionary(x => x.Key, x => new FieldElement(x.Value)); }
/// <summary> /// Constructor for creating interpolation polynomial builder based on Kotter's algorithm /// </summary> /// <param name="combinationsCountCalculator">Implementation of combinations count calculator contract</param> public KotterAlgorithmBasedBuilder(ICombinationsCountCalculator combinationsCountCalculator) { if (combinationsCountCalculator == null) { throw new ArgumentNullException(NameOfExtension.nameof(() => combinationsCountCalculator)); } _combinationsCountCalculator = combinationsCountCalculator; _zeroMonomial = new Tuple <int, int>(0, 0); }
/// <summary> /// Method for finding irreducible polynomial degree <paramref name="degree"/> with coefficients from field with order <paramref name="fieldOrder"/> /// </summary> /// <param name="fieldOrder">Field order from which irreducible polynomials coefficients come</param> /// <param name="degree">Irreducible polynomial degree</param> /// <returns>Irreducible polynomial with specified properties</returns> public GFPolynoms.Polynomial Find(int fieldOrder, int degree) { if (degree < 2) { throw new ArgumentException(NameOfExtension.nameof(() => degree)); } var field = new PrimeOrderField(fieldOrder); var result = GenerateTemplateGFPolynomial(field, degree); return(result); }
/// <summary> /// Method for dividing field element <paramref name="a"/> by field element <paramref name="b"/> /// </summary> /// <param name="a">Dividend</param> /// <param name="b">Divider</param> /// <returns>Quotient</returns> public int Divide(int a, int b) { ValidateArguments(a, b); if (b == 0) { throw new ArgumentException(NameOfExtension.nameof(() => b)); } return(a == 0 ? 0 : ElementsByPowers[(PowersByElements[a] - PowersByElements[b] + Order - 1) % (Order - 1)]); }
/// <summary> /// Constructor for creation zero polynomial over field <paramref name="field"/> /// </summary> /// <param name="field">Field from which the coefficients of the polynomial</param> public Polynomial(GaloisField field) { if (field == null) { throw new ArgumentNullException(NameOfExtension.nameof(() => field)); } Field = field; _coefficients = new List <int> { 0 }; }
/// <summary> /// Method for subtracting polynomial <paramref name="b"/> from current /// </summary> /// <param name="b">Subtrahend</param> public Polynomial Subtract(Polynomial b) { if (Field.Equals(b.Field) == false) { throw new ArgumentException(NameOfExtension.nameof(() => b)); } Enlarge(b.Degree); for (var i = 0; i <= b.Degree; i++) { _coefficients[i] = Field.Subtract(_coefficients[i], b[i]); } return(Truncate()); }
/// <summary> /// Constructor for creating instance of interpolation polynomial builder /// </summary> /// <param name="combinationsCountCalculator">Implementation of combinations count calculator contract</param> /// <param name="linearSystemSolver">Implementation of linear systems solver contract</param> public SimplePolynomialBuilder(ICombinationsCountCalculator combinationsCountCalculator, ILinearSystemSolver linearSystemSolver) { if (combinationsCountCalculator == null) { throw new ArgumentNullException(NameOfExtension.nameof(() => combinationsCountCalculator)); } if (linearSystemSolver == null) { throw new ArgumentNullException(NameOfExtension.nameof(() => linearSystemSolver)); } _combinationsCountCalculator = combinationsCountCalculator; _linearSystemSolver = linearSystemSolver; }
/// <summary> /// Constructor for creation implementation of contract of generating polynomials builder /// </summary> /// <param name="complementaryFiltersBuilder">Implementation of contract of complementary filters builder</param> /// <param name="linearSystemSolver">Implementation of contract of linear equations system solver</param> public LiftingSchemeBasedBuilder(IComplementaryFiltersBuilder complementaryFiltersBuilder, ILinearSystemSolver linearSystemSolver) { if (complementaryFiltersBuilder == null) { throw new ArgumentNullException(NameOfExtension.nameof(() => complementaryFiltersBuilder)); } if (linearSystemSolver == null) { throw new ArgumentNullException(NameOfExtension.nameof(() => linearSystemSolver)); } _complementaryFiltersBuilder = complementaryFiltersBuilder; _linearSystemSolver = linearSystemSolver; }
public DevisionResult(Polynomial quotient, Polynomial remainder) { if (quotient == null) { throw new ArgumentNullException(NameOfExtension.nameof(() => quotient)); } if (remainder == null) { throw new ArgumentNullException(NameOfExtension.nameof(() => remainder)); } Quotient = quotient; Remainder = remainder; }
/// <summary> /// Constructor for creation /// </summary> /// <param name="interpolationPolynomialBuilder"></param> /// <param name="interpolationPolynomialFactorizator"></param> public GsDecoder(IInterpolationPolynomialBuilder interpolationPolynomialBuilder, IInterpolationPolynomialFactorizator interpolationPolynomialFactorizator) { if (interpolationPolynomialBuilder == null) { throw new ArgumentNullException(NameOfExtension.nameof(() => interpolationPolynomialBuilder)); } if (interpolationPolynomialFactorizator == null) { throw new ArgumentNullException(NameOfExtension.nameof(() => interpolationPolynomialFactorizator)); } _interpolationPolynomialBuilder = interpolationPolynomialBuilder; _interpolationPolynomialFactorizator = interpolationPolynomialFactorizator; }
/// <summary> /// Constructor for creating oject with greates common divisor calculation results /// </summary> /// <param name="gcd">Greates common divisor</param> /// <param name="quotients">Calculated quotients</param> public GcdWithQuotients(Polynomial gcd, Polynomial[] quotients) { if (gcd == null) { throw new ArgumentNullException(NameOfExtension.nameof(() => gcd)); } if (quotients == null) { throw new ArgumentNullException(NameOfExtension.nameof(() => quotients)); } Gcd = gcd; Quotients = quotients; }
/// <summary> /// Method for calculating polynomial value for variable value <paramref name="variableValue"/> /// </summary> /// <param name="variableValue">Variable value</param> /// <returns>Polynomial value</returns> public int Evaluate(int variableValue) { if (Field.IsFieldElement(variableValue) == false) { throw new ArgumentException(NameOfExtension.nameof(() => variableValue)); } var result = 0; for (var i = _coefficients.Count - 1; i >= 0; i--) { result = Field.Add(_coefficients[i], Field.Multiply(result, variableValue)); } return(result); }
/// <summary> /// Creates polynomial p(x) = p_e(x^2)+x*p_o(x^2) /// </summary> /// <param name="evenComponent">p_e(x)</param> /// <param name="oddComponent">p_o(x)</param> /// <returns>Reconstructed polynomial</returns> public static Polynomial CreateFormPolyphaseComponents(Polynomial evenComponent, Polynomial oddComponent) { if (evenComponent == null) { throw new ArgumentNullException(NameOfExtension.nameof(() => evenComponent)); } if (oddComponent == null) { throw new ArgumentNullException(NameOfExtension.nameof(() => oddComponent)); } if (evenComponent.Field.Equals(oddComponent.Field) == false) { throw new ArgumentException("Fields mismatch"); } return(evenComponent.RaiseVariableDegree(2) + (oddComponent.RaiseVariableDegree(2) >> 1)); }