Annotation of OpenXM_contrib/pari/src/basemath/base3.c, Revision 1.1.1.1
1.1 maekawa 1: /*******************************************************************/
2: /* */
3: /* BASIC NF OPERATIONS */
4: /* */
5: /*******************************************************************/
6: /* $Id: base3.c,v 1.1.1.1 1999/09/16 13:47:20 karim Exp $ */
7: #include "pari.h"
8: int ker_trivial_mod_p(GEN x, GEN p);
9: long ideal_is_zk(GEN ideal,long N);
10: GEN idealaddtoone_i(GEN nf, GEN x, GEN y);
11:
12: /*******************************************************************/
13: /* */
14: /* OPERATIONS OVER NUMBER FIELD ELEMENTS. */
15: /* These are always represented as column vectors over the */
16: /* integral basis nf[7] */
17: /* */
18: /*******************************************************************/
19:
20: int
21: isnfscalar(GEN x)
22: {
23: long lx=lg(x),i;
24:
25: for (i=2; i<lx; i++)
26: if (!gcmp0((GEN)x[i])) return 0;
27: return 1;
28: }
29:
30: static GEN
31: checknfelt_mod(GEN nf, GEN x)
32: {
33: if (gegal((GEN)x[1],(GEN)nf[1])) return (GEN) x[2];
34: err(talker,"not the same polynomial in number field operation");
35: return NULL; /* not reached */
36: }
37:
38: static GEN
39: scal_mul(GEN nf, GEN x, GEN y, long ty)
40: {
41: long av=avma, tetpil;
42: GEN p1;
43:
44: if (!is_extscalar_t(ty))
45: {
46: if (ty!=t_COL) err(typeer,"nfmul");
47: y = gmul((GEN)nf[7],y);
48: }
49: p1 = gmul(x,y); tetpil=avma;
50: return gerepile(av,tetpil,algtobasis(nf,p1));
51: }
52:
53: /* product of x and y in nf */
54: GEN
55: element_mul(GEN nf, GEN x, GEN y)
56: {
57: long av,i,j,k,N,tx,ty;
58: GEN s,v,c,p1,tab;
59:
60: if (x == y) return element_sqr(nf,x);
61:
62: tx=typ(x); ty=typ(y);
63: nf=checknf(nf); tab = (GEN)nf[9]; N=lgef(nf[1])-3;
64: if (tx==t_POLMOD) x=checknfelt_mod(nf,x);
65: if (ty==t_POLMOD) y=checknfelt_mod(nf,y);
66: if (is_extscalar_t(tx)) return scal_mul(nf,x,y,ty);
67: if (is_extscalar_t(ty)) return scal_mul(nf,y,x,tx);
68: if (isnfscalar(x)) return gmul((GEN)x[1],y);
69: if (isnfscalar(y)) return gmul((GEN)y[1],x);
70:
71: v=cgetg(N+1,t_COL); av=avma;
72: for (k=1; k<=N; k++)
73: {
74: if (k == 1)
75: s = gmul((GEN)x[1],(GEN)y[1]);
76: else
77: s = gadd(gmul((GEN)x[1],(GEN)y[k]),
78: gmul((GEN)x[k],(GEN)y[1]));
79: for (i=2; i<=N; i++)
80: {
81: c=gcoeff(tab,k,(i-1)*N+i);
82: if (signe(c))
83: {
84: p1 = gmul((GEN)x[i],(GEN)y[i]);
85: if (!gcmp1(c)) p1 = gmul(p1,c);
86: s = gadd(s, p1);
87: }
88: for (j=i+1; j<=N; j++)
89: {
90: c=gcoeff(tab,k,(i-1)*N+j);
91: if (signe(c))
92: {
93: p1 = gadd(gmul((GEN)x[i],(GEN)y[j]),
94: gmul((GEN)x[j],(GEN)y[i]));
95: if (!gcmp1(c)) p1 = gmul(p1,c);
96: s = gadd(s, p1);
97: }
98: }
99: }
100: v[k]=(long)gerepileupto(av,s); av=avma;
101: }
102: return v;
103: }
104:
105: /* inverse of x in nf */
106: GEN
107: element_inv(GEN nf, GEN x)
108: {
109: long av=avma,tetpil,flx,i,N,tx=typ(x);
110: GEN p1,p;
111:
112: nf=checknf(nf); N=lgef(nf[1])-3;
113: if (is_extscalar_t(tx))
114: {
115: if (tx==t_POLMOD) checknfelt_mod(nf,x);
116: else if (tx==t_POL) x=gmodulcp(x,(GEN)nf[1]);
117: p1=ginv(x); tetpil=avma;
118: return gerepile(av,tetpil,algtobasis(nf,p1));
119: }
120: if (isnfscalar(x))
121: {
122: p1=cgetg(N+1,t_COL); p1[1]=linv((GEN)x[1]);
123: for (i=2; i<=N; i++) p1[i]=lcopy((GEN)x[i]);
124: return p1;
125: }
126: flx=1;
127: for (i=1; i<=N; i++)
128: if (typ(x[i])==t_INTMOD)
129: {
130: p=gmael(x,i,1); x=lift(x);
131: flx=0; break;
132: }
133: p1 = ginvmod(gmul((GEN)nf[7],x), (GEN)nf[1]);
134: p1 = algtobasis_intern(nf,p1);
135:
136: if (flx) return gerepileupto(av,p1);
137: tetpil=avma; return gerepile(av,tetpil,Fp_vec(p1, p));
138: }
139:
140: /* quotient of x and y in nf */
141: GEN
142: element_div(GEN nf, GEN x, GEN y)
143: {
144: long av=avma,tetpil,flx,i,N,tx=typ(x),ty=typ(y);
145: GEN p1,p;
146:
147: nf=checknf(nf); N=lgef(nf[1])-3;
148: if (tx==t_POLMOD) checknfelt_mod(nf,x);
149: else if (tx==t_POL) x=gmodulcp(x,(GEN)nf[1]);
150:
151: if (ty==t_POLMOD) checknfelt_mod(nf,y);
152: else if (ty==t_POL) y=gmodulcp(y,(GEN)nf[1]);
153:
154: if (is_extscalar_t(tx))
155: {
156: if (is_extscalar_t(ty)) p1=gdiv(x,y);
157: else
158: {
159: if (ty!=t_COL) err(typeer,"nfdiv");
160: p1=gdiv(x,gmodulcp(gmul((GEN)nf[7],y),(GEN)nf[1]));
161: }
162: tetpil=avma; return gerepile(av,tetpil,algtobasis(nf,p1));
163: }
164: if (is_extscalar_t(ty))
165: {
166: if (tx!=t_COL) err(typeer,"nfdiv");
167: p1=gdiv(gmodulcp(gmul((GEN)nf[7],x),(GEN)nf[1]),y);
168: tetpil=avma; return gerepile(av,tetpil,algtobasis(nf,p1));
169: }
170:
171: if (isnfscalar(y)) return gdiv(x,(GEN)y[1]);
172: if (isnfscalar(x))
173: {
174: p1=element_inv(nf,y); tetpil=avma;
175: return gerepile(av,tetpil,gmul((GEN)x[1],p1));
176: }
177:
178: flx=1;
179: for (i=1; i<=N; i++)
180: if (typ(x[i])==t_INTMOD)
181: {
182: p=gmael(x,i,1); x=lift(x);
183: flx=0; break;
184: }
185: for (i=1; i<=N; i++)
186: if (typ(y[i])==t_INTMOD)
187: {
188: p=gmael(y,i,1); y=lift(y);
189: flx=0; break;
190: }
191:
192: p1 = gmul(gmul((GEN)nf[7],x), ginvmod(gmul((GEN)nf[7],y), (GEN)nf[1]));
193: p1 = algtobasis_intern(nf, gres(p1, (GEN)nf[1]));
194: if (flx) return gerepileupto(av,p1);
195: tetpil=avma; return gerepile(av,tetpil, Fp_vec(p1,p));
196: }
197:
198: /* product of INTEGERS (i.e vectors with integral coeffs) x and y in nf */
199: GEN
200: element_muli(GEN nf, GEN x, GEN y)
201: {
202: long av,i,j,k,N=lgef(nf[1])-3;
203: GEN p1,s,v,c,tab = (GEN)nf[9];
204:
205: v=cgetg(N+1,t_COL); av=avma;
206: for (k=1; k<=N; k++)
207: {
208: if (k == 1)
209: s = mulii((GEN)x[1],(GEN)y[1]);
210: else
211: s = addii(mulii((GEN)x[1],(GEN)y[k]),
212: mulii((GEN)x[k],(GEN)y[1]));
213: for (i=2; i<=N; i++)
214: {
215: c=gcoeff(tab,k,(i-1)*N+i);
216: if (signe(c))
217: {
218: p1 = mulii((GEN)x[i],(GEN)y[i]);
219: if (!gcmp1(c)) p1 = mulii(p1,c);
220: s = addii(s,p1);
221: }
222: for (j=i+1; j<=N; j++)
223: {
224: c=gcoeff(tab,k,(i-1)*N+j);
225: if (signe(c))
226: {
227: p1 = addii(mulii((GEN)x[i],(GEN)y[j]),
228: mulii((GEN)x[j],(GEN)y[i]));
229: if (!gcmp1(c)) p1 = mulii(p1,c);
230: s = addii(s,p1);
231: }
232: }
233: }
234: v[k]=(long) gerepileuptoint(av,s); av=avma;
235: }
236: return v;
237: }
238:
239: /* product of INTEGERS (i.e vectors with integral coeffs) x and y in nf */
240: GEN
241: element_sqri(GEN nf, GEN x)
242: {
243: long av,i,j,k,N=lgef(nf[1])-3;
244: GEN p1,s,v,c,tab = (GEN)nf[9];
245:
246: v=cgetg(N+1,t_COL); av=avma;
247: for (k=1; k<=N; k++)
248: {
249: if (k == 1)
250: s = sqri((GEN)x[1]);
251: else
252: s = shifti(mulii((GEN)x[1],(GEN)x[k]), 1);
253: for (i=2; i<=N; i++)
254: {
255: c=gcoeff(tab,k,(i-1)*N+i);
256: if (signe(c))
257: {
258: p1 = sqri((GEN)x[i]);
259: if (!gcmp1(c)) p1 = mulii(p1,c);
260: s = addii(s,p1);
261: }
262: for (j=i+1; j<=N; j++)
263: {
264: c=gcoeff(tab,k,(i-1)*N+j);
265: if (signe(c))
266: {
267: p1 = shifti(mulii((GEN)x[i],(GEN)x[j]),1);
268: if (!gcmp1(c)) p1 = mulii(p1,c);
269: s = addii(s,p1);
270: }
271: }
272: }
273: v[k]=(long) gerepileuptoint(av,s); av=avma;
274: }
275: return v;
276: }
277:
278: /* square of x in nf */
279: GEN
280: element_sqr(GEN nf, GEN x)
281: {
282: long av,i,j,k,N=lgef(nf[1])-3;
283: GEN p1,s,v,c, tab = (GEN)nf[9];
284:
285: if (isnfscalar(x))
286: {
287: s=cgetg(N+1,t_COL); s[1]=lsqr((GEN)x[1]);
288: for (i=2; i<=N; i++) s[i]=lcopy((GEN)x[i]);
289: return s;
290: }
291: v=cgetg(N+1,t_COL); av=avma;
292: for (k=1; k<=N; k++)
293: {
294: if (k == 1)
295: s = gsqr((GEN)x[1]);
296: else
297: s = gmul2n(gmul((GEN)x[1],(GEN)x[k]), 1);
298: for (i=2; i<=N; i++)
299: {
300: c=gcoeff(tab,k,(i-1)*N+i);
301: if (signe(c))
302: {
303: p1 = gsqr((GEN)x[i]);
304: if (!gcmp1(c)) p1 = gmul(p1,c);
305: s = gadd(s,p1);
306: }
307: for (j=i+1; j<=N; j++)
308: {
309: c=gcoeff(tab,k,(i-1)*N+j);
310: if (signe(c))
311: {
312: p1 = gmul((GEN)x[i],(GEN)x[j]);
313: p1 = gcmp1(c)? gmul2n(p1,1): gmul(p1,shifti(c,1));
314: s = gadd(s,p1);
315: }
316: }
317: }
318: v[k]=(long)gerepileupto(av,s); av=avma;
319: }
320: return v;
321: }
322:
323: /* Compute x^n in nf, left-shift binary powering */
324: GEN
325: element_pow(GEN nf, GEN x, GEN n)
326: {
327: long s,av=avma,N,i,j,m;
328: GEN y,p1;
329:
330: if (typ(n)!=t_INT) err(talker,"not an integer exponent in nfpow");
331: nf=checknf(nf); N=lgef(nf[1])-3;
332: s=signe(n); if (!s) return gscalcol_i(gun,N);
333: if (typ(x)!=t_COL) x=algtobasis(nf,x);
334:
335: if (isnfscalar(x))
336: {
337: y = gscalcol_i(gun,N);
338: y[1] = (long)powgi((GEN)x[1],n); return y;
339: }
340: p1 = n+2; m = *p1;
341: y=x; j=1+bfffo(m); m<<=j; j = BITS_IN_LONG-j;
342: for (i=lgefint(n)-2;;)
343: {
344: for (; j; m<<=1,j--)
345: {
346: y = element_sqr(nf, y);
347: if (m<0) y=element_mul(nf, y, x);
348: }
349: if (--i == 0) break;
350: m = *++p1, j = BITS_IN_LONG;
351: }
352: if (s<0) y = element_inv(nf, y);
353: return av==avma? gcopy(y): gerepileupto(av,y);
354: }
355:
356: /* x in Z^n, compute lift(x^n mod p) */
357: GEN
358: element_pow_mod_p(GEN nf, GEN x, GEN n, GEN p)
359: {
360: long s,av=avma,N,i,j,m;
361: GEN y,p1;
362:
363: if (typ(n)!=t_INT) err(talker,"not an integer exponent in nfpow");
364: nf=checknf(nf); N=lgef(nf[1])-3;
365: s=signe(n); if (!s) return gscalcol_i(gun,N);
366: if (typ(x)!=t_COL) x=algtobasis(nf,x);
367:
368: if (isnfscalar(x))
369: {
370: y = gscalcol_i(gun,N);
371: y[1] = (long)powmodulo((GEN)x[1],n,p); return y;
372: }
373: p1 = n+2; m = *p1;
374: y=x; j=1+bfffo(m); m<<=j; j = BITS_IN_LONG-j;
375: for (i=lgefint(n)-2;;)
376: {
377: for (; j; m<<=1,j--)
378: {
379: y = element_sqri(nf, y);
380: if (m<0) y=element_muli(nf, y, x);
381: y = Fp_vec_red(y, p);
382: }
383: if (--i == 0) break;
384: m = *++p1, j = BITS_IN_LONG;
385: }
386: if (s<0) y = Fp_vec_red(element_inv(nf,y), p);
387: return av==avma? gcopy(y): gerepileupto(av,y);
388: }
389:
390: /* x = I-th vector of the Z-basis of Z_K, in Z^n, compute lift(x^n mod p) */
391: GEN
392: element_powid_mod_p(GEN nf, long I, GEN n, GEN p)
393: {
394: long s,av=avma,N,i,j,m;
395: GEN y,p1;
396:
397: if (typ(n)!=t_INT) err(talker,"not an integer exponent in nfpow");
398: nf=checknf(nf); N=lgef(nf[1])-3;
399: s=signe(n);
400: if (!s || I == 1) return gscalcol_i(gun,N);
401: p1 = n+2; m = *p1;
402: y = zerocol(N); y[I] = un;
403: j=1+bfffo(m); m<<=j; j = BITS_IN_LONG-j;
404: for (i=lgefint(n)-2;;)
405: {
406: for (; j; m<<=1,j--)
407: {
408: y = element_sqri(nf, y);
409: if (m<0) y=element_mulid(nf, y, I);
410: y = Fp_vec_red(y, p);
411: }
412: if (--i == 0) break;
413: m = *++p1, j = BITS_IN_LONG;
414: }
415: if (s<0) y = Fp_vec_red(element_inv(nf,y), p);
416: return av==avma? gcopy(y): gerepileupto(av,y);
417: }
418:
419: /* Outputs x.w_i, where w_i is the i-th elt of the integral basis */
420: GEN
421: element_mulid(GEN nf, GEN x, long i)
422: {
423: long av,j,k,N;
424: GEN s,v,c,p1, tab;
425:
426: if (i==1) return gcopy(x);
427: N = lgef(nf[1])-3;
428: tab = (GEN)nf[9]; tab += (i-1)*N;
429: v=cgetg(N+1,t_COL); av=avma;
430: for (k=1; k<=N; k++)
431: {
432: s = gzero;
433: for (j=1; j<=N; j++)
434: if (signe(c = gcoeff(tab,k,j)) && !gcmp0(p1 = (GEN)x[j]))
435: {
436: if (!gcmp1(c)) p1 = gmul(p1,c);
437: s = gadd(s,p1);
438: }
439: v[k]=lpileupto(av,s); av=avma;
440: }
441: return v;
442: }
443:
444: /* valuation of integer x, with resp. to prime ideal P above p.
445: * p.P^(-1) = b Z_K, v <= val_p(norm(x)), and N = deg(nf)
446: */
447: long
448: int_elt_val(GEN nf, GEN x, GEN p, GEN b, long v)
449: {
450: long i,k,w, N = lgef(nf[1])-3;
451: GEN r,a,y, mul = cgetg(N+1,t_MAT);
452:
453: for (i=1; i<=N; i++) mul[i] = (long)element_mulid(nf,b,i);
454: y = cgetg(N+1, t_COL); /* will hold the new x */
455: x = dummycopy(x);
456: for(w=0; w<=v; w++)
457: {
458: for (i=1; i<=N; i++)
459: { /* compute (x.b)_i */
460: a = mulii((GEN)x[1], gcoeff(mul,i,1));
461: for (k=2; k<=N; k++) a = addii(a, mulii((GEN)x[k], gcoeff(mul,i,k)));
462: /* is it divisible by p ? */
463: y[i] = ldvmdii(a,p,&r);
464: if (signe(r)) return w;
465: }
466: r=x; x=y; y=r;
467: }
468: return w;
469: }
470:
471: long
472: element_val(GEN nf, GEN x, GEN vp)
473: {
474: long av = avma,N,w,vcx,e;
475: GEN cx,p;
476:
477: if (gcmp0(x)) return VERYBIGINT;
478: nf=checknf(nf); N=lgef(nf[1])-3;
479: checkprimeid(vp); p=(GEN)vp[1]; e=itos((GEN)vp[3]);
480: switch(typ(x))
481: {
482: case t_INT: case t_FRAC: case t_FRACN:
483: return ggval(x,p)*e;
484: case t_POLMOD: x = (GEN)x[2]; /* fall through */
485: case t_POL:
486: x = algtobasis_intern(nf,x); break;
487: case t_COL:
488: if (lg(x)==N+1) break;
489: default: err(typeer,"element_val");
490: }
491: if (isnfscalar(x)) return ggval((GEN)x[1],p)*e;
492:
493: cx = content(x);
494: if (gcmp1(cx)) vcx=0; else { x = gdiv(x,cx); vcx = ggval(cx,p); }
495: w = int_elt_val(nf,x,p,(GEN)vp[5],VERYBIGINT);
496: avma=av; return w + vcx*e;
497: }
498:
499: /* d = a multiple of norm(x), x integral */
500: long
501: element_val2(GEN nf, GEN x, GEN d, GEN vp)
502: {
503: GEN p = (GEN)vp[1];
504: long av, v = ggval(d,p);
505:
506: if (!v) return 0;
507: av=avma;
508: v = int_elt_val(nf,x,p,(GEN)vp[5],v);
509: avma=av; return v;
510: }
511:
512: /* polegal without comparing variables */
513: long
514: polegal_spec(GEN x, GEN y)
515: {
516: long i = lgef(x);
517:
518: if (i != lgef(y)) return 0;
519: for (i--; i > 1; i--)
520: if (!gegal((GEN)x[i],(GEN)y[i])) return 0;
521: return 1;
522: }
523:
524: GEN
525: basistoalg(GEN nf, GEN x)
526: {
527: long tx=typ(x),lx=lg(x),i;
528: GEN z;
529:
530: nf=checknf(nf);
531: switch(tx)
532: {
533: case t_COL:
534: for (i=1; i<lx; i++)
535: {
536: long t = typ(x[i]);
537: if (is_matvec_t(t)) break;
538: }
539: if (i==lx)
540: {
541: z = cgetg(3,t_POLMOD);
542: z[1] = lcopy((GEN)nf[1]);
543: z[2] = lmul((GEN)nf[7],x); return z;
544: }
545: /* fall through */
546:
547: case t_VEC: case t_MAT: z=cgetg(lx,tx);
548: for (i=1; i<lx; i++) z[i]=(long)basistoalg(nf,(GEN)x[i]);
549: return z;
550:
551: case t_POLMOD:
552: if (!polegal_spec((GEN)nf[1],(GEN)x[1]))
553: err(talker,"not the same number field in basistoalg");
554: return gcopy(x);
555: default: z=cgetg(3,t_POLMOD);
556: z[1]=lcopy((GEN)nf[1]);
557: z[2]=lmul(x,polun[varn(nf[1])]); return z;
558: }
559: }
560:
561: /* return the (N-dimensional) vector of coeffs of p */
562: GEN
563: pol_to_vec(GEN x, long N)
564: {
565: long i,l=lgef(x)-1;
566: GEN z = cgetg(N+1,t_COL);
567: x++;
568: for (i=1; i<l ; i++) z[i]=x[i];
569: for ( ; i<=N; i++) z[i]=zero;
570: return z;
571: }
572:
573: /* valid for scalars and polynomial, degree less than N.
574: * No garbage collecting. No check (SEGV for vectors).
575: */
576: GEN
577: algtobasis_intern(GEN nf,GEN x)
578: {
579: long i,tx=typ(x),N=lgef(nf[1])-3;
580: GEN z;
581:
582: if (tx==t_POLMOD) { x=(GEN)x[2]; tx=typ(x); }
583: if (tx==t_POL)
584: {
585: if (lgef(x)-3 >= N) x=gres(x,(GEN)nf[1]);
586: return gmul((GEN)nf[8], pol_to_vec(x, N));
587: }
588: z = cgetg(N+1,t_COL);
589: z[1]=lcopy(x); for (i=2; i<=N; i++) z[i]=zero;
590: return z;
591: }
592:
593: GEN
594: algtobasis(GEN nf, GEN x)
595: {
596: long tx=typ(x),lx=lg(x),av=avma,i,N;
597: GEN z;
598:
599: nf=checknf(nf);
600: switch(tx)
601: {
602: case t_VEC: case t_COL: case t_MAT:
603: z=cgetg(lx,tx);
604: for (i=1; i<lx; i++) z[i]=(long)algtobasis(nf,(GEN)x[i]);
605: return z;
606: case t_POLMOD:
607: if (!polegal_spec((GEN)nf[1],(GEN)x[1]))
608: err(talker,"not the same number field in algtobasis");
609: x = (GEN)x[2]; /* fall through */
610: case t_POL:
611: return gerepileupto(av,algtobasis_intern(nf,x));
612:
613: default: N=lgef(nf[1])-3; return gscalcol(x,N);
614: }
615: }
616:
617: /* Given a and b in nf, gives an algebraic integer y in nf such that a-b.y
618: * is "small"
619: */
620: GEN
621: nfdiveuc(GEN nf, GEN a, GEN b)
622: {
623: long av=avma, tetpil;
624: a = element_div(nf,a,b); tetpil=avma;
625: return gerepile(av,tetpil,ground(a));
626: }
627:
628: /* Given a and b in nf, gives a "small" algebraic integer r in nf
629: * of the form a-b.y
630: */
631: GEN
632: nfmod(GEN nf, GEN a, GEN b)
633: {
634: long av=avma,tetpil;
635: GEN p1=gneg_i(element_mul(nf,b,ground(element_div(nf,a,b))));
636: tetpil=avma; return gerepile(av,tetpil,gadd(a,p1));
637: }
638:
639: /* Given a and b in nf, gives a two-component vector [y,r] in nf such
640: * that r=a-b.y is "small".
641: */
642: GEN
643: nfdivres(GEN nf, GEN a, GEN b)
644: {
645: long av=avma,tetpil;
646: GEN p1,z, y = ground(element_div(nf,a,b));
647:
648: p1=gneg_i(element_mul(nf,b,y)); tetpil=avma;
649: z=cgetg(3,t_VEC); z[1]=lcopy(y); z[2]=ladd(a,p1);
650: return gerepile(av,tetpil,z);
651: }
652:
653: /*************************************************************************/
654: /** **/
655: /** (Z_K/I)^* **/
656: /** **/
657: /*************************************************************************/
658:
659: /* return (column) vector of R1 signatures of x (coeff modulo 2)
660: * if arch = NULL, assume arch = [0,..0]
661: */
662: GEN
663: zsigne(GEN nf,GEN x,GEN arch)
664: {
665: GEN _0,_1, vecsign, rac = (GEN)nf[6];
666: long av, i,j,l;
667:
668: if (!arch) return cgetg(1,t_COL);
669: switch(typ(x))
670: {
671: case t_COL: x = gmul((GEN)nf[7],x); break;
672: case t_POLMOD: x = (GEN)x[2];
673: }
674: if (gcmp0(x)) err(talker,"zero element in zsigne");
675:
676: l = lg(arch); vecsign = cgetg(l,t_COL);
677: _0 = gmodulss(0,2);
678: _1 = gmodulss(1,2); av = avma;
679: for (j=1,i=1; i<l; i++)
680: if (signe(arch[i]))
681: vecsign[j++] = (gsigne(poleval(x,(GEN)rac[i])) > 0)? (long)_0
682: : (long)_1;
683: avma = av; setlg(vecsign,j); return vecsign;
684: }
685:
686: /* For internal use. Reduce x modulo ideal. We want a non-zero result */
687: GEN
688: nfreducemodideal(GEN nf,GEN x,GEN ideal)
689: {
690: long N = lg(x)-1, do_copy = 1, i;
691: GEN p1,q;
692:
693: ideal=idealhermite(nf,ideal);
694: for (i=N; i>=1; i--)
695: {
696: p1=gcoeff(ideal,i,i); q=gdivround((GEN)x[i],p1);
697: if (signe(q)) { x=gsub(x,gmul(q,(GEN)ideal[i])); do_copy=0; }
698: }
699: if (gcmp0(x)) return (GEN) ideal[1];
700: return do_copy? gcopy(x) : x;
701: }
702:
703: /* a usage interne...Reduction de la colonne x modulo la matrice y inversible
704: utilisant LLL */
705: GEN
706: lllreducemodmatrix(GEN x,GEN y)
707: {
708: long av = avma,tetpil;
709: GEN z = gmul(y,lllint(y));
710:
711: z = gneg(gmul(z, ground(gauss(z,x))));
712: tetpil=avma; return gerepile(av,tetpil,gadd(x,z));
713: }
714:
715: /* Reduce column x modulo y in HNF */
716: static GEN
717: colreducemodmat(GEN x,GEN y)
718: {
719: long av = avma, i;
720: GEN q;
721:
722: for (i=lg(x)-1; i>=1; i--)
723: {
724: q = gdivround((GEN)x[i], gcoeff(y,i,i));
725: if (signe(q)) { q = gneg(q); x = gadd(x, gmul(q,(GEN)y[i])); }
726: }
727: return avma==av? gcopy(x): gerepileupto(av,x);
728: }
729:
730: /* for internal use...Reduce matrix x modulo matrix y */
731: GEN
732: reducemodmatrix(GEN x, GEN y)
733: {
734: long i, lx = lg(x);
735: GEN z = cgetg(lx,t_MAT);
736:
737: if (DEBUGLEVEL>=8)
738: {
739: fprintferr("entering reducemodmatrix; avma-bot = %ld\n",avma-bot);
740: flusherr();
741: }
742: y = hnfmod(y,detint(y));
743: for (i=1; i<lx; i++)
744: {
745: if(DEBUGLEVEL>=8) { fprintferr("%ld ",i); flusherr(); }
746: z[i]=(long)colreducemodmat((GEN)x[i],y);
747: }
748: if(DEBUGLEVEL>=8) { fprintferr("\n"); flusherr(); }
749: return z;
750: }
751:
752: /* compute elt = x mod idele, with sign(elt) = sign(x) at arch */
753: GEN
754: nfreducemodidele(GEN nf,GEN x,GEN idele,GEN sarch)
755: {
756: GEN p1,p2,arch,gen;
757: long nba,i;
758:
759: if (gcmp0(x)) return gcopy(x);
760: if (!sarch || typ(idele)!=t_VEC || lg(idele)!=3)
761: return nfreducemodideal(nf,x,idele);
762:
763: arch =(GEN)idele[2];
764: nba = lg(sarch[1]);
765: gen =(GEN)sarch[2];
766: p1 = nfreducemodideal(nf,x,(GEN)idele[1]);
767: p2 = gadd(zsigne(nf,p1,arch), zsigne(nf,x,arch));
768: p2 = lift_intern(gmul((GEN)sarch[3],p2));
769: for (i=1; i<nba; i++)
770: if (signe(p2[i])) p1 = element_mul(nf,p1,(GEN)gen[i]);
771: return (gcmp(gnorml2(p1),gnorml2(x)) > 0)? x: p1;
772: }
773:
774: GEN
775: element_powmodideal(GEN nf,GEN x,GEN k,GEN ideal)
776: {
777: GEN y = gscalcol_i(gun,lgef(nf[1])-3);
778: for(;;)
779: {
780: if (mpodd(k)) y=element_mulmodideal(nf,x,y,ideal);
781: k=shifti(k,-1); if (!signe(k)) return y;
782: x = element_sqrmodideal(nf,x,ideal);
783: }
784: }
785:
786: GEN
787: element_powmodidele(GEN nf,GEN x,GEN k,GEN idele,GEN sarch)
788: {
789: GEN y = gscalcol_i(gun,lgef(nf[1])-3);
790: for(;;)
791: {
792: if (mpodd(k)) y=element_mulmodidele(nf,x,y,idele,sarch);
793: k=shifti(k,-1); if (!signe(k)) return y;
794: x = element_sqrmodidele(nf,x,idele,sarch);
795: }
796: }
797:
798: /* given 2 integral ideals x, y in HNF s.t x|y|x^2, compute the quotient
799: (1+x)/(1+y) in the form [[cyc],[gen],ux^-1]. */
800: static GEN
801: zidealij(GEN x, GEN y)
802: {
803: GEN p1,p2,p3,p4,d,z,x1;
804: long j,N,c;
805:
806: if(DEBUGLEVEL>=6)
807: {fprintferr("entree dans zidealij; avma-bot = %ld\n",avma-bot); flusherr();}
808: x1 = ginv(x);
809: p1 = gmul(x1,y);
810: if(DEBUGLEVEL>=6)
811: {fprintferr("p1 = y/x; avma-bot = %ld\n",avma-bot); flusherr();}
812: p2 = smith2(p1);
813: if(DEBUGLEVEL>=6)
814: {fprintferr("p2 = smith2(p1); avma-bot = %ld\n",avma-bot); flusherr();}
815: p3 = ginv((GEN)p2[1]);
816: if(DEBUGLEVEL>=6)
817: {fprintferr("p3 = 1/p2[1]; avma-bot = %ld\n",avma-bot); flusherr();}
818: p3 = reducemodmatrix(p3,p1);
819: p3 = gmul(x,p3); N=lg(p3)-1;
820: if(DEBUGLEVEL>=6)
821: {fprintferr("p3 = x.p3 mod p1; avma-bot = %ld\n",avma-bot); flusherr();}
822: for (j=1; j<=N; j++) coeff(p3,1,j)=laddsi(1,gcoeff(p3,1,j));
823: p4 = smithclean(p2); d=(GEN)p4[3];
824:
825: z=cgetg(4,t_VEC); c=lg(d); p1=cgetg(c,t_VEC);
826: /* transform p3 in a vector (gen) */
827: p3[0] = evaltyp(t_VEC) | evallg(c);
828: for (j=1; j<c; j++) p1[j] = coeff(d,j,j);
829: z[1]=(long)p1;
830: z[2]=(long)p3;
831: z[3] = lmul((GEN)p4[1],x1); return z;
832: }
833:
834: #if 0
835: /* un element g generateur d'un p^k divisant x etant donne, calcule
836: un element congru a g modulo p^k et a 1 modulo x/p^k et de plus
837: positif aux places de arch */
838: GEN
839: zconvert(GEN nf,GEN uv,GEN x,GEN arch,GEN structarch,GEN g)
840: {
841: long i,nba;
842: GEN p1,p2,generator;
843:
844: p1=nfreducemodideal(nf,gadd((GEN)uv[1],element_mul(nf,g,(GEN)uv[2])),x);
845: nba=lg(structarch[1])-1; generator=(GEN)structarch[2];
846: p2 = zsigne(nf,p1,arch);
847: for (i=1; i<=nba; i++)
848: if (signe(p2[i])) p1 = element_mul(nf,p1,(GEN)generator[i]);
849: return p1;
850: }
851: #endif
852:
853: static GEN
854: get_multab(GEN nf, GEN x)
855: {
856: long lx = lg(x), i;
857: GEN multab = cgetg(lx, t_MAT);
858: for (i=1; i<lx; i++)
859: multab[i]=(long)element_mulid(nf,x,i);
860: return multab;
861: }
862:
863: /* return mat * y mod prh */
864: static GEN
865: mul_matvec_mod_pr(GEN mat, GEN y, GEN prh)
866: {
867: long av,i,j, lx = lg(mat);
868: GEN v, res = cgetg(lx,t_COL), p = gcoeff(prh,1,1);
869:
870: av = avma; (void)new_chunk((lx-1) * lgefint(p));
871: v = zerocol(lx-1);
872: for (i=lx-1; i; i--)
873: {
874: GEN p1 = (GEN)v[i], t = (GEN)prh[i];
875: for (j=1; j<lx; j++)
876: p1 = addii(p1, mulii(gcoeff(mat,i,j), (GEN)y[j]));
877: p1 = modii(p1, p);
878: if (p1 != gzero && is_pm1(t[i]))
879: {
880: for (j=1; j<i; j++)
881: v[j] = lsubii((GEN)v[j], mulii(p1, (GEN)t[j]));
882: p1 = gzero;
883: }
884: if (p1 == gzero) /* intended */
885: res[i] = zero;
886: else
887: av = res[i] = (long)icopy_av(p1, (GEN)av);
888: }
889: avma = av; return res;
890: }
891:
892: /* smallest integer n such that g0^n=x modulo p prime */
893: static GEN
894: Fp_shanks(GEN x,GEN g0,GEN p)
895: {
896: long av=avma,av1,lim,lbaby,i,k,c;
897: GEN p1,smalltable,giant,perm,v,g0inv;
898:
899: x = modii(x,p);
900: if (is_pm1(x) || egalii(p,gdeux)) { avma = av; return gzero; }
901: p1 = addsi(-1, p);
902: if (egalii(p1,x)) { avma = av; return shifti(p,-1); }
903: p1 = racine(p1);
904: if (cmpis(p1,LGBITS) >= 0) err(talker,"module too large in Fp_shanks");
905: lbaby=itos(p1)+1; smalltable=cgetg(lbaby+1,t_VEC);
906: g0inv = mpinvmod(g0, p); p1 = x;
907:
908: c = 3 * lgefint(p);
909: for (i=1;;i++)
910: {
911: av1 = avma;
912: if (is_pm1(p1)) { avma=av; return stoi(i-1); }
913: smalltable[i]=(long)p1; if (i==lbaby) break;
914: new_chunk(c); p1 = mulii(p1,g0inv);
915: avma = av1; p1 = resii(p1, p);
916: }
917: giant = resii(mulii(x, mpinvmod(p1,p)), p);
918: p1=cgetg(lbaby+1,t_VEC);
919: perm = gen_sort(smalltable, cmp_IND | cmp_C, cmpii);
920: for (i=1; i<=lbaby; i++) p1[i]=smalltable[perm[i]];
921: smalltable=p1; p1=giant;
922:
923: av1 = avma; lim=stack_lim(av1,2);
924: for (k=1;;k++)
925: {
926: i=tablesearch(smalltable,p1,cmpii);
927: if (i)
928: {
929: v=addis(mulss(lbaby-1,k),perm[i]);
930: return gerepileuptoint(av,addsi(-1,v));
931: }
932: p1 = resii(mulii(p1,giant), p);
933:
934: if (low_stack(lim, stack_lim(av1,2)))
935: {
936: if(DEBUGMEM>1) err(warnmem,"Fp_shanks, k = %ld", k);
937: p1 = gerepileuptoint(av1, p1);
938: }
939: }
940: }
941:
942: /* smallest integer n such that g0^n=x modulo pr, assume g0 reduced */
943: /* TODO: should be done in F_(p^f), not in Z_k mod pr (done for f=1) */
944: GEN
945: nfshanks(GEN nf,GEN x,GEN g0,GEN pr,GEN prhall)
946: {
947: long av=avma,av1,lim,lbaby,i,k, f = itos((GEN)pr[4]);
948: GEN p1,smalltable,giant,perm,v,g0inv,prh = (GEN)prhall[1];
949: GEN multab, p = (GEN)pr[1];
950:
951: x = lift_intern(nfreducemodpr(nf,x,prhall));
952: if (f == 1) return gerepileuptoint(av, Fp_shanks((GEN)x[1],(GEN)g0[1],p));
953: p1 = addsi(-1, gpowgs(p,f));
954: if (isnfscalar(x))
955: {
956: x = (GEN)x[1];
957: if (gcmp1(x) || egalii((GEN)pr[1], gdeux)) { avma = av; return gzero; }
958: if (egalii(x, p1)) return gerepileuptoint(av,shifti(p1,-1));
959: v = divii(p1, addsi(-1,p));
960: g0 = lift_intern((GEN)element_powmodpr(nf,g0,v,prhall)[1]);
961: return gerepileuptoint(av, mulii(v, Fp_shanks(x,g0,p)));
962: }
963: p1 = racine(p1);
964: if (cmpis(p1,LGBITS) >= 0) err(talker,"module too large in nfshanks");
965: lbaby=itos(p1)+1; smalltable=cgetg(lbaby+1,t_VEC);
966: g0inv = lift_intern(element_invmodpr(nf,g0,prhall));
967: p1 = x;
968:
969: multab = get_multab(nf, g0inv);
970: for (i=lg(multab)-1; i; i--)
971: multab[i]=(long)Fp_vec_red((GEN)multab[i], p);
972:
973: for (i=1;;i++)
974: {
975: if (isnfscalar(p1) && gcmp1((GEN)p1[1])) { avma=av; return stoi(i-1); }
976:
977: smalltable[i]=(long)p1; if (i==lbaby) break;
978: p1 = mul_matvec_mod_pr(multab,p1,prh);
979: }
980: giant=lift_intern(element_divmodpr(nf,x,p1,prhall));
981: p1=cgetg(lbaby+1,t_VEC);
982: perm = gen_sort(smalltable, cmp_IND | cmp_C, cmp_vecint);
983: for (i=1; i<=lbaby; i++) p1[i]=smalltable[perm[i]];
984: smalltable=p1; p1=giant;
985:
986: multab = get_multab(nf, giant);
987: for (i=lg(multab)-1; i; i--)
988: multab[i]=(long)Fp_vec_red((GEN)multab[i], p);
989:
990: av1 = avma; lim=stack_lim(av1,2);
991: for (k=1;;k++)
992: {
993: i=tablesearch(smalltable,p1,cmp_vecint);
994: if (i)
995: {
996: v=addis(mulss(lbaby-1,k),perm[i]);
997: return gerepileuptoint(av,addsi(-1,v));
998: }
999: p1 = mul_matvec_mod_pr(multab,p1,prh);
1000:
1001: if (low_stack(lim, stack_lim(av1,2)))
1002: {
1003: if(DEBUGMEM>1) err(warnmem,"nfshanks");
1004: p1 = gerepileupto(av1, p1);
1005: }
1006: }
1007: }
1008:
1009: GEN
1010: znlog(GEN x, GEN g0)
1011: {
1012: long av=avma;
1013: GEN p = (GEN)g0[1];
1014: if (typ(g0) != t_INTMOD)
1015: err(talker,"not an element of (Z/pZ)* in znlog");
1016: switch(typ(x))
1017: {
1018: case t_INT: break;
1019: default: x = gmul(x, gmodulsg(1,p));
1020: if (typ(x) != t_INTMOD)
1021: err(talker,"not an element of (Z/pZ)* in znlog");
1022: case t_INTMOD: x = (GEN)x[2]; break;
1023: }
1024: return gerepileuptoint(av, Fp_shanks(x,(GEN)g0[2],p));
1025: }
1026:
1027: GEN
1028: dethnf(GEN mat)
1029: {
1030: long av,i,l = lg(mat);
1031: GEN s;
1032:
1033: if (l<3) return l<2? gun: icopy(gcoeff(mat,1,1));
1034: av = avma; s = gcoeff(mat,1,1);
1035: for (i=2; i<l; i++) s = gmul(s,gcoeff(mat,i,i));
1036: return av==avma? gcopy(s): gerepileupto(av,s);
1037: }
1038:
1039: GEN
1040: dethnf_i(GEN mat)
1041: {
1042: long av,i,l = lg(mat);
1043: GEN s;
1044:
1045: if (l<3) return l<2? gun: icopy(gcoeff(mat,1,1));
1046: av = avma; s = gcoeff(mat,1,1);
1047: for (i=2; i<l; i++) s = mulii(s,gcoeff(mat,i,i));
1048: return gerepileuptoint(av,s);
1049: }
1050:
1051: static GEN
1052: makeprimetoideal(GEN nf,GEN id,GEN uv,GEN x)
1053: {
1054: GEN p1 = gadd((GEN)uv[1], element_mul(nf,x,(GEN)uv[2]));
1055: return nfreducemodideal(nf,p1,id);
1056: }
1057:
1058: static GEN
1059: makeprimetoidealvec(GEN nf,GEN ideal,GEN uv,GEN listgen)
1060: {
1061: long i, lx = lg(listgen);
1062: GEN y = cgetg(lx,t_VEC);
1063:
1064: for (i=1; i<lx; i++)
1065: y[i] = (long)makeprimetoideal(nf,ideal,uv,(GEN)listgen[i]);
1066: return y;
1067: }
1068:
1069: /* Given an ideal pr^ep, and an integral ideal x (in HNF form) compute a list
1070: * of vectors, each with 5 components as follows :
1071: * [[clh],[gen1],[gen2],[signat2],U.X^-1]. Each component corresponds to
1072: * d_i,g_i,g'_i,s_i. Generators g_i are not necessarily prime to x, the
1073: * generators g'_i are. signat2 is the (horizontal) vector made of the
1074: * signatures (column vectors) of the g'_i. If x = NULL, the original ideal
1075: * was a prime power
1076: */
1077: static GEN
1078: zprimestar(GEN nf,GEN pr,GEN ep,GEN x,GEN arch)
1079: {
1080: long av=avma,av1,N,f,nbp,j,n,m,tetpil,i,e,a,b;
1081: GEN prh,p,pf_1,list,v,p1,p2,p3,p4,prk,uv,g0,newgen,pra,prb;
1082: GEN *gptr[2];
1083:
1084: if(DEBUGLEVEL>=4)
1085: { fprintferr("treating pr = %Z ^ %Z\n",pr,ep); flusherr(); }
1086: prh=prime_to_ideal(nf,pr); N=lg(prh)-1;
1087: f=itos((GEN)pr[4]); p=(GEN)pr[1];
1088:
1089: pf_1 = addis(gpowgs(p,f), -1);
1090: v = zerocol(N);
1091: if (f==1) v[1]=gener(p)[2];
1092: else
1093: {
1094: GEN prhall = cgetg(3,t_VEC);
1095: long psim;
1096: if (is_bigint(p)) err(talker,"prime too big in zprimestar");
1097: psim = itos(p);
1098: list = (GEN)factor(pf_1)[1]; nbp=lg(list)-1;
1099: prhall[1]=(long)prh; prhall[2]=zero;
1100: for (n=psim; n>=0; n++)
1101: {
1102: m=n;
1103: for (i=1; i<=N; i++)
1104: if (!gcmp1(gcoeff(prh,i,i))) { v[i]=lstoi(m%psim); m/=psim; }
1105: for (j=1; j<=nbp; j++)
1106: {
1107: p1 = divii(pf_1,(GEN)list[j]);
1108: p1 = lift_intern(element_powmodpr(nf,v,p1,prhall));
1109: if (isnfscalar(p1) && gcmp1((GEN)p1[1])) break;
1110: }
1111: if (j>nbp) break;
1112: }
1113: if (n < 0) err(talker,"prime too big in zprimestar");
1114: }
1115: /* v generates (Z_K / pr)^* */
1116: if(DEBUGLEVEL>=4) {fprintferr("v calcule\n");flusherr();}
1117: e = itos(ep); prk=(e==1)? pr: idealpow(nf,pr,ep);
1118: if(DEBUGLEVEL>=4) {fprintferr("prk calcule\n");flusherr();}
1119: g0 = v;
1120: if (x)
1121: {
1122: uv = idealaddtoone(nf,prk,idealdivexact(nf,x,prk));
1123: g0 = makeprimetoideal(nf,x,uv,v);
1124: }
1125: if(DEBUGLEVEL>=4) {fprintferr("g0 calcule\n");flusherr();}
1126:
1127: list=cgetg(2,t_VEC);
1128: p1=cgetg(6,t_VEC); list[1]=(long)p1; p1[5]=un;
1129: p2=cgetg(2,t_VEC); p1[1]=(long)p2; p2[1]=(long)pf_1;
1130: p2=cgetg(2,t_VEC); p1[2]=(long)p2; p2[1]=(long)v;
1131: p2=cgetg(2,t_VEC); p1[3]=(long)p2; p2[1]=(long)g0;
1132: p2=cgetg(2,t_VEC); p1[4]=(long)p2; p2[1]=(long)zsigne(nf,g0,arch);
1133: if (e==1)
1134: {
1135: tetpil=avma; return gerepile(av,tetpil,gcopy(list));
1136: }
1137:
1138: a=1; b=2; av1=avma;
1139: pra = prh; prb = (e==2)? prk: idealpow(nf,pr,gdeux);
1140: for(;;)
1141: {
1142: if(DEBUGLEVEL>=4)
1143: {fprintferr("on traite a = %ld, b = %ld\n",a,b); flusherr();}
1144: p1 = zidealij(pra,prb);
1145: newgen = dummycopy((GEN)p1[2]);
1146: p3 = cgetg(lg(newgen),t_VEC);
1147: if(DEBUGLEVEL>=4) {fprintferr("zidealij fait\n"); flusherr();}
1148: for (i=1; i<lg(newgen); i++)
1149: {
1150: if (x) newgen[i]=(long)makeprimetoideal(nf,x,uv,(GEN)newgen[i]);
1151: p3[i]=(long)zsigne(nf,(GEN)newgen[i],arch);
1152: }
1153: p2=cgetg(2,t_VEC); p4=cgetg(6,t_VEC); p2[1]=(long)p4;
1154: p4[1] = p1[1];
1155: p4[2] = p1[2];
1156: p4[3] = (long)newgen;
1157: p4[4] = (long)p3;
1158: p4[5] = p1[3];
1159:
1160: a=b; b=min(e,b<<1); tetpil = avma;
1161: list = concat(list,p2);
1162: if (a==b) return gerepile(av,tetpil,list);
1163:
1164: pra = gcopy(prb);
1165: gptr[0]=&pra; gptr[1]=&list;
1166: gerepilemanysp(av1,tetpil,gptr,2);
1167: prb = (b==(a<<1))? idealpow(nf,pra,gdeux): prk;
1168: }
1169: }
1170:
1171: /* x ideal, compute elements in 1+x whose sign matrix is invertible */
1172: GEN
1173: zarchstar(GEN nf,GEN x,GEN arch,long nba)
1174: {
1175: long av,N,i,j,k,r,rr,limr,zk,lgmat;
1176: GEN p1,y,bas,genarch,mat,lambda;
1177:
1178: if (!nba)
1179: {
1180: y=cgetg(4,t_VEC);
1181: y[1]=lgetg(1,t_VEC);
1182: y[2]=lgetg(1,t_VEC);
1183: y[3]=lgetg(1,t_MAT); return y;
1184: }
1185: N=lgef(nf[1])-3; y=cgetg(4,t_VEC);
1186: p1=cgetg(nba+1,t_VEC); for (i=1; i<=nba; i++) p1[i]=deux;
1187: y[1]=(long)p1; av = avma;
1188: if (N==1)
1189: {
1190: p1 = scalarpol(subsi(1, shifti(gcoeff(x,1,1),1)), varn(nf[1]));
1191: p1 = gerepileupto(av, p1);
1192: y[2]=lgetg(2,t_VEC); mael(y,2,1) = (long)p1;
1193: y[3]=(long)gscalmat(gun,1); return y;
1194: }
1195: zk = ideal_is_zk(x,N);
1196: x = gmul(x,lllintpartial(x));
1197: genarch = cgetg(nba+1,t_VEC);
1198: mat = cgetg(nba+1,t_MAT); setlg(mat,2);
1199: for (i=1; i<=nba; i++) mat[i] = lgetg(nba+1, t_MAT);
1200: lambda = new_chunk(N+1);
1201:
1202: bas = dummycopy(gmael(nf,5,1)); r = lg(arch);
1203: for (k=1,i=1; i<r; i++)
1204: if (signe(arch[i]))
1205: {
1206: if (k < i)
1207: for (j=1; j<=N; j++) coeff(bas,k,j) = coeff(bas,i,j);
1208: k++;
1209: }
1210: r = nba+1;
1211: for (i=1; i<=N; i++) setlg(bas[i], r);
1212: bas = gmul(bas, x);
1213:
1214: for (lgmat=1,r=1, rr=3; ; r<<=1, rr=(r<<1)+1)
1215: {
1216: if (DEBUGLEVEL>5) fprintferr("zarchstar: r = %ld\n",r);
1217: p1 = gpuigs(stoi(rr),N);
1218: limr = (cmpis(p1,BIGINT) > 0)? BIGINT: p1[2];
1219: limr = (limr-1)>>1;
1220: k = zk? rr: 1; /* to avoid 0 */
1221: for ( ; k<=limr; k++)
1222: {
1223: long av1=avma, kk = k;
1224: GEN alpha = gzero;
1225: for (i=1; i<=N; i++)
1226: {
1227: lambda[i] = (kk+r)%rr - r; kk/=rr;
1228: if (lambda[i])
1229: alpha = gadd(alpha, gmulsg(lambda[i],(GEN)bas[i]));
1230: }
1231: for (i=1; i<=nba; i++)
1232: alpha[i] = ladd((GEN)alpha[i], gun);
1233: p1 = (GEN)mat[lgmat];
1234: for (i=1; i<=nba; i++)
1235: p1[i] = (gsigne((GEN)alpha[i]) > 0)? zero: un;
1236:
1237: if (ker_trivial_mod_p(mat, gdeux)) avma = av1;
1238: else
1239: { /* new vector indep. of previous ones */
1240: avma = av1; alpha = gzero;
1241: for (i=1; i<=N; i++)
1242: if (lambda[i])
1243: alpha = gadd(alpha, gmulsg(lambda[i],(GEN)x[i]));
1244: alpha[1] = ladd((GEN)alpha[1], gun);
1245: genarch[lgmat++] = (long)alpha;
1246: if (lgmat > nba)
1247: {
1248: GEN *gptr[2];
1249: mat = ginv(mat); gptr[0]=&genarch; gptr[1]=&mat;
1250: gerepilemany(av,gptr,2);
1251: y[2]=(long)genarch;
1252: y[3]=(long)mat; return y;
1253: }
1254: setlg(mat,lgmat+1);
1255: }
1256: }
1257: }
1258: }
1259:
1260: /* Retourne la decomposition de a sur les nbgen generateurs successifs
1261: * contenus dans list_set et si index !=0 on ne fait ce calcul que pour
1262: * l'ideal premier correspondant a cet index en mettant a 0 les autres
1263: * composantes
1264: */
1265: static GEN
1266: zinternallog(GEN nf,GEN list_set,long nbgen,GEN arch,GEN fa,GEN a,long index)
1267: {
1268: GEN prlist,ep,y,ainit,list,pr,prk,cyc,gen,psigne,p1,p2,p3;
1269: long av,nbp,cp,i,j,k;
1270:
1271: y = cgetg(nbgen+1,t_COL); cp=0; av=avma;
1272: prlist=(GEN)fa[1]; ep=(GEN)fa[2]; nbp=lg(ep)-1;
1273: i=typ(a); if (is_extscalar_t(i)) a = algtobasis(nf,a);
1274: if (DEBUGLEVEL>3)
1275: {
1276: fprintferr("entering zinternallog, "); flusherr();
1277: if (DEBUGLEVEL>5) fprintferr("with a = %Z\n",a);
1278: }
1279: ainit = a; psigne = zsigne(nf,ainit,arch);
1280: for (k=1; k<=nbp; k++)
1281: {
1282: list=(GEN)list_set[k];
1283: if (index && index!=k)
1284: {
1285: for (j=1; j<lg(list); j++)
1286: {
1287: cyc = gmael(list,j,1);
1288: for (i=1; i<lg(cyc); i++) y[++cp]=zero;
1289: }
1290: continue;
1291: }
1292: pr=(GEN)prlist[k]; prk=idealpow(nf,pr,(GEN)ep[k]);
1293: for (j=1; j<lg(list); j++)
1294: {
1295: p1 = (GEN)list[j]; cyc=(GEN)p1[1]; gen=(GEN)p1[2];
1296: if (j==1)
1297: {
1298: if (DEBUGLEVEL>5) { fprintferr("do nfshanks\n"); flusherr(); }
1299: a=ainit; p3=nfmodprinit(nf,pr);
1300: p3 = nfshanks(nf,a,(GEN)gen[1],pr,p3);
1301: }
1302: else
1303: {
1304: p3 = (GEN)a[1]; a[1] = laddsi(-1,(GEN)a[1]);
1305: p2 = gmul((GEN)p1[5],a); a[1] = (long)p3;
1306: if (lg(p2)!=lg(cyc)) err(bugparier,"zinternallog");
1307: p3 = (GEN)p2[1];
1308: }
1309: for(i=1;;)
1310: {
1311: p3 = modii(negi(p3), (GEN)cyc[i]);
1312: y[++cp] = lnegi(p3);
1313: if (signe(p3))
1314: {
1315: if (mpodd((GEN)y[cp])) psigne = gadd(psigne,gmael(p1,4,i));
1316: if (DEBUGLEVEL>5) fprintferr("do element_powmodideal\n");
1317: p3 = element_powmodideal(nf,(GEN)gen[i],p3,prk);
1318: a = element_mulmodideal(nf,a,p3,prk);
1319: }
1320: i++; if (i==lg(cyc)) break;
1321: p3 = (GEN)p2[i];
1322: }
1323: }
1324: }
1325: p1=lift_intern(gmul(gmael(list_set,nbp+1,3), psigne));
1326: avma=av; for (i=1; i<lg(p1); i++) y[++cp] = p1[i];
1327: if (DEBUGLEVEL>3) { fprintferr("leaving\n"); flusherr(); }
1328: for (i=1; i<=nbgen; i++) y[i] = licopy((GEN)y[i]);
1329: return y;
1330: }
1331:
1332: GEN
1333: compute_gen(GEN nf, GEN u1, GEN met, GEN gen, GEN module, long nbp, GEN sarch)
1334: {
1335: long i,j,s,nba, c = lg(met), lgen = lg(gen);
1336: GEN basecl=cgetg(c,t_VEC), unnf = gscalcol_i(gun, lgef(nf[1])-3);
1337: GEN arch,x,p1,p2,p3,p4,p5,generator;
1338:
1339: if (sarch)
1340: {
1341: arch = (GEN)module[2];
1342: x = (GEN)module[1];
1343: generator = (GEN)sarch[2];
1344: nba = lg(generator)-1;
1345: }
1346: else
1347: {
1348: x = (typ(module) == t_MAT)? module: (GEN)module[1];
1349: nba = 0;
1350: }
1351: for (j=1; j<c; j++)
1352: {
1353: GEN *op, plus = unnf, minus = unnf;
1354:
1355: for (i=1; i<lgen; i++)
1356: {
1357: p1 = gcoeff(u1,i,j);
1358: if (!(s = signe(p1))) continue;
1359:
1360: if (s > 0) op = + else { op = − p1 = negi(p1); }
1361: p1 = element_powmodidele(nf,(GEN)gen[i],p1,module,sarch);
1362: *op = *op==unnf? p1: element_mulmodidele(nf,*op,p1,module,sarch);
1363: }
1364: if (nbp)
1365: {
1366: p5=idealaddtoone_i(nf,minus,x);
1367: p4=element_div(nf,p5,minus); /* = minus^(-1) mod x */
1368: p3=element_mulmodideal(nf,plus,p4,x);
1369: }
1370: else p3=unnf;
1371:
1372: if (nba)
1373: { /* correct so that sign(p3) == sign(plus/minus) */
1374: p4=gadd(gadd(zsigne(nf,p3,arch),
1375: zsigne(nf,plus,arch)),
1376: zsigne(nf,minus,arch));
1377: p2=lift_intern(gmul((GEN)sarch[3],p4));
1378: for (i=1; i<=nba; i++)
1379: if (signe(p2[i])) p3=element_mul(nf,p3,(GEN)generator[i]);
1380: }
1381: basecl[j]=(long)p3;
1382: }
1383: return basecl;
1384: }
1385:
1386: /* Compute [[ideal,arch], [h,[cyc],[gen]], idealfact, [liste], U]
1387: gen not computed unless add_gen != 0 */
1388: GEN
1389: zidealstarinitall(GEN nf, GEN ideal,long add_gen)
1390: {
1391: long av=avma,tetpil,i,j,k,nba,nbp,R1,nbgen,cp;
1392: GEN p1,p2,p3,p4,y,h,met,u1,u1u2,u1u2clean,fa,fa2,ep,x,arch,gen,list,sarch;
1393:
1394: nf = checknf(nf); R1=itos(gmael(nf,2,1));
1395: if (typ(ideal)==t_VEC && lg(ideal)==3)
1396: {
1397: arch=(GEN)ideal[2]; ideal = (GEN)ideal[1];
1398: i = typ(arch);
1399: if (!is_vec_t(i) || lg(arch) != R1+1)
1400: err(talker,"incorrect archimedean component in zidealstarinit");
1401: for (nba=0,i=1; i<=R1; i++)
1402: if (signe(arch[i])) nba++;
1403: }
1404: else
1405: {
1406: arch=cgetg(R1+1,t_VEC);
1407: for (nba=0,i=1; i<=R1; i++) arch[i]=zero;
1408: }
1409: x = idealhermite(nf,ideal);
1410: if (!gcmp1(denom(x)))
1411: err(talker,"zidealstarinit needs an integral ideal. x =\n%Z\n",x);
1412: p1=cgetg(3,t_VEC); ideal=p1;
1413: p1[1]=(long)x;
1414: p1[2]=(long)arch;
1415:
1416: fa=idealfactor(nf,x); list=(GEN)fa[1]; ep=(GEN)fa[2];
1417: nbp=lg(list)-1; fa2=cgetg(nbp+2,t_VEC);
1418:
1419: /* compute them */
1420: gen = cgetg(1,t_VEC);
1421: p2 = (nbp==1)? (GEN)NULL: x;
1422: for (i=1; i<=nbp; i++)
1423: {
1424: p1 = zprimestar(nf,(GEN)list[i],(GEN)ep[i],p2,arch);
1425: fa2[i]=(long)p1;
1426: for (j=1; j<lg(p1); j++)
1427: gen = concatsp(gen,gmael(p1,j,3));
1428: }
1429: sarch = zarchstar(nf,x,arch,nba);
1430: fa2[i]=(long)sarch;
1431: gen = concatsp(gen,(GEN)sarch[2]);
1432: nbgen = lg(gen)-1;
1433: h=cgetg(nbgen+1,t_MAT); cp=0;
1434: for (i=1; i<=nbp; i++)
1435: {
1436: list=(GEN)fa2[i];
1437: for (j=1; j<lg(list); j++)
1438: {
1439: p1=(GEN)list[j]; p2=(GEN)p1[1]; p3=(GEN)p1[3];
1440: for (k=1; k<lg(p3); k++)
1441: {
1442: if (DEBUGLEVEL>=6)
1443: { fprintferr("entering element_powmodidele\n"); flusherr(); }
1444: p4 = element_powmodidele(nf,(GEN)p3[k],(GEN)p2[k],ideal,sarch);
1445: h[++cp] = lneg(zinternallog(nf,fa2,nbgen,arch,fa,p4,i));
1446: coeff(h,cp,cp) = p2[k];
1447: }
1448: }
1449: }
1450: for (j=1; j<=nba; j++)
1451: { h[++cp]=(long)zerocol(nbgen); coeff(h,cp,cp)=deux; }
1452: if (cp!=nbgen) err(talker,"bug in zidealstarinit");
1453: u1u2 = smith2(h); u1u2clean = smithclean(u1u2);
1454: met=(GEN)u1u2clean[3];
1455: if (add_gen)
1456: {
1457: u1 = reducemodmatrix(ginv((GEN)u1u2[1]),h);
1458: p1 = cgetg(4,t_VEC);
1459: p1[3] = (long)compute_gen(nf,u1,met,gen,ideal, nbp,sarch);
1460: }
1461: else p1 = cgetg(3,t_VEC);
1462: y = cgetg(6,t_VEC);
1463: y[1]=(long)ideal;
1464: y[2]=(long)p1;
1465: p1[1]=(long)dethnf(met);
1466: p1[2]=(long)mattodiagonal(met);
1467: y[3]=(long)fa;
1468: y[4]=(long)fa2;
1469: y[5] = u1u2clean[1];
1470: tetpil=avma; return gerepile(av,tetpil,gcopy(y));
1471: }
1472:
1473: GEN
1474: zidealstarinitgen(GEN nf, GEN ideal)
1475: {
1476: return zidealstarinitall(nf,ideal,1);
1477: }
1478:
1479: GEN
1480: zidealstarinit(GEN nf, GEN ideal)
1481: {
1482: return zidealstarinitall(nf,ideal,0);
1483: }
1484:
1485: GEN
1486: zidealstar(GEN nf, GEN ideal)
1487: {
1488: long av = avma,tetpil;
1489: GEN y = zidealstarinitall(nf,ideal,1);
1490: tetpil=avma; return gerepile(av,tetpil,gcopy((GEN)y[2]));
1491: }
1492:
1493: GEN
1494: idealstar0(GEN nf, GEN ideal,long flag)
1495: {
1496: switch(flag)
1497: {
1498: case 0: return zidealstar(nf,ideal);
1499: case 1: return zidealstarinit(nf,ideal);
1500: case 2: return zidealstarinitgen(nf,ideal);
1501: default: err(flagerr,"idealstar");
1502: }
1503: return NULL; /* not reached */
1504: }
1505:
1506: /* x is not integral, but check that v_p(x)=0 for all prime divisors of the
1507: * ideal. We need x = a/b with integral a and b, prime to ideal
1508: * denmat = den * id.
1509: */
1510: static GEN
1511: rat_zinternallog(GEN nf, GEN x, GEN bigideal, GEN denmat)
1512: {
1513: long nbp,i,v,k, N = lgef(nf[1])-3;
1514: GEN den,fa,list,ep,pr,p1,p2,p3,x1,dinv,ideal;
1515:
1516: ideal = (GEN)bigideal[1];
1517: if (lg(ideal) == 3) ideal = (GEN)ideal[1];
1518: fa=(GEN)bigideal[3]; list=(GEN)fa[1]; ep=(GEN)fa[2];
1519: den=gmael(denmat,1,1); k=1; nbp=lg(list)-1;
1520: for (i=1; i<=nbp; i++)
1521: {
1522: pr=(GEN)list[i];
1523: v = (ggval(den,(GEN)pr[1])*itos((GEN)pr[3])) / itos((GEN)ep[i]) + 1;
1524: if (v>k) k=v;
1525: }
1526: p3=idealpow(nf,ideal,stoi(k));
1527: p1=idealadd(nf,denmat,p3); dinv=idealinv(nf,p1);
1528: p2=idealmullll(nf,denmat,dinv);
1529: p3=idealmullll(nf,p3,dinv);
1530: x1=idealaddtoone_i(nf,p2,p3);
1531: if (gcmp0(x1)) x1 = (GEN)denmat[1];
1532: /* x = a/b is suitable, with a=x1*x, b=x1 */
1533: p1=element_mul(nf,x1,x);
1534: /* x1 is prime to ideal. Check that x1 * x also */
1535: p2=idealadd(nf,p1,ideal);
1536: if (! ideal_is_zk(p2,N))
1537: err(talker,"element is not coprime to ideal in zideallog");
1538: p1=zideallog(nf,p1,bigideal);
1539: p2=zideallog(nf,x1,bigideal);
1540: return gsub(p1,p2);
1541: }
1542:
1543: /* Given x (not necessarily integral), and bid as output by zidealstarinit,
1544: * compute the vector of components on the generators bid[2]
1545: */
1546: GEN
1547: zideallog(GEN nf, GEN x, GEN bid)
1548: {
1549: long av,l,i,N,c;
1550: GEN fa,fa2,ideal,arch,den,p1,cyc,y;
1551:
1552: nf=checknf(nf); checkbid(bid);
1553: cyc=gmael(bid,2,2); c=lg(cyc);
1554: y=cgetg(c,t_COL); av=avma;
1555: N = lgef(nf[1])-3; ideal = (GEN) bid[1];
1556: if (typ(ideal)==t_VEC && lg(ideal)==3)
1557: arch = (GEN)ideal[2];
1558: else
1559: arch = NULL;
1560: switch(typ(x))
1561: {
1562: case t_INT: case t_FRAC: case t_FRACN:
1563: x = gscalcol_i(x,N); break;
1564: case t_POLMOD: case t_POL:
1565: x = algtobasis(nf,x); break;
1566: case t_COL: break;
1567: default: err(talker,"not an element in zideallog");
1568: }
1569: if (lg(x) != N+1) err(talker,"not an element in zideallog");
1570:
1571: den=denom(x);
1572: if (!gcmp1(den))
1573: p1 = rat_zinternallog(nf,x,bid, gscalmat(den,N));
1574: else
1575: {
1576: l=lg(bid[5])-1; fa=(GEN)bid[3]; fa2=(GEN)bid[4];
1577: p1 = zinternallog(nf,fa2,l,arch,fa,x,0);
1578: p1 = gmul((GEN)bid[5],p1); /* apply smith */
1579: }
1580: if (lg(p1)!=c) err(bugparier,"zideallog");
1581: for (i=1; i<c; i++)
1582: y[i] = lmodii((GEN)p1[i],(GEN)cyc[i]);
1583: avma=av; /* following line does a gerepile ! */
1584: for (i=1; i<c; i++)
1585: y[i] = (long)icopy((GEN)y[i]);
1586: return y;
1587: }
1588:
1589: /* Etant donnes bid1, bid2 resultats de zidealstarinit pour deux modules m1
1590: * et m2 premiers entre eux sans partie archimedienne, calcule le
1591: * zidealstarinit [[ideal,arch],[h,[cyc],[gen]],idealfact,[liste],U] du
1592: * produit
1593: */
1594: static GEN
1595: zidealstarinitjoinall(GEN nf, GEN bid1, GEN bid2, long add_gen)
1596: {
1597: long av=avma,i,j,nbp,nbgen,lx1,lx2,llx1,llx2,lx,llx;
1598: GEN module1,module2,struct1,struct2,fact1,fact2,liste1,liste2,U1,U2;
1599: GEN module,liste,fact,U,cyc,ex1,ex2,uv;
1600: GEN p1,p2,y,met,u1;
1601: GEN fa1,fa2,gen,u1u2,u1u2clean;
1602:
1603: nf=checknf(nf); checkbid(bid1); checkbid(bid2);
1604: module1=(GEN)bid1[1]; struct1=(GEN)bid1[2]; fact1=(GEN)bid1[3];
1605: module2=(GEN)bid2[1]; struct2=(GEN)bid2[2]; fact2=(GEN)bid2[3];
1606: module=cgetg(3,t_VEC);
1607: module[1]=(long)idealmul(nf,(GEN)module1[1],(GEN)module2[1]);
1608: module[2]=ladd((GEN)module1[2],(GEN)module2[2]);
1609: if (gcmpgs(vecmax((GEN)module[2]),1)>=0)
1610: err(talker,"nontrivial Archimedian components in zidealstarinitjoin");
1611:
1612: fa1=(GEN)fact1[1]; ex1=(GEN)fact1[2];
1613: fa2=(GEN)fact2[1]; ex2=(GEN)fact2[2];
1614: fact=cgetg(3,t_MAT);
1615: fact[1]=lconcat(fa1,fa2); lx1=lg(fa1);
1616: fact[2]=lconcat(ex1,ex2); lx2=lg(fa2);
1617: nbp=lx1+lx2-2;
1618: for (i=1; i<lx1; i++)
1619: if (isinvector(fa2,(GEN)fa1[i],lx2-1))
1620: err(talker,"noncoprime ideals in zidealstarinitjoin");
1621:
1622: liste1=(GEN)bid1[4]; lx1=lg(liste1);
1623: liste2=(GEN)bid2[4]; lx2=lg(liste2);
1624: lx=lx1+lx2-2; liste = cgetg(lx,t_VEC);
1625: for (i=1; i<lx1-1; i++) liste[i]=liste1[i];
1626: for ( ; i<lx; i++) liste[i]=liste2[i-lx1+2];
1627: U1=(GEN)bid1[5]; lx1=lg(U1);
1628: U2=(GEN)bid2[5]; lx2=lg(U2);
1629: lx=lx1+lx2-1; U = cgetg(lx,t_MAT);
1630:
1631: llx1=lg(struct1[2]);
1632: llx2=lg(struct2[2]);
1633: llx=llx1+llx2-1; nbgen=llx-1;
1634: cyc = diagonal(concatsp((GEN)struct1[2],(GEN)struct2[2]));
1635: u1u2=smith2(cyc); u1u2clean=smithclean(u1u2);
1636: met=(GEN)u1u2clean[3];
1637: if (nbgen)
1638: {
1639: for (j=1; j<lx1; j++)
1640: {
1641: p1=cgetg(llx,t_COL); U[j]=(long)p1;
1642: p2=(GEN)U1[j];
1643: for (i=1; i<llx1; i++) p1[i]=p2[i];
1644: for ( ; i<llx; i++) p1[i]=zero;
1645: }
1646: for ( ; j<lx; j++)
1647: {
1648: p1=cgetg(llx,t_COL); U[j]=(long)p1;
1649: p2=((GEN)U2[j-(lx1-1)]) + 1-llx1;
1650: for (i=1; i<llx1; i++) p1[i]=zero;
1651: for ( ; i<llx; i++) p1[i]=p2[i];
1652: }
1653: U = gmul((GEN)u1u2clean[1],U);
1654: }
1655: else
1656: for (j=1; j<lx; j++) U[j]=lgetg(1,t_COL);
1657:
1658: if (add_gen)
1659: {
1660: if (lg(struct1)<=3 || lg(struct2)<=3)
1661: err(talker,"please apply idealstar(,,2) and not idealstar(,,1)");
1662:
1663: uv = idealaddtoone(nf,(GEN)module1[1],(GEN)module2[1]);
1664: p1 = makeprimetoidealvec(nf,(GEN)module[1],uv,(GEN)struct1[3]);
1665: p2=(GEN)uv[1]; uv[1]=uv[2]; uv[2]=(long)p2;
1666: p2 = makeprimetoidealvec(nf,(GEN)module[1],uv,(GEN)struct2[3]);
1667: gen=concatsp(p1,p2);
1668:
1669: u1 = reducemodmatrix(ginv((GEN)u1u2[1]),cyc);
1670: p1 = cgetg(4,t_VEC);
1671: p1[3] = (long)compute_gen(nf,u1,met,gen,module, nbp,NULL);
1672: }
1673: else p1 = cgetg(3,t_VEC);
1674:
1675: y=cgetg(6,t_VEC);
1676: y[1]=(long)module;
1677: y[2]=(long)p1;
1678: p1[1]=(long)dethnf(met);
1679: p1[2]=(long)mattodiagonal(met);
1680: y[3]=(long)fact;
1681: y[4]=(long)liste;
1682: y[5]=(long)U;
1683: return gerepileupto(av,gcopy(y));
1684: }
1685:
1686: GEN
1687: zidealstarinitjoin(GEN nf, GEN bid1, GEN bid2)
1688: {
1689: return zidealstarinitjoinall(nf,bid1,bid2,0);
1690: }
1691:
1692: GEN
1693: zidealstarinitjoingen(GEN nf, GEN bid1, GEN bid2)
1694: {
1695: return zidealstarinitjoinall(nf,bid1,bid2,1);
1696: }
1697:
1698: /* Etant donnes bid1 resultat de zidealstarinit pour un module m1 sans partie
1699: * archimedienne et une partie archimedienne arch, calcule le zidealstarinit
1700: * [[ideal,arch],[h,[cyc],[gen]],idealfact,[liste],U] du produit
1701: */
1702: static GEN
1703: zidealstarinitjoinarchall(GEN nf, GEN bid1, GEN arch, long nba, long add_gen)
1704: {
1705: long av=avma,i,nbp,lx1,lx;
1706: GEN module1,struct1,fact1,liste1,U1;
1707: GEN module,liste,h,p1,y,met,u1,x,gen,sarch,u1u2,u1u2clean;
1708:
1709: nf=checknf(nf); checkbid(bid1);
1710: module1=(GEN)bid1[1]; struct1=(GEN)bid1[2]; fact1=(GEN)bid1[3];
1711: nbp=lg((GEN)fact1[1])-1;
1712: x=(GEN)module1[1];
1713: sarch = zarchstar(nf,x,arch,nba);
1714: module=cgetg(3,t_VEC);
1715: module[1]=(long)x;
1716: module[2]=(long)arch;
1717: if (gcmpgs(vecmax((GEN)module1[2]),1)>=0)
1718: err(talker,"nontrivial Archimedian components in zidealstarinitjoinarchall");
1719: liste1=(GEN)bid1[4]; lx=lg(liste1);
1720: liste=cgetg(lx,t_VEC); for (i=1; i<lx-1; i++) liste[i]=liste1[i];
1721: liste[lx-1]=(long)sarch;
1722: U1=(GEN)bid1[5]; lx1=lg(U1);
1723: lx=lx1+nba;
1724: h = diagonal(concatsp((GEN)struct1[2],(GEN)sarch[1]));
1725: u1u2 = smith2(h); u1u2clean = smithclean(u1u2);
1726: met=(GEN)u1u2clean[3];
1727:
1728: if (add_gen)
1729: {
1730: if (lg(struct1)<=3)
1731: err(talker,"please apply idealstar(,,2) and not idealstar(,,1)");
1732: gen=concatsp((GEN)struct1[3],(GEN)sarch[2]);
1733:
1734: u1 = reducemodmatrix(ginv((GEN)u1u2[1]),h);
1735: p1 = cgetg(4,t_VEC);
1736: p1[3] = (long)compute_gen(nf,u1,met,gen,module, nbp,sarch);
1737: }
1738: else p1 = cgetg(3,t_VEC);
1739:
1740: y=cgetg(6,t_VEC);
1741: y[1]=(long)module;
1742: y[2]=(long)p1;
1743: p1[1]=(long)dethnf(met);
1744: p1[2]=(long)mattodiagonal(met);
1745: y[3]=(long)fact1;
1746: y[4]=(long)liste;
1747: y[5] = u1u2clean[1];
1748: return gerepileupto(av,gcopy(y));
1749: }
1750:
1751: GEN
1752: zidealstarinitjoinarch(GEN nf, GEN bid1, GEN arch, long nba)
1753: {
1754: return zidealstarinitjoinarchall(nf,bid1,arch,nba,0);
1755: }
1756:
1757: GEN
1758: zidealstarinitjoinarchgen(GEN nf, GEN bid1, GEN arch, long nba)
1759: {
1760: return zidealstarinitjoinarchall(nf,bid1,arch,nba,1);
1761: }
1762:
1763: /* calcule la matrice des zinternallog des unites */
1764: GEN
1765: logunitmatrix(GEN nf,GEN funits,GEN racunit,GEN bid)
1766: {
1767: long R,j,sizeh;
1768: GEN m,fa2,fa,arch;
1769:
1770: R=lg(funits)-1; m=cgetg(R+2,t_MAT);
1771: fa2=(GEN)bid[4]; sizeh=lg(bid[5])-1; arch=gmael(bid,1,2);
1772: fa=(GEN)bid[3];
1773: m[1]=(long)zinternallog(nf,fa2,sizeh,arch,fa,racunit,0);
1774: for (j=2; j<=R+1; j++)
1775: m[j]=(long)zinternallog(nf,fa2,sizeh,arch,fa,(GEN)funits[j-1],0);
1776: return m;
1777: }
1778:
1779: /* calcule la matrice des zinternallog des unites */
1780: static GEN
1781: logunitmatrixarch(GEN nf,GEN funits,GEN racunit,GEN bid)
1782: {
1783: long R,j;
1784: GEN m,liste,structarch,arch;
1785:
1786: R=lg(funits)-1; m=cgetg(R+2,t_MAT); arch=gmael(bid,1,2);
1787: liste=(GEN)bid[4]; structarch=(GEN)liste[lg(liste)-1];
1788: m[1]=(long)zsigne(nf,racunit,arch);
1789: for (j=2; j<=R+1; j++)
1790: m[j]=(long)zsigne(nf,(GEN)funits[j-1],arch);
1791: return lift_intern(gmul((GEN)structarch[3],m));
1792: }
1793:
1794: /* concatenation verticale de Q1 et Q2. Ne cree pas le resultat. */
1795: GEN
1796: vconcat(GEN Q1, GEN Q2)
1797: {
1798: long lc,lr,lx1,lx2,i,j;
1799: GEN m,p1,p2,p3;
1800:
1801: lc=lg(Q1); if (lc==1) return Q1;
1802: lx1=lg(Q1[1]); lx2=lg(Q2[1]); lr=lx1+lx2-1;
1803: m=cgetg(lc,t_MAT);
1804: for (j=1; j<lc; j++)
1805: {
1806: p1=cgetg(lr,t_COL); m[j]=(long)p1; p2=(GEN)Q1[j]; p3=(GEN)Q2[j];
1807: for (i=1; i<lx1; i++) p1[i]=p2[i];
1808: for ( ; i<lr; i++) p1[i]=p3[i-lx1+1];
1809: }
1810: return m;
1811: }
1812:
1813: static void
1814: init_units(GEN bnf, GEN *funits, GEN *racunit)
1815: {
1816: GEN p1;
1817: bnf = checkbnf(bnf); p1=(GEN)bnf[8];
1818: if (lg(p1)==5) *funits=(GEN)buchfu(bnf)[1];
1819: else
1820: {
1821: if (lg(p1)!=7) err(talker,"incorrect big number field");
1822: *funits=(GEN)p1[5];
1823: }
1824: *racunit=gmael(p1,4,2);
1825: }
1826:
1827: /* flag &1 : generateurs, sinon non
1828: * flag &2 : unites, sinon pas.
1829: * flag &4 : ideaux, sinon zidealstar.
1830: */
1831: static GEN
1832: ideallistzstarall(GEN bnf,long bound,long flag)
1833: {
1834: byteptr ptdif=diffptr;
1835: long lim,av0=avma,av,i,j,k,l,q2,lp1,q;
1836: long do_gen = flag & 1, do_units = flag & 2, big_id = !(flag & 4);
1837: GEN y,nf,p,z,z2,p1,p2,p3,fa,pr,ideal,lu,lu2,funits,racunit,embunit;
1838:
1839: nf=checknf(bnf);
1840: z = cgetg(bound+1,t_VEC);
1841: for (i=2; i<=bound; i++) z[i] = lgetg(1,t_VEC);
1842: if (do_units)
1843: {
1844: init_units(bnf,&funits,&racunit);
1845: lu = cgetg(bound+1,t_VEC);
1846: for (i=2; i<=bound; i++) lu[i]=lgetg(1,t_VEC);
1847: }
1848:
1849: ideal = idmat(lgef(nf[1])-3);
1850: if (big_id) ideal = zidealstarinitall(nf,ideal,do_gen);
1851: p2 = cgetg(2,t_VEC); z[1] = (long)p2;
1852: p2[1] = (long)ideal;
1853: if (do_units)
1854: {
1855: p2 = cgetg(2,t_VEC); lu[1] = (long)p2;
1856: p2[1] = (long)logunitmatrix(nf,funits,racunit,ideal);
1857: }
1858:
1859: p=cgeti(3); p[1]=evalsigne(1) | evallgefint(3);
1860: av=avma; lim=stack_lim(av,1);
1861: for (p[2]=0; p[2]<=bound; )
1862: {
1863: if (!*ptdif) err(primer1);
1864: p[2] += *ptdif++;
1865: if (DEBUGLEVEL>1) { fprintferr("%ld ",p[2]); flusherr(); }
1866: fa = primedec(nf,p);
1867: for (j=1; j<lg(fa); j++)
1868: {
1869: pr = (GEN)fa[j]; p1 = powgi(p,(GEN)pr[4]);
1870: if (is_bigint(p1) || (q = itos(p1)) > bound) continue;
1871:
1872: q2=q; ideal=pr; z2=dummycopy(z);
1873: if (do_units) lu2=dummycopy(lu);
1874: for (l=2; ;l++)
1875: {
1876: if (big_id) ideal = zidealstarinitall(nf,ideal,do_gen);
1877: if (do_units) embunit = logunitmatrix(nf,funits,racunit,ideal);
1878: for (i=q; i<=bound; i+=q)
1879: {
1880: p1 = (GEN)z[i/q];
1881: if ((lp1 = lg(p1)) == 1) continue;
1882:
1883: p2 = cgetg(lp1,t_VEC);
1884: for (k=1; k<lp1; k++)
1885: if (big_id)
1886: p2[k] = (long)zidealstarinitjoinall(nf,(GEN)p1[k],ideal,do_gen);
1887: else
1888: p2[k] = (long)idealmul(nf,(GEN)p1[k],ideal);
1889: z2[i] = (long)concatsp((GEN)z2[i],p2);
1890: if (do_units)
1891: {
1892: p1 = (GEN)lu[i/q];
1893: p2 = cgetg(lp1,t_VEC);
1894: for (k=1; k<lp1; k++)
1895: p2[k] = (long)vconcat((GEN)p1[k],embunit);
1896: lu2[i] = (long)concatsp((GEN)lu2[i],p2);
1897: }
1898: }
1899: q *= q2; if ((ulong)q > (ulong)bound) break;
1900: ideal = idealpows(nf,pr,l);
1901: }
1902: z = z2; if (do_units) lu = lu2;
1903: }
1904: if (low_stack(lim, stack_lim(av,1)))
1905: {
1906: GEN *gptr[2]; gptr[0]=&z; gptr[1]=&lu;
1907: if(DEBUGMEM>1) err(warnmem,"ideallistzstarall");
1908: gerepilemany(av,gptr,do_units?2:1);
1909: }
1910: }
1911: if (!do_units) return gerepileupto(av0, gcopy(z));
1912: y = cgetg(3,t_VEC);
1913: y[1] = lcopy(z);
1914: lu2 = cgetg(lg(z),t_VEC);
1915: for (i=1; i<lg(z); i++)
1916: {
1917: p1=(GEN)z[i]; p2=(GEN)lu[i]; lp1=lg(p1);
1918: p3=cgetg(lp1,t_VEC); lu2[i]=(long)p3;
1919: for (j=1; j<lp1; j++) p3[j] = lmul(gmael(p1,j,5),(GEN)p2[j]);
1920: }
1921: y[2]=(long)lu2; return gerepileupto(av0, y);
1922: }
1923:
1924: GEN
1925: ideallist0(GEN bnf,long bound, long flag)
1926: {
1927: if (flag<0 || flag>4) err(flagerr,"ideallist");
1928: return ideallistzstarall(bnf,bound,flag);
1929: }
1930:
1931: GEN
1932: ideallistzstar(GEN nf,long bound)
1933: {
1934: return ideallistzstarall(nf,bound,0);
1935: }
1936:
1937: GEN
1938: ideallistzstargen(GEN nf,long bound)
1939: {
1940: return ideallistzstarall(nf,bound,1);
1941: }
1942:
1943: GEN
1944: ideallistunit(GEN nf,long bound)
1945: {
1946: return ideallistzstarall(nf,bound,2);
1947: }
1948:
1949: GEN
1950: ideallistunitgen(GEN nf,long bound)
1951: {
1952: return ideallistzstarall(nf,bound,3);
1953: }
1954:
1955: GEN
1956: ideallist(GEN bnf,long bound)
1957: {
1958: return ideallistzstarall(bnf,bound,4);
1959: }
1960:
1961: static GEN
1962: ideallist_arch(GEN nf,GEN list,GEN arch,long flun)
1963: {
1964: long nba,i,j,lx,ly;
1965: GEN p1,z,p2;
1966:
1967: nba=0; for (i=1; i<lg(arch); i++) if (signe(arch[i])) nba++;
1968: lx=lg(list); z=cgetg(lx,t_VEC);
1969: for (i=1; i<lx; i++)
1970: {
1971: p2=(GEN)list[i]; checkbid(p2); ly=lg(p2);
1972: p1=cgetg(ly,t_VEC); z[i]=(long)p1;
1973: for (j=1; j<ly; j++)
1974: p1[j]=(long)zidealstarinitjoinarchall(nf,(GEN)p2[j],arch,nba,flun);
1975: }
1976: return z;
1977: }
1978:
1979: static GEN
1980: ideallistarchall(GEN bnf,GEN list,GEN arch,long flag)
1981: {
1982: long av,tetpil,i,j,lp1;
1983: long do_units = flag & 2;
1984: GEN nf = checknf(bnf), p1,p2,p3,racunit,funits,lu2,lu,embunit,z,y;
1985:
1986: if (typ(list) != t_VEC || (do_units && lg(list) != 3))
1987: err(typeer, "ideallistarch");
1988: if (lg(list) == 1) return cgetg(1,t_VEC);
1989: if (do_units)
1990: {
1991: y = cgetg(3,t_VEC);
1992: z = (GEN)list[1];
1993: lu= (GEN)list[2]; if (typ(lu) != t_VEC) err(typeer, "ideallistarch");
1994: }
1995: else z = list;
1996: if (typ(z) != t_VEC) err(typeer, "ideallistarch");
1997: z = ideallist_arch(nf,z,arch, flag & 1);
1998: if (!do_units) return z;
1999: y[1]=(long)z; av=avma;
2000: init_units(bnf,&funits,&racunit);
2001: lu2=cgetg(lg(z),t_VEC);
2002: for (i=1; i<lg(z); i++)
2003: {
2004: p1=(GEN)z[i]; p2=(GEN)lu[i]; lp1=lg(p1);
2005: p3=cgetg(lp1,t_VEC); lu2[i]=(long)p3;
2006: for (j=1; j<lp1; j++)
2007: {
2008: embunit = logunitmatrixarch(nf,funits,racunit,(GEN)p1[j]);
2009: p3[j] = lmul(gmael(p1,j,5), vconcat((GEN)p2[j],embunit));
2010: }
2011: }
2012: tetpil=avma; y[2]=lpile(av,tetpil,gcopy(lu2)); return y;
2013: }
2014:
2015: GEN
2016: ideallistarch(GEN nf, GEN list, GEN arch)
2017: {
2018: return ideallistarchall(nf,list,arch,0);
2019: }
2020:
2021: GEN
2022: ideallistarchgen(GEN nf, GEN list, GEN arch)
2023: {
2024: return ideallistarchall(nf,list,arch,1);
2025: }
2026:
2027: GEN
2028: ideallistunitarch(GEN bnf,GEN list,GEN arch)
2029: {
2030: return ideallistarchall(bnf,list,arch,2);
2031: }
2032:
2033: GEN
2034: ideallistunitarchgen(GEN bnf,GEN list,GEN arch)
2035: {
2036: return ideallistarchall(bnf,list,arch,3);
2037: }
2038:
2039: GEN
2040: ideallistarch0(GEN nf, GEN list, GEN arch,long flag)
2041: {
2042: if (!arch) arch=cgetg(1,t_VEC);
2043: if (flag<0 || flag>3) err(flagerr,"ideallistarch");
2044: return ideallistarchall(nf,list,arch,flag);
2045: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>