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