Exemplo n.º 1
0
        /// <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;
            }
        }
Exemplo n.º 2
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 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);
        }
Exemplo n.º 3
0
        /// <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);
        }
Exemplo n.º 6
0
        /// <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();
        }
Exemplo n.º 9
0
        /// <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());
        }
Exemplo n.º 10
0
        /// <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);
        }
Exemplo n.º 11
0
        /// <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;
        }
Exemplo n.º 12
0
        /// <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;
        }
Exemplo n.º 14
0
        /// <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;
        }
Exemplo n.º 16
0
        /// <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;
        }
Exemplo n.º 17
0
 /// <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));
     }
 }
Exemplo n.º 18
0
        /// <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));
        }
Exemplo n.º 19
0
        /// <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);
        }
Exemplo n.º 20
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);
        }
Exemplo n.º 21
0
        /// <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)]);
        }
Exemplo n.º 22
0
        /// <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
            };
        }
Exemplo n.º 23
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;
        }
Exemplo n.º 26
0
            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;
            }
Exemplo n.º 27
0
        /// <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;
        }
Exemplo n.º 28
0
        /// <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;
        }
Exemplo n.º 29
0
        /// <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));
        }