long ComputeDegree(const ZZ_pX& h, const ZZ_pXModulus& F) // f = F.f is assumed to be an "equal degree" polynomial // h = X^p mod f // the common degree of the irreducible factors of f is computed { if (F.n == 1 || IsX(h)) return 1; FacVec fvec; FactorInt(fvec, F.n); return RecComputeDegree(fvec.length()-1, h, F, fvec); }
void FactorInt(FacVec& fvec, long n) { if (n <= 1) LogicError("internal error: FactorInt(FacVec,long n) with n<=1"); if (NTL_OVERFLOW(n, 1, 0)) ResourceError("internal error: FactorInt(FacVec,long n) with n too large"); long NumFactors; long q; fvec.SetLength(2*NextPowerOfTwo(n)); NumFactors = 0; q = 2; while (n != 1) { if (n%q == 0) { fvec[NumFactors].q = q; n = n/q; fvec[NumFactors].a = 1; fvec[NumFactors].val = q; while (n%q == 0) { n = n/q; (fvec[NumFactors].a)++; fvec[NumFactors].val *= q; } fvec[NumFactors].link = -1; NumFactors++; } q++; } fvec.SetLength(2*NumFactors-1); long lo = 0; long hi = NumFactors - 1; while (lo < hi) { FindMin(fvec, lo, hi); FindMin(fvec, lo+1, hi); hi++; fvec[hi].link = lo; fvec[hi].val = fvec[lo].val * fvec[lo+1].val; lo += 2; } }
void BuildIrred(ZZ_pEX& f, long n) { if (n <= 0) LogicError("BuildIrred: n must be positive"); if (NTL_OVERFLOW(n, 1, 0)) ResourceError("overflow in BuildIrred"); if (n == 1) { SetX(f); return; } FacVec fvec; FactorInt(fvec, n); RecBuildIrred(f, fvec.length()-1, fvec); }
long DetIrredTest(const ZZ_pEX& f) { if (deg(f) <= 0) return 0; if (deg(f) == 1) return 1; ZZ_pEXModulus F; build(F, f); ZZ_pEX h; FrobeniusMap(h, F); ZZ_pEX s; PowerCompose(s, h, F.n, F); if (!IsX(s)) return 0; FacVec fvec; FactorInt(fvec, F.n); return RecIrredTest(fvec.length()-1, h, F, fvec); }