public RingDecomposeList FactorIntPolynomialOverBigModule(out RingDecomposeList fFactorization) { IntPolynomial f = this; IntPolynomial hasSquares; IntPolynomial.GCD(f, f.Derivative(), out hasSquares); IntPolynomial SquareFreef = (f / hasSquares).Quotient; RingDecomposeList LiftedFactorisation; if (SquareFreef.degree > 1) { BigInteger mod = SelectAppropriateMod(f, SquareFreef); RingPolynomial.SetModContext(mod); RingPolynomial fRing = new RingPolynomial(f); fFactorization = fRing.BerlekampFactor(); List <RingPolynomial> GCDCoeffs = RingPolynomial.GetGCDCoefficientForHensel(fFactorization); LiftedFactorisation = RingPolynomial.HenselLiftingUntilTheEnd(f, fFactorization, GCDCoeffs); LiftedFactorisation.polyCoef = f[f.size - 1]; } else { RingPolynomial.SetModContext(5); // f состоит из кратных множителей первой степени LiftedFactorisation = new RingDecomposeList(); BigInteger coeff = SquareFreef.CoeffGCD(); IntPolynomial Multiplier = SquareFreef / coeff; // находим наибольшее число в f, чтобы подобрать модуль BigInteger biggestCoeff = f[0]; for (int i = 0; i < f.size; i++) { if (f[i] > biggestCoeff) { biggestCoeff = f[i]; } } BigInteger mod = getNextPrime(biggestCoeff); RingPolynomial.SetModContext(mod); for (int i = 0; i < f.size - 1; i++) { LiftedFactorisation.Add(new RingPolynomial(Multiplier)); } LiftedFactorisation.polyCoef *= (RingBint)coeff; fFactorization = LiftedFactorisation; } return(LiftedFactorisation); }