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); }
/* Let x be a polynomial with coefficients in Z or nf (vectors or polymods) * return the same polynomial with coefficients expressed: * if flag=t_COL: as vectors (on the integral basis). * if flag=t_POLMOD: as polmods. */ GEN unifpol(GEN nf, GEN x, long flag) { if (typ(x)==t_POL && varncmp(varn(x), varn(nf[1])) < 0) { long i, d = lg(x); GEN y = cgetg(d,t_POL); y[1] = x[1]; for (i=2; i<d; i++) gel(y,i) = unifpol0(nf, gel(x,i), flag); return y; } return unifpol0(nf, x, flag); }
/* 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 int cmp_by_var(void *E,GEN x, GEN y) { (void)E; return varncmp((long)x,(long)y); }
static int _lower(void *E, hashentry *e) { long v = (long)e->val; return (varncmp(v, (long)E) > 0); }