/// <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> /// Quadra um valor um número especificado de vezes. /// </summary> /// <param name="value">O valor.</param> /// <param name="times">O número de vezes.</param> /// <param name="modularField">O objecto responsável pelas operações modulares.</param> /// <returns>O resultado.</returns> private NumberType SquareValue(NumberType value, NumberType times, IModularField <NumberType> modularField) { var result = value; var i = this.integerNumber.AdditiveUnity; for (; this.integerNumber.Compare(i, times) < 0; i = this.integerNumber.Successor(i)) { result = modularField.Multiply(result, result); } return(result); }
/// <summary> /// Tenta encontrar o índice i tal que temp^(2^i) seja congruente com a unidade. /// </summary> /// <param name="temp">O valor de temp.</param> /// <param name="upperLimit">O valor do limite superior.</param> /// <param name="modularField">O objecto responsável pelas operações modulares.</param> /// <returns>O índice procurado.</returns> private NumberType FindLowestIndex(NumberType temp, NumberType upperLimit, IModularField <NumberType> modularField) { var result = this.integerNumber.MapFrom(-1); var innerTemp = temp; var i = this.integerNumber.AdditiveUnity; for (; this.integerNumber.Compare(i, upperLimit) < 0; i = this.integerNumber.Successor(i)) { if (this.integerNumber.IsMultiplicativeUnity(innerTemp)) { result = i; i = upperLimit; } else { innerTemp = modularField.Multiply(innerTemp, innerTemp); } } return(result); }
/// <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)); } }