Beispiel #1
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>
        /// 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));
            }
        }