Exemple #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));
        }
        /// <summary>
        /// Inicialia o estado do algoritmo caso seja aplicável.
        /// </summary>
        /// <param name="status">O estado a ser tratado.</param>
        /// <param name="polynomialDomain">O domínio polinomial.</param>
        /// <param name="modularField">O corpo modular.</param>
        /// <returns>Verdadeiro caso se verifique alguma inicialização e falso caso contrário.</returns>
        /// <exception cref="ArgumentNullException">Se o estado for nulo.</exception>
        private bool Initialize(
            LinearLiftingStatus <T> status,
            IEuclidenDomain <UnivariatePolynomialNormalForm <T> > polynomialDomain,
            IModularField <T> modularField)
        {
            var result = false;

            if (status.NotInitialized)
            {
                var leadingCoeff = status.W1Factor.GetLeadingCoefficient(modularField);
                if (modularField.IsMultiplicativeUnity(leadingCoeff))
                {
                    result = true;

                    var domainAlg = new LagrangeAlgorithm <UnivariatePolynomialNormalForm <T> >(
                        polynomialDomain);
                    var domainResult = domainAlg.Run(status.U1Factor, status.W1Factor);

                    var invGcd = modularField.MultiplicativeInverse(
                        domainResult.GreatestCommonDivisor.GetAsValue(modularField));
                    status.SPol = domainResult.FirstFactor.Multiply(
                        invGcd,
                        modularField);
                    status.TPol = domainResult.SecondFactor.Multiply(
                        invGcd,
                        modularField);

                    status.UFactor = status.U1Factor;
                    status.WFactor = status.W1Factor;

                    modularField.Module = this.integerNumber.Multiply(modularField.Module, modularField.Module);
                    status.InitializedFactorizationModulus = modularField.Module;
                    var ePol = polynomialDomain.Multiply(status.UFactor, status.WFactor);
                    ePol = polynomialDomain.Add(
                        status.Polynom,
                        polynomialDomain.AdditiveInverse(ePol));
                    status.EPol = ePol;

                    status.NotInitialized = false;
                }
                else
                {
                    throw new MathematicsException(
                              "The W factor in lifting algorithm must be a monic polynomial.");
                }
            }

            return(result);
        }