Beispiel #1
0
        /// <summary>
        /// Method for calculatin (<paramref name="r"/>, <paramref name="s"/>) Hasse derivative value for bivariate polynomial <paramref name="polynomial"/> at point the (<paramref name="xValue"/>, <paramref name="yValue"/>)
        /// </summary>
        /// <param name="polynomial">Polynomial which Hasse derivative'll be calculated</param>
        /// <param name="r">Hasse derivative order by x variable</param>
        /// <param name="s">Hasse derivative order by y variable</param>
        /// <param name="xValue">Value for x variable</param>
        /// <param name="yValue">Value fro y variable</param>
        /// <param name="combinationsCountCalculator">Combinations calculator contract implementation</param>
        /// <param name="combinationsCache">Cache for storing calculated numbers of combinations</param>
        /// <returns>Hasse derivative value</returns>
        public static FieldElement CalculateHasseDerivative(this BiVariablePolynomial polynomial,
                                                            int r, int s, FieldElement xValue, FieldElement yValue,
                                                            ICombinationsCountCalculator combinationsCountCalculator, FieldElement[][] combinationsCache = null)
        {
            var field           = polynomial.Field;
            var derivativeValue = 0;

            foreach (var coefficient in polynomial)
            {
                if (coefficient.Key.Item1 < r || coefficient.Key.Item2 < s)
                {
                    continue;
                }

                var currentAddition = combinationsCountCalculator.Calculate(field, coefficient.Key.Item1, r, combinationsCache).Representation;
                currentAddition = field.Multiply(currentAddition,
                                                 combinationsCountCalculator.Calculate(field, coefficient.Key.Item2, s, combinationsCache).Representation);
                currentAddition = field.Multiply(currentAddition, coefficient.Value.Representation);
                currentAddition = field.Multiply(currentAddition, field.Pow(xValue.Representation, coefficient.Key.Item1 - r));
                currentAddition = field.Multiply(currentAddition, field.Pow(yValue.Representation, coefficient.Key.Item2 - s));

                derivativeValue = field.Add(derivativeValue, currentAddition);
            }

            return(new FieldElement(field, derivativeValue));
        }
        /// <summary>
        /// Method for creating linear equations system for finding interpolation polynomial
        /// </summary>
        /// <param name="field">Finite field from which system coefficients'll be taken</param>
        /// <param name="degreeWeight">Weight of bivariate monomials degree</param>
        /// <param name="maxWeightedDegree">Maximum value of bivariate monomial degree</param>
        /// <param name="maxXDegree">Maximum value of bivariate monomial x variable degree</param>
        /// <param name="roots">Roots of the interpolation polynomial</param>
        /// <param name="rootsMultiplicity">Multiplicity of bivariate polynomial's roots</param>
        /// <param name="variableIndexByMonomial">Mapping for bivariate monomials to their numbers</param>
        /// <param name="monomialByVariableIndex">Mapping from numbers to bivariate monomials</param>
        /// <returns>Linear system's representation</returns>
        private List <List <Tuple <int, FieldElement> > > BuildEquationsSystem(
            GaloisField field,
            Tuple <int, int> degreeWeight,
            int maxWeightedDegree,
            int maxXDegree,
            IEnumerable <Tuple <FieldElement, FieldElement> > roots,
            int rootsMultiplicity,
            IDictionary <Tuple <int, int>, int> variableIndexByMonomial,
            IDictionary <int, Tuple <int, int> > monomialByVariableIndex)
        {
            var equations         = new List <List <Tuple <int, FieldElement> > >();
            var combinationsCache = new FieldElement[Math.Max(maxWeightedDegree / degreeWeight.Item1, maxWeightedDegree / degreeWeight.Item2) + 1][]
                                    .MakeSquare();

            foreach (var root in roots)
            {
                for (var r = 0; r < rootsMultiplicity; r++)
                {
                    for (var s = 0; r + s < rootsMultiplicity; s++)
                    {
                        var equation = new List <Tuple <int, FieldElement> >();
                        equations.Add(equation);

                        for (var i = r; i <= maxXDegree; i++)
                        {
                            for (var j = s; i *degreeWeight.Item1 + j *degreeWeight.Item2 <= maxWeightedDegree; j++)
                            {
                                var variableIndex = GetVariableIndexByMonomial(variableIndexByMonomial, monomialByVariableIndex, i, j);
                                var coefficient   = _combinationsCountCalculator.Calculate(field, i, r, combinationsCache)
                                                    * _combinationsCountCalculator.Calculate(field, j, s, combinationsCache)
                                                    * FieldElement.Pow(root.Item1, i - r)
                                                    * FieldElement.Pow(root.Item2, j - s);

                                equation.Add(new Tuple <int, FieldElement>(variableIndex, coefficient));
                            }
                        }
                    }
                }
            }

            return(equations);
        }