/// <summary> /// Method for transforming linear system matrix into rectangular form and finding system solution /// </summary> /// <param name="field">Finite field from which system coefficients were taken</param> /// <param name="variablesCount">Variables count</param> /// <param name="equationsSystem">Linear system's representation</param> /// <returns>Linear system's solution</returns> private SystemSolution SolveEquationsSystem( GaloisField field, int variablesCount, IReadOnlyList <List <Tuple <int, FieldElement> > > equationsSystem) { var linearSystemMatrix = new FieldElement[equationsSystem.Count, variablesCount]; var zeros = new FieldElement[equationsSystem.Count]; for (var i = 0; i < equationsSystem.Count; i++) { zeros[i] = field.Zero(); for (var j = 0; j < variablesCount; j++) { linearSystemMatrix[i, j] = field.Zero(); } } for (var i = 0; i < equationsSystem.Count; i++) { for (var j = 0; j < equationsSystem[i].Count; j++) { linearSystemMatrix[i, equationsSystem[i][j].Item1] = equationsSystem[i][j].Item2; } } return(_linearSystemSolver.Solve(linearSystemMatrix, zeros)); }
/// <summary> /// Method for calculating number of combinations from <paramref name="n"/> by <paramref name="k"/> over field <paramref name="field"/> /// </summary> /// <param name="field">Field over which combinations count'll calculated</param> /// <param name="n">Total elements count</param> /// <param name="k">Selected elements count</param> /// <param name="combinationsCache">Cache for storing combinations count</param> /// <returns>Combinations count</returns> public FieldElement Calculate(GaloisField field, int n, int k, FieldElement[][] combinationsCache = null) { var combinationsCount = combinationsCache?[n][k]; if (combinationsCount == null) { if (k == 0 || n == k) { combinationsCount = field.One(); } else { if (n < k) { combinationsCount = field.Zero(); } else { combinationsCount = Calculate(field, n - 1, k - 1, combinationsCache) + Calculate(field, n - 1, k, combinationsCache); } } if (combinationsCache != null && n < combinationsCache.Length && k < combinationsCache[n].Length) { combinationsCache[n][k] = combinationsCount; } } return(combinationsCount); }
private static IEnumerable <FieldElement[]> PlaceErrors(GaloisField field, int codewordLength, IReadOnlyList <int> errorsPositions, IList <int> noiseValue, int currentErrorPosition) { if (currentErrorPosition == errorsPositions.Count) { var additiveNoise = Enumerable.Repeat(field.Zero(), codewordLength).ToArray(); for (var i = 0; i < errorsPositions.Count; i++) { additiveNoise[errorsPositions[i]] = field.CreateElement(noiseValue[i]); } yield return(additiveNoise); yield break; } for (var i = noiseValue[currentErrorPosition]; i < field.Order; i++) { noiseValue[currentErrorPosition] = i; foreach (var additiveNoise in PlaceErrors(field, codewordLength, errorsPositions, noiseValue, currentErrorPosition + 1)) { yield return(additiveNoise); } } noiseValue[currentErrorPosition] = 1; }
/// <summary> /// Indexing property for obtain bivariate polynomial coefficient by <paramref name="monomial"/> /// </summary> /// <param name="monomial">Monomial which coefficient is required</param> /// <returns>Bivariate polynomial coefficient</returns> public FieldElement this[Tuple <int, int> monomial] { get { FieldElement coefficient; if (_coefficients.TryGetValue(monomial, out coefficient) == false) { coefficient = Field.Zero(); } return(coefficient); } set { if (Field.Equals(value.Field) == false) { throw new ArgumentException("Incorrect field"); } if (value.Representation != 0) { _coefficients[monomial] = value; } else { _coefficients.Remove(monomial); } } }
static BiVariablePolynomialTests() { Gf5 = new PrimeOrderField(5); var polynomialForEvoluation = new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(1, 1)] = new FieldElement(Gf5, 2), [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 1), [new Tuple <int, int>(2, 0)] = new FieldElement(Gf5, 1), [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 1), [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 4) }; EvaluateTestsData = new[] { new object[] { polynomialForEvoluation, new FieldElement(Gf5, 1), new FieldElement(Gf5, 3), Gf5.Zero() }, new object[] { polynomialForEvoluation, new FieldElement(Gf5, 2), new FieldElement(Gf5, 4), Gf5.Zero() }, new object[] { polynomialForEvoluation, new FieldElement(Gf5, 3), new FieldElement(Gf5, 2), Gf5.Zero() }, new object[] { polynomialForEvoluation, new FieldElement(Gf5, 2), new FieldElement(Gf5, 3), Gf5.Zero() }, }; AddTestsData = new[] { new object[] { new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 2), [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 3) }, new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 3), [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 4) }, new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 3), [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 4) } }, new object[] { new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 2), [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 3), [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 4) }, new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 4), [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 4), [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 4) }, new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 2), [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 3), [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 1) } } }; SubtractTestsData = new[] { new object[] { new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 2), [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 3) }, new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 3), [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 4) }, new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 4), [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 3), [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 1) } }, new object[] { new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 2), [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 3), [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 4) }, new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 4), [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 4), [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 4) }, new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 3), [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 4) } } }; MultiplyPolynomialsTestsData = new[] { new object[] { new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 2), [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 3) }, new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 3), [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 4) }, new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 1), [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 4), [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 3), [new Tuple <int, int>(1, 1)] = new FieldElement(Gf5, 2) } }, new object[] { new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 2), [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 3), [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 4) }, new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 4), [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 1), [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 2) }, new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 3), [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 4), [new Tuple <int, int>(2, 0)] = new FieldElement(Gf5, 3), [new Tuple <int, int>(0, 2)] = new FieldElement(Gf5, 3) } }, new object[] { new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 2), [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 3), [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 4) }, new BiVariablePolynomial(Gf5), new BiVariablePolynomial(Gf5) } }; var polynomialForMultiplication = new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 3), [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 2), [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 4), [new Tuple <int, int>(1, 1)] = new FieldElement(Gf5, 1) }; MultiplyByFieldElementTestsData = new[] { new object[] { polynomialForMultiplication, Gf5.Zero(), new BiVariablePolynomial(Gf5) }, new object[] { polynomialForMultiplication, new FieldElement(Gf5, 2), new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 1), [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 4), [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 3), [new Tuple <int, int>(1, 1)] = new FieldElement(Gf5, 2) } } }; SubstitutionTestsData = new[] { new object[] { new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 1), [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 3), [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 2) }, new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 1) }, new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 3), [new Tuple <int, int>(1, 1)] = new FieldElement(Gf5, 1) }, new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 2), [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 3), [new Tuple <int, int>(1, 1)] = new FieldElement(Gf5, 2) } }, new object[] { new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 1), [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 2), [new Tuple <int, int>(2, 0)] = new FieldElement(Gf5, 1), [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 3), [new Tuple <int, int>(1, 1)] = new FieldElement(Gf5, 1) }, new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 1), [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 1) }, new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 2), [new Tuple <int, int>(1, 1)] = new FieldElement(Gf5, 1) }, new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 2), [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 1), [new Tuple <int, int>(2, 0)] = new FieldElement(Gf5, 1), [new Tuple <int, int>(1, 1)] = new FieldElement(Gf5, 4), [new Tuple <int, int>(2, 1)] = new FieldElement(Gf5, 1) } }, new object[] { new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 1), [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 3), [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 2) }, new BiVariablePolynomial(Gf5), new BiVariablePolynomial(Gf5), new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 1) } } }; DivideByXDegreeTestsData = new[] { new object[] { new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 2), [new Tuple <int, int>(2, 0)] = new FieldElement(Gf5, 1), [new Tuple <int, int>(1, 1)] = new FieldElement(Gf5, 3) }, new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 2), [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 1), [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 3) } }, new object[] { new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 2), [new Tuple <int, int>(2, 0)] = new FieldElement(Gf5, 1), [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 3) }, new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 2), [new Tuple <int, int>(2, 0)] = new FieldElement(Gf5, 1), [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 3) } }, new object[] { new BiVariablePolynomial(Gf5), new BiVariablePolynomial(Gf5) } }; EvaluateXTestsData = new[] { new object[] { new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 3), [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 2), [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 1) }, new FieldElement(Gf5, 1), new Polynomial(Gf5, 0, 1) }, new object[] { new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 3), [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 2), [new Tuple <int, int>(1, 1)] = new FieldElement(Gf5, 1) }, Gf5.Zero(), new Polynomial(Gf5, 3) }, new object[] { new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 2), [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 3), [new Tuple <int, int>(2, 0)] = new FieldElement(Gf5, 2), [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 1), [new Tuple <int, int>(1, 1)] = new FieldElement(Gf5, 1), [new Tuple <int, int>(0, 2)] = new FieldElement(Gf5, 1) }, new FieldElement(Gf5, 3), new Polynomial(Gf5, 4, 4, 1) } }; EvaluateYTestsData = new[] { new object[] { new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 3), [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 1), [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 2) }, new FieldElement(Gf5, 1), new Polynomial(Gf5, 0, 1) }, new object[] { new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 3), [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 2), [new Tuple <int, int>(1, 1)] = new FieldElement(Gf5, 1) }, Gf5.Zero(), new Polynomial(Gf5, 3) }, new object[] { new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 2), [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 3), [new Tuple <int, int>(2, 0)] = new FieldElement(Gf5, 2), [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 1), [new Tuple <int, int>(1, 1)] = new FieldElement(Gf5, 1), [new Tuple <int, int>(0, 2)] = new FieldElement(Gf5, 1) }, new FieldElement(Gf5, 2), new Polynomial(Gf5, 3, 0, 2) } }; CalculateHasseDerivativeTestsData = new[] { new object[] { new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 2), [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 2), [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 2), [new Tuple <int, int>(2, 0)] = new FieldElement(Gf5, 1), [new Tuple <int, int>(0, 2)] = new FieldElement(Gf5, 1) }, 1, 1, Gf5.One(), Gf5.One(), Gf5.Zero() }, new object[] { new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 2), [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 2), [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 2), [new Tuple <int, int>(2, 2)] = new FieldElement(Gf5, 1) }, 1, 1, Gf5.One(), Gf5.One(), new FieldElement(Gf5, 4) }, new object[] { new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(0, 0)] = new FieldElement(Gf5, 2), [new Tuple <int, int>(1, 0)] = new FieldElement(Gf5, 2), [new Tuple <int, int>(0, 1)] = new FieldElement(Gf5, 2), [new Tuple <int, int>(2, 2)] = new FieldElement(Gf5, 1) }, 2, 1, Gf5.One(), Gf5.One(), new FieldElement(Gf5, 2) } }; }
static BiVariablePolynomialTests() { Gf5 = new PrimeOrderField(5); var polynomialForEvoluation = new BiVariablePolynomial(Gf5) { [new Tuple <int, int>(1, 1)] = Gf5.CreateElement(2), [new Tuple <int, int>(0, 1)] = Gf5.One(), [new Tuple <int, int>(2, 0)] = Gf5.One(), [new Tuple <int, int>(1, 0)] = Gf5.One(), [new Tuple <int, int>(0, 0)] = Gf5.CreateElement(4) }; EvaluateTestsData = new TheoryData <EvaluationTestCase> { new EvaluationTestCase { Polynomial = polynomialForEvoluation, XValue = Gf5.One(), YValue = Gf5.CreateElement(3), Expected = Gf5.Zero() }, new EvaluationTestCase { Polynomial = polynomialForEvoluation, XValue = Gf5.CreateElement(2), YValue = new FieldElement(Gf5, 4), Expected = Gf5.Zero() }, new EvaluationTestCase { Polynomial = polynomialForEvoluation, XValue = Gf5.CreateElement(3), YValue = Gf5.CreateElement(2), Expected = Gf5.Zero() }, new EvaluationTestCase { Polynomial = polynomialForEvoluation, XValue = Gf5.CreateElement(2), YValue = Gf5.CreateElement(3), Expected = Gf5.Zero() }, }; AddTestsData = new TheoryData <BinaryOperationTestCase> { new BinaryOperationTestCase { FirstOperand = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(2), [Tuple.Create(1, 0)] = Gf5.CreateElement(3) }, SecondOperand = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(3), [Tuple.Create(0, 1)] = Gf5.CreateElement(4) }, Expected = new BiVariablePolynomial(Gf5) { [Tuple.Create(1, 0)] = Gf5.CreateElement(3), [Tuple.Create(0, 1)] = Gf5.CreateElement(4) } }, new BinaryOperationTestCase { FirstOperand = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(2), [Tuple.Create(1, 0)] = Gf5.CreateElement(3), [Tuple.Create(0, 1)] = Gf5.CreateElement(4) }, SecondOperand = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 1)] = Gf5.CreateElement(4), [Tuple.Create(0, 0)] = Gf5.CreateElement(4), [Tuple.Create(1, 0)] = Gf5.CreateElement(4) }, Expected = new BiVariablePolynomial(Gf5) { [Tuple.Create(1, 0)] = Gf5.CreateElement(2), [Tuple.Create(0, 1)] = Gf5.CreateElement(3), [Tuple.Create(0, 0)] = Gf5.One() } } }; SubtractTestsData = new TheoryData <BinaryOperationTestCase> { new BinaryOperationTestCase { FirstOperand = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(2), [Tuple.Create(1, 0)] = Gf5.CreateElement(3) }, SecondOperand = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(3), [Tuple.Create(0, 1)] = Gf5.CreateElement(4) }, Expected = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(4), [Tuple.Create(1, 0)] = Gf5.CreateElement(3), [Tuple.Create(0, 1)] = Gf5.One() } }, new BinaryOperationTestCase { FirstOperand = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(2), [Tuple.Create(1, 0)] = Gf5.CreateElement(3), [Tuple.Create(0, 1)] = Gf5.CreateElement(4) }, SecondOperand = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(4), [Tuple.Create(1, 0)] = Gf5.CreateElement(4), [Tuple.Create(0, 1)] = Gf5.CreateElement(4) }, Expected = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(3), [Tuple.Create(1, 0)] = Gf5.CreateElement(4) } } }; MultiplyPolynomialsTestsData = new TheoryData <BinaryOperationTestCase> { new BinaryOperationTestCase { FirstOperand = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(2), [Tuple.Create(1, 0)] = Gf5.CreateElement(3) }, SecondOperand = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(3), [Tuple.Create(0, 1)] = Gf5.CreateElement(4) }, Expected = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.One(), [Tuple.Create(1, 0)] = Gf5.CreateElement(4), [Tuple.Create(0, 1)] = Gf5.CreateElement(3), [Tuple.Create(1, 1)] = Gf5.CreateElement(2) } }, new BinaryOperationTestCase { FirstOperand = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(2), [Tuple.Create(1, 0)] = Gf5.CreateElement(3), [Tuple.Create(0, 1)] = Gf5.CreateElement(4) }, SecondOperand = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(4), [Tuple.Create(1, 0)] = Gf5.One(), [Tuple.Create(0, 1)] = Gf5.CreateElement(2) }, Expected = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(3), [Tuple.Create(1, 0)] = Gf5.CreateElement(4), [Tuple.Create(2, 0)] = Gf5.CreateElement(3), [Tuple.Create(0, 2)] = Gf5.CreateElement(3) } }, new BinaryOperationTestCase { FirstOperand = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(2), [Tuple.Create(1, 0)] = Gf5.CreateElement(3), [Tuple.Create(0, 1)] = Gf5.CreateElement(4) }, SecondOperand = new BiVariablePolynomial(Gf5), Expected = new BiVariablePolynomial(Gf5) } }; var polynomialForMultiplication = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(3), [Tuple.Create(1, 0)] = Gf5.CreateElement(2), [Tuple.Create(0, 1)] = Gf5.CreateElement(4), [Tuple.Create(1, 1)] = Gf5.One() }; MultiplyByFieldElementTestsData = new TheoryData <MultiplicationByFieldElementTestCase> { new MultiplicationByFieldElementTestCase { Polynomial = polynomialForMultiplication, Multiplier = Gf5.Zero(), Expected = new BiVariablePolynomial(Gf5) }, new MultiplicationByFieldElementTestCase { Polynomial = polynomialForMultiplication, Multiplier = Gf5.CreateElement(2), Expected = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.One(), [Tuple.Create(1, 0)] = Gf5.CreateElement(4), [Tuple.Create(0, 1)] = Gf5.CreateElement(3), [Tuple.Create(1, 1)] = Gf5.CreateElement(2) } } }; SubstitutionTestsData = new TheoryData <SubstitutionTestCase> { new SubstitutionTestCase { Polynomial = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.One(), [Tuple.Create(1, 0)] = Gf5.CreateElement(3), [Tuple.Create(0, 1)] = Gf5.CreateElement(2) }, XSubstitution = new BiVariablePolynomial(Gf5) { [Tuple.Create(1, 0)] = Gf5.One() }, YSubstitution = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(3), [Tuple.Create(1, 1)] = Gf5.One() }, Expected = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(2), [Tuple.Create(1, 0)] = Gf5.CreateElement(3), [Tuple.Create(1, 1)] = Gf5.CreateElement(2) } }, new SubstitutionTestCase { Polynomial = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.One(), [Tuple.Create(1, 0)] = Gf5.CreateElement(2), [Tuple.Create(2, 0)] = Gf5.One(), [Tuple.Create(0, 1)] = Gf5.CreateElement(3), [Tuple.Create(1, 1)] = Gf5.One() }, XSubstitution = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.One(), [Tuple.Create(1, 0)] = Gf5.One() }, YSubstitution = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(2), [Tuple.Create(1, 1)] = Gf5.One() }, Expected = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(2), [Tuple.Create(1, 0)] = Gf5.One(), [Tuple.Create(2, 0)] = Gf5.One(), [Tuple.Create(1, 1)] = Gf5.CreateElement(4), [Tuple.Create(2, 1)] = Gf5.One() } }, new SubstitutionTestCase { Polynomial = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.One(), [Tuple.Create(1, 0)] = Gf5.CreateElement(3), [Tuple.Create(0, 1)] = Gf5.CreateElement(2) }, XSubstitution = new BiVariablePolynomial(Gf5), YSubstitution = new BiVariablePolynomial(Gf5), Expected = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.One() } } }; DivideByXDegreeTestsData = new TheoryData <DivideByXDegreeTestCase> { new DivideByXDegreeTestCase { Polynomial = new BiVariablePolynomial(Gf5) { [Tuple.Create(1, 0)] = Gf5.CreateElement(2), [Tuple.Create(2, 0)] = Gf5.One(), [Tuple.Create(1, 1)] = Gf5.CreateElement(3) }, Expected = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(2), [Tuple.Create(1, 0)] = Gf5.One(), [Tuple.Create(0, 1)] = Gf5.CreateElement(3) } }, new DivideByXDegreeTestCase { Polynomial = new BiVariablePolynomial(Gf5) { [Tuple.Create(1, 0)] = Gf5.CreateElement(2), [Tuple.Create(2, 0)] = Gf5.One(), [Tuple.Create(0, 1)] = Gf5.CreateElement(3) }, Expected = new BiVariablePolynomial(Gf5) { [Tuple.Create(1, 0)] = Gf5.CreateElement(2), [Tuple.Create(2, 0)] = Gf5.One(), [Tuple.Create(0, 1)] = Gf5.CreateElement(3) } }, new DivideByXDegreeTestCase { Polynomial = new BiVariablePolynomial(Gf5), Expected = new BiVariablePolynomial(Gf5) } }; EvaluateXTestsData = new TheoryData <PartialEvaluationTestCase> { new PartialEvaluationTestCase { Polynomial = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(3), [Tuple.Create(1, 0)] = Gf5.CreateElement(2), [Tuple.Create(0, 1)] = Gf5.One() }, VariableValue = Gf5.One(), Expected = new Polynomial(Gf5, 0, 1) }, new PartialEvaluationTestCase { Polynomial = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(3), [Tuple.Create(1, 0)] = Gf5.CreateElement(2), [Tuple.Create(1, 1)] = Gf5.One() }, VariableValue = Gf5.Zero(), Expected = new Polynomial(Gf5, 3) }, new PartialEvaluationTestCase { Polynomial = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(2), [Tuple.Create(1, 0)] = Gf5.CreateElement(3), [Tuple.Create(2, 0)] = Gf5.CreateElement(2), [Tuple.Create(0, 1)] = Gf5.One(), [Tuple.Create(1, 1)] = Gf5.One(), [Tuple.Create(0, 2)] = Gf5.One() }, VariableValue = Gf5.CreateElement(3), Expected = new Polynomial(Gf5, 4, 4, 1) } }; EvaluateYTestsData = new TheoryData <PartialEvaluationTestCase> { new PartialEvaluationTestCase { Polynomial = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(3), [Tuple.Create(1, 0)] = Gf5.One(), [Tuple.Create(0, 1)] = Gf5.CreateElement(2) }, VariableValue = Gf5.One(), Expected = new Polynomial(Gf5, 0, 1) }, new PartialEvaluationTestCase { Polynomial = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(3), [Tuple.Create(0, 1)] = Gf5.CreateElement(2), [Tuple.Create(1, 1)] = Gf5.One() }, VariableValue = Gf5.Zero(), Expected = new Polynomial(Gf5, 3) }, new PartialEvaluationTestCase { Polynomial = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(2), [Tuple.Create(1, 0)] = Gf5.CreateElement(3), [Tuple.Create(2, 0)] = Gf5.CreateElement(2), [Tuple.Create(0, 1)] = Gf5.One(), [Tuple.Create(1, 1)] = Gf5.One(), [Tuple.Create(0, 2)] = Gf5.One() }, VariableValue = Gf5.CreateElement(2), Expected = new Polynomial(Gf5, 3, 0, 2) } }; HasseDerivativeCalculationTestsData = new TheoryData <HasseDerivativeCalculationTestCase> { new HasseDerivativeCalculationTestCase { Polynomial = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(2), [Tuple.Create(1, 0)] = Gf5.CreateElement(2), [Tuple.Create(0, 1)] = Gf5.CreateElement(2), [Tuple.Create(2, 0)] = Gf5.One(), [Tuple.Create(0, 2)] = Gf5.One() }, R = 1, S = 1, XValue = Gf5.One(), YValue = Gf5.One(), Expected = Gf5.Zero() }, new HasseDerivativeCalculationTestCase { Polynomial = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(2), [Tuple.Create(1, 0)] = Gf5.CreateElement(2), [Tuple.Create(0, 1)] = Gf5.CreateElement(2), [Tuple.Create(2, 2)] = Gf5.One() }, R = 1, S = 1, XValue = Gf5.One(), YValue = Gf5.One(), Expected = new FieldElement(Gf5, 4) }, new HasseDerivativeCalculationTestCase { Polynomial = new BiVariablePolynomial(Gf5) { [Tuple.Create(0, 0)] = Gf5.CreateElement(2), [Tuple.Create(1, 0)] = Gf5.CreateElement(2), [Tuple.Create(0, 1)] = Gf5.CreateElement(2), [Tuple.Create(2, 2)] = Gf5.One() }, R = 2, S = 1, XValue = Gf5.One(), YValue = Gf5.One(), Expected = Gf5.CreateElement(2) } }; }