GEN nffactormod(GEN nf, GEN x, GEN pr) { long j, l, vx = varn(x), vn; pari_sp av = avma; GEN F, E, rep, xrd, modpr, T, p; nf = checknf(nf); vn = varn(nf[1]); if (typ(x)!=t_POL) pari_err(typeer,"nffactormod"); if (varncmp(vx,vn) >= 0) pari_err(talker,"polynomial variable must have highest priority in nffactormod"); modpr = nf_to_ff_init(nf, &pr, &T, &p); xrd = modprX(x, nf, modpr); rep = FqX_factor(xrd,T,p); settyp(rep, t_MAT); F = gel(rep,1); l = lg(F); E = gel(rep,2); settyp(E, t_COL); for (j = 1; j < l; j++) { gel(F,j) = modprX_lift(gel(F,j), modpr); gel(E,j) = stoi(E[j]); } return gerepilecopy(av, rep); }
GEN bnflogdegree(GEN nf, GEN A, GEN ell) { pari_sp av = avma; GEN AZ, A0Z, NA0; long vAZ; if (typ(ell) != t_INT) pari_err_TYPE("bnflogdegree", ell); nf = checknf(nf); A = idealhnf(nf, A); AZ = gcoeff(A,1,1); vAZ = Z_pvalrem(AZ, ell, &A0Z); if (is_pm1(A0Z)) NA0 = gen_1; else (void)Z_pvalrem(idealnorm(nf,A), ell, &NA0); if (vAZ) { GEN Aell = ZM_hnfmodid(A, powiu(ell,vAZ)); GEN S = idealprimedec(nf, ell), T; long l, i, s = 0; T = padicfact(nf, S, 100); l = lg(S); for (i = 1; i < l; i++) { GEN P = gel(S,i); long v = idealval(nf, Aell, P); if (v) s += v * ftilde(nf, P, gel(T,i)); } if (s) NA0 = gmul(NA0, gpowgs(ell1(ell), s)); } return gerepileupto(av, NA0); }
/* K number field, pr a maximal ideal, let K_pr be the attached local * field, K_pr = Q_p[X] / (T), T irreducible. Return \tilde{e}(K_pr/Q_p) */ static long etilde(GEN nf, GEN pr, GEN T) { GEN gp = pr_get_p(pr); ulong e = pr_get_e(pr); long v, voo, vmin, p, k; if (!u_pval(e, gp)) { v = u_pval(pr_get_f(pr), gp); return itou( mului(e, powiu(gp, v)) ); } nf = checknf(nf); p = itou(gp); k = e / (p-1) + 1; /* log Norm_{F_P/Q_p} (1 + P^k) = Tr(P^k) = p^[(k + v(Diff))/ e] Z_p */ voo = (k + idealval(nf, nf_get_diff(nf), pr)) / e; vmin = vlognorm(nf, T, pr_get_gen(pr), gp, voo); if (k > 1) { GEN U = idealprincipalunits(nf, pr, k); GEN gen = abgrp_get_gen(U), cyc = abgrp_get_cyc(U); long i, l = lg(cyc); for (i = 1; i < l; i++) { if (voo - Z_lval(gel(cyc,i), p) >= vmin) break; vmin = vlognorm(nf, T, gel(gen,i), gp, vmin); } } v = u_lval(degpol(T), p) + (p == 2UL? 2 : 1) - vmin; (void)u_lvalrem(e, p, &e); return e * upowuu(p,v); }
/* assume x is squarefree */ int nfissplit(GEN nf, GEN x) { pari_sp av = avma; long l; if (typ(x) != t_POL) pari_err(typeer, "nfissplit"); l = lg(nfsqff(checknf(nf), x, 2)); avma = av; return l != 1; }
GEN nfrootsall_and_pr(GEN nf, GEN pol) { GEN J1,J2, pr, T; pari_sp av = avma; GEN z = gerepileupto(av, nfsqff(checknf(nf), pol, 2)); if (lg(z) == 1) return NULL; (void)nf_pick_prime(1, nf, unifpol(nf, pol, t_COL), 2, &J1, &J2, &pr, &T); return mkvec2(z, pr); }
GEN bnflogef(GEN nf, GEN pr) { pari_sp av = avma; long e, f, ef; GEN p; checkprid(pr); p = pr_get_p(pr); nf = checknf(nf); e = pr_get_e(pr); f = pr_get_f(pr); ef = e*f; if (u_pval(ef, p)) { GEN T = gel(factorpadic(nf_get_pol(nf), p, 100), 1); long j = get_ZpX_index(nf, pr, T); e = etilde(nf, pr, gel(T,j)); f = ef / e; } avma = av; return mkvec2s(e,f); }
/* return the characteristic polynomial of alpha over nf, where alpha is an element of the algebra nf[X]/(T) given as a polynomial in X */ GEN rnfcharpoly(GEN nf, GEN T, GEN alpha, long v) { long vnf, vT, lT; pari_sp av = avma; GEN p1; nf=checknf(nf); vnf = varn(nf[1]); if (v<0) v = 0; T = fix_relative_pol(nf,T,1); if (typ(alpha) == t_POLMOD) alpha = lift_to_pol(alpha); lT = lg(T); if (typ(alpha) != t_POL || varn(alpha) == vnf) return gerepileupto(av, gpowgs(gsub(pol_x[v], alpha), lT - 3)); vT = varn(T); if (varn(alpha) != vT || varncmp(v, vnf)>=0) pari_err(talker,"incorrect variables in rnfcharpoly"); if (lg(alpha) >= lT) alpha = RgX_rem(alpha, T); if (lT <= 4) return gerepileupto(av, gsub(pol_x[v], alpha)); p1 = caract2(T, unifpol(nf,alpha, t_POLMOD), v); return gerepileupto(av, unifpol(nf, p1, t_POLMOD)); }
/* return the roots of pol in nf */ GEN nfroots(GEN nf,GEN pol) { pari_sp av = avma; GEN A,g, T; long d; if (!nf) return nfrootsQ(pol); nf = checknf(nf); T = gel(nf,1); if (typ(pol) != t_POL) pari_err(notpoler,"nfroots"); if (varncmp(varn(pol), varn(T)) >= 0) pari_err(talker,"polynomial variable must have highest priority in nfroots"); d = degpol(pol); if (d == 0) return cgetg(1,t_VEC); if (d == 1) { A = gneg_i(gdiv(gel(pol,2),gel(pol,3))); return gerepilecopy(av, mkvec( basistoalg(nf,A) )); } A = fix_relative_pol(nf,pol,0); A = Q_primpart( lift_intern(A) ); if (DEBUGLEVEL>3) fprintferr("test if polynomial is square-free\n"); g = nfgcd(A, derivpol(A), T, gel(nf,4)); if (degpol(g)) { /* not squarefree */ g = QXQX_normalize(g, T); A = RgXQX_div(A,g,T); } A = QXQX_normalize(A, T); A = Q_primpart(A); A = nfsqff(nf,A,1); A = RgXQV_to_mod(A, T); return gerepileupto(av, gen_sort(A, 0, cmp_pol)); }
/* return the factorization of x in nf */ GEN nffactor(GEN nf,GEN pol) { GEN A,g,y,p1,T, rep = cgetg(3, t_MAT); long l, j, dA; pari_sp av = avma; pari_timer ti; if (DEBUGLEVEL>2) { TIMERstart(&ti); fprintferr("\nEntering nffactor:\n"); } nf = checknf(nf); T = gel(nf,1); if (typ(pol) != t_POL) pari_err(notpoler,"nffactor"); if (varncmp(varn(pol), varn(T)) >= 0) pari_err(talker,"polynomial variable must have highest priority in nffactor"); A = fix_relative_pol(nf,pol,0); dA = degpol(A); if (dA <= 0) { avma = (pari_sp)(rep + 3); return dA == 0? trivfact(): zerofact(varn(pol)); } A = Q_primpart( QXQX_normalize(A, T) ); if (dA == 1) { GEN c; A = gerepilecopy(av, A); c = gel(A,2); if (typ(c) == t_POL && degpol(c) > 0) gel(A,2) = mkpolmod(c, gcopy(T)); gel(rep,1) = mkcol(A); gel(rep,2) = mkcol(gen_1); return rep; } if (degpol(T) == 1) return gerepileupto(av, factpol(Q_primpart(simplify(pol)), 0)); A = Q_primpart( lift_intern(A) ); g = nfgcd(A, derivpol(A), T, gel(nf,4)); A = QXQX_normalize(A, T); A = Q_primpart(A); if (DEBUGLEVEL>2) msgTIMER(&ti, "squarefree test"); if (degpol(g)) { /* not squarefree */ pari_sp av1; GEN ex; g = QXQX_normalize(g, T); A = RgXQX_div(A,g, T); y = nfsqff(nf,A,0); av1 = avma; l = lg(y); ex=(GEN)gpmalloc(l * sizeof(long)); for (j=l-1; j>=1; j--) { GEN fact = lift(gel(y,j)), quo = g, q; long e = 0; for(e = 1;; e++) { q = RgXQX_divrem(quo,fact,T, ONLY_DIVIDES); if (!q) break; quo = q; } ex[j] = e; } avma = av1; y = gerepileupto(av, RgXQXV_to_mod(y,T)); p1 = cgetg(l, t_COL); for (j=l-1; j>=1; j--) gel(p1,j) = utoipos(ex[j]); free(ex); } else { y = gerepileupto(av, RgXQXV_to_mod(nfsqff(nf,A,0), T)); l = lg(y); p1 = cgetg(l, t_COL); for (j=l-1; j>=1; j--) gel(p1,j) = gen_1; } if (DEBUGLEVEL>3) fprintferr("number of factor(s) found: %ld\n", lg(y)-1); gel(rep,1) = y; gel(rep,2) = p1; return sort_factor(rep, cmp_pol); }
static GEN bnflog_i(GEN bnf, GEN ell) { long prec0, prec; GEN nf, US, vdegS, S, T, M, CLp, CLt, Ftilde, vtG, ellk; GEN D, Ap, cycAp, bnfS; long i, j, lS, lvAp; checkbnf(bnf); nf = checknf(bnf); S = idealprimedec(nf, ell); bnfS = bnfsunit0(bnf, S, nf_GENMAT, LOWDEFAULTPREC); /* S-units */ US = leafcopy(gel(bnfS,1)); prec0 = maxss(30, vtilde_prec(nf, US, ell)); US = shallowconcat(bnf_get_fu(bnf), US); settyp(US, t_COL); T = padicfact(nf, S, prec0); lS = lg(S); Ftilde = cgetg(lS, t_VECSMALL); for (j = 1; j < lS; j++) Ftilde[j] = ftilde(nf, gel(S,j), gel(T,j)); CLp = CL_prime(bnf, ell, S); cycAp = gel(CLp,1); Ap = gel(CLp,2); for(;;) { CLt = CL_tilde(nf, US, ell, T, Ftilde, &vtG, prec0); if (CLt) break; prec0 <<= 1; T = padicfact(nf, S, prec0); } prec = ellexpo(cycAp, ell) + ellexpo(CLt,ell) + 1; if (prec == 1) return mkvec3(cgetg(1,t_VEC), cgetg(1,t_VEC), cgetg(1,t_VEC)); vdegS = get_vdegS(Ftilde, ell, prec0); ellk = powiu(ell, prec); lvAp = lg(Ap); if (lvAp > 1) { GEN Kcyc = bnf_get_cyc(bnf); GEN C = zeromatcopy(lvAp-1, lS-1); GEN Rell = gel(CLp,3), Uell = gel(CLp,4), ordS = gel(CLp,5); for (i = 1; i < lvAp; i++) { GEN a, b, bi, A = gel(Ap,i), d = gel(cycAp,i); bi = isprincipal(bnf, A); a = vecmodii(ZC_Z_mul(bi,d), Kcyc); /* a in subgroup generated by S = Rell; hence b integral */ b = hnf_invimage(Rell, a); b = vecmodii(ZM_ZC_mul(Uell, ZC_neg(b)), ordS); A = mkvec2(A, cgetg(1,t_MAT)); A = idealpowred(nf, A, d); /* find a principal representative of A_i^cycA_i up to elements of S */ a = isprincipalfact(bnf,gel(A,1),S,b,nf_GENMAT|nf_FORCE); if (!gequal0(gel(a,1))) pari_err_BUG("bnflog"); a = famat_mul_shallow(gel(A,2), gel(a,2)); /* principal part */ if (lg(a) == 1) continue; for (j = 1; j < lS; j++) gcoeff(C,i,j) = vtilde(nf, a, gel(T,j), gel(vdegS,j), ell, prec0); } C = gmod(gneg(C),ellk); C = shallowtrans(C); M = mkmat2(mkcol2(diagonal_shallow(cycAp), C), mkcol2(gen_0, vtG)); M = shallowmatconcat(M); /* relation matrix */ } else M = vtG; M = ZM_hnfmodid(M, ellk); D = matsnf0(M, 4); if (lg(D) == 1 || !dvdii(gel(D,1), ellk)) pari_err_BUG("bnflog [missing Z_l component]"); D = vecslice(D,2,lg(D)-1); return mkvec3(D, CLt, ellsylow(cycAp, ell)); }