void FindFactors(vec_ZZ_pEX& factors, const ZZ_pEX& f, const ZZ_pEX& g, const vec_ZZ_pE& roots) { long r = roots.length(); factors.SetMaxLength(r); factors.SetLength(0); RecFindFactors(factors, f, g, roots, 0, r-1); }
static void GenerateBabySteps(ZZ_pEX& h1, const ZZ_pEX& f, const ZZ_pEX& h, long k, long verbose) { double t; if (verbose) { cerr << "generating baby steps..."; t = GetTime(); } ZZ_pEXModulus F; build(F, f); ZZ_pEXArgument H; #if 0 double n2 = sqrt(double(F.n)); double n4 = sqrt(n2); double n34 = n2*n4; long sz = long(ceil(n34/sqrt(sqrt(2.0)))); #else long sz = 2*SqrRoot(F.n); #endif build(H, h, F, sz); h1 = h; long i; if (!use_files) { BabyStepFile.kill(); BabyStepFile.SetLength(k-1); } for (i = 1; i <= k-1; i++) { if (use_files) { ofstream s; OpenWrite(s, FileName(ZZ_pEX_stem, "baby", i)); s << h1 << "\n"; s.close(); } else BabyStepFile(i) = h1; CompMod(h1, h1, H, F); if (verbose) cerr << "+"; } if (verbose) cerr << (GetTime()-t) << "\n"; }
static void FileCleanup(long k, long l) { if (use_files) { long i; for (i = 1; i <= k-1; i++) remove(FileName(ZZ_pEX_stem, "baby", i)); for (i = 1; i <= l; i++) remove(FileName(ZZ_pEX_stem, "giant", i)); } else { BabyStepFile.kill(); GiantStepFile.kill(); } }
static void MulByXPlusY(vec_ZZ_pEX& h, const ZZ_pEX& f, const ZZ_pEX& g) // h represents the bivariate polynomial h[0] + h[1]*Y + ... + h[n-1]*Y^k, // where the h[i]'s are polynomials in X, each of degree < deg(f), // and k < deg(g). // h is replaced by the bivariate polynomial h*(X+Y) (mod f(X), g(Y)). { long n = deg(g); long k = h.length()-1; if (k < 0) return; if (k < n-1) { h.SetLength(k+2); h[k+1] = h[k]; for (long i = k; i >= 1; i--) { MulByXMod(h[i], h[i], f); add(h[i], h[i], h[i-1]); } MulByXMod(h[0], h[0], f); } else { ZZ_pEX b, t; b = h[n-1]; for (long i = n-1; i >= 1; i--) { mul(t, b, g.rep[i]); MulByXMod(h[i], h[i], f); add(h[i], h[i], h[i-1]); sub(h[i], h[i], t); } mul(t, b, g.rep[0]); MulByXMod(h[0], h[0], f); sub(h[0], h[0], t); } // normalize k = h.length()-1; while (k >= 0 && IsZero(h[k])) k--; h.SetLength(k+1); }
void EDF(vec_ZZ_pEX& factors, const ZZ_pEX& ff, const ZZ_pEX& bb, long d, long verbose) { ZZ_pEX f = ff; ZZ_pEX b = bb; if (!IsOne(LeadCoeff(f))) LogicError("EDF: bad args"); long n = deg(f); long r = n/d; if (r == 0) { factors.SetLength(0); return; } if (r == 1) { factors.SetLength(1); factors[0] = f; return; } if (d == 1) { RootEDF(factors, f, verbose); return; } double t; if (verbose) { cerr << "computing EDF(" << d << "," << r << ")..."; t = GetTime(); } factors.SetLength(0); RecEDF(factors, f, b, d, verbose); if (verbose) cerr << (GetTime()-t) << "\n"; }
void IterFindFactors(vec_ZZ_pEX& factors, const ZZ_pEX& f, const ZZ_pEX& g, const vec_ZZ_pE& roots) { long r = roots.length(); long i; ZZ_pEX h; factors.SetLength(r); for (i = 0; i < r; i++) { sub(h, g, roots[i]); GCD(factors[i], f, h); } }
void RootEDF(vec_ZZ_pEX& factors, const ZZ_pEX& f, long verbose) { vec_ZZ_pE roots; double t; if (verbose) { cerr << "finding roots..."; t = GetTime(); } FindRoots(roots, f); if (verbose) { cerr << (GetTime()-t) << "\n"; } long r = roots.length(); factors.SetLength(r); for (long j = 0; j < r; j++) { SetX(factors[j]); sub(factors[j], factors[j], roots[j]); } }
void SFCanZass(vec_ZZ_pEX& factors, const ZZ_pEX& ff, long verbose) { ZZ_pEX f = ff; if (!IsOne(LeadCoeff(f))) LogicError("SFCanZass: bad args"); if (deg(f) == 0) { factors.SetLength(0); return; } if (deg(f) == 1) { factors.SetLength(1); factors[0] = f; return; } factors.SetLength(0); double t; ZZ_pEXModulus F; build(F, f); ZZ_pEX h; if (verbose) { cerr << "computing X^p..."; t = GetTime(); } FrobeniusMap(h, F); if (verbose) { cerr << (GetTime()-t) << "\n"; } vec_pair_ZZ_pEX_long u; if (verbose) { cerr << "computing DDF..."; t = GetTime(); } NewDDF(u, f, h, verbose); if (verbose) { t = GetTime()-t; cerr << "DDF time: " << t << "\n"; } ZZ_pEX hh; vec_ZZ_pEX v; long i; for (i = 0; i < u.length(); i++) { const ZZ_pEX& g = u[i].a; long d = u[i].b; long r = deg(g)/d; if (r == 1) { // g is already irreducible append(factors, g); } else { // must perform EDF if (d == 1) { // root finding RootEDF(v, g, verbose); append(factors, v); } else { // general case rem(hh, h, g); EDF(v, g, hh, d, verbose); append(factors, v); } } } }