Пример #1
0
        /// <summary>
        /// Aplica o método da factorização em corpos finitos ao polinómio simples.
        /// </summary>
        /// <param name="polynom">O polinómio simples.</param>
        /// <param name="integerModule">O corpo responsável pelas operações sobre os coeficientes.</param>
        /// <param name="polynomField">O corpo responsável pelo produto de polinómios.</param>
        /// <param name="bachetBezoutAlgorithm">O objecto responsável pelo algoritmo de máximo divisor comum.</param>
        /// <returns>A lista dos factores.</returns>
        private FiniteFieldPolynomialFactorizationResult <CoeffType> Factorize(
            UnivariatePolynomialNormalForm <CoeffType> polynom,
            IModularField <CoeffType> integerModule,
            UnivarPolynomEuclideanDomain <CoeffType> polynomField,
            LagrangeAlgorithm <UnivariatePolynomialNormalForm <CoeffType> > bachetBezoutAlgorithm)
        {
            var result = new List <UnivariatePolynomialNormalForm <CoeffType> >();

            var polynomialStack = new Stack <UnivariatePolynomialNormalForm <CoeffType> >();
            var processedPols   = this.Process(
                polynom,
                result,
                integerModule,
                polynomField,
                bachetBezoutAlgorithm);

            foreach (var processedPol in processedPols)
            {
                polynomialStack.Push(processedPol);
            }

            while (polynomialStack.Count > 0)
            {
                var topPolynomial = polynomialStack.Pop();
                processedPols = this.Process(
                    topPolynomial,
                    result,
                    integerModule,
                    polynomField,
                    bachetBezoutAlgorithm);

                foreach (var processedPol in processedPols)
                {
                    polynomialStack.Push(processedPol);
                }
            }

            for (int i = 0; i < result.Count; ++i)
            {
                var leadingMon = result[i].GetLeadingCoefficient(integerModule);
                if (!integerModule.IsMultiplicativeUnity(leadingMon))
                {
                    var invLeadingMon = integerModule.MultiplicativeInverse(leadingMon);
                    result[i] = result[i].ApplyFunction(
                        c => integerModule.Multiply(c, invLeadingMon),
                        integerModule);
                }
            }

            var mainLeadingMon = polynom.GetLeadingCoefficient(integerModule);

            return(new FiniteFieldPolynomialFactorizationResult <CoeffType>(
                       mainLeadingMon,
                       result,
                       polynom));
        }
Пример #2
0
        /// <summary>
        /// Quadra um valor um número especificado de vezes.
        /// </summary>
        /// <param name="value">O valor.</param>
        /// <param name="times">O número de vezes.</param>
        /// <param name="modularField">O objecto responsável pelas operações modulares.</param>
        /// <returns>O resultado.</returns>
        private NumberType SquareValue(NumberType value, NumberType times, IModularField <NumberType> modularField)
        {
            var result = value;
            var i      = this.integerNumber.AdditiveUnity;

            for (; this.integerNumber.Compare(i, times) < 0; i = this.integerNumber.Successor(i))
            {
                result = modularField.Multiply(result, result);
            }

            return(result);
        }
Пример #3
0
        /// <summary>
        /// Tenta encontrar o índice i tal que temp^(2^i) seja congruente com a unidade.
        /// </summary>
        /// <param name="temp">O valor de temp.</param>
        /// <param name="upperLimit">O valor do limite superior.</param>
        /// <param name="modularField">O objecto responsável pelas operações modulares.</param>
        /// <returns>O índice procurado.</returns>
        private NumberType FindLowestIndex(NumberType temp, NumberType upperLimit, IModularField <NumberType> modularField)
        {
            var result    = this.integerNumber.MapFrom(-1);
            var innerTemp = temp;
            var i         = this.integerNumber.AdditiveUnity;

            for (; this.integerNumber.Compare(i, upperLimit) < 0; i = this.integerNumber.Successor(i))
            {
                if (this.integerNumber.IsMultiplicativeUnity(innerTemp))
                {
                    result = i;
                    i      = upperLimit;
                }
                else
                {
                    innerTemp = modularField.Multiply(innerTemp, innerTemp);
                }
            }

            return(result);
        }
Пример #4
0
        /// <summary>
        /// Obtém a divisão de um polinómio geral por um polinómio mónico.
        /// </summary>
        /// <param name="dividend">O polinómio geral.</param>
        /// <param name="divisor">O polinómio mónico.</param>
        /// <param name="modularField">
        /// O domínio sobre os quais as operações sobre os coeficientes são realizadas.
        /// </param>
        /// <returns>O resultado da divisão.</returns>
        private DomainResult <UnivariatePolynomialNormalForm <T> > GetMonicDivision(
            UnivariatePolynomialNormalForm <T> dividend,
            UnivariatePolynomialNormalForm <T> divisor,
            IModularField <T> modularField)
        {
            if (dividend.IsZero)
            {
                return(new DomainResult <UnivariatePolynomialNormalForm <T> >(
                           dividend,
                           dividend));
            }
            else if (divisor.Degree > dividend.Degree)
            {
                return(new DomainResult <UnivariatePolynomialNormalForm <T> >(
                           new UnivariatePolynomialNormalForm <T>(dividend.VariableName),
                           dividend));
            }
            else
            {
                var remainderSortedCoeffs  = dividend.GetOrderedCoefficients(Comparer <int> .Default);
                var divisorSorteCoeffs     = divisor.GetOrderedCoefficients(Comparer <int> .Default);
                var quotientCoeffs         = new UnivariatePolynomialNormalForm <T>(dividend.VariableName);
                var remainderLeadingDegree = remainderSortedCoeffs.Keys[remainderSortedCoeffs.Keys.Count - 1];
                var divisorLeadingDegree   = divisorSorteCoeffs.Keys[divisorSorteCoeffs.Keys.Count - 1];
                while (remainderLeadingDegree >= divisorLeadingDegree && remainderSortedCoeffs.Count > 0)
                {
                    var remainderLeadingCoeff = remainderSortedCoeffs[remainderLeadingDegree];
                    var differenceDegree      = remainderLeadingDegree - divisorLeadingDegree;
                    quotientCoeffs = quotientCoeffs.Add(remainderLeadingCoeff, differenceDegree, modularField);
                    remainderSortedCoeffs.Remove(remainderLeadingDegree);
                    for (int i = 0; i < divisorSorteCoeffs.Keys.Count - 1; ++i)
                    {
                        var currentDivisorDegree = divisorSorteCoeffs.Keys[i];
                        var currentCoeff         = modularField.Multiply(
                            divisorSorteCoeffs[currentDivisorDegree],
                            remainderLeadingCoeff);
                        currentDivisorDegree += differenceDegree;
                        var addCoeff = default(T);
                        if (remainderSortedCoeffs.TryGetValue(currentDivisorDegree, out addCoeff))
                        {
                            addCoeff = modularField.Add(
                                addCoeff,
                                modularField.AdditiveInverse(currentCoeff));
                            if (modularField.IsAdditiveUnity(addCoeff))
                            {
                                remainderSortedCoeffs.Remove(currentDivisorDegree);
                            }
                            else
                            {
                                remainderSortedCoeffs[currentDivisorDegree] = addCoeff;
                            }
                        }
                        else
                        {
                            remainderSortedCoeffs.Add(
                                currentDivisorDegree,
                                modularField.AdditiveInverse(currentCoeff));
                        }
                    }

                    if (remainderSortedCoeffs.Count > 0)
                    {
                        remainderLeadingDegree = remainderSortedCoeffs.Keys[remainderSortedCoeffs.Keys.Count - 1];
                    }
                    else
                    {
                        remainderLeadingDegree = 0;
                    }
                }

                var remainder = new UnivariatePolynomialNormalForm <T>(
                    remainderSortedCoeffs,
                    dividend.VariableName,
                    modularField);
                return(new DomainResult <UnivariatePolynomialNormalForm <T> >(
                           quotientCoeffs,
                           remainder));
            }
        }