Example #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));
        }
Example #2
0
 /// <summary>
 /// Cria instâncias de objectos do tipo <see cref="ModularBigIntegerField"/>.
 /// </summary>
 /// <remarks>
 /// A determinação da inversa multiplicativa é efectuada por intermédio de algoritmos relacionados
 /// com o algoritmo que permite determinar o máximo divisor comum. Neste caso, é necessário indicar
 /// qual será o algoritmo responsável por essa operação.
 /// </remarks>
 /// <param name="module">O módulo.</param>
 /// <exception cref="ArgumentException">
 /// Se o módulo for 0, 1, ou -1.
 /// </exception>
 public ModularBigIntegerField(BigInteger module)
 {
     if (module == 0 || module == 1 || module == -1)
     {
         throw new ArgumentException("Module can't neither 0, 1 nor -1.");
     }
     else
     {
         this.module           = module;
         this.inverseAlgorithm = new LagrangeAlgorithm <BigInteger>(
             new BigIntegerDomain());
     }
 }
 /// <summary>
 /// Cria instâncias de objectos do tipo <see cref="ModularSymmetricIntField"/>.
 /// </summary>
 /// <remarks>
 /// A determinação da inversa multiplicativa é efectuada por intermédio de algoritmos relacionados
 /// com o algoritmo que permite determinar o máximo divisor comum. Neste caso, é necessário indicar
 /// qual será o algoritmo responsável por essa operação.
 /// </remarks>
 /// <param name="modulus">O módulo.</param>
 /// <exception cref="ArgumentException">
 /// Se o módulo for 0, 1 ou -1.
 /// </exception>
 public ModularSymmetricIntField(int modulus)
 {
     if (modulus == 0 || modulus == 1 || modulus == -1)
     {
         throw new ArgumentException("Module can't neither 0, 1 nor -1.");
     }
     else
     {
         this.modulus          = modulus;
         this.halfModulus      = modulus >> 1;
         this.inverseAlgorithm = new LagrangeAlgorithm <int>(
             new IntegerDomain());
     }
 }
Example #4
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);
        }
Example #5
0
        /// <summary>
        /// Executa o algoritmo sobre o polinómio com coeficientes inteiros.
        /// </summary>
        /// <remarks>
        /// O polinómio tem de ser livre de quadrados. Caso contrário, o resultado da aplicação do algoritmo
        /// é imprevisível.
        /// </remarks>
        /// <param name="polymomial">O polinómio.</param>
        /// <param name="modularField">O corpo modular.</param>
        /// <returns>A factorização do polinómio.</returns>
        public FiniteFieldPolynomialFactorizationResult <CoeffType> Run(
            UnivariatePolynomialNormalForm <CoeffType> polymomial,
            IModularField <CoeffType> modularField)
        {
            var fractionField = new FractionField <CoeffType>(this.integerNumber);
            var polynomDomain = new UnivarPolynomEuclideanDomain <CoeffType>(
                polymomial.VariableName,
                modularField);
            var bachetBezourAlg = new LagrangeAlgorithm <UnivariatePolynomialNormalForm <CoeffType> >(polynomDomain);

            var polynomialField = new UnivarPolynomEuclideanDomain <CoeffType>(
                polymomial.VariableName,
                modularField);

            var result = this.Factorize(
                polymomial,
                modularField,
                polynomialField,
                bachetBezourAlg);

            return(result);
        }
Example #6
0
        /// <summary>
        /// Processa o polinómio determinando os respectivos factores.
        /// </summary>
        /// <remarks>
        /// Os factores constantes são ignorados, os factores lineares são anexados ao resultado e os factores
        /// cujos graus são superiores são retornados para futuro processamento. Se o polinómio a ser processado
        /// for irredutível, é adicionado ao resultado.
        /// </remarks>
        /// <param name="polynom">O polinómio a ser processado.</param>
        /// <param name="result">O contentor dos factores sucessivamente processados.</param>
        /// <param name="integerModule">O objecto responsável pelas operações sobre inteiros.</param>
        /// <param name="polynomField">O objecto responsável pelas operações sobre os polinómios.</param>
        /// <param name="inverseAlgorithm">O algoritmo inverso.</param>
        /// <returns></returns>
        List <UnivariatePolynomialNormalForm <CoeffType> > Process(
            UnivariatePolynomialNormalForm <CoeffType> polynom,
            List <UnivariatePolynomialNormalForm <CoeffType> > result,
            IModularField <CoeffType> integerModule,
            UnivarPolynomEuclideanDomain <CoeffType> polynomField,
            LagrangeAlgorithm <UnivariatePolynomialNormalForm <CoeffType> > inverseAlgorithm)
        {
            var resultPol = new List <UnivariatePolynomialNormalForm <CoeffType> >();

            if (polynom.Degree < 2)
            {
                result.Add(polynom);
            }
            else
            {
                var module = new ModularBachetBezoutField <UnivariatePolynomialNormalForm <CoeffType> >(
                    polynom,
                    inverseAlgorithm);

                var degree      = polynom.Degree;
                var arrayMatrix = new ArrayMathMatrix <CoeffType>(degree, degree, integerModule.AdditiveUnity);
                arrayMatrix[0, 0] = integerModule.AdditiveUnity;
                var pol = new UnivariatePolynomialNormalForm <CoeffType>(
                    integerModule.MultiplicativeUnity,
                    1,
                    polynom.VariableName,
                    integerModule);

                var integerModuleValue = this.integerNumber.ConvertToInt(integerModule.Module);

                pol = MathFunctions.Power(pol, integerModuleValue, module);
                foreach (var term in pol)
                {
                    arrayMatrix[term.Key, 1] = term.Value;
                }

                var auxPol = pol;
                for (int i = 2; i < degree; ++i)
                {
                    auxPol = module.Multiply(auxPol, pol);
                    foreach (var term in auxPol)
                    {
                        arrayMatrix[term.Key, i] = term.Value;
                    }
                }

                for (int i = 1; i < degree; ++i)
                {
                    var value = arrayMatrix[i, i];
                    value = integerModule.Add(
                        value,
                        integerModule.AdditiveInverse(integerModule.MultiplicativeUnity));
                    arrayMatrix[i, i] = value;
                }

                var emtpyMatrix          = new ZeroMatrix <CoeffType>(degree, 1, integerModule);
                var linearSystemSolution = this.linearSystemSolver.Run(arrayMatrix, emtpyMatrix);

                var numberOfFactors = linearSystemSolution.VectorSpaceBasis.Count;
                if (numberOfFactors < 2)
                {
                    result.Add(polynom);
                }
                else
                {
                    var hPol = default(UnivariatePolynomialNormalForm <CoeffType>);
                    var linearSystemCount = linearSystemSolution.VectorSpaceBasis.Count;
                    for (int i = 0; i < linearSystemCount; ++i)
                    {
                        var currentBaseSolution = linearSystemSolution.VectorSpaceBasis[i];
                        var rowsLength          = currentBaseSolution.Length;
                        for (int j = 1; j < rowsLength; ++j)
                        {
                            if (!integerModule.IsAdditiveUnity(currentBaseSolution[j]))
                            {
                                hPol = this.GetPolynomial(currentBaseSolution, integerModule, polynom.VariableName);
                                j    = rowsLength;
                            }

                            if (hPol != null)
                            {
                                j = rowsLength;
                            }
                        }

                        if (hPol != null)
                        {
                            i = linearSystemCount;
                        }
                    }

                    for (int i = 0, k = 0; k < numberOfFactors && i < integerModuleValue; ++i)
                    {
                        var converted  = this.integerNumber.MapFrom(i);
                        var currentPol = MathFunctions.GreatCommonDivisor(
                            polynom,
                            hPol.Subtract(converted, integerModule),
                            polynomField);
                        var currentDegree = currentPol.Degree;
                        if (currentDegree == 1)
                        {
                            result.Add(currentPol);
                            ++k;
                        }
                        else if (currentDegree > 1)
                        {
                            resultPol.Add(currentPol);
                            ++k;
                        }
                    }
                }
            }

            return(resultPol);
        }
        /// <summary>
        /// Executa o algoritmo que permite obter uma factorização livre de quadrados.
        /// </summary>
        /// <param name="polynomial">O polinómio de entrada.</param>
        /// <returns>A factorização livre de quadrados.</returns>
        /// <exception cref="ArgumentNullException">
        /// Se o argumento for nulo.
        /// </exception>
        public SquareFreeFactorizationResult <Fraction <CoeffType>, CoeffType> Run(
            UnivariatePolynomialNormalForm <Fraction <CoeffType> > polynomial)
        {
            if (polynomial == null)
            {
                throw new ArgumentNullException("polynomial");
            }
            else
            {
                var independentCoeff = this.fractionField.MultiplicativeUnity;
                var result           = new Dictionary <int, UnivariatePolynomialNormalForm <CoeffType> >();
                var currentDegree    = 1;
                var polynomDomain    = new UnivarPolynomEuclideanDomain <Fraction <CoeffType> >(
                    polynomial.VariableName,
                    this.fractionField);

                var lagAlg         = new LagrangeAlgorithm <CoeffType>(this.integerNumber);
                var dataDerivative = polynomial.GetPolynomialDerivative(this.fractionField);
                var gcd            = this.GreatCommonDivisor(polynomial, dataDerivative, polynomDomain);
                if (gcd.Degree == 0)
                {
                    var lcm = this.GetDenominatorLcm(polynomial, lagAlg);
                    if (this.integerNumber.IsMultiplicativeUnity(lcm))
                    {
                        var integerPol = this.GetIntegerPol(polynomial);
                        result.Add(currentDegree, integerPol);
                    }
                    else
                    {
                        independentCoeff = new Fraction <CoeffType>(
                            this.integerNumber.MultiplicativeUnity,
                            lcm,
                            this.integerNumber);
                        var multipliable = new Fraction <CoeffType>(
                            lcm,
                            this.integerNumber.MultiplicativeUnity,
                            this.integerNumber);
                        var multipliedPol = polynomial.Multiply(independentCoeff, this.fractionField);
                        var integerPol    = this.GetIntegerPol(multipliedPol);
                        result.Add(currentDegree, integerPol);
                    }
                }
                else
                {
                    var polyCoffactor    = polynomDomain.Quo(polynomial, gcd);
                    var nextGcd          = this.GreatCommonDivisor(gcd, polyCoffactor, polynomDomain);
                    var squareFreeFactor = polynomDomain.Quo(polyCoffactor, nextGcd);
                    polyCoffactor = gcd;
                    gcd           = nextGcd;
                    if (squareFreeFactor.Degree > 0)
                    {
                        var lcm = this.GetDenominatorLcm(squareFreeFactor, lagAlg);
                        if (this.integerNumber.IsMultiplicativeUnity(lcm))
                        {
                            var integerPol = this.GetIntegerPol(squareFreeFactor);
                            result.Add(currentDegree, integerPol);
                        }
                        else if (this.fractionField.IsAdditiveUnity(independentCoeff))
                        {
                            independentCoeff = new Fraction <CoeffType>(
                                this.integerNumber.MultiplicativeUnity,
                                MathFunctions.Power(lcm, currentDegree, this.integerNumber),
                                this.integerNumber);
                            var multipliable = new Fraction <CoeffType>(
                                lcm,
                                this.integerNumber.MultiplicativeUnity,
                                this.integerNumber);
                            var multipliedPol = squareFreeFactor.Multiply(independentCoeff, this.fractionField);
                            var integerPol    = this.GetIntegerPol(multipliedPol);
                            result.Add(currentDegree, integerPol);
                        }
                        else
                        {
                            var multiplicationCoeff = new Fraction <CoeffType>(
                                this.integerNumber.MultiplicativeUnity,
                                MathFunctions.Power(lcm, currentDegree, this.integerNumber),
                                this.integerNumber);
                            independentCoeff = this.fractionField.Multiply(independentCoeff, multiplicationCoeff);
                            var multipliable = new Fraction <CoeffType>(
                                lcm,
                                this.integerNumber.MultiplicativeUnity,
                                this.integerNumber);
                            var multipliedPol = squareFreeFactor.Multiply(independentCoeff, this.fractionField);
                            var integerPol    = this.GetIntegerPol(multipliedPol);
                            result.Add(currentDegree, integerPol);
                        }
                    }
                    else
                    {
                        var value = squareFreeFactor.GetAsValue(this.fractionField);
                        if (!this.fractionField.IsMultiplicativeUnity(value))
                        {
                            if (this.fractionField.IsMultiplicativeUnity(independentCoeff))
                            {
                                independentCoeff = value;
                            }
                            else
                            {
                                independentCoeff = this.fractionField.Multiply(independentCoeff, value);
                            }
                        }
                    }

                    ++currentDegree;
                    while (gcd.Degree > 0)
                    {
                        polyCoffactor    = polynomDomain.Quo(polyCoffactor, gcd);
                        nextGcd          = MathFunctions.GreatCommonDivisor(gcd, polyCoffactor, polynomDomain);
                        squareFreeFactor = polynomDomain.Quo(gcd, nextGcd);
                        gcd = nextGcd;
                        if (squareFreeFactor.Degree > 0)
                        {
                            var lcm = this.GetDenominatorLcm(squareFreeFactor, lagAlg);
                            if (this.integerNumber.IsMultiplicativeUnity(lcm))
                            {
                                var integerPol = this.GetIntegerPol(squareFreeFactor);
                                result.Add(currentDegree, integerPol);
                            }
                            else if (this.fractionField.IsAdditiveUnity(independentCoeff))
                            {
                                independentCoeff = new Fraction <CoeffType>(
                                    this.integerNumber.MultiplicativeUnity,
                                    MathFunctions.Power(lcm, currentDegree, this.integerNumber),
                                    this.integerNumber);
                                var multipliable = new Fraction <CoeffType>(
                                    lcm,
                                    this.integerNumber.MultiplicativeUnity,
                                    this.integerNumber);
                                var multipliedPol = squareFreeFactor.Multiply(independentCoeff, this.fractionField);
                                var integerPol    = this.GetIntegerPol(multipliedPol);
                                result.Add(currentDegree, integerPol);
                            }
                            else
                            {
                                var multiplicationCoeff = new Fraction <CoeffType>(
                                    this.integerNumber.MultiplicativeUnity,
                                    MathFunctions.Power(lcm, currentDegree, this.integerNumber),
                                    this.integerNumber);
                                independentCoeff = this.fractionField.Multiply(independentCoeff, multiplicationCoeff);
                                var multipliable = new Fraction <CoeffType>(
                                    lcm,
                                    this.integerNumber.MultiplicativeUnity,
                                    this.integerNumber);
                                var multipliedPol = squareFreeFactor.Multiply(multipliable, this.fractionField);
                                var integerPol    = this.GetIntegerPol(multipliedPol);
                                result.Add(currentDegree, integerPol);
                            }
                        }
                        else
                        {
                            var value = squareFreeFactor.GetAsValue(this.fractionField);
                            if (!this.fractionField.IsMultiplicativeUnity(value))
                            {
                                if (this.fractionField.IsMultiplicativeUnity(independentCoeff))
                                {
                                    independentCoeff = value;
                                }
                                else
                                {
                                    independentCoeff = this.fractionField.Multiply(independentCoeff, value);
                                }
                            }
                        }

                        ++currentDegree;
                    }

                    var cofactorValue = polyCoffactor.GetAsValue(this.fractionField);
                    if (!this.fractionField.IsMultiplicativeUnity(cofactorValue))
                    {
                        if (this.fractionField.IsMultiplicativeUnity(independentCoeff))
                        {
                            independentCoeff = cofactorValue;
                        }
                        else
                        {
                            independentCoeff = this.fractionField.Multiply(independentCoeff, cofactorValue);
                        }
                    }
                }

                return(new SquareFreeFactorizationResult <Fraction <CoeffType>, CoeffType>(
                           independentCoeff,
                           result));
            }
        }