예제 #1
0
        /// <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);
        }
예제 #2
0
        /// <summary>
        /// Aplica o lema do levantamento para elevar a factorização módulo m um número superior m'.
        /// </summary>
        /// <remarks>
        /// Não é realizada qualquer verificação da integridade dos dados associados aos parâmetros de entrada.
        /// Caso estes não sejam iniciados convenientemente, os resultados obtidos poderão não estar correctos.
        /// </remarks>
        /// <param name="status">Contém os dados de entrada.</param>
        /// <param name="iterationsNumber">O número de iterações.</param>
        /// <returns>Verdadeiro caso seja executada alguma iteração e falso caso contrário.</returns>
        /// <exception cref="ArgumentNullException">
        /// Se os dados de entrada forem passados com um apontador nulo.
        /// </exception>
        public bool Run(
            LinearLiftingStatus <T> status,
            int iterationsNumber)
        {
            if (status == null)
            {
                throw new ArgumentNullException("status");
            }
            else if (iterationsNumber < 1)
            {
                return(false);
            }
            else
            {
                var modularField     = this.modularFieldFactory.CreateInstance(status.InitializedFactorizationModulus);
                var polynomialDomain = this.polynomialDomainFactory.CreateInstance(
                    status.Polynom.VariableName,
                    modularField);
                var result = this.Initialize(status, polynomialDomain, modularField);
                var k      = 0;
                if (!status.FoundSolution &&
                    k < iterationsNumber)
                {
                    result = true;
                    do
                    {
                        var sigmaProd = polynomialDomain.Multiply(
                            status.SPol,
                            status.EPol);

                        var monicDivisionResult = this.GetMonicDivision(
                            sigmaProd,
                            status.WFactor,
                            modularField);

                        // Cálculo dos factores
                        var firstMultTemp  = polynomialDomain.Multiply(status.TPol, status.EPol);
                        var secondMultTemp = polynomialDomain.Multiply(
                            monicDivisionResult.Quotient,
                            status.UFactor);
                        status.UFactor = polynomialDomain.Add(status.UFactor, firstMultTemp);
                        status.UFactor = polynomialDomain.Add(status.UFactor, secondMultTemp);
                        status.WFactor = polynomialDomain.Add(status.WFactor, monicDivisionResult.Remainder);

                        // Cálculo dos restantes parâmetros
                        firstMultTemp  = polynomialDomain.Multiply(status.SPol, status.UFactor);
                        secondMultTemp = polynomialDomain.Multiply(status.TPol, status.WFactor);
                        var b = polynomialDomain.Add(firstMultTemp, secondMultTemp);
                        b = b.Add(
                            modularField.AdditiveInverse(modularField.MultiplicativeUnity),
                            modularField);
                        firstMultTemp       = polynomialDomain.Multiply(b, status.SPol);
                        monicDivisionResult = this.GetMonicDivision(
                            firstMultTemp,
                            status.WFactor,
                            modularField);

                        status.SPol = polynomialDomain.Add(
                            status.SPol,
                            polynomialDomain.AdditiveInverse(monicDivisionResult.Remainder));
                        firstMultTemp  = polynomialDomain.Multiply(status.TPol, b);
                        secondMultTemp = polynomialDomain.Multiply(status.UFactor, monicDivisionResult.Quotient);
                        firstMultTemp  = polynomialDomain.Add(firstMultTemp, secondMultTemp);
                        status.TPol    = polynomialDomain.Add(
                            status.TPol,
                            polynomialDomain.AdditiveInverse(firstMultTemp));

                        status.LiftedFactorizationModule = modularField.Module;
                        modularField.Module = this.integerNumber.Multiply(
                            modularField.Module,
                            modularField.Module);
                        status.InitializedFactorizationModulus = modularField.Module;

                        status.EPol = polynomialDomain.Add(
                            status.Polynom,
                            polynomialDomain.AdditiveInverse(polynomialDomain.Multiply(
                                                                 status.UFactor,
                                                                 status.WFactor)));
                        status.FoundSolution = polynomialDomain.IsAdditiveUnity(status.EPol);
                        ++k;
                    } while (!status.FoundSolution &&
                             k < iterationsNumber);
                }

                return(result);
            }
        }
예제 #3
0
        /// <summary>
        /// Contrói a árvore de factores.
        /// </summary>
        /// <param name="multiFactorLiftingStatus">Contém a factorização que se pretende elevar.</param>
        /// <param name="modularField">O corpo modular sobre o qual são efectuadas as operações.</param>
        /// <returns>A árvore.</returns>
        private Tree <LinearLiftingStatus <CoeffType> > MountFactorTree(
            MultiFactorLiftingStatus <CoeffType> multiFactorLiftingStatus,
            IModularField <CoeffType> modularField)
        {
            var tree             = new Tree <LinearLiftingStatus <CoeffType> >();
            var currentNodes     = new List <TreeNode <LinearLiftingStatus <CoeffType> > >();
            var factorEnumerator = multiFactorLiftingStatus.Factorization.Factors.GetEnumerator();

            if (factorEnumerator.MoveNext())
            {
                var factor = factorEnumerator.Current;
                if (!modularField.IsMultiplicativeUnity(multiFactorLiftingStatus.Factorization.IndependentCoeff))
                {
                    factor = factor.Multiply(multiFactorLiftingStatus.Factorization.IndependentCoeff, modularField);
                }

                currentNodes.Add(new TreeNode <LinearLiftingStatus <CoeffType> >(
                                     new LinearLiftingStatus <CoeffType>(factor, modularField.Module),
                                     tree,
                                     null));

                while (factorEnumerator.MoveNext())
                {
                    factor = factorEnumerator.Current;
                    currentNodes.Add(new TreeNode <LinearLiftingStatus <CoeffType> >(
                                         new LinearLiftingStatus <CoeffType>(factor, modularField.Module),
                                         tree,
                                         null));
                }
            }

            if (currentNodes.Count < 2)
            {
                return(null);
            }
            else
            {
                var temporaryNodes = new List <TreeNode <LinearLiftingStatus <CoeffType> > >();
                var count          = 0;
                while (currentNodes.Count > 1)
                {
                    temporaryNodes.Clear();
                    var i = 0;
                    while (i < currentNodes.Count)
                    {
                        var parentNode = default(TreeNode <LinearLiftingStatus <CoeffType> >);
                        var first      = currentNodes[i];
                        ++i;
                        if (i < currentNodes.Count)
                        {
                            var second  = currentNodes[i];
                            var product = first.NodeObject.Polynom.Multiply(
                                second.NodeObject.Polynom,
                                modularField);

                            var liftingStatus = new LinearLiftingStatus <CoeffType>(
                                product,
                                first.NodeObject.Polynom,
                                second.NodeObject.Polynom,
                                modularField.Module);

                            parentNode = new TreeNode <LinearLiftingStatus <CoeffType> >(
                                liftingStatus,
                                tree,
                                null);

                            first.InternalParent  = parentNode;
                            second.InternalParent = parentNode;
                            parentNode.Add(first);
                            parentNode.Add(second);
                            ++i;
                        }
                        else
                        {
                            parentNode = first;
                        }

                        temporaryNodes.Add(parentNode);
                    }

                    var swap = currentNodes;
                    currentNodes   = temporaryNodes;
                    temporaryNodes = swap;
                    ++count;
                }

                var lastNode = currentNodes[0];
                tree.InternalRootNode = lastNode;
                return(tree);
            }
        }