Annotation of OpenXM_contrib/pari/src/modules/nffactor.c, Revision 1.1.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>