コード例 #1
0
        /// <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));
            }
        }
コード例 #2
0
        /// <summary>
        /// Aplica o algoritmo de factorização livre de quadrados a um polinómio.
        /// </summary>
        /// <param name="data">O polinómio.</param>
        /// <param name="field">O corpos responsável pelas operações sobre os coeficientes.</param>
        /// <returns>O resultado da factorização livre de quadrados.</returns>
        /// <exception cref="ArgumentNullException">Caso algum dos argumentos seja nulo.</exception>
        public SquareFreeFactorizationResult <CoeffType, CoeffType> Run(
            UnivariatePolynomialNormalForm <CoeffType> data,
            IField <CoeffType> field)
        {
            if (field == null)
            {
                throw new ArgumentNullException("field");
            }
            else if (data == null)
            {
                throw new ArgumentNullException("data");
            }
            else
            {
                var independentCoeff = field.MultiplicativeUnity;
                var result           = new Dictionary <int, UnivariatePolynomialNormalForm <CoeffType> >();
                var currentDegree    = 1;
                var polynomDomain    = new UnivarPolynomEuclideanDomain <CoeffType>(data.VariableName, field);
                var dataDerivative   = data.GetPolynomialDerivative(field);
                var gcd = this.GreatCommonDivisor(data, dataDerivative, polynomDomain, field);
                if (polynomDomain.IsMultiplicativeUnity(gcd))
                {
                    result.Add(currentDegree, data.Clone());
                }
                else
                {
                    var polyCoffactor    = polynomDomain.Quo(data, gcd);
                    var nextGcd          = this.GreatCommonDivisor(gcd, polyCoffactor, polynomDomain, field);
                    var squareFreeFactor = polynomDomain.Quo(polyCoffactor, nextGcd);
                    polyCoffactor = gcd;
                    gcd           = nextGcd;
                    if (squareFreeFactor.Degree > 0)
                    {
                        result.Add(currentDegree, squareFreeFactor);
                    }
                    else
                    {
                        var value = squareFreeFactor.GetAsValue(field);
                        if (!field.IsMultiplicativeUnity(value))
                        {
                            if (field.IsMultiplicativeUnity(independentCoeff))
                            {
                                independentCoeff = value;
                            }
                            else
                            {
                                independentCoeff = field.Multiply(independentCoeff, value);
                            }
                        }
                    }

                    ++currentDegree;
                    while (gcd.Degree > 0)
                    {
                        polyCoffactor    = polynomDomain.Quo(polyCoffactor, gcd);
                        nextGcd          = this.GreatCommonDivisor(gcd, polyCoffactor, polynomDomain, field);
                        squareFreeFactor = polynomDomain.Quo(gcd, nextGcd);
                        gcd = nextGcd;
                        if (squareFreeFactor.Degree > 0)
                        {
                            result.Add(currentDegree, squareFreeFactor);
                        }
                        else
                        {
                            var value = squareFreeFactor.GetAsValue(field);
                            if (!field.IsMultiplicativeUnity(value))
                            {
                                if (field.IsMultiplicativeUnity(independentCoeff))
                                {
                                    independentCoeff = value;
                                }
                                else
                                {
                                    independentCoeff = field.Multiply(independentCoeff, value);
                                }
                            }
                        }

                        ++currentDegree;
                    }

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

                return(new SquareFreeFactorizationResult <CoeffType, CoeffType>(
                           independentCoeff,
                           result));
            }
        }
コード例 #3
0
        /// <summary>
        /// Permite processar as restantes combinações.
        /// </summary>
        /// <param name="modularFactors">Os factores modulares.</param>
        /// <param name="integerFactors">Os factores inteiros.</param>
        /// <param name="primePower">A potência de um número primo que servirá de módulo.</param>
        /// <param name="halfPrimePower">A metade da potência do número primo.</param>
        /// <param name="testValue">O valor de teste.</param>
        /// <param name="combinationsNumber">O número máximo de polinómios nas combinações.</param>
        /// <param name="modularPolynomialDomain">O corpo responsável pelas operações modulares.</param>
        private void ProcessRemainingPolynomials(
            List <UnivariatePolynomialNormalForm <CoeffType> > modularFactors,
            List <UnivariatePolynomialNormalForm <CoeffType> > integerFactors,
            CoeffType primePower,
            CoeffType halfPrimePower,
            CoeffType testValue,
            int combinationsNumber,
            UnivarPolynomEuclideanDomain <CoeffType> modularPolynomialDomain)
        {
            if (combinationsNumber > 1 && modularFactors.Count > 1)
            {
                var modularProduct           = default(UnivariatePolynomialNormalForm <CoeffType>);
                var currentCombinationNumber = 2;
                var productStack             = new Stack <UnivariatePolynomialNormalForm <CoeffType> >();
                productStack.Push(modularFactors[0]);
                var pointers = new Stack <int>();
                pointers.Push(0);
                pointers.Push(1);
                var state = 0;
                while (state != -1)
                {
                    if (state == 0)
                    {
                        if (pointers.Count == currentCombinationNumber)
                        {
                            var topPointer = pointers.Pop();
                            var topPol     = productStack.Pop();

                            // Obtém o produto de todos os polinómios.
                            var currentPol = modularPolynomialDomain.Multiply(
                                topPol,
                                modularFactors[topPointer]);
                            currentPol = currentPol.ApplyFunction(
                                c => this.GetSymmetricRemainder(
                                    c,
                                    primePower,
                                    halfPrimePower),
                                this.integerNumber);

                            // Compara as normas com o valor de teste
                            var firstNorm = this.GetPlynomialNorm(currentPol);
                            if (this.integerNumber.Compare(firstNorm, testValue) < 0)
                            {
                                if (modularProduct == null)
                                {
                                    modularProduct = this.ComputeModularProduct(
                                        modularFactors,
                                        modularPolynomialDomain);
                                }

                                var coPol = modularPolynomialDomain.Quo(
                                    modularProduct,
                                    currentPol);
                                coPol = coPol.ApplyFunction(
                                    c => this.GetSymmetricRemainder(
                                        c,
                                        primePower,
                                        halfPrimePower),
                                    this.integerNumber);
                                var secondNorm = this.GetPlynomialNorm(coPol);
                                var normProd   = this.integerNumber.Multiply(firstNorm, secondNorm);
                                if (this.integerNumber.Compare(normProd, testValue) < 0)
                                {
                                    integerFactors.Add(currentPol);
                                    modularFactors.RemoveAt(topPointer);
                                    while (pointers.Count > 0)
                                    {
                                        var removeIndex = pointers.Pop();
                                        modularFactors.RemoveAt(removeIndex);
                                    }

                                    productStack.Clear();
                                    if (modularFactors.Count < currentCombinationNumber)
                                    {
                                        state = -1;
                                    }
                                    else
                                    {
                                        productStack.Push(modularFactors[0]);
                                        pointers.Push(0);
                                        pointers.Push(1);
                                    }
                                }
                                else
                                {
                                    productStack.Push(topPol);
                                    pointers.Push(topPointer);
                                    state = 1;
                                }
                            }
                            else
                            {
                                productStack.Push(topPol);
                                pointers.Push(topPointer);
                                state = 1;
                            }
                        }
                        else
                        {
                            var topPointer = pointers.Pop();
                            var topPol     = productStack.Pop();
                            var currentPol = modularPolynomialDomain.Multiply(
                                topPol,
                                modularFactors[topPointer]);
                            currentPol = currentPol.ApplyFunction(
                                c => this.GetSymmetricRemainder(
                                    c,
                                    primePower,
                                    halfPrimePower),
                                this.integerNumber);

                            productStack.Push(topPol);
                            productStack.Push(currentPol);
                            pointers.Push(topPointer);
                            pointers.Push(topPointer + 1);
                        }
                    }
                    else if (state == 1)
                    {
                        var pointerLimit = modularFactors.Count - combinationsNumber + pointers.Count + 1;
                        if (pointers.Count > 1)
                        {
                            var topPointer = pointers.Pop();
                            ++topPointer;
                            if (topPointer < pointerLimit)
                            {
                                pointers.Push(topPointer);
                                state = 0;
                            }
                            else
                            {
                                productStack.Pop();
                            }
                        }
                        else
                        {
                            var topPointer = pointers.Pop();
                            ++topPointer;
                            if (topPointer < pointerLimit)
                            {
                                pointers.Push(topPointer);
                                productStack.Push(modularFactors[topPointer]);
                                pointers.Push(topPointer + 1);
                            }
                            else
                            {
                                ++currentCombinationNumber;
                                if (currentCombinationNumber < combinationsNumber)
                                {
                                    state = -1;
                                }
                                else if (modularFactors.Count < currentCombinationNumber)
                                {
                                    state = -1;
                                }
                                else
                                {
                                    pointers.Push(0);
                                    pointers.Push(1);
                                    productStack.Push(modularFactors[0]);
                                }
                            }
                        }
                    }
                }
            }
        }