Annotation of OpenXM_contrib/pari/src/modules/nffactor.c, Revision 1.1
1.1 ! maekawa 1: /*******************************************************************/
! 2: /* */
! 3: /* Factorisation dans un corps de nombres */
! 4: /* et modulo un ideal premier */
! 5: /* */
! 6: /*******************************************************************/
! 7: /* $Id: nffactor.c,v 1.5 1999/09/23 18:48:42 xavier Exp $ */
! 8: #include "pari.h"
! 9:
! 10: GEN hensel_lift(GEN pol,GEN fk,GEN fkk,GEN p,long e);
! 11: GEN hensel_lift_fact(GEN pol, GEN fact, GEN p, GEN pev, long e);
! 12: GEN nf_get_T2(GEN base, GEN polr);
! 13: GEN nfreducemodpr_i(GEN x, GEN prh);
! 14: GEN sort_factor(GEN y, int (*cmp)(GEN,GEN));
! 15:
! 16: static GEN nf_pol_mul(GEN nf,GEN pol1,GEN pol2);
! 17: static GEN nf_pol_sqr(GEN nf,GEN pol1);
! 18: static GEN nf_pol_divres(GEN nf,GEN pol1,GEN pol2, GEN *pr);
! 19: static GEN nf_pol_subres(GEN nf,GEN pol1,GEN pol2);
! 20: static GEN nfmod_pol_reduce(GEN nf,GEN prhall,GEN pol);
! 21: static GEN nfmod_pol_mul(GEN nf,GEN prhall,GEN pol1,GEN pol2);
! 22: static GEN nfmod_pol_sqr(GEN nf,GEN prhall,GEN pol1);
! 23: static GEN nfmod_pol_divres(GEN nf,GEN prhall,GEN pol1,GEN pol2, GEN *pr);
! 24: static GEN nfmod_split2(GEN nf,GEN prhall,GEN pmod,GEN pol,GEN exp);
! 25: static GEN nfmod_pol_gcd(GEN nf,GEN prhall,GEN pol1,GEN pol2);
! 26: static GEN nfmod_pol_pow(GEN nf,GEN prhall,GEN pmod,GEN pol,GEN exp);
! 27: static GEN nf_bestlift(GEN id,GEN idinv,GEN den,GEN elt);
! 28: static GEN nf_pol_lift(GEN id,GEN idinv,GEN den,GEN pol);
! 29: static GEN nfsqff(GEN nf,GEN pol,long fl);
! 30: static int nf_combine_factors(GEN nf,long fxn,GEN psf,long dlim,long hint);
! 31:
! 32: typedef struct Nfcmbf /* for use in nfsqff */
! 33: {
! 34: GEN pol, h, hinv, fact, res, lt, den;
! 35: long nfact, nfactmod;
! 36: } Nfcmbf;
! 37: static Nfcmbf nfcmbf;
! 38:
! 39: static GEN
! 40: unifpol0(GEN nf,GEN pol,long flag)
! 41: {
! 42: static long n = 0;
! 43: static GEN vun = NULL;
! 44: GEN f = (GEN) nf[1];
! 45: long i = lgef(f)-3, av;
! 46:
! 47: if (i != n)
! 48: {
! 49: n=i; if (vun) free(vun);
! 50: vun = (GEN) gpmalloc((n+1)*sizeof(long));
! 51: vun[0] = evaltyp(t_COL) | evallg(n+1); vun[1]=un;
! 52: for ( ; i>=2; i--) vun[i]=zero;
! 53: }
! 54:
! 55: av = avma;
! 56: switch(typ(pol))
! 57: {
! 58: case t_INT: case t_FRAC: case t_RFRAC:
! 59: pol = gmul(pol,vun); break;
! 60:
! 61: case t_POL:
! 62: pol = gmodulcp(pol,f); /* fall through */
! 63: case t_POLMOD:
! 64: pol = algtobasis(nf,pol);
! 65: }
! 66: if (flag) pol = basistoalg(nf, lift(pol));
! 67: return gerepileupto(av,pol);
! 68: }
! 69:
! 70: /* Pour pol un polynome a coefficients dans Z, nf ou l'algebre correspondant
! 71: * renvoie le meme polynome avec pour coefficients:
! 72: * si flag=0: des vecteurs sur la base d'entiers.
! 73: * si flag=1: des polymods.
! 74: */
! 75: GEN
! 76: unifpol(GEN nf,GEN pol,long flag)
! 77: {
! 78: if (typ(pol)==t_POL && varn(pol) < varn(nf[1]))
! 79: {
! 80: long i, d = lgef(pol);
! 81: GEN p1 = pol;
! 82:
! 83: pol=cgetg(d,t_POL); pol[1]=p1[1];
! 84: for (i=2; i<d; i++)
! 85: pol[i] = (long) unifpol0(nf,(GEN) p1[i],flag);
! 86:
! 87: return pol;
! 88: }
! 89: return unifpol0(nf,(GEN) pol, flag);
! 90: }
! 91:
! 92: /* cree un polynome unitaire de degre d a entrees au hazard dans Z_nf */
! 93: GEN
! 94: random_pol(GEN nf,long d)
! 95: {
! 96: long i,j, n = lgef(nf[1])-3;
! 97: GEN pl,p;
! 98:
! 99: pl=cgetg(d+3,t_POL);
! 100: for (i=2; i<d+2; i++)
! 101: {
! 102: p=cgetg(n+1,t_COL); pl[i]=(long)p;
! 103: for (j=1; j<=n; j++)
! 104: p[j] = lstoi(mymyrand()%101 - 50);
! 105: }
! 106: p=cgetg(n+1,t_COL); pl[i]=(long)p;
! 107: p[1]=un; for (i=2; i<=n; i++) p[i]=zero;
! 108:
! 109: pl[1] = evalsigne(1) | evallgef(d+3) | evalvarn(0);
! 110: return pl;
! 111: }
! 112:
! 113: /* multiplication de x par y dans nf (x element accepte) */
! 114: static GEN
! 115: nf_pol_mul(GEN nf,GEN x,GEN y)
! 116: {
! 117: long tetpil,av=avma;
! 118: GEN res = gmul(unifpol(nf,x,1), unifpol(nf,y,1));
! 119:
! 120: tetpil = avma;
! 121: return gerepile(av,tetpil,unifpol(nf,res,0));
! 122: }
! 123:
! 124: /* calcule x^2 dans nf (x element accepte) */
! 125: static GEN
! 126: nf_pol_sqr(GEN nf,GEN x)
! 127: {
! 128: long tetpil,av=avma;
! 129: GEN res = gsqr(unifpol(nf,x,1));
! 130:
! 131: tetpil = avma;
! 132: return gerepile(av,tetpil,unifpol(nf,res,0));
! 133: }
! 134:
! 135: /* Reduction modulo phall des coefficients de pol (pol element accepte) */
! 136: static GEN
! 137: nfmod_pol_reduce(GEN nf,GEN prhall,GEN pol)
! 138: {
! 139: long av=avma,tetpil,i;
! 140: GEN p1;
! 141:
! 142: if (typ(pol)!=t_POL) return nfreducemodpr(nf,pol,prhall);
! 143: pol=unifpol(nf,pol,0);
! 144:
! 145: tetpil=avma; i=lgef(pol);
! 146: p1=cgetg(i,t_POL); p1[1]=pol[1];
! 147: for (i--; i>=2; i--)
! 148: p1[i] = (long) nfreducemodpr(nf,(GEN)pol[i],prhall);
! 149: return gerepile(av,tetpil, normalizepol(p1));
! 150: }
! 151:
! 152: /* x^2 modulo prhall ds nf (x elt accepte) */
! 153: static GEN
! 154: nfmod_pol_sqr(GEN nf,GEN prhall,GEN x)
! 155: {
! 156: long av=avma,tetpil;
! 157: GEN px;
! 158:
! 159: px = nfmod_pol_reduce(nf,prhall,x);
! 160: px = unifpol(nf,lift(px),1);
! 161: px = unifpol(nf,nf_pol_sqr(nf,px),0);
! 162: tetpil=avma;
! 163: return gerepile(av,tetpil,nfmod_pol_reduce(nf,prhall,px));
! 164: }
! 165:
! 166: /* multiplication des polynomes x et y modulo prhall ds nf (x elt accepte) */
! 167: static GEN
! 168: nfmod_pol_mul(GEN nf,GEN prhall,GEN x,GEN y)
! 169: {
! 170: long av=avma,tetpil;
! 171: GEN px,py;
! 172:
! 173: px = nfmod_pol_reduce(nf,prhall,x); px = unifpol(nf,lift(px),1);
! 174: py = nfmod_pol_reduce(nf,prhall,y); py = unifpol(nf,lift(py),1);
! 175: px = unifpol(nf,nf_pol_mul(nf,px,py),0);
! 176: tetpil=avma;
! 177: return gerepile(av,tetpil,nfmod_pol_reduce(nf,prhall,px));
! 178: }
! 179:
! 180: /* division euclidienne du polynome x par le polynome y */
! 181: static GEN
! 182: nf_pol_divres(GEN nf,GEN x,GEN y,GEN *pr)
! 183: {
! 184: long av = avma,tetpil;
! 185: GEN nq = poldivres(unifpol(nf,x,1),unifpol(nf,y,1),pr);
! 186: GEN *gptr[2];
! 187:
! 188: tetpil=avma; nq=unifpol(nf,nq,0);
! 189: if (pr) *pr = unifpol(nf,*pr,0);
! 190: gptr[0]=&nq; gptr[1]=pr;
! 191: gerepilemanysp(av,tetpil,gptr,pr ? 2:1);
! 192: return nq;
! 193: }
! 194:
! 195: /* division euclidienne du polynome x par le polynome y modulo prhall */
! 196: static GEN
! 197: nfmod_pol_divres(GEN nf,GEN prhall,GEN x,GEN y, GEN *pr)
! 198: {
! 199: long av=avma,dx,dy,dz,i,j,k,l,n,tetpil;
! 200: GEN z,p1,p2,p3,px,py;
! 201:
! 202: py = nfmod_pol_reduce(nf,prhall,y);
! 203: if (gcmp0(py))
! 204: err(talker, "division by zero in nfmod_pol_divres");
! 205:
! 206: tetpil=avma;
! 207: px=nfmod_pol_reduce(nf,prhall,x);
! 208: dx=lgef(px)-3; dy=lgef(py)-3; dz=dx-dy;
! 209: if (dx<dy)
! 210: {
! 211: GEN vzero;
! 212:
! 213: if (pr) *pr = gerepile(av,tetpil,px);
! 214: else avma = av;
! 215:
! 216: n=lgef(nf[1])-3;
! 217: vzero = cgetg(n+1,t_COL);
! 218: n=lgef(nf[1])-3;
! 219: for (i=1; i<=n; i++) vzero[i]=zero;
! 220:
! 221: z=cgetg(3,t_POL); z[2]=(long)vzero;
! 222: z[1]=evallgef(2) | evalvarn(varn(px));
! 223: return z;
! 224: }
! 225:
! 226: z=cgetg(dz+3,t_POL); z[1]=evalsigne(1) | evallgef(3+dz);
! 227: setvarn(z,varn(px));
! 228: z[dz+2] = (long) element_divmodpr(nf,(GEN)px[dx+2],(GEN)py[dy+2],prhall);
! 229: for (i=dx-1; i>=dy; --i)
! 230: {
! 231: l=avma; p1=nfreducemodpr(nf,(GEN)px[i+2],prhall);
! 232: for (j=i-dy+1; j<=i && j<=dz; j++)
! 233: {
! 234: p2=element_mul(nf,(GEN)z[j+2],(GEN)py[i-j+2]);
! 235: p2=nfreducemodpr(nf,p2,prhall); p1=gsub(p1,p2);
! 236: }
! 237: tetpil=avma; p3=element_divmodpr(nf,p1,(GEN)py[dy+2],prhall);
! 238: z[i-dy+2]=lpile(l,tetpil,p3);
! 239: z[i-dy+2]=(long)nfreducemodpr(nf,(GEN)z[i-dy+2],prhall);
! 240: }
! 241: l=avma;
! 242: for (i=dy-1; i>=0; --i)
! 243: {
! 244: l=avma; p1=((GEN)px[i+2]);
! 245: for (j=0; j<=i && j<=dz; j++)
! 246: {
! 247: p2=element_mul(nf,(GEN)z[j+2],(GEN)py[i-j+2]);
! 248: p2=nfreducemodpr(nf,p2,prhall); tetpil=avma; p1=gsub(p1,p2);
! 249: }
! 250: p1=gerepile(l,tetpil,p1);
! 251: if (!gcmp0(nfreducemodpr(nf,p1,prhall))) break;
! 252: }
! 253:
! 254: if (!pr) { avma = l; return z; }
! 255:
! 256: if (i<0)
! 257: {
! 258: avma=l;
! 259: p3 = cgetg(3,t_POL); p3[2]=zero;
! 260: p3[1] = evallgef(2) | evalvarn(varn(px));
! 261: *pr=p3; return z;
! 262: }
! 263:
! 264: p3=cgetg(i+3,t_POL);
! 265: p3[1]=evalsigne(1) | evallgef(i+3) | evalvarn(varn(px));
! 266: p3[i+2]=(long)nfreducemodpr(nf,p1,prhall);
! 267: for (k=i-1; k>=0; --k)
! 268: {
! 269: l=avma; p1=((GEN)px[k+2]);
! 270: for (j=0; j<=k && j<=dz; j++)
! 271: {
! 272: p2=element_mul(nf,(GEN)z[j+2],(GEN)py[k-j+2]);
! 273: p2=nfreducemodpr(nf,p2,prhall); tetpil=avma; p1=gsub(p1,p2);
! 274: }
! 275: p3[k+2]=lpile(l,tetpil,nfreducemodpr(nf,p1,prhall));
! 276: }
! 277: *pr=p3; return z;
! 278: }
! 279:
! 280: /* PGCD des polynomes x et y, par l'algorithme du sub-resultant */
! 281: static GEN
! 282: nf_pol_subres(GEN nf,GEN x,GEN y)
! 283: {
! 284: long av=avma,tetpil;
! 285: GEN s = srgcd(unifpol(nf,x,1), unifpol(nf,y,1));
! 286:
! 287: tetpil=avma; return gerepile(av,tetpil,unifpol(nf,s,1));
! 288: }
! 289:
! 290: /* PGCD des polynomes x et y modulo prhall */
! 291: static GEN
! 292: nfmod_pol_gcd(GEN nf,GEN prhall,GEN x,GEN y)
! 293: {
! 294: long av=avma;
! 295: GEN p1,p2;
! 296:
! 297: if (lgef(x)<lgef(y)) { p1=y; y=x; x=p1; }
! 298: p1=nfmod_pol_reduce(nf,prhall,x);
! 299: p2=nfmod_pol_reduce(nf,prhall,y);
! 300: while (!isexactzero(p2))
! 301: {
! 302: GEN p3;
! 303:
! 304: nfmod_pol_divres(nf,prhall,p1,p2,&p3);
! 305: p1=p2; p2=p3;
! 306: }
! 307: return gerepileupto(av,p1);
! 308: }
! 309:
! 310: /* Calcul pol^e modulo prhall et le polynome pmod */
! 311: static GEN
! 312: nfmod_pol_pow(GEN nf,GEN prhall,GEN pmod,GEN pol,GEN e)
! 313: {
! 314: long i, av = avma, n = lgef(nf[1])-3;
! 315: GEN p1,p2,vun;
! 316:
! 317: vun=cgetg(n+1,t_COL); vun[1]=un; for (i=2; i<=n; i++) vun[i]=zero;
! 318: p1=gcopy(polun[varn(pol)]); p1[2]=(long)vun;
! 319: if (gcmp0(e)) return p1;
! 320:
! 321: p2=nfmod_pol_reduce(nf,prhall,pol);
! 322: for(;;)
! 323: {
! 324: if (!vali(e))
! 325: {
! 326: p1=nfmod_pol_mul(nf,prhall,p1,p2);
! 327: nfmod_pol_divres(nf,prhall,p1,pmod,&p1);
! 328: }
! 329: if (gcmp1(e)) break;
! 330:
! 331: e=shifti(e,-1);
! 332: p2=nfmod_pol_sqr(nf,prhall,p2);
! 333: nfmod_pol_divres(nf,prhall,p2,pmod,&p2);
! 334: }
! 335: return gerepileupto(av,p1);
! 336: }
! 337:
! 338: /* factorisation du polynome x modulo pr */
! 339: GEN
! 340: nffactormod(GEN nf,GEN pol,GEN pr)
! 341: {
! 342: long av = avma, tetpil,lb,nbfact,psim,N,n,i,j,k,d,e,vf,r,kk;
! 343: GEN y,ex,*t,f1,f2,f3,df1,g1,polb,pold,polu,vker;
! 344: GEN Q,f,x,u,v,v2,v3,vz,q,vun,vzero,prhall;
! 345:
! 346: nf=checknf(nf);
! 347: if (typ(pol)!=t_POL) err(typeer,"nffactormod");
! 348: if (varn(pol) >= varn(nf[1]))
! 349: err(talker,"polynomial variable must have highest priority in nffactormod");
! 350:
! 351: prhall=nfmodprinit(nf,pr); n=lgef(nf[1])-3;
! 352: vun = gscalcol_i(gun, n);
! 353: vzero = gscalcol_i(gzero, n);
! 354:
! 355: f=unifpol(nf,pol,0); f=nfmod_pol_reduce(nf,prhall,f);
! 356: d=lgef(f)-3; vf=varn(f);
! 357: t = (GEN*)new_chunk(d+1);
! 358: ex= new_chunk(d+1);
! 359: x=gcopy(polx[vf]); x[3]=(long)vun; x[2]=(long)vzero;
! 360: if (d<=1) { nbfact=2; t[1] = f; ex[1]=1; }
! 361: else
! 362: {
! 363: q = (GEN)pr[1]; psim = VERYBIGINT;
! 364: if (!is_bigint(q)) psim = itos(q);
! 365: /* psim has an effect only when p is small. If too big, set it to a huge
! 366: * number (i.e ignore it) to avoid an error in itos on next line.
! 367: */
! 368: q=gpuigs(q, itos((GEN)pr[4]));
! 369: f1=f; e=1; nbfact=1;
! 370: while (lgef(f1)>3)
! 371: {
! 372: df1=deriv(f1,vf); f2=nfmod_pol_gcd(nf,prhall,f1,df1);
! 373: g1=nfmod_pol_divres(nf,prhall,f1,f2,NULL); k=0;
! 374: while (lgef(g1)>3)
! 375: {
! 376: k++;
! 377: if (k%psim == 0)
! 378: {
! 379: k++; f2=nfmod_pol_divres(nf,prhall,f2,g1,NULL);
! 380: }
! 381: f3=nfmod_pol_gcd(nf,prhall,f2,g1);
! 382: u = nfmod_pol_divres(nf,prhall,g1,f3,NULL);
! 383: f2= nfmod_pol_divres(nf,prhall,f2,f3,NULL);
! 384: g1=f3;
! 385: if (lgef(u)>3)
! 386: {
! 387: N=lgef(u)-3; Q=cgetg(N+1,t_MAT);
! 388: v3=cgetg(N+1,t_COL); Q[1]=(long)v3;
! 389: v3[1]=(long)vun; for (i=2; i<=N; i++) v3[i]=(long)vzero;
! 390:
! 391: v2 = v = nfmod_pol_pow(nf,prhall,u,x,q);
! 392: for (j=2; j<=N; j++)
! 393: {
! 394: v3=cgetg(N+1,t_COL); Q[j]=(long)v3;
! 395: for (i=1; i<=lgef(v2)-2; i++) v3[i]=v2[i+1];
! 396: for (; i<=N; i++) v3[i]=(long)vzero;
! 397: if (j<N)
! 398: {
! 399: v2=nfmod_pol_mul(nf,prhall,v2,v);
! 400: nfmod_pol_divres(nf,prhall,v2,u,&v2);
! 401: }
! 402: }
! 403: for (i=1; i<=N; i++)
! 404: coeff(Q,i,i)=lsub((GEN)coeff(Q,i,i),vun);
! 405: v2=nfkermodpr(nf,Q,prhall); r=lg(v2)-1; t[nbfact]=gcopy(u); kk=1;
! 406: if (r>1)
! 407: {
! 408: vker=cgetg(r+1,t_COL);
! 409: for (i=1; i<=r; i++)
! 410: {
! 411: v3=cgetg(N+2,t_POL);
! 412: v3[1]=evalsigne(1)+evallgef(2+N); setvarn(v3,vf);
! 413: vker[i]=(long)v3; for (j=1; j<=N; j++) v3[j+1]=coeff(v2,j,i);
! 414: normalizepol(v3);
! 415: }
! 416: }
! 417: while (kk<r)
! 418: {
! 419: v=gcopy(polun[vf]); v[2]=(long)vzero;
! 420: for (i=1; i<=r; i++)
! 421: {
! 422: vz=cgetg(n+1,t_COL);
! 423: for (j=1; j<=n; j++)
! 424: vz[j] = lmodsi(mymyrand()>>8, q);
! 425: vz=nfreducemodpr(nf,vz,prhall);
! 426: v=gadd(v,nfmod_pol_mul(nf,prhall,vz,(GEN)vker[i]));
! 427: }
! 428: for (i=1; i<=kk && kk<r; i++)
! 429: {
! 430: polb=t[nbfact+i-1]; lb=lgef(polb);
! 431: if (lb>4)
! 432: {
! 433: if(psim==2)
! 434: polu=nfmod_split2(nf,prhall,polb,v,q);
! 435: else
! 436: {
! 437: polu=nfmod_pol_pow(nf,prhall,polb,v,shifti(q,-1));
! 438: polu=gsub(polu,vun);
! 439: }
! 440: pold=nfmod_pol_gcd(nf,prhall,polb,polu);
! 441: if (lgef(pold)>3 && lgef(pold)<lb)
! 442: {
! 443: t[nbfact+i-1]=pold; kk++;
! 444: t[nbfact+kk-1]=nfmod_pol_divres(nf,prhall,polb,pold,NULL);
! 445: }
! 446: }
! 447: }
! 448: }
! 449: for (i=nbfact; i<nbfact+r; i++) ex[i]=e*k;
! 450: nbfact+=r;
! 451: }
! 452: }
! 453: e*=psim; j=(lgef(f2)-3)/psim+3; f1=cgetg(j,t_POL);
! 454: f1[1] = evalsigne(1) | evallgef(j) | evalvarn(vf);
! 455: for (i=2; i<j; i++)
! 456: f1[i]=(long)element_powmodpr(nf,(GEN)f2[psim*(i-2)+2],
! 457: gdiv(q,(GEN)pr[1]),prhall);
! 458: }
! 459: }
! 460: if (nbfact < 2)
! 461: err(talker, "%Z not a prime (nffactormod)", q);
! 462: v=element_divmodpr(nf,vun,gmael(t,1,lgef(t[1])-1),prhall);
! 463: t[1]=unifpol(nf,nfmod_pol_mul(nf,prhall,v,(GEN)t[1]),1);
! 464: for (j=2; j<nbfact; j++)
! 465: if (ex[j])
! 466: {
! 467: v=element_divmodpr(nf,vun,gmael(t,j,lgef(t[j])-1),prhall);
! 468: t[j]=unifpol(nf,nfmod_pol_mul(nf,prhall,v,(GEN)t[j]),1);
! 469: }
! 470:
! 471: tetpil=avma; y=cgetg(3,t_MAT);
! 472: u=cgetg(nbfact,t_COL); y[1]=(long)u;
! 473: v=cgetg(nbfact,t_COL); y[2]=(long)v;
! 474: for (j=1,k=0; j<nbfact; j++)
! 475: if (ex[j])
! 476: {
! 477: k++;
! 478: u[k]=lcopy((GEN)t[j]);
! 479: v[k]=lstoi(ex[j]);
! 480: }
! 481: return gerepile(av,tetpil,y);
! 482: }
! 483:
! 484: /* Calcule pol + pol^2 + ... + pol^(q/2) modulo prhall et le polynome pmod */
! 485: static GEN
! 486: nfmod_split2(GEN nf,GEN prhall,GEN pmod,GEN pol,GEN exp)
! 487: {
! 488: long av = avma;
! 489: GEN p1,p2,q;
! 490:
! 491: if (cmpis(exp,2)<=0) return pol;
! 492: p2=p1=pol; q=shifti(exp,-1);
! 493: while (!gcmp1(q))
! 494: {
! 495: p2=nfmod_pol_sqr(nf,prhall,p2);
! 496: nfmod_pol_divres(nf,prhall,p2,pmod,&p2);
! 497: q=shifti(q,-1); p1=gadd(p1,p2);
! 498: }
! 499: return gerepileupto(av,p1);
! 500: }
! 501:
! 502: /* If p doesn't divide either a or b and has a divisor of degree 1, return it.
! 503: * Return NULL otherwise.
! 504: */
! 505: static GEN
! 506: p_ok(GEN nf, GEN p, GEN a)
! 507: {
! 508: long av,m,i;
! 509: GEN dec;
! 510:
! 511: if (divise(a,p)) return NULL;
! 512: av = avma; dec = primedec(nf,p); m=lg(dec);
! 513: for (i=1; i<m; i++)
! 514: {
! 515: GEN pr = (GEN)dec[i];
! 516: if (is_pm1(pr[4]))
! 517: {
! 518: if (DEBUGLEVEL>=4)
! 519: fprintferr("Premier choisi pour decomposition: %Z\n", pr);
! 520: return pr;
! 521: }
! 522: }
! 523: avma = av; return NULL;
! 524: }
! 525:
! 526: static GEN
! 527: choose_prime(GEN nf, GEN dk, GEN lim)
! 528: {
! 529: GEN p, pr;
! 530:
! 531: p = nextprime(lim);
! 532: for (;;)
! 533: {
! 534: if ((pr = p_ok(nf,p,dk))) break;
! 535: p = nextprime(addis(p,2));
! 536: }
! 537:
! 538: return pr;
! 539: }
! 540:
! 541: /* Renvoie les racines de pol contenues dans nf */
! 542: GEN
! 543: nfroots(GEN nf,GEN pol)
! 544: {
! 545: long av=avma,tetpil,i,d=lgef(pol);
! 546: GEN p1,p2,polbase,polmod,den;
! 547:
! 548: nf=checknf(nf);
! 549: if (typ(pol)!=t_POL) err(talker,"not a polynomial in nfroots");
! 550: if (varn(pol) >= varn(nf[1]))
! 551: err(talker,"polynomial variable must have highest priority in nfroots");
! 552:
! 553: polbase=unifpol(nf,pol,0);
! 554:
! 555: if (d==3)
! 556: {
! 557: tetpil=avma; p1=cgetg(1,t_VEC);
! 558: return gerepile(av,tetpil,p1);
! 559: }
! 560:
! 561: if (d==4)
! 562: {
! 563: tetpil=avma; p1=cgetg(2,t_VEC);
! 564: p1[1] = (long)basistoalg(nf,gneg_i(
! 565: element_div(nf,(GEN)polbase[2],(GEN)polbase[3])));
! 566: return gerepile(av,tetpil,p1);
! 567: }
! 568:
! 569: p1=element_inv(nf,leading_term(polbase));
! 570: polbase=nf_pol_mul(nf,p1,polbase);
! 571:
! 572: den=gun;
! 573: for (i=2; i<d; i++)
! 574: if (! gcmp0((GEN)polbase[i]))
! 575: den = glcm(den,denom((GEN)polbase[i]));
! 576: if (! gcmp1(absi(den)))
! 577: for (i=2; i<d; i++)
! 578: polbase[i] = lmul(den,(GEN)polbase[i]);
! 579:
! 580: polmod=unifpol(nf,polbase,1);
! 581:
! 582: if (DEBUGLEVEL>=4)
! 583: fprintferr("On teste si le polynome est square-free\n");
! 584:
! 585: p1=derivpol(polmod);
! 586: p2=nf_pol_subres(nf,polmod,p1);
! 587:
! 588: if (degree(p2) > 0)
! 589: {
! 590: p1=element_inv(nf,leading_term(p2));
! 591: p2=nf_pol_mul(nf,p1,p2);
! 592: polmod=nf_pol_divres(nf,polmod,p2,NULL);
! 593:
! 594: p1=element_inv(nf,leading_term(polmod));
! 595: polmod=nf_pol_mul(nf,p1,polmod);
! 596:
! 597: d=lgef(polmod); den=gun;
! 598: for (i=2; i<d; i++)
! 599: if (!gcmp0((GEN)polmod[i]))
! 600: den = glcm(den,denom((GEN)polmod[i]));
! 601: if (!gcmp1(absi(den)))
! 602: for (i=2; i<d; i++)
! 603: polmod[i] = lmul(den,(GEN)polmod[i]);
! 604:
! 605: polmod=unifpol(nf,polmod,1);
! 606: }
! 607:
! 608: p1 = nfsqff(nf,polmod,1);
! 609: tetpil=avma; return gerepile(av, tetpil, gen_sort(p1, 0, cmp_pol));
! 610: }
! 611:
! 612: /* Relevement de elt modulo id minimal */
! 613: static GEN
! 614: nf_bestlift(GEN id,GEN idinv,GEN den,GEN elt)
! 615: {
! 616: return gsub(elt,gmul(id,ground(gmul(den,gmul(idinv,elt)))));
! 617: }
! 618:
! 619: /* Releve le polynome pol avec des coeff de norme t2 <= C si possible */
! 620: static GEN
! 621: nf_pol_lift(GEN id,GEN idinv,GEN den,GEN pol)
! 622: {
! 623: long i, d = lgef(pol);
! 624: GEN p1 = pol;
! 625:
! 626: pol=cgetg(d,t_POL); pol[1]=p1[1];
! 627: for (i=2; i<d; i++)
! 628: pol[i] = (long) nf_bestlift(id,idinv,den,(GEN)p1[i]);
! 629: return pol;
! 630: }
! 631:
! 632: #if 0
! 633: /* Evalue le polynome pol en elt */
! 634: static GEN
! 635: nf_pol_eval(GEN nf,GEN pol,GEN elt)
! 636: {
! 637: long av=avma,tetpil,i;
! 638: GEN p1;
! 639:
! 640: i=lgef(pol)-1; if (i==2) return gcopy((GEN)pol[2]);
! 641:
! 642: p1=element_mul(nf,(GEN)pol[i],elt);
! 643: for (i--; i>=3; i--)
! 644: p1=element_mul(nf,elt,gadd((GEN)pol[i],p1));
! 645: tetpil=avma; return gerepile(av,tetpil,gadd(p1,(GEN)pol[2]));
! 646: }
! 647: #endif
! 648:
! 649: /* Calcule la factorisation du polynome x dans nf */
! 650: GEN
! 651: nffactor(GEN nf,GEN pol)
! 652: { GEN y,p1,p2,den,p3,p4,quot, rep = cgetg(3,t_MAT);
! 653: long av = avma,tetpil,i,d;
! 654:
! 655: if (DEBUGLEVEL >= 4) timer2();
! 656:
! 657: nf=checknf(nf);
! 658: if (typ(pol)!=t_POL) err(typeer,"nffactor");
! 659: if (varn(pol) >= varn(nf[1]))
! 660: err(talker,"polynomial variable must have highest priority in nffactor");
! 661:
! 662: d=lgef(pol);
! 663: if (d==3)
! 664: {
! 665: rep[1]=lgetg(1,t_COL);
! 666: rep[2]=lgetg(1,t_COL);
! 667: return rep;
! 668: }
! 669: if (d==4)
! 670: {
! 671: p1=cgetg(2,t_COL); rep[1]=(long)p1; p1[1]=lcopy(pol);
! 672: p1=cgetg(2,t_COL); rep[2]=(long)p1; p1[1]=un;
! 673: return rep;
! 674: }
! 675:
! 676: p1=element_inv(nf,leading_term(pol));
! 677: pol=nf_pol_mul(nf,p1,pol);
! 678:
! 679: p1=unifpol(nf,pol,0); den=gun;
! 680: for (i=2; i<d; i++)
! 681: if (! gcmp0((GEN)p1[i]))
! 682: den = glcm(den,denom((GEN)p1[i]));
! 683: if (! gcmp1(absi(den)))
! 684: for (i=2; i<d; i++)
! 685: p1[i] = lmul(den,(GEN)p1[i]);
! 686:
! 687: if (DEBUGLEVEL>=4)
! 688: fprintferr("On teste si le polynome est square-free\n");
! 689:
! 690: p2=derivpol(p1);
! 691: p3=nf_pol_subres(nf,p1,p2);
! 692:
! 693: if (degree(p3) > 0)
! 694: {
! 695: p4=element_inv(nf,leading_term(p3));
! 696: p3=nf_pol_mul(nf,p4,p3);
! 697:
! 698: p2=nf_pol_divres(nf,p1,p3,NULL);
! 699: p4=element_inv(nf,leading_term(p2));
! 700: p2=nf_pol_mul(nf,p4,p2);
! 701:
! 702: d=lgef(p2); den=gun;
! 703: for (i=2; i<d; i++)
! 704: if (!gcmp0((GEN)p2[i]))
! 705: den = glcm(den,denom((GEN)p2[i]));
! 706: if (!gcmp1(absi(den)))
! 707: for (i=2; i<d; i++)
! 708: p2[i] = lmul(den,(GEN)p2[i]);
! 709:
! 710: p2=unifpol(nf,p2,1);
! 711: tetpil = avma; y = nfsqff(nf,p2,0);
! 712: i = nfcmbf.nfact;
! 713:
! 714: quot=nf_pol_divres(nf,p1,p2,NULL);
! 715: p3=(GEN)gpmalloc((i+1) * sizeof(long));
! 716: for ( ; i>=1; i--)
! 717: {
! 718: GEN fact=(GEN)y[i], quo = quot, rem;
! 719: long e = 0;
! 720:
! 721: do
! 722: {
! 723: quo = nf_pol_divres(nf,quo,fact,&rem);
! 724: e++;
! 725: }
! 726: while (gcmp0(rem));
! 727: p3[i]=lstoi(e);
! 728: }
! 729: avma = (long)y; y = gerepile(av, tetpil, y);
! 730: p2=cgetg(i+1, t_COL); for (; i>=1; i--) p2[i]=lstoi(p3[i]);
! 731: free(p3);
! 732: }
! 733: else
! 734: {
! 735: tetpil=avma; y = gerepile(av,tetpil,nfsqff(nf,p1,0));
! 736: i = nfcmbf.nfact;
! 737: p2=cgetg(i+1, t_COL); for (; i>=1; i--) p2[i]=un;
! 738: }
! 739: if (DEBUGLEVEL>=4)
! 740: fprintferr("Nombre de facteur(s) trouve(s) : %ld\n", nfcmbf.nfact);
! 741: rep[1]=(long)y;
! 742: rep[2]=(long)p2; return sort_factor(rep, cmp_pol);
! 743: }
! 744:
! 745: /* teste si la matrice M est suffisament orthogonale */
! 746: static long
! 747: test_mat(GEN M, GEN p, GEN C2, long k)
! 748: {
! 749: long av = avma, i, N = lg(M);
! 750: GEN min, prod, L2, R;
! 751:
! 752: min = prod = gcoeff(M,1,1);
! 753: for (i = 2; i < N; i++)
! 754: {
! 755: L2 = gcoeff(M,i,i); prod = mpmul(prod,L2);
! 756: if (mpcmp(L2,min) < 0) min = L2;
! 757: }
! 758: R = mpmul(min, gpowgs(p, k<<1));
! 759: i = mpcmp(mpmul(C2,prod), R); avma = av;
! 760: return (i < 0);
! 761: }
! 762:
! 763: /* calcule la matrice correspondant a pr^e jusqu'a ce que R(pr^e) > C */
! 764: static GEN
! 765: T2_matrix_pow(GEN nf, GEN pre, GEN p, GEN C, long *kmax, long prec)
! 766: {
! 767: long av=avma,av1,lim, k = *kmax, N = lgef((GEN)nf[1])-3;
! 768: int tot_real = !signe(gmael(nf,2,2));
! 769: GEN p1,p2,p3,u,C2,T2, x = (GEN)nf[1];
! 770:
! 771: C2 = gdiv(gmul2n(C,2), absi((GEN)nf[3]));
! 772: p1 = gmul(pre,lllintpartial(pre)); av1 = avma;
! 773: T2 = tot_real? gmael(nf,5,4)
! 774: : nf_get_T2((GEN) nf[7], roots(x,prec));
! 775: p3 = qf_base_change(T2,p1,1);
! 776:
! 777: if (N <= 6 && test_mat(p3,p,C2,k))
! 778: {
! 779: avma = av1; return gerepileupto(av,p1);
! 780: }
! 781:
! 782: av1=avma; lim = stack_lim(av1,2);
! 783: for (;;)
! 784: {
! 785: if (DEBUGLEVEL>2) fprintferr("exponent: %ld\n",k);
! 786:
! 787: for(;;)
! 788: {
! 789: u = tot_real? lllgramint(p3): lllgramintern(p3,100,1,prec);
! 790: if (u) break;
! 791:
! 792: prec=(prec<<1)-2;
! 793: if (DEBUGLEVEL > 1) err(warnprec,"nffactor[1]",prec);
! 794: T2 = nf_get_T2((GEN) nf[7], roots(x,prec));
! 795: p3 = qf_base_change(T2,p1,1);
! 796: }
! 797: if (DEBUGLEVEL>2) msgtimer("lllgram + base change");
! 798: p3 = qf_base_change(p3,u,1);
! 799: if (test_mat(p3,p,C2,k))
! 800: {
! 801: *kmax = k;
! 802: return gerepileupto(av,gmul(p1,u));
! 803: }
! 804:
! 805: /* il faut augmenter la precision en meme temps */
! 806: p2=shifti(gceil(mulsr(k, glog(p,DEFAULTPREC))),-1);
! 807: prec += (long)(itos(p2)*pariK1);
! 808: if (DEBUGLEVEL > 1) err(warnprec,"nffactor[2]",prec);
! 809: k = k<<1; p1 = idealmullll(nf,p1,p1);
! 810: if (low_stack(lim, stack_lim(av1,2)))
! 811: {
! 812: if (DEBUGMEM>1) err(warnmem,"T2_matrix_pow");
! 813: p1 = gerepileupto(av1,p1);
! 814: }
! 815: if (!tot_real) T2 = nf_get_T2((GEN) nf[7], roots(x,prec));
! 816: p3 = qf_base_change(T2,p1,1);
! 817: }
! 818: }
! 819:
! 820: /* Calcule la factorisation du polynome x qui est sans facteurs carres dans nf,
! 821: Le polynome est a coefficients dans Z_k et son terme dominant est un entier
! 822: rationnel, si fl=1 renvoie seulement les racines du polynome contenues
! 823: dans le corps */
! 824: static GEN
! 825: nfsqff(GEN nf,GEN pol, long fl)
! 826: {
! 827: long d=lgef(pol),i,k,m,n,av=avma,tetpil,newprec,prec;
! 828: GEN p1,pr,p2,rep,k2,C,h,dk,dki,p,prh,p3,T2,polbase,fact,pk;
! 829: GEN polmod,polred,hinv,lt,minp,den,maxp=shifti(gun,32),run;
! 830:
! 831: dk=absi((GEN)nf[3]);
! 832: dki=mulii(dk,(GEN)nf[4]);
! 833: n=lgef(nf[1])-3;
! 834:
! 835: polbase = unifpol(nf,pol,0);
! 836: polmod = unifpol(nf,pol,1);
! 837: dki=mulii(dki,gnorm((GEN)polmod[d-1]));
! 838:
! 839: prec = DEFAULTPREC;
! 840: for (;;)
! 841: {
! 842: if (prec <= gprecision(nf))
! 843: T2 = gprec_w(gmael(nf,5,3), prec);
! 844: else
! 845: T2 = nf_get_T2((GEN)nf[7], roots((GEN)nf[1], prec));
! 846:
! 847: run=realun(prec);
! 848: p1=realzero(prec);
! 849: for (i=2; i<d; i++)
! 850: {
! 851: p2 = gmul(run, (GEN)polbase[i]);
! 852: p1 = addrr(p1, qfeval(T2, p2));
! 853: if (signe(p1) < 0) break;
! 854: }
! 855:
! 856: if (signe(p1) > 0) break;
! 857:
! 858: prec = (prec<<1)-2;
! 859: if (DEBUGLEVEL > 1) err(warnprec, "nfsqff", prec);
! 860: }
! 861:
! 862: if (DEBUGLEVEL>=4)
! 863: fprintferr("La norme de ce polynome est : %Z\n", p1);
! 864:
! 865: lt=(GEN)leading_term(polbase)[1];
! 866: p2=mulis(sqri(lt),n);
! 867: C=mpadd(p1,p2);
! 868: C=mpadd(C,gsqrt(gmul(p1,p2),prec));
! 869:
! 870: if (!fl)
! 871: C=mpmul(C,sqri(binome(shifti(stoi(n-1),-1),(n-1)>>2)));
! 872:
! 873: C=gmul(C,sqri(lt));
! 874:
! 875: if (DEBUGLEVEL>=4)
! 876: fprintferr("La borne de la norme des coeff du diviseur est : %Z\n", C);
! 877:
! 878: k2=gmul2n(gmulgs(glog(gdivgs(gmul2n(C,2),n),DEFAULTPREC),n),-1);
! 879: if (!fl) k2=mulrr(k2,dbltor(1.1));
! 880:
! 881: minp=gmin(gexp(gmul2n(k2,-6),BIGDEFAULTPREC), maxp);
! 882: minp=gceil(minp);
! 883:
! 884: if (DEBUGLEVEL>=4)
! 885: {
! 886: fprintferr("borne inf. sur les nombres premiers : %Z\n", minp);
! 887: msgtimer("Calcul des bornes");
! 888: }
! 889: for (;;)
! 890: {
! 891: pr=choose_prime(nf,dki,minp); p=(GEN)pr[1];
! 892: prh=prime_to_ideal(nf,pr);
! 893:
! 894: polred=gcopy(polbase);
! 895: lt=(GEN)leading_term(polbase)[1];
! 896: lt=mpinvmod(lt,p);
! 897:
! 898: for (i=2; i<d; i++)
! 899: polred[i] = nfreducemodpr_i(gmul(lt,(GEN)polbase[i]), prh)[1];
! 900: if (!divise(discsr(polred),p)) break;
! 901: minp = addis(p,1);
! 902: }
! 903:
! 904: k = itos(gceil(gdiv(k2,glog(p,BIGDEFAULTPREC))));
! 905: rep=(GEN)simplefactmod(polred,p)[1];
! 906:
! 907: if (DEBUGLEVEL>=4)
! 908: {
! 909: msgtimer("Choix de l'ideal premier");
! 910: fprintferr("Nombre de facteurs irreductibles modulo pr = %ld\n", lg(rep)-1);
! 911: }
! 912: if (lg(rep)==2)
! 913: {
! 914: if (fl) { avma=av; return cgetg(1,t_VEC); }
! 915: rep=cgetg(2,t_VEC); rep[1]=lcopy(polmod);
! 916: nfcmbf.nfact=1; return gerepileupto(av, rep);
! 917: }
! 918:
! 919: p2=cgetr(DEFAULTPREC);
! 920: affir(mulii(absi(dk),gpowgs(p,k)),p2);
! 921: p2=shifti(gceil(mplog(p2)),-1);
! 922:
! 923: newprec = MEDDEFAULTPREC + (long)(itos(p2)*pariK1);
! 924: if (DEBUGLEVEL>=4)
! 925: fprintferr("nouvelle precision : %ld\n",newprec);
! 926:
! 927: prh = idealpows(nf,pr,k); m = k;
! 928: h = T2_matrix_pow(nf,prh,p,C, &k, newprec);
! 929: if (m != k) prh=idealpows(nf,pr,k);
! 930:
! 931: if (DEBUGLEVEL>=4)
! 932: {
! 933: fprintferr("un exposant convenable est : %ld\n",(long)k);
! 934: msgtimer("Calcul de H");
! 935: }
! 936:
! 937: pk = gcoeff(prh,1,1);
! 938: lt=(GEN)leading_term(polbase)[1];
! 939: lt=mpinvmod(lt,pk);
! 940:
! 941: polred[1] = polbase[1];
! 942: for (i=2; i<d; i++)
! 943: polred[i] = nfreducemodpr_i(gmul(lt,(GEN)polbase[i]), prh)[1];
! 944:
! 945: fact = lift_intern((GEN)factmod(polred,p)[1]);
! 946: rep = hensel_lift_fact(polred,fact,p,pk,k);
! 947:
! 948: if (DEBUGLEVEL >= 4) msgtimer("Calcul de la factorisation pr-adique");
! 949:
! 950: den=ginv(det(h));
! 951: hinv=adj(h);
! 952: lt=(GEN)leading_term(polbase)[1];
! 953:
! 954: if (fl)
! 955: {
! 956: long x_a[] = { evaltyp(t_POL)|m_evallg(4), 0,0,0 };
! 957: GEN mlt = negi(lt), rem;
! 958: x_a[1] = polbase[1]; setlgef(x_a, 4);
! 959: x_a[3] = un;
! 960: p1=cgetg(lg(rep)+1,t_VEC);
! 961: polbase = unifpol(nf,polbase,1);
! 962: for (m=1,i=1; i<lg(rep); i++)
! 963: {
! 964: p2=(GEN)rep[i]; if (lgef(p2)!=4) break;
! 965:
! 966: p3 = algtobasis(nf, gmul(mlt,(GEN)p2[2]));
! 967: p3 = nf_bestlift(h,hinv,den,p3);
! 968: p3 = gdiv(p3,lt);
! 969: x_a[2] = lneg(p3); /* check P(p3) == 0 */
! 970: p2 = poldivres(polbase, unifpol(nf,x_a,1), &rem);
! 971: if (!signe(rem)) { polbase = p2; p1[m++] = (long)p3; }
! 972: }
! 973: tetpil=avma; rep=cgetg(m,t_VEC);
! 974: for (i=1; i<m; i++) rep[i]=(long)basistoalg(nf,(GEN)p1[i]);
! 975: return gerepile(av,tetpil,rep);
! 976: }
! 977:
! 978: for (i=1; i<lg(rep); i++)
! 979: rep[i] = (long)unifpol(nf,(GEN)rep[i],0);
! 980:
! 981: nfcmbf.pol = polmod;
! 982: nfcmbf.lt = lt;
! 983: nfcmbf.h = h;
! 984: nfcmbf.hinv = hinv;
! 985: nfcmbf.den = den;
! 986: nfcmbf.fact = rep;
! 987: nfcmbf.res = cgetg(lg(rep)+1,t_VEC);
! 988: nfcmbf.nfact = 0;
! 989: nfcmbf.nfactmod = lg(rep)-1;
! 990: nf_combine_factors(nf,1,NULL,d-3,1);
! 991:
! 992: if (DEBUGLEVEL >= 4) msgtimer("Reconnaissance des facteurs");
! 993:
! 994: i = nfcmbf.nfact;
! 995: if (lgef(nfcmbf.pol)>3)
! 996: {
! 997: nfcmbf.res[++i] = (long) nf_pol_divres(nf,nfcmbf.pol,nfcmbf.lt,NULL);
! 998: nfcmbf.nfact = i;
! 999: }
! 1000:
! 1001: tetpil=avma; rep=cgetg(i+1,t_VEC);
! 1002: for ( ; i>=1; i--)
! 1003: rep[i]=(long)unifpol(nf,(GEN)nfcmbf.res[i],1);
! 1004: return gerepile(av,tetpil,rep);
! 1005: }
! 1006:
! 1007: static int
! 1008: nf_combine_factors(GEN nf,long fxn,GEN psf,long dlim,long hint)
! 1009: {
! 1010: int val=0; /* assume failure */
! 1011: GEN newf, newpsf = NULL;
! 1012: long newd,ltop,i;
! 1013:
! 1014: if (dlim<=0) return 0;
! 1015: if (fxn > nfcmbf.nfactmod) return 0;
! 1016: /* first, try deeper factors without considering the current one */
! 1017: if (fxn != nfcmbf.nfactmod)
! 1018: {
! 1019: val=nf_combine_factors(nf,fxn+1,psf,dlim,hint);
! 1020: if (val && psf) return 1;
! 1021: }
! 1022:
! 1023: /* second, try including the current modular factor in the product */
! 1024: newf=(GEN)nfcmbf.fact[fxn];
! 1025: if (!newf) return val; /* modular factor already used */
! 1026: newd=lgef(newf)-3;
! 1027: if (newd>dlim) return val; /* degree of new factor is too large */
! 1028:
! 1029: if (newd%hint == 0)
! 1030: {
! 1031: GEN p, quot,rem;
! 1032:
! 1033: newpsf = nf_pol_mul(nf, (psf)? psf: nfcmbf.lt, newf);
! 1034: newpsf = nf_pol_lift(nfcmbf.h,nfcmbf.hinv,nfcmbf.den,newpsf);
! 1035: /* try out the new combination */
! 1036: ltop=avma;
! 1037: quot=nf_pol_divres(nf,nfcmbf.pol,newpsf,&rem);
! 1038: if (gcmp0(rem)) /* found a factor */
! 1039: {
! 1040: p = nf_pol_mul(nf,element_inv(nf,leading_term(newpsf)),newpsf);
! 1041: nfcmbf.res[++nfcmbf.nfact] = (long) p; /* store factor */
! 1042: nfcmbf.fact[fxn]=0; /* remove used modular factor */
! 1043:
! 1044: /* fix up target */
! 1045: p=gun; quot=unifpol(nf,quot,0);
! 1046: for (i=2; i<lgef(quot); i++)
! 1047: if (!gcmp0((GEN)quot[i]))
! 1048: p = glcm(p, denom((GEN)quot[i]));
! 1049:
! 1050: nfcmbf.pol = nf_pol_mul(nf,p,quot);
! 1051: nfcmbf.lt = leading_term(nfcmbf.pol);
! 1052: return 1;
! 1053: }
! 1054: avma=ltop;
! 1055: }
! 1056:
! 1057: /* newpsf needs more; try for it */
! 1058: if (newd==dlim) return val; /* no more room in degree limit */
! 1059: if (fxn==nfcmbf.nfactmod) return val; /* no more modular factors to try */
! 1060:
! 1061: if (nf_combine_factors(nf,fxn+1,newpsf,dlim-newd,hint))
! 1062: {
! 1063: nfcmbf.fact[fxn]=0; /* remove used modular factor */
! 1064: return 1;
! 1065: }
! 1066: return val;
! 1067: }
! 1068:
! 1069: /* Calcule le polynome caracteristique de alpha sur nf ou alpha est un
! 1070: element de l'algebre nf[X]/(T) exprime comme polynome en x */
! 1071: GEN
! 1072: rnfcharpoly(GEN nf,GEN T,GEN alpha,int v)
! 1073: {
! 1074: long av=avma,tetpil;
! 1075: GEN p1;
! 1076:
! 1077: nf=checknf(nf); if (v<0) v = 0;
! 1078: if (typ(alpha) == t_POLMOD) alpha = lift_to_pol(alpha);
! 1079: p1 = caract2(unifpol(nf,T,1), unifpol(nf,alpha,1), v);
! 1080: tetpil=avma; return gerepile(av,tetpil,unifpol(nf,p1,1));
! 1081: }
! 1082:
! 1083: #if 0
! 1084: /* Calcule le polynome minimal de alpha sur nf ou alpha est un
! 1085: element de l'algebre nf[X]/(T) exprime comme polynome en x */
! 1086: GEN
! 1087: rnfminpoly(GEN nf,GEN T,GEN alpha,int n)
! 1088: {
! 1089: long av=avma,tetpil;
! 1090: GEN p1,p2;
! 1091:
! 1092: nf=checknf(nf); p1=rnfcharpoly(nf,T,alpha,n);
! 1093: tetpil=avma; p2=nf_pol_subres(nf,p1,deriv(p1,varn(T)));
! 1094: if (lgef(p2)==3) { avma=tetpil; return p1; }
! 1095:
! 1096: p1 = nf_pol_divres(nf,p1,p2,NULL);
! 1097: p2 = element_inv(nf,leading_term(p1));
! 1098: tetpil=avma; return gerepile(av,tetpil,unifpol(nf,nf_pol_mul(nf,p2,p1),1));
! 1099: }
! 1100: #endif
! 1101:
! 1102: /* relative Dedekind criterion over nf, applied to the order defined by a
! 1103: * root of irreducible polynomial T, modulo the prime ideal pr. Returns
! 1104: * [flag,basis,val], where basis is a pseudo-basis of the enlarged order,
! 1105: * flag is 1 iff this order is pr-maximal, and val is the valuation in pr of
! 1106: * the order discriminant
! 1107: */
! 1108: GEN
! 1109: rnfdedekind(GEN nf,GEN T,GEN pr)
! 1110: {
! 1111: long av=avma,vt,tetpil,r,d,da,n,m,i,j;
! 1112: GEN p1,p2,p,tau,g,vecun,veczero,matid;
! 1113: GEN prhall,res,h,k,base,Ca;
! 1114:
! 1115: nf=checknf(nf); Ca=unifpol(nf,T,0);
! 1116: res=cgetg(4,t_VEC);
! 1117: if (typ(pr)==t_VEC && lg(pr)==3)
! 1118: { prhall = (GEN)pr[2]; pr = (GEN)pr[1]; }
! 1119: else
! 1120: prhall=nfmodprinit(nf,pr);
! 1121: p=(GEN)pr[1]; tau=gdiv((GEN)pr[5],p);
! 1122: n=lgef(nf[1])-3; m=lgef(T)-3;
! 1123:
! 1124: vecun=cgetg(n+1,t_COL); vecun[1]=un;
! 1125: veczero=cgetg(n+1,t_COL); veczero[1]=zero;
! 1126: for (i=2; i<=n; i++) vecun[i] = veczero[i] = zero;
! 1127: matid=idmat(n);
! 1128:
! 1129: p1=(GEN)nffactormod(nf,Ca,pr)[1];
! 1130: g=lift((GEN)p1[1]); r=lg(p1);
! 1131: for (i=2; i<r; i++)
! 1132: g = nf_pol_mul(nf,g, lift((GEN)p1[i]));
! 1133: h=nfmod_pol_divres(nf,prhall,Ca,g,NULL);
! 1134: k=nf_pol_mul(nf,tau,gsub(Ca, nf_pol_mul(nf,lift(g),lift(h))));
! 1135: p2=nfmod_pol_gcd(nf,prhall,g,h);
! 1136: k= nfmod_pol_gcd(nf,prhall,p2,k);
! 1137:
! 1138: d=lgef(k)-3;
! 1139: vt = idealval(nf,discsr(T),pr) - 2*d;
! 1140: res[3]=lstoi(vt);
! 1141: if (!d || vt<=1) res[1]=un; else res[1]=zero;
! 1142:
! 1143: base=cgetg(3,t_VEC);
! 1144: p1=cgetg(m+d+1,t_MAT); base[1]=(long)p1;
! 1145: p2=cgetg(m+d+1,t_VEC); base[2]=(long)p2;
! 1146: for (j=1; j<=m; j++)
! 1147: {
! 1148: p2[j]=(long)matid;
! 1149: p1[j]=lgetg(m+1,t_COL);
! 1150: for (i=1; i<=m; i++)
! 1151: coeff(p1,i,j) = (i==j)?(long)vecun:(long)veczero;
! 1152: }
! 1153:
! 1154: if (d)
! 1155: {
! 1156: GEN pal = lift(nfmod_pol_divres(nf,prhall,Ca,k,NULL));
! 1157: GEN prinv=idealinv(nf,pr);
! 1158: GEN nfx=unifpol(nf,polx[varn(T)],0);
! 1159:
! 1160: for (j=m+1; j<=m+d; j++)
! 1161: {
! 1162: p1[j]=lgetg(m+1,t_COL);
! 1163: da=lgef(pal)-3;
! 1164: for (i=1; i<=da+1; i++) coeff(p1,i,j)=pal[i+1];
! 1165: for ( ; i<=m; i++) coeff(p1,i,j)=(long)veczero;
! 1166: p2[j]=(long)prinv;
! 1167: nf_pol_divres(nf,nf_pol_mul(nf,pal,nfx),T,&pal);
! 1168: }
! 1169: base=nfhermite(nf,base);
! 1170: }
! 1171: res[2]=(long)base; tetpil=avma; return gerepile(av,tetpil,gcopy(res));
! 1172: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>