Annotation of OpenXM_contrib/pari/src/basemath/buch3.c, Revision 1.1.1.1
1.1 maekawa 1: /*******************************************************************/
2: /* */
3: /* RAY CLASS FIELDS */
4: /* */
5: /*******************************************************************/
6: /* $Id: buch3.c,v 1.2 1999/09/23 17:50:56 karim Exp $ */
7: #include "pari.h"
8: #include "parinf.h"
9:
10: GEN compute_class_number(GEN mit,GEN *met,GEN *u1,GEN *u2);
11: GEN logunitmatrix(GEN nf,GEN funits,GEN racunit,GEN bid);
12: GEN vconcat(GEN Q1, GEN Q2);
13: GEN ideleaddone_aux(GEN nf,GEN x,GEN ideal);
14:
15: static GEN
16: get_full_rank(GEN nf, GEN v, GEN _0, GEN _1, GEN vecsign, GEN gen,
17: long ngen, long rankmax)
18: {
19: GEN v1,p1,alpha, bas=(GEN)nf[7], rac=(GEN)nf[6];
20: long rankinit=lg(v)-1, N=lgef(nf[1])-3, va=varn(nf[1]);
21: long limr,i,k,kk,r,rr;
22:
23: for (r=1,rr=3; ; r++,rr+=2)
24: {
25: p1 = gpuigs(stoi(rr),N);
26: limr=(cmpis(p1,BIGINT)>1)? BIGINT: p1[2]; /* min(BIGINT,rr^N) */
27: limr = (limr-1)>>1;
28: for (k=rr; k<=limr; k++)
29: {
30: long av1=avma;
31: alpha = gzero;
32: for (kk=k,i=1; i<=N; i++,kk/=rr)
33: {
34: long lambda = (kk+r)%rr - r;
35: if (lambda)
36: alpha = gadd(alpha,gmulsg(lambda,(GEN)bas[i]));
37: }
38: for (i=1; i<=rankmax; i++)
39: vecsign[i] = (gsigne(gsubst(alpha,va,(GEN)rac[i])) > 0)? (long)_0
40: : (long)_1;
41: v1 = concatsp(v, vecsign);
42: if (rank(v1) == rankinit) avma=av1;
43: else
44: {
45: v=v1; rankinit++; ngen++;
46: gen[ngen] = (long) alpha;
47: if (rankinit == rankmax) return ginv(v); /* full rank */
48: }
49: }
50: }
51: }
52:
53: GEN
54: buchnarrow(GEN bnf)
55: {
56: GEN nf,_0mod2,_1mod2,cyc,gen,v,matsign,arch;
57: GEN dataunit,p1,p2,p3,h,vecsign,clh,basecl,met,u1,u2;
58: long R1,R,i,j,ngen,sizeh,t,lo,c;
59: long av=avma,tetpil;
60:
61: if (typ(bnf)!=t_VEC || lg(bnf)!=11)
62: err(talker,"not a big number field vector in buchnarrow");
63: nf=checknf(bnf); R1=itos(gmael(nf,2,1));
64: if (!R1) return gcopy(gmael(bnf,8,1));
65:
66: _1mod2=gmodulss(1,2); _0mod2=gmodulss(0,2);
67: v=cgetg(R1+1,t_COL); vecsign=cgetg(R1+1,t_COL);
68: for (i=1; i<=R1; i++) v[i]=(long)_1mod2;
69: cyc=gmael3(bnf,8,1,2); gen=gmael3(bnf,8,1,3); ngen=lg(gen)-1;
70: matsign=signunits(bnf); R=lg(matsign); dataunit=cgetg(R+1,t_MAT);
71: for (j=1; j<R; j++)
72: {
73: p1=cgetg(R1+1,t_COL); dataunit[j]=(long)p1;
74: for (i=1; i<=R1; i++)
75: p1[i] = (signe(gcoeff(matsign,i,j)) > 0)? (long)_0mod2: (long)_1mod2;
76: }
77: dataunit[R]=(long)v; v=image(dataunit); t=lg(v)-1;
78: sizeh=ngen+R1-t; p1 = cgetg(sizeh+1,t_COL);
79: for (i=1; i<=ngen; i++) p1[i]=gen[i];
80: gen = p1;
81: if (t<R1)
82: v = get_full_rank(nf,v,_0mod2,_1mod2,vecsign,gen,ngen,R1);
83:
84: h=cgetg(sizeh+1,t_MAT); arch = cgetg(R1+1,t_VEC);
85: for (i=1; i<=R1; i++) arch[i]=un;
86: for (j=1; j<=ngen; j++)
87: {
88: p1 = cgetg(sizeh+1,t_COL); h[j]=(long)p1;
89: p2 = idealpow(nf, (GEN)gen[j], (GEN)cyc[j]);
90: p2 = (GEN)isprincipalall(bnf,p2,nf_GEN | nf_FORCE)[2];
91: p2 = gmul(v,zsigne(nf,p2,arch));
92: for (i=1; i<=ngen; i++) p1[i] = (i==j)? cyc[j]: zero;
93: for ( ; i<=sizeh; i++) p1[i] = llift((GEN)p2[i+t-ngen]);
94: }
95: for ( ; j<=sizeh; j++)
96: {
97: p1 = cgetg(sizeh+1,t_COL); h[j]=(long)p1;
98: for (i=1; i<=sizeh; i++) p1[i]=(i==j)?deux:zero;
99: }
100: clh=compute_class_number(h,&met,&u1,&u2);
101: u1=reducemodmatrix(u1,h); lo=lg(met)-1; c=0;
102: for (c=1; c<=lo; c++)
103: if (gcmp1(gcoeff(met,c,c))) break;
104: basecl=cgetg(c,t_VEC);
105: for (j=1; j<c; j++)
106: {
107: p1=gcoeff(u1,1,j);
108: p3=idealpow(nf,(GEN)gen[1],p1);
109: if (signe(p1)<0) p3=numer(p3);
110: for (i=2; i<=lo; i++)
111: {
112: p1=gcoeff(u1,i,j);
113: if (signe(p1))
114: {
115: p3 = idealmul(nf,p3, idealpow(nf,(GEN)gen[i],p1));
116: p1 = content(p3); if (!gcmp1(p1)) p3 = gdiv(p3,p1);
117: }
118: }
119: basecl[j]=(long)p3;
120: }
121: tetpil=avma; v=cgetg(4,t_VEC);
122: v[1]=lcopy(clh); setlg(met,c);
123: v[2]=(long)mattodiagonal(met);
124: v[3]=lcopy(basecl); return gerepile(av,tetpil,v);
125: }
126:
127: GEN idealaddtoone_i(GEN nf, GEN x, GEN y);
128:
129: /* given two coprime ideals x (integral) and id, compute alpha in x,
130: * alpha = 1 mod (id), with x/alpha nearly reduced.
131: */
132: static GEN
133: findalpha(GEN nf,GEN x,GEN id,long prec)
134: {
135: GEN p1,idprod,y;
136: GEN alp = idealaddtoone_i(nf,x,id);
137:
138: idprod = idealmullll(nf,x,id);
139: y = lllgram(qf_base_change(gmael(nf,5,3),idprod,1), 2*prec-2);
140: y = gmul(idprod, (GEN)y[1]); /* small vector in idprod */
141:
142: p1 = ground(element_div(nf,alp,y));
143: alp = gsub(alp,element_mul(nf,p1,y));
144: return gcmp0(alp)? y: alp;
145: }
146:
147: static int
148: too_big(GEN nf, GEN bet)
149: {
150: GEN x = gnorm(basistoalg(nf,bet));
151: switch (typ(x))
152: {
153: case t_INT: return absi_cmp(x, gun);
154: case t_FRAC: return absi_cmp((GEN)x[1], (GEN)x[2]);
155: }
156: err(bugparier, "wrong type in too_big");
157: return 0; /* not reached */
158: }
159:
160: static GEN
161: idealmodidele(GEN nf, GEN x, GEN ideal, GEN sarch, GEN arch, long prec)
162: {
163: long av = avma,i,l;
164: GEN p1,p2,alp,bet,b;
165:
166: nf=checknf(nf); alp=findalpha(nf,x,ideal,prec);
167: p1=idealdiv(nf,alp,x);
168: bet = element_div(nf,findalpha(nf,p1,ideal,prec),alp);
169: if (too_big(nf,bet) > 0) { avma=av; return x; }
170: p1=(GEN)sarch[2]; l=lg(p1);
171: if (l > 1)
172: {
173: b=bet; p2=lift_intern(gmul((GEN)sarch[3],zsigne(nf,bet,arch)));
174: for (i=1; i<l; i++)
175: if (signe(p2[i])) bet = element_mul(nf,bet,(GEN)p1[i]);
176: if (b != bet && too_big(nf,bet) > 0) { avma=av; return x; }
177: }
178: return idealmul(nf,bet,x);
179: }
180:
181: static GEN
182: idealmulmodidele(GEN nf,GEN x,GEN y, GEN ideal,GEN sarch,GEN arch,long prec)
183: {
184: return idealmodidele(nf,idealmul(nf,x,y),ideal,sarch,arch,prec);
185: }
186:
187: /* assume n > 0 */
188: static GEN
189: idealpowmodidele(GEN nf,GEN x,GEN n, GEN ideal,GEN sarch,GEN arch,long prec)
190: {
191: long i,m,av=avma;
192: GEN y;
193: ulong j;
194:
195: if (cmpis(n, 16) < 0)
196: {
197: if (gcmp1(n)) return x;
198: x = idealpow(nf,x,n);
199: x = idealmodidele(nf,x,ideal,sarch,arch,prec);
200: return gerepileupto(av,x);
201: }
202:
203: i = lgefint(n)-1; m=n[i]; j=HIGHBIT;
204: while ((m&j)==0) j>>=1;
205: y = x;
206: for (j>>=1; j; j>>=1)
207: {
208: y = idealmul(nf,y,y);
209: if (m&j) y = idealmul(nf,y,x);
210: y = idealmodidele(nf,y,ideal,sarch,arch,prec);
211: }
212: for (i--; i>=2; i--)
213: for (m=n[i],j=HIGHBIT; j; j>>=1)
214: {
215: y = idealmul(nf,y,y);
216: if (m&j) y = idealmul(nf,y,x);
217: y = idealmodidele(nf,y,ideal,sarch,arch,prec);
218: }
219: return gerepileupto(av,y);
220: }
221:
222: static GEN
223: buchrayall(GEN bnf,GEN module,long flag,long prec)
224: {
225: GEN nf,cyc,gen,genplus,fa2,sarch,hmatu,u,clg;
226: GEN dataunit,p1,p2,h,clh,basecl,met,u1,u2,u1old;
227: GEN racunit,bigres,bid,resbid2,resbid3,x,y,funits,hmat,vecel;
228: long RU,R3,i,j,ngen,lh,lo,c,av=avma,N;
229:
230: bnf = checkbnf(bnf); nf=checknf(bnf); bigres=(GEN)bnf[8];
231: funits = check_units(bnf, "buchrayall");
232: N=lgef(nf[1])-3;
233: cyc=gmael(bigres,1,2);
234: gen=gmael(bigres,1,3); ngen=lg(cyc)-1;
235:
236: bid = zidealstarinitall(nf,module,1);
237: resbid2=gmael(bid,2,2);
238: resbid3=gmael(bid,2,3);
239: R3=lg(resbid2)-1; lh=ngen+R3;
240:
241: x = idealhermite(nf,module);
242: if (R3 || flag & (nf_INIT|nf_GEN))
243: {
244: vecel=cgetg(ngen+1,t_VEC);
245: for (j=1; j<=ngen; j++)
246: vecel[j]=(long)idealcoprime(nf,(GEN)gen[j],x);
247: }
248: if (flag & nf_GEN)
249: {
250: genplus=cgetg(lh+1,t_VEC);
251: for (j=1; j<=ngen; j++)
252: genplus[j] = (long) idealmul(nf,(GEN)vecel[j],(GEN)gen[j]);
253: for ( ; j<=lh; j++)
254: genplus[j] = resbid3[j-ngen];
255: }
256: if (!R3)
257: {
258: if (!(flag & nf_GEN)) clg=cgetg(3,t_VEC);
259: else
260: { clg=cgetg(4,t_VEC); clg[3]=(long)genplus; }
261: clg[1]=mael(bigres,1,1);
262: clg[2]=(long)cyc;
263: if (!(flag & nf_INIT)) return gerepileupto(av,gcopy(clg));
264: y = cgetg(7,t_VEC);
265: y[1]=lcopy(bnf);
266: y[2]=lcopy(bid);
267: y[3]=lcopy(vecel);
268: y[4]=(long)idmat(ngen);
269: y[5]=lcopy(clg); u=cgetg(3,t_VEC);
270: y[6]=(long)u;
271: u[1]=lgetg(1,t_MAT);
272: u[2]=(long)idmat(lg(funits));
273: return gerepileupto(av,y);
274: }
275: fa2=(GEN)bid[4]; sarch=(GEN)fa2[lg(fa2)-1];
276:
277: RU=lg(funits); dataunit=cgetg(RU+R3+1,t_MAT);
278: racunit=gmael(bigres,4,2);
279: dataunit[1] = (long)zideallog(nf,racunit,bid);
280: for (j=2; j<=RU; j++)
281: dataunit[j] = (long)zideallog(nf,(GEN)funits[j-1],bid);
282: for ( ; j<=RU+R3; j++)
283: {
284: p1=cgetg(R3+1,t_COL); dataunit[j]=(long)p1;
285: for (i=1; i<=R3; i++)
286: p1[i] = (i==(j-RU))? resbid2[i]: zero;
287: }
288: h=cgetg(lh+1,t_MAT);
289: for (j=1; j<=ngen; j++)
290: {
291: p1=cgetg(lh+1,t_COL); h[j]=(long)p1;
292: p2 = idealpow(nf, (GEN)gen[j], (GEN)cyc[j]);
293: p2 = (GEN)isprincipalall(bnf,p2,nf_GEN | nf_FORCE)[2];
294: p2 = element_mul(nf,p2,element_pow(nf,(GEN)vecel[j],(GEN)cyc[j]));
295: p2 = zideallog(nf,p2,bid);
296: for (i=1; i<=ngen; i++) p1[i] = (i==j)? cyc[j]: zero;
297: for ( ; i<=lh; i++) p1[i] = lnegi((GEN)p2[i-ngen]);
298: }
299:
300: hmatu=hnfall(dataunit); hmat=(GEN)hmatu[1];
301: for ( ; j<=lh; j++)
302: {
303: p1=cgetg(lh+1,t_COL); h[j]=(long)p1;
304: for (i=1; i<=ngen; i++) p1[i]=zero;
305: for ( ; i<=lh; i++) p1[i]=coeff(hmat,i-ngen,j-ngen);
306: }
307: clh = compute_class_number(h,&met,&u1,&u2);
308: u1old=u1; lo=lg(met)-1;
309: for (c=1; c<=lo; c++)
310: if (gcmp1(gcoeff(met,c,c))) break;
311:
312: if (flag & nf_GEN)
313: {
314: GEN Id=idmat(N), arch=(GEN)module[2];
315: u1 = reducemodmatrix(u1,h);
316: basecl=cgetg(c,t_VEC);
317: for (j=1; j<c; j++)
318: {
319: GEN *op, minus = Id, plus = Id;
320: long av1 = avma, s;
321: for (i=1; i<=lo; i++)
322: {
323: p1 = gcoeff(u1,i,j);
324: if (!(s = signe(p1))) continue;
325:
326: if (s > 0) op = + else { op = − p1 = negi(p1); }
327: p1 = idealpowmodidele(nf,(GEN)genplus[i],p1,x,sarch,arch,prec);
328: *op = *op==Id? p1
329: : idealmulmodidele(nf,*op,p1,x,sarch,arch,prec);
330: }
331: if (minus == Id) p1 = plus;
332: else
333: {
334: p2 = ideleaddone_aux(nf,minus,module);
335: p1 = idealdivexact(nf,idealmul(nf,p2,plus),minus);
336: p1 = idealmodidele(nf,p1,x,sarch,arch,prec);
337: }
338: basecl[j]=lpileupto(av1,p1);
339: }
340: clg=cgetg(4,t_VEC); clg[3]=lcopy(basecl);
341: } else clg=cgetg(3,t_VEC);
342: clg[1]=licopy(clh); setlg(met,c);
343: clg[2]=(long)mattodiagonal(met);
344: if (!(flag & nf_INIT)) return gerepileupto(av,clg);
345:
346: u2 = cgetg(R3+1,t_MAT);
347: u1 = cgetg(RU+1,t_MAT); u = (GEN)hmatu[2];
348: for (j=1; j<=RU; j++) { u1[j]=u[j]; setlg(u[j],RU+1); }
349: u += RU;
350: for (j=1; j<=R3; j++) { u2[j]=u[j]; setlg(u[j],RU+1); }
351: p1=lllint(u1); p2=ginv(hmat);
352: y=cgetg(7,t_VEC);
353: y[1]=lcopy(bnf);
354: y[2]=lcopy(bid);
355: y[3]=lcopy(vecel);
356: y[4]=linv(u1old);
357: y[5]=lcopy(clg); u=cgetg(3,t_VEC);
358: y[6]=(long)u;
359: u[1]=lmul(u2,p2);
360: u[2]=lmul(u1,p1);
361: return gerepileupto(av,y);
362: }
363:
364: GEN
365: buchrayinitgen(GEN bignf, GEN ideal,long prec)
366: {
367: return buchrayall(bignf,ideal, nf_INIT | nf_GEN,prec);
368: }
369:
370: GEN
371: buchrayinit(GEN bignf, GEN ideal,long prec)
372: {
373: return buchrayall(bignf,ideal, nf_INIT,prec);
374: }
375:
376: GEN
377: buchray(GEN bignf, GEN ideal,long prec)
378: {
379: return buchrayall(bignf,ideal, nf_GEN,prec);
380: }
381:
382: GEN
383: bnrclass0(GEN bignf, GEN ideal, long flag, long prec)
384: {
385: switch(flag)
386: {
387: case 0: flag = nf_GEN; break;
388: case 1: flag = nf_INIT; break;
389: case 2: flag = nf_INIT | nf_GEN; break;
390: default: err(flagerr,"bnrclass");
391: }
392: return buchrayall(bignf,ideal,flag,prec);
393: }
394:
395: GEN
396: bnrinit0(GEN bignf, GEN ideal, long flag, long prec)
397: {
398: switch(flag)
399: {
400: case 0: flag = nf_INIT; break;
401: case 1: flag = nf_INIT | nf_GEN; break;
402: default: err(flagerr,"bnrinit");
403: }
404: return buchrayall(bignf,ideal,flag,prec);
405: }
406:
407: GEN
408: rayclassno(GEN bnf,GEN ideal)
409: {
410: GEN nf,clno,dataunit,p1;
411: GEN racunit,bigres,bid,resbid,resbid2,funits,hmat;
412: long RU,R3,i,j,av=avma;
413:
414: bnf = checkbnf(bnf); nf=(GEN)bnf[7]; bigres=(GEN)bnf[8];
415: funits = check_units(bnf,"rayclassno");
416: clno = gmael(bigres,1,1);
417: bid = zidealstarinitall(nf,ideal,0);
418: resbid=(GEN)bid[2]; resbid2=(GEN)resbid[2];
419: R3=lg(resbid2)-1; if (!R3) { avma=av; return icopy(clno); }
420:
421: RU=lg(funits); dataunit=cgetg(RU+R3+1,t_MAT);
422: racunit=gmael(bigres,4,2); dataunit[1]=(long)zideallog(nf,racunit,bid);
423: for (j=2; j<=RU; j++)
424: dataunit[j]=(long)zideallog(nf,(GEN)funits[j-1],bid);
425: for ( ; j<=RU+R3; j++)
426: {
427: p1=cgetg(R3+1,t_COL); dataunit[j]=(long)p1;
428: for (i=1; i<=R3; i++)
429: p1[i] = (i==(j-RU))?resbid2[i]:zero;
430: }
431: hmat=hnfmod(dataunit,(GEN)resbid[1]);
432: for (i=lg(hmat)-1 ; i; i--) clno = mulii(clno,gcoeff(hmat,i,i));
433: avma=av; return icopy(clno);
434: }
435:
436: GEN
437: isprincipalrayall(GEN bnr, GEN x, long flag)
438: {
439: long av=avma,tetpil,i,j,c,N,ngen,ngzk;
440: GEN bnf,nf,bid,vecel,vecep,matu,ep,p1,p2,p3,p4,beta,idep,y,rayclass;
441: GEN divray,genray,alpha,alphaall,racunit,res,funit,pol;
442:
443: checkbnr(bnr); bnf=(GEN)bnr[1]; bid=(GEN)bnr[2];
444: vecel=(GEN)bnr[3]; matu=(GEN)bnr[4];
445: rayclass=(GEN)bnr[5]; nf=(GEN)bnf[7]; ngen=lg(vecel)-1;
446: idep=isprincipalall(bnf,x,nf_GEN | nf_FORCE);
447: if (lg(idep[1]) != ngen+1)
448: err(talker,"incorrect generator length in isprincipalray");
449: pol=(GEN)nf[1]; N=lgef(pol)-3;
450: p2=cgetg(N+1,t_COL); p2[1]=un;
451: for (i=2; i<=N; i++) p2[i]=zero;
452: ep=(GEN)idep[1];
453: for (i=1; i<=ngen; i++)
454: if (typ(vecel[i]) != t_INT)
455: p2=element_mul(nf,p2,element_pow(nf,(GEN)vecel[i],(GEN)ep[i]));
456: beta=element_div(nf,(GEN)idep[2],p2);
457: p3=zideallog(nf,beta,bid); ngzk=lg(p3)-1;
458: vecep=cgetg(ngen+ngzk+1,t_COL);
459: for (i=1; i<=ngen; i++) vecep[i]=ep[i];
460: for ( ; i<=ngen+ngzk; i++) vecep[i]=p3[i-ngen];
461: p1=gmul(matu,vecep);
462: divray=(GEN)rayclass[2]; c=lg(divray);
463: tetpil=avma; y=cgetg(c,t_COL);
464: for (i=1; i<c; i++)
465: y[i] = lmodii((GEN)p1[i],(GEN)divray[i]);
466: if (!(flag & nf_GEN)) return gerepile(av,tetpil,y);
467:
468: if (lg(rayclass)<=3)
469: err(talker,"please apply bnrinit(,,1) and not bnrinit(,,0)");
470:
471: genray=(GEN)rayclass[3]; p1=idmat(N);
472: for (i=1; i<c; i++)
473: p1=idealmul(nf,idealpow(nf,(GEN)genray[i],(GEN)y[i]),p1);
474: alphaall = isprincipalall(bnf,idealdiv(nf,x,p1),nf_GEN | nf_FORCE);
475: if (!gcmp0((GEN)alphaall[1])) err(bugparier,"isprincipalray (bug1)");
476:
477: res=(GEN)bnf[8];
478: funit = check_units(bnf,"isprincipalrayall");
479: racunit=(GEN)res[4];
480: alpha = basistoalg(nf,(GEN)alphaall[2]);
481: p3=zideallog(nf,(GEN)alphaall[2],bid);
482: if (lg(p3)>1)
483: {
484: p4=(GEN)bnr[6]; p3=gmul((GEN)p4[1],p3);
485: if (!gcmp1(denom(p3))) err(bugparier,"isprincipalray (bug2)");
486:
487: x=lllreducemodmatrix(p3,(GEN)p4[2]);
488: p3=gpui(gmodulcp((GEN)racunit[2],pol),(GEN)x[1],0);
489: for (j=1; j<lg(funit); j++)
490: p3=gmul(p3,gpui(gmodulcp((GEN)funit[j],pol),(GEN)x[j+1],0));
491: alpha = gdiv(alpha,p3);
492: }
493: tetpil=avma; p1=cgetg(4,t_VEC);
494: p1[1]=lcopy(y); p1[2]=(long)algtobasis(nf,alpha);
495: p1[3]=lmin((GEN)idep[3],(GEN)alphaall[3]);
496: return gerepile(av,tetpil,p1);
497: }
498:
499: GEN
500: isprincipalray(GEN bignfray, GEN x)
501: {
502: return isprincipalrayall(bignfray,x,nf_REGULAR);
503: }
504:
505: GEN
506: isprincipalraygen(GEN bignfray, GEN x)
507: {
508: return isprincipalrayall(bignfray,x,nf_GEN);
509: }
510:
511: /* DK = |dK|; give c[N][R1] */
512: static GEN
513: zimmertbound(long N,long R1,GEN DK)
514: {
515: long av,tetpil,i,R2;
516: GEN w,p1,minkowski;
517:
518: if (N<2) return gun;
519: av=avma;
520: if (N<21)
521: {
522: double **c=(double**)gpmalloc(sizeof(double*)*21);
523: for (i=1; i<=20; i++) c[i]=(double*)gpmalloc(sizeof(double)*21);
524: c[2][2] = -0.6931; c[3][3] = -1.71733859;
525: c[2][0] = -0.45158; c[3][1] = -1.37420604;
526:
527: c[4][4] = -2.91799837; c[5][5] = -4.22701425;
528: c[4][2] = -2.50091538; c[5][3] = -3.75471588;
529: c[4][0] = -2.11943331; c[5][1] = -3.31196660;
530:
531: c[6][6] = -5.61209925; c[7][7] = -7.05406203;
532: c[6][4] = -5.09730381; c[7][5] = -6.50550021;
533: c[6][2] = -4.60693851; c[7][3] = -5.97735406;
534: c[6][0] = -4.14303665; c[7][1] = -5.47145968;
535:
536: c[8][8] = -8.54052636; c[9][9] = -10.0630022;
537: c[8][6] = -7.96438858; c[9][7] = -9.46382812;
538: c[8][4] = -7.40555445; c[9][5] = -8.87952524;
539: c[8][2] = -6.86558259; c[9][3] = -8.31139202;
540: c[8][0] = -6.34608077; c[9][1] = -7.76081149;
541:
542: c[10][10]= -11.6153797; c[11][11]= -13.1930961;
543: c[10][8] = -10.9966020; c[11][9] = -12.5573772;
544: c[10][6] = -10.3907654; c[11][7] = -11.9330458;
545: c[10][4] = -9.79895170; c[11][5] = -11.3210061;
546: c[10][2] = -9.22232770; c[11][3] = -10.7222412;
547: c[10][0] = -8.66213267; c[11][1] = -10.1378082;
548:
549: c[12][12]= -14.7926394; c[13][13]= -16.4112395;
550: c[12][10]= -14.1420915; c[13][11]= -15.7475710;
551: c[12][8] = -13.5016616; c[13][9] = -15.0929680;
552: c[12][6] = -12.8721114; c[13][7] = -14.4480777;
553: c[12][4] = -12.2542699; c[13][5] = -13.8136054;
554: c[12][2] = -11.6490374; c[13][3] = -13.1903162;
555: c[12][0] = -11.0573775; c[13][1] = -12.5790381;
556:
557: c[14][14]= -18.0466672; c[15][15]= -19.6970961;
558: c[14][12]= -17.3712806; c[15][13]= -19.0111606;
559: c[14][10]= -16.7040780; c[15][11]= -18.3326615;
560: c[14][8] = -16.0456127; c[15][9] = -17.6620757;
561: c[14][6] = -15.3964878; c[15][7] = -16.9999233;
562: c[14][4] = -14.7573587; c[15][5] = -16.3467686;
563: c[14][2] = -14.1289364; c[15][3] = -15.7032228;
564: c[14][0] = -13.5119848; c[15][1] = -15.0699480;
565:
566: c[16][16]= -21.3610081; c[17][17]= -23.0371259;
567: c[16][14]= -20.6655103; c[17][15]= -22.3329066;
568: c[16][12]= -19.9768082; c[17][13]= -21.6349299;
569: c[16][10]= -19.2953176; c[17][11]= -20.9435607;
570: c[16][8] = -18.6214885; c[17][9] = -20.2591899;
571: c[16][6] = -17.9558093; c[17][7] = -19.5822454;
572: c[16][4] = -17.2988108; c[17][5] = -18.9131878;
573: c[16][2] = -16.6510652; c[17][3] = -18.2525157;
574: c[16][0] = -16.0131906; c[17][1] = -17.6007672;
575:
576: c[18][18]= -24.7243611; c[19][19]= -26.4217792;
577: c[18][16]= -24.0121449; c[19][17]= -25.7021950;
578: c[18][14]= -23.3056902; c[19][15]= -24.9879497;
579: c[18][12]= -22.6053167; c[19][13]= -24.2793271;
580: c[18][10]= -21.9113705; c[19][11]= -23.5766321;
581: c[18][8] = -21.2242247; c[19][9] = -22.8801952;
582: c[18][6] = -20.5442836; c[19][7] = -22.1903709;
583: c[18][4] = -19.8719830; c[19][5] = -21.5075437;
584: c[18][2] = -19.2077941; c[19][3] = -20.8321263;
585: c[18][0] = -18.5522234; c[19][1] = -20.1645647;
586:
587: c[20][20]= -28.1285704;
588: c[20][18]= -27.4021674;
589: c[20][16]= -26.6807314;
590: c[20][14]= -25.9645140;
591: c[20][12]= -25.2537867;
592: c[20][10]= -24.5488420;
593: c[20][8] = -23.8499943;
594: c[20][6] = -23.1575823;
595: c[20][4] = -22.4719720;
596: c[20][2] = -21.7935548;
597: c[20][0] = -21.1227537;
598: w=gexp(dbltor(c[N][R1]),6);
599: for (i=1; i<=20; i++) free(c[i]); free(c);
600: p1=gmul(gsqrt(DK,MEDDEFAULTPREC),w);
601: tetpil=avma; return gerepile(av,tetpil,ground(p1));
602: }
603: R2=(N-R1)>>1; p1=gdiv(mpfact(N),gpuigs(stoi(N),N));
604: minkowski=ground(gmul(gmul(p1,gpuigs(gdivsg(4,mppi(MEDDEFAULTPREC)),R2)),gsqrt(DK,MEDDEFAULTPREC)));
605: if (cmpis(minkowski,500000)>0)
606: err(talker,"The field has degree more than 20 and the Minkowski bound is larger than 500 000: it is unrealistic to certify it");
607:
608: tetpil=avma; return gerepile(av,tetpil,gcopy(minkowski));
609: }
610:
611: /* all primes up to Minkowski bound factor on factorbase ? */
612: static void
613: testprime(GEN bnf,GEN minkowski)
614: {
615: long av = avma, pp,i,nbideal,k,pmax;
616: GEN f,p1,vectpp,fb,dK, nf=checknf(bnf);
617: byteptr delta = diffptr;
618:
619: if (DEBUGLEVEL>=2)
620: fprintferr("PHASE 1: check primes to Zimmert bound = %Z\n\n",minkowski);
621: f=(GEN)nf[4]; dK=(GEN)nf[3];
622: if (!gcmp1(f))
623: {
624: GEN different = gmael(nf,5,5);
625: if (DEBUGLEVEL>=2)
626: fprintferr("**** Testing Different = %Z\n",different);
627: p1 = isprincipalall(bnf,different,nf_FORCE);
628: if (DEBUGLEVEL>=2) fprintferr(" is %Z\n",p1);
629: }
630: fb=(GEN)bnf[5];
631: p1 = gmael(fb, lg(fb)-1, 1); /* largest p in factorbase */
632: pp = 0; pmax = is_bigint(p1)? VERYBIGINT: itos(p1);
633: while (cmpsi(pp,minkowski)<1)
634: {
635: pp += *delta++; if (!*delta) err(primer1);
636: if (DEBUGLEVEL>=2) fprintferr("*** p = %ld\n",pp);
637: vectpp=primedec(bnf,stoi(pp)); nbideal=lg(vectpp)-1;
638: /* loop through all P | p if ramified, all but one otherwise */
639: if (!smodis(dK,pp)) nbideal++;
640: for (i=1; i<nbideal; i++)
641: {
642: GEN P = (GEN)vectpp[i]; /* non inert */
643: if (DEBUGLEVEL>=2)
644: fprintferr(" Testing P = %Z\n",P);
645: if (cmpii(idealnorm(bnf,P),minkowski) < 1)
646: {
647: if (pp <= pmax && (k = tablesearch(fb, P, cmp_prime_ideal)))
648: {
649: if (DEBUGLEVEL>=2) fprintferr(" #%ld in factor base\n",k);
650: }
651: else
652: {
653: p1=isprincipalall(bnf,P,nf_FORCE);
654: if (DEBUGLEVEL>=2) fprintferr(" is %Z\n",p1);
655: }
656: }
657: else if (DEBUGLEVEL>=2)
658: fprintferr(" Norm(P) > Zimmert bound\n");
659: }
660: }
661: avma=av;
662: if (DEBUGLEVEL>=2) { fprintferr("End of PHASE 1.\n\n"); flusherr(); }
663: }
664:
665: /* rend constante d'Hermite^n si connue, sinon une borne sup */
666: static GEN
667: hermiteconstant(long n)
668: {
669: long av,tetpil;
670: GEN h,h1;
671:
672: switch(n)
673: {
674: case 1: return gun;
675: case 2: h=cgetg(3,t_FRAC); h[1]=lstoi(4); h[2]=lstoi(3); return h;
676: case 3: return gdeux;
677: case 4: return stoi(4);
678: case 5: return stoi(8);
679: case 6: h=cgetg(3,t_FRAC); h[1]=lstoi(64); h[2]=lstoi(3); return h;
680: case 7: return stoi(64);
681: case 8: return stoi(256);
682: }
683: av = avma;
684: h = gpuigs(gdiv(gdeux,mppi(DEFAULTPREC)),n);
685: h1 = gsqr(ggamma(gdivgs(stoi(n+4),2),DEFAULTPREC));
686: tetpil=avma; return gerepile(av,tetpil,gmul(h,h1));
687: }
688:
689: /* 1 primitif, 0 s'il est peut etre imprimitif... */
690: static long
691: isprimitive(GEN nf)
692: {
693: long N,first,i,l,ep;
694: GEN d,fa;
695:
696: N = lgef(nf[1])-3; fa = (GEN)factor(stoi(N))[1]; /* primes | N */
697: first = itos((GEN)fa[1]); if (first==N) return 1;
698:
699: d=absi((GEN)nf[3]); fa=(GEN)factor(d)[2]; /* expo. primes | disc(nf) */
700: if (mod2(d))
701: { i=1; ep=1; }
702: else
703: { i=2; ep=itos((GEN)fa[1])>>1; }
704: l=lg(fa);
705: for ( ; i < l; i++)
706: {
707: if (ep >= first) return 0;
708: ep = itos((GEN)fa[i]);
709: }
710: return 1;
711: }
712:
713: static GEN
714: regulatorbound(GEN bnf)
715: {
716: long N,R1,R2,R;
717: GEN nf,dKa,bound,p1,c1;
718:
719: nf=(GEN)bnf[7]; N=lgef(nf[1])-3;
720: bound=dbltor(0.2);
721: if (!isprimitive(nf))
722: {
723: if (DEBUGLEVEL>=2)
724: { fprintferr("Default bound for regulator: 0.2\n"); flusherr(); }
725: return bound;
726: }
727: dKa=absi((GEN)nf[3]);
728: R1=itos(gmael(nf,2,1));
729: R2=itos(gmael(nf,2,2)); R=R1+R2-1;
730: if (!R2 && N<12) c1=gpuigs(stoi(4),N>>1); else c1=gpuigs(stoi(N),N);
731: if (cmpii(dKa,c1)<=0)
732: {
733: if (DEBUGLEVEL>=2)
734: { fprintferr("Default bound for regulator: 0.2\n"); flusherr(); }
735: return bound;
736: }
737: p1 = gsqr(glog(gdiv(dKa,c1),DEFAULTPREC));
738: p1 = gdivgs(gmul2n(gpuigs(gdivgs(gmulgs(p1,3),N*(N*N-1)-6*R2),R),R2),N);
739: p1 = gsqrt(gdiv(p1, hermiteconstant(R)), DEFAULTPREC);
740: if (gcmp(p1,bound) > 0) bound = p1;
741: if (DEBUGLEVEL>=2)
742: { fprintferr("Mahler bound for regulator: "); outerr(p1); flusherr(); }
743: return bound;
744: }
745:
746: #define NBMAX 5000
747: /* should use smallvectors */
748: static GEN
749: minimforunits(GEN nf, long borne, long stockmax)
750: {
751: long av = avma,av1,n1,n,i,j,k,s,norme,normax,*x,fl1,cmpt;
752: GEN u,r,S,S1,a,base,p1;
753: double p;
754: double **q,*v,*y,*z;
755: double eps=0.000001;
756:
757: if (DEBUGLEVEL>=2)
758: {
759: fprintferr("Searching minimum of T2-form on units:\n");
760: if (DEBUGLEVEL>2) fprintferr(" borne = %ld\n",borne);
761: flusherr();
762: }
763: a=gmael(nf,5,3); n1=lg(a);
764: n=n1-1;
765: x=(long*)gpmalloc(n1*sizeof(long));
766: y=(double*)gpmalloc(n1*sizeof(double));
767: z=(double*)gpmalloc(n1*sizeof(double));
768: v=(double*)gpmalloc(n1*sizeof(double));
769: q=(double**)gpmalloc(n1*sizeof(double*));
770: for (j=1; j<=n; j++) q[j]=(double*)gpmalloc(n1*sizeof(double));
771: u=lllgram(a,BIGDEFAULTPREC); base=gmul((GEN)nf[7],u);
772: a=gmul(qf_base_change(a,u,1), realun(BIGDEFAULTPREC));
773: r=sqred1(a);
774: for (j=1; j<=n; j++)
775: {
776: v[j]=rtodbl(gcoeff(r,j,j));
777: for (i=1; i<j; i++)
778: q[i][j]=rtodbl(gcoeff(r,i,j));
779: }
780: normax=0;
781: if (stockmax) S=cgetg(stockmax+1,t_MAT);
782: s=0; k=n; cmpt=0; y[n]=z[n]=0;
783: x[n]=(long)(sqrt(borne/v[n]+eps));
784:
785: for(;;)
786: {
787: do
788: {
789: if (k>1)
790: {
791: k--; z[k]=0;
792: for (j=k+1; j<=n; j++) z[k]=z[k]+q[k][j]*x[j];
793: p=x[k+1]+z[k+1];
794: y[k]=y[k+1]+p*p*v[k+1];
795: x[k]=(long)floor(sqrt((borne-y[k]+eps)/v[k])-z[k]);
796: }
797: while (v[k]*(x[k]+z[k])*(x[k]+z[k]) > borne-y[k]+eps)
798: {
799: k++; x[k]--;
800: }
801: }
802: while (k>1);
803: if (!x[1] && y[1]<=eps) break;
804:
805: cmpt++;
806: if (cmpt>NBMAX)
807: {
808: free(x); free(y); free(z); free(v);
809: for (j=1; j<=n; j++) free(q[j]); free(q);
810: av=avma; return NULL;
811: }
812: if (DEBUGLEVEL>8){ fprintferr("."); flusherr(); }
813: norme=(long)(y[1]+v[1]*(x[1]+z[1])*(x[1]+z[1])+eps);
814: if (norme>normax) normax=norme;
815: av1=avma; p1=gzero;
816: for (i=1; i<=n; i++) p1=gadd(p1,gmulsg(x[i],(GEN)base[i]));
817: fl1=gcmp1(gabs(subres(p1,(GEN)nf[1]),0)); avma=av1;
818: if (fl1)
819: {
820: if (DEBUGLEVEL>=2) { fprintferr("*"); flusherr(); }
821: s++; cmpt=0;
822: if (s<=stockmax)
823: {
824: p1=cgetg(n+1,t_COL);
825: for (i=1; i<=n; i++) p1[i]=lstoi(x[i]);
826: S[s]=lmul(u,p1);
827: }
828: }
829: x[k]--;
830: }
831: free(x); free(y); free(z); free(v);
832: for (j=1; j<=n; j++) free(q[j]); free(q);
833: if (DEBUGLEVEL>=2){ fprintferr("\n"); flusherr(); }
834: if (stockmax)
835: {
836: av1=avma;
837: k=(s<stockmax)? s:stockmax;
838: S1=cgetg(k+1,t_MAT);
839: for (j=1; j<=k; j++) S1[j]=lcopy((GEN)S[j]);
840: S=gerepile(av,av1,S1);
841: }
842: else { avma=av; S=cgetg(1,t_MAT); }
843: u=cgetg(4,t_VEC);
844: u[1]=lstoi(s<<1);
845: u[2]=lstoi(normax);
846: u[3]=(long)S;
847: return u;
848: }
849:
850: #undef NBMAX
851:
852: static GEN
853: compute_M0(GEN M_star,long N) /* On connait M_star; on calcule M0 */
854: {
855: long av1,tetpil,m1,m2,n1,n2,n3,k,kk,lr,lr1,lr2,i,j,l,vx,vy,vz,vM,PREC,prec;
856: GEN eps,pol,p1,p2,p3,p4,p5,p6,u,v,w,r,r1,r2,M0,M0_pro,S,P,M_formel;
857: GEN f1,f2,f3,g1,g2,g3,pg1,pg2,pg3,pf1,pf2,pf3,p7,p8,p9,p10,p11;
858: GEN x,y,z;
859:
860: PREC=gprecision(M_star);
861: if (N==2) return gmul2n(gsqr(gach(gmul2n(M_star,-1),PREC)), -1);
862: vM = fetch_var(); M_formel=polx[vM];
863: vz = fetch_var(); z=polx[vz];
864: vy = fetch_var(); y=polx[vy];
865: vx = fetch_var(); x=polx[vx];
866: vx=varn(x); vy=varn(y); vz=varn(z); vM=varn(M_formel);
867:
868: PREC = PREC>>1; if (!PREC) PREC=DEFAULTPREC;
869: eps=dbltor(0.0000001); M0=gzero; m1=(N-(N%3))/3;
870: for (n1=1; n1<=m1; n1++)
871: {
872: m2 = (N-n1)>>1;
873: for (n2=n1; n2<=m2; n2++)
874: {
875: av1=avma; n3=N-n1-n2; prec=PREC;
876: if (!(N%3) && n1==n2 && n1==n3)
877: {
878: p1=gdivgs(M_star,m1); p2=gaddsg(1,p1); p3=gsubgs(p1,3);
879: p4=gsqrt(gmul(p2,p3),prec); p5=gsubgs(p1,1);
880: u=gun; v=gmul2n(gadd(p5,p4),-1); w=gmul2n(gsub(p5,p4),-1);
881: M0_pro=gmul2n(gmulsg(m1,gadd(gsqr(glog(v,prec)),gsqr(glog(w,prec)))),-2);
882: if (DEBUGLEVEL>2)
883: {
884: fprintferr("[%ld,%ld,%ld]: ",n1,n2,n3);
885: outerr(M0_pro); flusherr();
886: }
887: if (gcmp0(M0) || gcmp(M0_pro,M0)<0)
888: {
889: M0=M0_pro; tetpil=avma; M0=gerepile(av1,tetpil,gcopy(M0));
890: }
891: else avma=av1;
892: }
893: else if (n1==n2 || n1==n3 || n2==n3)
894: {
895: if (n1==n2) k=n1; else if (n2==n3) k=n3;
896: kk=N-2*k;
897: p2=gsub(M_star,gmulgs(x,k));
898: p3=gmul(gpuigs(stoi(kk),kk),gpuigs(gsubgs(gmul(M_star,p2),kk*kk),k));
899: pol=gsub(p3,gmul(gmul(gpuigs(stoi(k),k),gpuigs(x,k)),gpuigs(p2,N-k)));
900: prec=gprecision(pol); if (!prec) prec=5;
901: r=roots(pol,prec); lr=lg(r)-1;
902: for (i=1; i<=lr; i++)
903: {
904: if (gcmp(gabs(gimag((GEN)r[i]),prec),eps) < 0 &&
905: gsigne(S=greal((GEN)r[i])) > 0)
906: {
907: p4=gsub(M_star,gmulsg(k,S));
908: P=gdiv(gmul(gmulsg(k,S),p4),gsubgs(gmul(M_star,p4),kk*kk));
909: p5=gsub(gsqr(S),gmul2n(P,2));
910: if (gsigne(p5)>=0)
911: {
912: p6=gsqrt(p5,prec);
913: u=gmul2n(gadd(S,p6),-1); v=gmul2n(gsub(S,p6),-1);
914: if ((gsigne(u)>0)&&(gsigne(v)>0))
915: {
916: w=gpui(P,gdivgs(stoi(-k),kk),prec);
917: p6=gmulsg(k,gadd(gsqr(glog(u,prec)),gsqr(glog(v,prec))));
918: M0_pro=gmul2n(gadd(p6,gmulsg(kk,gsqr(glog(w,prec)))),-2);
919: if (DEBUGLEVEL>2)
920: {
921: fprintferr("[%ld,%ld,%ld] : ",n1,n2,n3);
922: outerr(M0_pro); flusherr();
923: }
924: if (gcmp0(M0) || gcmp(M0_pro,M0)<0) M0=M0_pro;
925: }
926: }
927: }
928: }
929: tetpil=avma; M0=gerepile(av1,tetpil,gcopy(M0));
930: }
931: else
932: {
933: f1=gadd(gmulsg(n1,x),gadd(gmulsg(n2,y),gmulsg(n3,z)));
934: f1=gsub(f1,M_formel);
935: f2=gmulsg(n1,gmul(y,z));
936: f2=gadd(f2,gmulsg(n2,gmul(x,z)));
937: f2=gadd(f2,gmulsg(n3,gmul(x,y)));
938: f2=gsub(f2,gmul(M_formel,gmul(x,gmul(y,z))));
939: f3=gsub(gmul(gpuigs(x,n1),gmul(gpuigs(y,n2),gpuigs(z,n3))),gun);
940: g1=subres(f1,f2); g1=gdiv(g1,content(g1));
941: g2=subres(f1,f3); g2=gdiv(g2,content(g2));
942: g3=subres(g1,g2); g3=gdiv(g3,content(g3));
943: pf1=gsubst(f1,vM,M_star); pg1=gsubst(g1,vM,M_star);
944: pf2=gsubst(f2,vM,M_star); pg2=gsubst(g2,vM,M_star);
945: pf3=gsubst(f3,vM,M_star); pg3=gsubst(g3,vM,M_star);
946: prec=gprecision(pg3); if (!prec) prec=5;
947: r=roots(pg3,prec); lr=lg(r)-1;
948: for (i=1; i<=lr; i++)
949: {
950: if (gcmp(gabs(gimag((GEN)r[i]),prec),eps) < 0 &&
951: gsigne(w=greal((GEN)r[i])) > 0)
952: {
953: p1=gsubst(pg1,vz,w); p2=gsubst(pg2,vz,w);
954: p3=gsubst(pf1,vz,w); p4=gsubst(pf2,vz,w); p5=gsubst(pf3,vz,w);
955: prec=gprecision(p1); if (!prec) prec=5;
956: r1=roots(p1,prec); lr1=lg(r1)-1;
957: for (j=1; j<=lr1; j++)
958: {
959: if (gcmp(gabs(gimag((GEN)r1[j]),prec),eps) < 0 &&
960: gsigne(v=greal((GEN)r1[j])) > 0)
961: {
962: p6=gsubst(p2,vy,v);
963: if (gcmp(gabs(p6,prec),eps)<0)
964: {
965: p7=gsubst(p3,vy,v); p8=gsubst(p4,vy,v); p9=gsubst(p5,vy,v);
966: prec=gprecision(p7); if (!prec) prec=5;
967: r2=roots(p7,prec); lr2=lg(r2)-1;
968: for (l=1; l<=lr2; l++)
969: {
970: if (gcmp(gabs(gimag((GEN)r2[l]),prec),eps) < 0 &&
971: gsigne(u=greal((GEN)r2[l])) > 0)
972: {
973: p10=gsubst(p8,vx,u);
974: if (gcmp(gabs(p10,prec),eps)<0)
975: {
976: p11=gsubst(p9,vx,u);
977: if (gcmp(gabs(p11,prec),eps)<0)
978: {
979: M0_pro=gmulsg(n1,gsqr(glog(u,prec)));
980: M0_pro=gadd(M0_pro,gmulsg(n2,gsqr(glog(v,prec))));
981: M0_pro=gadd(M0_pro,gmulsg(n3,gsqr(glog(w,prec))));
982: M0_pro=gmul2n(M0_pro,-2);
983: if (DEBUGLEVEL>2)
984: {
985: fprintferr("[ %ld,%ld,%ld ] : ",n1,n2,n3);
986: outerr(M0_pro); flusherr();
987: }
988: if (gcmp0(M0) || gcmp(M0_pro,M0) < 0) M0=M0_pro;
989: }
990: }
991: }
992: }
993: }
994: }
995: }
996: }
997: }
998: tetpil=av1; M0_pro=gerepile(av1,tetpil,gcopy(M0));
999: }
1000: }
1001: }
1002: for (i=1;i<=4;i++) delete_var();
1003: return M0;
1004: }
1005:
1006: static GEN
1007: lowerboundforregulator(GEN bnf,GEN units)
1008: {
1009: long N,R1,R2,RU,i,nbrootsofone,nbmin;
1010: GEN rootsofone,nf,M0,M,m,col,T2,bound,minunit,newminunit;
1011: GEN vecminim,colalg,p1,pol,y;
1012:
1013: rootsofone=gmael(bnf,8,4); nbrootsofone=itos((GEN)rootsofone[1]);
1014: nf=(GEN)bnf[7]; T2=gmael(nf,5,3); N=lgef(nf[1])-3;
1015: R1=itos(gmael(nf,2,1)); R2=itos(gmael(nf,2,2)); RU=R1+R2-1;
1016: if (RU==0) return gun;
1017:
1018: units=algtobasis(bnf,units); minunit=qfeval(T2,(GEN)units[1]);
1019: for (i=2; i<=RU; i++)
1020: {
1021: newminunit=qfeval(T2,(GEN)units[i]);
1022: if (gcmp(newminunit,minunit)<0) minunit=newminunit;
1023: }
1024: if (gcmpgs(minunit,1000000000)>0) return regulatorbound(bnf);
1025:
1026: vecminim=minimforunits(nf,itos(gceil(minunit)),10000);
1027: if (!vecminim) return regulatorbound(bnf);
1028: m=(GEN)vecminim[3]; nbmin=lg(m)-1;
1029: if (nbmin==10000) return regulatorbound(bnf);
1030: bound=gaddgs(minunit,1);
1031: for (i=1; i<=nbmin; i++)
1032: {
1033: col=(GEN)m[i]; colalg=basistoalg(nf,col);
1034: if (!gcmp1(lift_intern(gpuigs(colalg,nbrootsofone))))
1035: {
1036: newminunit=qfeval(T2,col);
1037: if (gcmp(newminunit,bound)<0) bound=newminunit;
1038: }
1039: }
1040: if (gcmp(bound,minunit)>0) err(talker,"bug in lowerboundforregulator");
1041: if (DEBUGLEVEL>=2)
1042: {
1043: fprintferr("M* = "); outerr(bound); flusherr();
1044: if (DEBUGLEVEL>2)
1045: {
1046: p1=polx[0]; pol=gaddgs(gsub(gpuigs(p1,N),gmul(bound,p1)),N-1);
1047: fprintferr("pol = "); outerr(pol); flusherr();
1048: p1=roots(pol,DEFAULTPREC);
1049: if (N&1) y=greal((GEN)p1[3]); else y=greal((GEN)p1[2]);
1050: fprintferr("y = "); outerr(y); flusherr();
1051: M0=gmul2n(gmulsg(N*(N-1),gsqr(glog(y,DEFAULTPREC))),-2);
1052: fprintferr("old fashion M0 = "); outerr(M0); flusherr();
1053: }
1054: }
1055: M0=compute_M0(bound,N);
1056: if (DEBUGLEVEL>=2) { fprintferr("M0 = "); outerr(M0); flusherr(); }
1057: M=gmul2n(gdivgs(gdiv(gpuigs(M0,RU),hermiteconstant(RU)),N),R2);
1058: if (gcmp(M,dbltor(0.04))<0) return regulatorbound(bnf);
1059: M = gsqrt(M,DEFAULTPREC);
1060: if (DEBUGLEVEL>=2)
1061: { fprintferr("(lower bound for regulator) M = "); outerr(M); flusherr(); }
1062: return M;
1063: }
1064:
1065: /* Calcule une matrice carree de rang lg(beta) associee a une famille
1066: * d'ideaux premiers P_i tels que : 1<=i<=nombre de beta; N(P_i) congru a 1
1067: * mod pp v_(P_i)(beta[j])=0 pour tout 1<=j<=nbalphapro et 1<=i<=lg(beta)
1068: */
1069: static void
1070: primecertify(GEN bnf,GEN beta,long pp,GEN big)
1071: {
1072: long i,j,qq,nbcol,sizeofmat,nbqq,ra,N;
1073: GEN nf,mat,mat1,qgen,decqq,newcol,eltgen,qrhall,Q;
1074:
1075: nbcol=0; nf=(GEN)bnf[7]; N=lgef(nf[1])-3;
1076: sizeofmat=lg(beta)-1; mat=cgetg(1,t_MAT); qq=1;
1077: for(;;)
1078: {
1079: qq += 2*pp; qgen=stoi(qq);
1080: if (smodis(big,qq)==0 || !isprime(qgen)) continue;
1081:
1082: decqq=primedec(bnf,qgen); nbqq=lg(decqq)-1;
1083: for (i=1; i<=nbqq; i++)
1084: {
1085: Q=(GEN)decqq[i];
1086: if (!gcmp1((GEN)Q[4])) continue;
1087:
1088: qrhall=nfmodprinit(nf,Q); nbcol++;
1089: newcol=cgetg(sizeofmat+1,t_COL);
1090: if (DEBUGLEVEL>=2)
1091: fprintferr(" prime ideal Q: %Z\n",Q);
1092: eltgen = gscalcol_i(lift(gener(qgen)), N);
1093: for (j=1; j<=sizeofmat; j++)
1094: newcol[j]=(long)nfshanks(nf,(GEN)beta[j],eltgen,Q,qrhall);
1095: if (DEBUGLEVEL>=2)
1096: {
1097: fprintferr(" generator of (Zk/Q)^*: "); outerr(eltgen);
1098: fprintferr(" column #%ld of the matrix log(b_j/Q): ",nbcol);
1099: outerr(newcol);
1100: }
1101: mat1=concatsp(mat,newcol); ra=rank(mat1);
1102: if (DEBUGLEVEL>=2)
1103: {
1104: fprintferr(" new rank of the matrix: %ld\n\n",ra); flusherr();
1105: }
1106: if (ra!=nbcol) nbcol--;
1107: else
1108: {
1109: if (nbcol==sizeofmat) return;
1110: mat=mat1;
1111: }
1112: }
1113: }
1114: }
1115:
1116: static void
1117: check_prime(long p, GEN bnf, GEN h, GEN cyc, long R, GEN alpha,
1118: GEN funits, GEN rootsofone, GEN big)
1119: {
1120: long av = avma, nbpro,nbalpha,i, nbgen = lg(cyc)-1;
1121: GEN p1,beta, nf = (GEN)bnf[7], nbrootsofone = (GEN)rootsofone[1];
1122:
1123: if (DEBUGLEVEL>=2)
1124: { fprintferr("***** Testing prime p = %ld\n",p); flusherr(); }
1125: if (smodis(h,p)) nbpro=0;
1126: else
1127: {
1128: if (DEBUGLEVEL>=2) { fprintferr(" p divides cl(k)\n"); flusherr(); }
1129: for (nbpro=nbgen; nbpro; nbpro--)
1130: if (!smodis((GEN)cyc[nbpro],p)) break;
1131: }
1132: nbalpha=nbpro+R;
1133: if (smodis(nbrootsofone,p)) p1 = (GEN) alpha[nbpro];
1134: else
1135: {
1136: if (DEBUGLEVEL>=2) { fprintferr(" p divides w(k)\n"); flusherr(); }
1137: nbalpha++; nbpro++; p1 = algtobasis(nf,(GEN)rootsofone[2]);
1138: }
1139: if (DEBUGLEVEL>=2)
1140: { fprintferr(" t+r+e = %ld\n",nbalpha); flusherr(); }
1141: beta=cgetg(nbalpha+1,t_VEC);
1142: if (nbpro)
1143: {
1144: for (i=1; i<nbpro; i++) beta[i]=alpha[i];
1145: beta[nbpro]=(long) p1;
1146: }
1147: for (i=1; i<=R; i++)
1148: beta[i+nbpro]=(long)algtobasis(nf,(GEN)funits[i]);
1149: if (DEBUGLEVEL>=2)
1150: { fprintferr(" Beta list = "); outerr(beta); flusherr(); }
1151: primecertify(bnf,beta,p,big); avma=av;
1152: }
1153:
1154: long
1155: certifybuchall(GEN bnf)
1156: {
1157: long av = avma, nbgen,i,j,pp,N,R1,R2,R,nfa,nbf1,bound;
1158: GEN big,nf,reg,rootsofone,funits,gen,p1,gbound,DK,alpha,factfd1,f1,h,cyc;
1159: byteptr delta = diffptr;
1160:
1161: bnf = checkbnf(bnf); nf = (GEN)bnf[7];
1162: N=lgef(nf[1])-3; if (N==1) return 1;
1163: R1=itos(gmael(nf,2,1)); R2=itos(gmael(nf,2,2)); R=R1+R2-1;
1164: funits = check_units(bnf,"bnfcertify");
1165: DK=absi((GEN)nf[3]);
1166: testprime(bnf,zimmertbound(N,R1,DK));
1167: p1=gmael(bnf,8,1); reg=gmael(bnf,8,2);
1168: h=(GEN)p1[1];
1169: cyc=(GEN)p1[2]; nbgen=lg(cyc)-1;
1170: gen=(GEN)p1[3]; rootsofone=gmael(bnf,8,4);
1171: if (DEBUGLEVEL>1)
1172: {
1173: fprintferr("Class number = "); outerr(h);
1174: fprintferr("Cyclic components = "); outerr(cyc);
1175: fprintferr("Generators = "); outerr(gen);
1176: fprintferr("Regulator = "); outerr(reg);
1177: fprintferr("Roots of one = "); outerr(rootsofone);
1178: fprintferr("Fundamental units = "); outerr(funits);
1179: }
1180: alpha=cgetg(nbgen+1,t_VEC);
1181: for (i=1; i<=nbgen; i++)
1182: {
1183: p1=idealpow(nf,(GEN)gen[i],(GEN)cyc[i]);
1184: alpha[i]=isprincipalall(bnf,p1,nf_GEN | nf_FORCE)[2];
1185: }
1186: gbound = ground(gdiv(reg,lowerboundforregulator(bnf,funits)));
1187: if (is_bigint(gbound))
1188: err(talker,"sorry, too many primes to check");
1189:
1190: bound = gbound[2];
1191: if (DEBUGLEVEL>=2)
1192: {
1193: fprintferr("\nPHASE 2: are all primes good ?\n\n");
1194: fprintferr(" Testing primes <= B (= %ld)\n\n",bound); flusherr();
1195: }
1196: for (big=gun,i=1; i<=nbgen; i++)
1197: big = mulii(big,idealnorm(nf,(GEN)gen[i]));
1198: for (pp = *delta++; pp <= bound; pp += *delta++)
1199: check_prime(pp,bnf,h,cyc,R,alpha,funits,rootsofone,big);
1200:
1201: nfa = 0;
1202: if (nbgen)
1203: {
1204: factfd1=factor((GEN)cyc[1]);
1205: nbf1=lg(factfd1[1]); f1=(GEN)factfd1[1];
1206: for (i=1; i<nbf1; i++)
1207: if (cmpis((GEN)f1[i],bound) > 0) nfa++;
1208: }
1209: if (DEBUGLEVEL>=2 && nfa)
1210: { fprintferr(" Testing primes > B (# = %ld)\n\n",nfa); flusherr(); }
1211: for (j=1; j<=nfa; j++)
1212: {
1213: pp = itos((GEN)f1[nbf1-j]);
1214: check_prime(pp,bnf,gzero,cyc,R,alpha,funits,rootsofone,big);
1215: }
1216: avma=av; return 1;
1217: }
1218:
1219: /*******************************************************************/
1220: /* */
1221: /* CORPS DE CLASSES DE RAYON : CONDUCTEURS ET DISCRIMINANTS */
1222: /* */
1223: /*******************************************************************/
1224:
1225: /* Si s est la surjection de Cl_m sur Cl_n et H ssgroupe de Cl_m,
1226: * retourne le ssgroupe s(H) de Cl_n
1227: */
1228: static GEN
1229: imageofgroup0(GEN gen,GEN bnr,GEN subgroup)
1230: {
1231: long j,l;
1232: GEN E,Delta = diagonal(gmael(bnr,5,2));
1233:
1234: if (gcmp0(subgroup)) return Delta;
1235:
1236: l=lg(gen); E=cgetg(l,t_MAT);
1237: for (j=1; j<l; j++)
1238: E[j] = (long)isprincipalray(bnr,(GEN)gen[j]);
1239: E = concatsp(gmul(E,subgroup),Delta);
1240: return hnf(E);
1241: }
1242:
1243: static GEN
1244: imageofgroup(GEN gen,GEN bnr,GEN subgroup)
1245: {
1246: long av = avma;
1247: return gerepileupto(av,imageofgroup0(gen,bnr,subgroup));
1248: }
1249:
1250: /* retourne le cardinal de Cl_n / s(H) */
1251: static GEN
1252: cardofimagofquotientgroup(GEN H,GEN bnr2,GEN subgroup)
1253: {
1254: return dethnf_i(imageofgroup0(H,bnr2,subgroup));
1255: }
1256:
1257: static GEN
1258: args_to_bnr(GEN arg0, GEN arg1, GEN arg2, GEN *subgroup, long prec)
1259: {
1260: GEN bnr,bnf;
1261:
1262: if (typ(arg0)!=t_VEC)
1263: err(talker,"neither bnf nor bnr in conductor or discray");
1264: if (!arg1) arg1 = gzero;
1265: if (!arg2) arg2 = gzero;
1266:
1267: switch(lg(arg0))
1268: {
1269: case 7: /* bnr */
1270: bnr=arg0; (void)checkbnf((GEN)bnr[1]);
1271: *subgroup=arg1; break;
1272:
1273: case 11: /* bnf */
1274: bnf = checkbnf(arg0);
1275: bnr=buchrayall(bnf,arg1,nf_INIT | nf_GEN,prec);
1276: *subgroup=arg2; break;
1277:
1278: default: err(talker,"neither bnf nor bnr in conductor or discray");
1279: }
1280: if (!gcmp0(*subgroup))
1281: {
1282: long tx=typ(*subgroup);
1283: if (!is_matvec_t(tx))
1284: err(talker,"bad subgroup in conductor or discray");
1285: }
1286: return bnr;
1287: }
1288:
1289: GEN
1290: bnrconductor(GEN arg0,GEN arg1,GEN arg2,long all,long prec)
1291: {
1292: GEN sub=arg1, bnr=args_to_bnr(arg0,arg1,arg2,&sub,prec);
1293: return conductor(bnr,sub,all,prec);
1294: }
1295:
1296: long
1297: bnrisconductor(GEN arg0,GEN arg1,GEN arg2,long prec)
1298: {
1299: GEN sub=arg1, bnr=args_to_bnr(arg0,arg1,arg2,&sub,prec);
1300: return itos(conductor(bnr,sub,-1,prec));
1301: }
1302:
1303: /* Given a number field bnf=bnr[1], a ray class group bnr (from buchrayinit),
1304: * and a subgroup (HNF form) of the ray class group, compute the conductor
1305: * of the subgroup (copy of discrayrelall) if all=0. If all > 0, compute
1306: * furthermore the corresponding subgroup and output
1307: * [[ideal,arch],[hm,cyc,gen],subgroup] if all = 1, and output
1308: * [[ideal,arch],newbnr,subgroup] if all = 2. If all<0, answer only 1 is
1309: * module is the conductor, 0 otherwise.
1310: */
1311: GEN
1312: conductor(GEN bnr,GEN subgroup,long all,long prec)
1313: {
1314: long r1,j,av=avma,tetpil,k,ep,trivial=0;
1315: GEN bnf,nf,cl,cyc,gen,bid,ideal,arch,p1,p2,clhray,clhss;
1316: GEN fa,arch2,bnr2,fa2,ex;
1317:
1318: checkbnrgen(bnr); bnf=(GEN)bnr[1]; bid=(GEN)bnr[2];
1319: cl=(GEN)bnr[5]; cyc=(GEN)cl[2]; gen=(GEN)cl[3];
1320: nf=(GEN)bnf[7]; r1=itos(gmael(nf,2,1));
1321: p1=(GEN)bid[1]; ideal=(GEN)p1[1]; arch=(GEN)p1[2];
1322: if (gcmp0(subgroup)) { trivial=1; clhray=(GEN)cl[1]; }
1323: else
1324: {
1325: p1 = gauss(subgroup,diagonal(cyc));
1326: if (!gcmp1(denom(p1)))
1327: err(talker,"incorrect subgroup in conductor");
1328: if (gcmp1(det(p1))) trivial=1;
1329: clhray = absi(det(subgroup));
1330: }
1331: fa=(GEN)bid[3]; fa2=(GEN)fa[1]; ex=(GEN)fa[2];
1332: p2=cgetg(3,t_VEC); p2[2]=(long)arch;
1333: for (k=1; k<lg(fa2); k++)
1334: {
1335: GEN pr=(GEN)fa2[k], prinv=idealinv(nf,pr);
1336: ep = (all>=0)? itos((GEN)ex[k]): 1;
1337: for (j=1; j<=ep; j++)
1338: {
1339: p2[1]=(long)idealmul(nf,ideal,prinv);
1340: if (trivial) clhss=rayclassno(bnf,p2);
1341: else
1342: {
1343: bnr2=buchrayall(bnf,p2,nf_INIT,prec);
1344: clhss=cardofimagofquotientgroup(gen,bnr2,subgroup);
1345: }
1346: if (!egalii(clhss,clhray)) break;
1347: if (all<0) { avma=av; return gzero; }
1348: ideal = (GEN)p2[1];
1349: }
1350: }
1351: p2[1]=(long)ideal; arch2=dummycopy(arch); p2[2]=(long)arch2;
1352: for (k=1; k<=r1; k++)
1353: if (signe(arch[k]))
1354: {
1355: arch2[k]=zero;
1356: if (trivial) clhss=rayclassno(bnf,p2);
1357: else
1358: {
1359: bnr2=buchrayall(bnf,p2,nf_INIT,prec);
1360: clhss=cardofimagofquotientgroup(gen,bnr2,subgroup);
1361: }
1362: if (!egalii(clhss,clhray)) arch2[k]=un;
1363: else if (all<0) { avma=av; return gzero; }
1364: }
1365: if (all<0) {avma=av; return gun;}
1366: if (!all) { tetpil=avma; return gerepile(av,tetpil,gcopy(p2)); }
1367:
1368: bnr2=buchrayall(bnf,p2,nf_INIT | nf_GEN,prec);
1369: tetpil=avma; p1=cgetg(4,t_VEC);
1370: p1[3]=(long)imageofgroup(gen,bnr2,subgroup);
1371: if (all==1) bnr2=(GEN)bnr2[5];
1372: p1[2]=lcopy(bnr2);
1373: p1[1]=lcopy(p2); return gerepile(av,tetpil,p1);
1374: }
1375:
1376: /* etant donne un bnr et un polynome relatif, trouve le groupe des normes
1377: correspondant a l'extension relative en supposant qu'elle est abelienne
1378: et que le module donnant bnr est multiple du conducteur (tout ceci n'etant
1379: bien sur pas verifie). */
1380: GEN
1381: rnfnormgroup(GEN bnr, GEN polrel)
1382: {
1383: long av=avma,i,j,reldeg,sizemat,prime,nfac,k;
1384: GEN bnf,polreldisc,nf,raycl,group,detgroup,fa,pr,famo,ep,fac,col,p1;
1385: byteptr d = diffptr;
1386:
1387: checkbnr(bnr); bnf=(GEN)bnr[1]; raycl=(GEN)bnr[5];
1388: if (typ(polrel)!=t_POL) err(typeer,"rnfnormgroup");
1389: reldeg=lgef(polrel)-3; detgroup=(GEN)raycl[1];
1390: group = diagonal((GEN)raycl[2]);
1391: k = cmpis(detgroup,reldeg);
1392: if (k<0) err(talker,"not an Abelian extension in rnfnormgroup?");
1393: if (!k) return group;
1394:
1395: polreldisc=discsr(polrel); nf=(GEN)bnf[7];
1396: sizemat=lg(group)-1; prime = *d++;
1397: /* tant que nffactormod est bugge pour p=2 on commence a prime = 3 */
1398: for(;;)
1399: {
1400: prime += *d++; if (!*d) err(primer1);
1401: fa=primedec(nf,stoi(prime));
1402: for (i=1; i<lg(fa); i++)
1403: {
1404: pr = (GEN)fa[i];
1405: if (element_val(nf,polreldisc,pr)==0)
1406: {
1407: famo=nffactormod(nf,polrel,pr);
1408: ep=(GEN)famo[2]; fac=(GEN)famo[1];
1409: nfac=lg(ep)-1; k=lgef((GEN)fac[1])-3;
1410: for (j=1; j<=nfac; j++)
1411: {
1412: if (!gcmp1((GEN)ep[j])) err(bugparier,"rnfnormgroup");
1413: if (lgef(fac[j])-3 != k)
1414: err(talker,"non Galois extension in rnfnormgroup");
1415: }
1416: col=gmulsg(k,isprincipalrayall(bnr,pr,nf_REGULAR));
1417: p1=cgetg(sizemat+2,t_MAT);
1418: for (j=1; j<=sizemat; j++) p1[j]=group[j];
1419: p1[sizemat+1]=(long)col;
1420: group=hnf(p1); detgroup=dethnf(group);
1421: k = cmpis(detgroup,reldeg);
1422: if (k<0) err(talker,"not an Abelian extension in rnfnormgroup?");
1423: if (!k) { cgiv(detgroup); return gerepileupto(av,group); }
1424: }
1425: }
1426: }
1427: }
1428:
1429: /* Etant donne un bnf et un polynome relatif polrel definissant une extension
1430: abelienne (ce qui n'est pas verifie), calcule le conducteur et le groupe de
1431: congruence correspondant a l'extension definie par polrel sous la forme
1432: [[ideal,arch],[hm,cyc,gen],group] ou [ideal,arch] est le conducteur, et
1433: [hm,cyc,gen] est le groupe de classes de rayon correspondant. */
1434: GEN
1435: rnfconductor(GEN bnf, GEN polrel, long prec)
1436: {
1437: long av=avma,tetpil,R1,i,v;
1438: GEN nf,module,arch,bnr,group,p1,pol2;
1439:
1440: bnf = checkbnf(bnf); nf=(GEN)bnf[7];
1441: module=cgetg(3,t_VEC); R1=itos(gmael(nf,2,1));
1442: v=varn(polrel);
1443: p1=unifpol((GEN)bnf[7],polrel,0);
1444: p1=denom(gtovec(p1));
1445: pol2=gsubst(polrel,v,gdiv(polx[v],p1));
1446: pol2=gmul(pol2,gpuigs(p1,degree(pol2)));
1447: module[1]=rnfdiscf(nf,pol2)[1]; arch=cgetg(R1+1,t_VEC);
1448: module[2]=(long)arch; for (i=1; i<=R1; i++) arch[i]=un;
1449: bnr=buchrayall(bnf,module,nf_INIT | nf_GEN,prec);
1450: group=rnfnormgroup(bnr,pol2); tetpil=avma;
1451: return gerepile(av,tetpil,conductor(bnr,group,1,prec));
1452: }
1453:
1454: /* Etant donnes un corps de nombres bnf=bnr[1], un groupe de classes de rayon
1455: * bnr calcule par buchrayinit(), et une matrice HNF subgroup definissant un
1456: * sous-groupe du groupe de classes de rayon, calcule [n,r1,dk] associe a ce
1457: * sous groupe (cf. discrayall()). si flcond=0 le calcul est arrete si le
1458: * module n'est pas le conducteur et le programme retourne gzero. Si
1459: * flrel=0, seul la norme de l'ideal dk est calculee au lieu de dk lui-meme
1460: */
1461: static GEN
1462: discrayrelall(GEN bnr,GEN subgroup,long flag,long prec)
1463: {
1464: long r1,degk,j,av=avma,tetpil,k,ep,nbdezero;
1465: long trivial=0, flrel = flag & nf_REL, flcond = flag & nf_COND;
1466: GEN bnf,nf,cyc,gen,bid,ideal,arch,p1,p2,clhray,clhss;
1467: GEN fa,dlk,arch2,bnr2,idealrel,fa2,ex,som;
1468:
1469: checkbnrgen(bnr); bnf=(GEN)bnr[1];
1470: cyc=gmael(bnr,5,2); gen=gmael(bnr,5,3);
1471: nf=(GEN)bnf[7]; r1=itos(gmael(nf,2,1));
1472:
1473: if (gcmp0(subgroup)) { trivial=1; clhray=gmael(bnr,5,1); }
1474: else
1475: {
1476: p1=gauss(subgroup,diagonal(cyc));
1477: if (!gcmp1(denom(p1)))
1478: err(talker,"incorrect subgroup in discray");
1479: if (gcmp1(det(p1))) trivial=1;
1480: clhray = det(subgroup);
1481: }
1482: bid=(GEN)bnr[2]; ideal=gmael(bid,1,1); arch=gmael(bid,1,2);
1483: fa=(GEN)bid[3]; fa2=(GEN)fa[1]; ex=(GEN)fa[2];
1484:
1485: degk=lgef(nf[1])-3;
1486: idealrel=flrel?idmat(degk):gun;
1487:
1488: p2=cgetg(3,t_VEC); p2[2]=(long)arch;
1489: for (k=1; k<lg(fa2); k++)
1490: {
1491: GEN pr=(GEN)fa2[k], prinv=idealinv(nf,pr);
1492:
1493: ep=itos((GEN)ex[k]); p2[1]=(long)ideal; som=gzero;
1494: for (j=1; j<=ep; j++)
1495: {
1496: p2[1]=(long)idealmul(nf,(GEN)p2[1],prinv);
1497: if (trivial) clhss=rayclassno(bnf,p2);
1498: else
1499: {
1500: bnr2=buchrayall(bnf,p2,nf_INIT,prec);
1501: clhss=cardofimagofquotientgroup(gen,bnr2,subgroup);
1502: }
1503: if (j==1 && egalii(clhss,clhray) && flcond) { avma=av; return gzero; }
1504: if (is_pm1(clhss)) { som = addis(som, ep-j+1); break; }
1505: som = addii(som, clhss);
1506: }
1507: idealrel = flrel
1508: ? idealmul(nf,idealrel, idealpow(nf,pr, som))
1509: : mulii(idealrel, powgi((GEN)pr[1], mulii(som,(GEN)pr[4])));
1510: }
1511: dlk = flrel
1512: ? idealdiv(nf,idealpow(nf,ideal,clhray),idealrel)
1513: : divii(powgi(dethnf(ideal),clhray),idealrel);
1514:
1515: p2[1]=(long)ideal; arch2=dummycopy(arch); p2[2]=(long)arch2; nbdezero=0;
1516: for (k=1; k<=r1; k++)
1517: {
1518: if (signe(arch[k]))
1519: {
1520: arch2[k]=zero;
1521: if (trivial) clhss=rayclassno(bnf,p2);
1522: else
1523: {
1524: bnr2=buchrayall(bnf,p2,nf_INIT,prec);
1525: clhss=cardofimagofquotientgroup(gen,bnr2,subgroup);
1526: }
1527: arch2[k]=un;
1528: if (egalii(clhss,clhray))
1529: {
1530: if (flcond) { avma=av; return gzero; }
1531: nbdezero++;
1532: }
1533: }
1534: else nbdezero++;
1535: }
1536: tetpil=avma; p1=cgetg(4,t_VEC);
1537: p1[1]=lcopy(clhray);
1538: p1[2]=lstoi(nbdezero);
1539: p1[3]=lcopy(dlk); return gerepile(av,tetpil,p1);
1540: }
1541:
1542: static GEN
1543: discrayabsall(GEN bnr, GEN subgroup,long flag,long prec)
1544: {
1545: long av=avma,tetpil,degk,clhray,n,R1;
1546: GEN p1,p2,p3,p4,nf,dkabs,bnf;
1547:
1548: p1=discrayrelall(bnr,subgroup,flag,prec);
1549: if (flag & nf_REL) return p1;
1550: if (p1==gzero) { avma=av; return gzero; }
1551:
1552: bnf=(GEN)bnr[1]; nf=(GEN)bnf[7]; degk=lgef(nf[1])-3;
1553: dkabs=absi((GEN)nf[3]); p2=(GEN)p1[3];
1554: clhray=itos((GEN)p1[1]); p3=gpuigs(dkabs,clhray);
1555: n = degk * clhray; R1 = itos((GEN)p1[2]) * clhray;
1556: if (((n-R1)&3)==2) p2=negi(p2);
1557: tetpil=avma; p4=cgetg(4,t_VEC);
1558: p4[1]=lstoi(n);
1559: p4[2]=lstoi(R1);
1560: p4[3]=lmulii(p2,p3); return gerepile(av,tetpil,p4);
1561: }
1562:
1563: GEN
1564: bnrdisc0(GEN arg0, GEN arg1, GEN arg2, long flag, long prec)
1565: {
1566: GEN subgroup, bnr = args_to_bnr(arg0,arg1,arg2,&subgroup,prec);
1567: return discrayabsall(bnr,subgroup,flag,prec);
1568: }
1569:
1570: GEN
1571: discrayrel(GEN bnr, GEN subgroup,long prec)
1572: {
1573: return discrayrelall(bnr,subgroup,nf_REL,prec);
1574: }
1575:
1576: GEN
1577: discrayrelcond(GEN bnr, GEN subgroup,long prec)
1578: {
1579: return discrayrelall(bnr,subgroup,nf_REL | nf_COND,prec);
1580: }
1581:
1582: GEN
1583: discrayabs(GEN bnr, GEN subgroup,long prec)
1584: {
1585: return discrayabsall(bnr,subgroup,nf_REGULAR,prec);
1586: }
1587:
1588: GEN
1589: discrayabscond(GEN bnr, GEN subgroup,long prec)
1590: {
1591: return discrayabsall(bnr,subgroup,nf_COND,prec);
1592: }
1593:
1594: /* Etant donnes un corps de nombres bnf=bnr[1], un groupe de classes de rayon
1595: * bnr calcule par buchrayinit(), et un vecteur chi representant un caractere
1596: * sur les generateurs bnr[2][3], calcule le conducteur de ce caractere.
1597: */
1598: GEN
1599: bnrconductorofchar(GEN bnr,GEN chi,long prec)
1600: {
1601: long nbgen,i,av=avma,tetpil;
1602: GEN p1,m,u,d1,cl,cyclic;
1603:
1604: checkbnrgen(bnr); cl=(GEN)bnr[5];
1605: cyclic=(GEN)cl[2]; nbgen=lg(cyclic)-1;
1606: if (lg(chi)-1 != nbgen)
1607: err(talker,"incorrect character length in conductorofchar");
1608: if (!nbgen) return conductor(bnr,gzero,0,prec);
1609:
1610: d1=(GEN)cyclic[1]; m=cgetg(nbgen+2,t_MAT);
1611: for (i=1; i<=nbgen; i++)
1612: {
1613: p1=cgetg(2,t_COL); m[i]=(long)p1;
1614: p1[1]=ldiv(gmul((GEN)chi[i],d1),(GEN)cyclic[i]);
1615: if (typ(p1[1])!=t_INT) err(typeer,"conductorofchar");
1616: }
1617: p1=cgetg(2,t_COL); m[i]=(long)p1;
1618: p1[1]=(long)d1; u=(GEN)hnfall(m)[2];
1619: tetpil=avma; setlg(u,nbgen+1);
1620: for (i=1; i<=nbgen; i++) setlg(u[i],nbgen+1);
1621: return gerepile(av,tetpil,conductor(bnr,u,0,prec));
1622: }
1623:
1624: /* Etant donne la liste des zidealstarinit et des matrices d'unites
1625: * correspondantes, sort la liste des nombres de classes
1626: */
1627: GEN
1628: rayclassnolist(GEN bnf,GEN listes)
1629: {
1630: long av=avma,tetpil,i,j,k,kk,nc,nq,lx,ly;
1631: GEN h,modulist,unitlist,classlist,sous,sousu,sousclass,p2,m,bid,q,cyclic;
1632:
1633: if (typ(listes)!=t_VEC || lg(listes)!=3) err(typeer,"rayclassnolist");
1634: bnf = checkbnf(bnf); h=gmael3(bnf,8,1,1);
1635: modulist=(GEN)listes[1]; unitlist=(GEN)listes[2];
1636: lx=lg(modulist); classlist=cgetg(lx,t_VEC);
1637: for (i=1; i<lx; i++)
1638: {
1639: sous=(GEN)modulist[i]; sousu=(GEN)unitlist[i]; ly=lg(sous);
1640: sousclass=cgetg(ly,t_VEC); classlist[i]=(long)sousclass;
1641: for (j=1; j<ly; j++)
1642: {
1643: bid=(GEN)sous[j]; q=(GEN)sousu[j]; nq=lg(q)-1;
1644: cyclic=gmael(bid,2,2); nc=lg(cyclic)-1;
1645: if (lg(q[1]) != nc+1) err(bugparier,"rayclassnolist");
1646: m=cgetg(nq+nc+1,t_MAT);
1647: for (k=1; k<=nq; k++) m[k]=q[k];
1648: for ( ; k<=nq+nc; k++)
1649: {
1650: p2=cgetg(nc+1,t_COL); m[k]=(long)p2;
1651: for (kk=1; kk<=nc; kk++) p2[kk]=(kk==k-nq)?cyclic[kk]:zero;
1652: }
1653: sousclass[j] = lmul(h,dethnf(hnf(m)));
1654: }
1655: }
1656: tetpil=avma; return gerepile(av,tetpil,gcopy(classlist));
1657: }
1658:
1659: static GEN
1660: rayclassnolistes(GEN sous, GEN sousclass, GEN fac)
1661: {
1662: long i;
1663: for (i=1; i<lg(sous); i++)
1664: if (gegal(gmael(sous,i,3),fac)) return (GEN)sousclass[i];
1665: err(bugparier,"discrayabslist");
1666: return NULL; /* not reached */
1667: }
1668:
1669: static GEN
1670: rayclassnolistessimp(GEN sous, GEN fac)
1671: {
1672: long i;
1673: for (i=1; i<lg(sous); i++)
1674: if (gegal(gmael(sous,i,1),fac)) return gmael(sous,i,2);
1675: err(bugparier,"discrayabslistlong");
1676: return NULL; /* not reached */
1677: }
1678:
1679: static GEN
1680: factormul(GEN fa1,GEN fa2)
1681: {
1682: GEN pr,prnew,ex,exnew,v,p,y=cgetg(3,t_MAT);
1683: long i,c,lx;
1684:
1685: pr=concatsp((GEN)fa1[1],(GEN)fa2[1]); y[1]=(long)pr;
1686: ex=concatsp((GEN)fa1[2],(GEN)fa2[2]); y[2]=(long)ex;
1687: v=sindexsort(pr); lx=lg(pr);
1688: prnew=cgetg(lx,t_COL); exnew=cgetg(lx,t_COL);
1689: for (i=1; i<lx; i++) prnew[i]=pr[v[i]];
1690: for (i=1; i<lx; i++) exnew[i]=ex[v[i]];
1691: p=gzero; c=0;
1692: for (i=1; i<lx; i++)
1693: {
1694: if (gegal((GEN)prnew[i],p))
1695: ex[c]=laddii((GEN)ex[c],(GEN)exnew[i]);
1696: else
1697: {
1698: c++; p=(GEN)prnew[i]; pr[c]=(long)p; ex[c]=exnew[i];
1699: }
1700: }
1701: setlg(pr,c+1); setlg(ex,c+1); return y;
1702: }
1703:
1704: static GEN
1705: factordivexact(GEN fa1,GEN fa2)
1706: {
1707: long i,j,k,c,lx1,lx2;
1708: GEN listpr,listex,y,listpr1,listex1,listpr2,listex2,p1;
1709:
1710: listpr1=(GEN)fa1[1]; listex1=(GEN)fa1[2]; lx1=lg(listpr1);
1711: listpr2=(GEN)fa2[1]; listex2=(GEN)fa2[2]; lx2=lg(listpr1);
1712: y=cgetg(3,t_MAT);
1713: listpr=cgetg(lx1,t_COL); y[1]=(long)listpr;
1714: listex=cgetg(lx1,t_COL); y[2]=(long)listex;
1715: for (c=0,i=1; i<lx1; i++)
1716: {
1717: j=isinvector(listpr2,(GEN)listpr1[i],lx2-1);
1718: if (!j) { c++; listpr[c]=listpr1[i]; listex[c]=listex1[i]; }
1719: else
1720: {
1721: p1=subii((GEN)listex1[i],(GEN)listex2[j]); k=signe(p1);
1722: if (k<0) err(talker,"factordivexact is not exact!");
1723: if (k>0) { c++; listpr[c]=listpr1[i]; listex[c]=(long)p1; }
1724: }
1725: }
1726: setlg(listpr,c+1); setlg(listex,c+1); return y;
1727: }
1728:
1729: static GEN
1730: factorpow(GEN fa,long n)
1731: {
1732: GEN y=cgetg(3,t_MAT);
1733:
1734: if (!n) { y[1]=lgetg(1,t_COL); y[2]=lgetg(1,t_COL); return y; }
1735: y[1]=fa[1]; y[2]=lmulsg(n,(GEN)fa[2]); return y;
1736: }
1737:
1738: /* Etant donne la liste des zidealstarinit et des matrices d'unites
1739: * correspondantes, sort la liste des discrayabs. On ne garde pas les modules
1740: * qui ne sont pas des conducteurs
1741: */
1742: GEN
1743: discrayabslist(GEN bnf,GEN listes)
1744: {
1745: long av=avma,tetpil,ii,jj,i,j,k,clhss,ep,clhray,lx,ly,r1,som,degk,nbdezero;
1746: long n,R1,normps,normi,lfa2;
1747: GEN classlist,modulist,disclist,nf,dkabs,sous,sousclass,sousdisc;
1748: GEN bid,module,ideal,arch,fa,fa2,ex,idealrel,p1,p2,pr;
1749: GEN dlk,arch2,p3,fac,normp,fad,fad1,fad2,no1,no2;
1750:
1751: classlist=rayclassnolist(bnf,listes); lx=lg(classlist);
1752: modulist=(GEN)listes[1];
1753: disclist=cgetg(lx,t_VEC); nf=(GEN)bnf[7]; r1=itos(gmael(nf,2,1));
1754: degk=lgef(nf[1])-3; dkabs=gabs((GEN)nf[3],0);
1755: for (ii=1; ii<lx; ii++)
1756: {
1757: sous=(GEN)modulist[ii]; sousclass=(GEN)classlist[ii];
1758: ly=lg(sous); sousdisc=cgetg(ly,t_VEC); disclist[ii]=(long)sousdisc;
1759: for (jj=1; jj<ly; jj++)
1760: {
1761: bid=(GEN)sous[jj]; clhray=itos((GEN)sousclass[jj]);
1762: module=(GEN)bid[1]; ideal=(GEN)module[1]; arch=(GEN)module[2];
1763: fa=(GEN)bid[3]; fa2=(GEN)fa[1]; ex=(GEN)fa[2]; fac=gcopy(fa);
1764: idealrel=cgetg(3,t_MAT);
1765: idealrel[1]=lgetg(1,t_COL);
1766: idealrel[2]=lgetg(1,t_COL); lfa2=lg(fa2);
1767: for (k=1; k<lfa2; k++)
1768: {
1769: pr=(GEN)fa2[k]; ep=itos((GEN)ex[k]); som=0;
1770: normp=gpui((GEN)pr[1],(GEN)pr[4],0);
1771: normps=itos(normp); normi=ii;
1772: normp=cgetg(3,t_MAT);
1773: no1=cgetg(2,t_COL); no1[1]=pr[1]; normp[1]=(long)no1;
1774: no2=cgetg(2,t_COL); no2[1]=pr[4]; normp[2]=(long)no2;
1775: for (j=1; j<=ep; j++)
1776: {
1777: if (j<ep) { coeff(fac,k,2)=lstoi(ep-j); fad=fac; }
1778: else
1779: {
1780: fad=cgetg(3,t_MAT);
1781: fad1=cgetg(lfa2-1,t_COL); fad[1]=(long)fad1;
1782: fad2=cgetg(lfa2-1,t_COL); fad[2]=(long)fad2;
1783: for (i=1; i<k; i++)
1784: { fad1[i]=coeff(fac,i,1); fad2[i]=coeff(fac,i,2); }
1785: for ( ; i<lfa2-1; i++)
1786: { fad1[i]=coeff(fac,i+1,1); fad2[i]=coeff(fac,i+1,2); }
1787: }
1788: normi /= normps;
1789: clhss = itos(rayclassnolistes((GEN)modulist[normi],
1790: (GEN)classlist[normi],fad));
1791: if (j==1 && clhss==clhray)
1792: {
1793: clhray=0; coeff(fac,k,2)=ex[k]; goto LLDISCRAY;
1794: }
1795: if (clhss==1) { som += ep-j+1; break; }
1796: som += clhss;
1797: }
1798: coeff(fac,k,2)=ex[k];
1799: idealrel=factormul(idealrel,factorpow(normp,som));
1800: }
1801: dlk=factordivexact(factorpow(factor(stoi(ii)),clhray),idealrel);
1802: p2=cgetg(3,t_VEC);
1803: p2[1]=(long)ideal; arch2=dummycopy(arch);
1804: p2[2]=(long)arch2; nbdezero=0;
1805: for (k=1; k<=r1; k++)
1806: {
1807: if (signe(arch[k]))
1808: {
1809: arch2[k]=zero;
1810: clhss=itos(rayclassno(bnf,p2));
1811: arch2[k]=un;
1812: if (clhss==clhray) { clhray=0; break; }
1813: }
1814: else nbdezero++;
1815: }
1816: LLDISCRAY:
1817: if (!clhray) sousdisc[jj]=lgetg(1,t_VEC);
1818: else
1819: {
1820: p3=factorpow(factor(dkabs),clhray); n=clhray*degk; R1=nbdezero*clhray;
1821: if (((n-R1)&3) == 2)
1822: {
1823: normp=cgetg(3,t_MAT);
1824: no1=cgetg(2,t_COL); normp[1]=(long)no1; no1[1]=lstoi(-1);
1825: no2=cgetg(2,t_COL); normp[2]=(long)no2; no2[1]=un;
1826: dlk=factormul(normp,dlk);
1827: }
1828: p1=cgetg(4,t_VEC); p1[1]=lstoi(n);
1829: p1[2]=lstoi(R1); p1[3]=(long)factormul(dlk,p3);
1830: sousdisc[jj]=(long)p1;
1831: }
1832: }
1833: }
1834: tetpil=avma; return gerepile(av,tetpil,gcopy(disclist));
1835: }
1836:
1837: #define SHLGVINT 15
1838: #define LGVINT 32768 /* must be 1<<SHLGVINT */
1839:
1840: /* Attention: bound est le nombre de vraies composantes voulues. */
1841: static GEN
1842: bigcgetvec(long bound)
1843: {
1844: long nbcext,nbfinal,i;
1845: GEN vext;
1846:
1847: nbcext = ((bound-1)>>SHLGVINT)+1;
1848: nbfinal = bound-((nbcext-1)<<SHLGVINT);
1849: vext = cgetg(nbcext+1,t_VEC);
1850: for (i=1; i<nbcext; i++) vext[i]=lgetg(LGVINT+1,t_VEC);
1851: vext[nbcext]=lgetg(nbfinal+1,t_VEC); return vext;
1852: }
1853:
1854: static GEN
1855: getcompobig(GEN vext,long i)
1856: {
1857: long cext;
1858:
1859: if (i<=LGVINT) return gmael(vext,1,i);
1860: cext=((i-1)>>SHLGVINT)+1;
1861: return gmael(vext,cext,i-((cext-1)<<SHLGVINT));
1862: }
1863:
1864: static void
1865: putcompobig(GEN vext,long i,GEN x)
1866: {
1867: long cext;
1868:
1869: if (i<=LGVINT) { mael(vext,1,i)=(long)x; return; }
1870: cext=((i-1)>>SHLGVINT)+1; mael(vext,cext,i-((cext-1)<<SHLGVINT))=(long)x;
1871: return;
1872: }
1873:
1874: static GEN
1875: zsimp(GEN bid, GEN matunit)
1876: {
1877: GEN y=cgetg(5,t_VEC);
1878: y[1]=lcopy((GEN)bid[3]); y[2]=lcopy(gmael(bid,2,2));
1879: y[3]=lcopy((GEN)bid[5]); y[4]=lcopy(matunit); return y;
1880: }
1881:
1882: static GEN
1883: zsimpjoin(GEN bidsimp, GEN bidp, GEN faussefa, GEN matunit)
1884: {
1885: long i,j,lx,lx1,lx2,llx,llx1,llx2,nbgen,av=avma,tetpil,c;
1886: GEN y,U1,U2,cyclic1,cyclic2,U,cyc,u1u2,p1,p2,met;
1887:
1888: y=cgetg(5,t_VEC); y[1]=(long)vconcat((GEN)bidsimp[1],faussefa);
1889: U1=(GEN)bidsimp[3]; U2=(GEN)bidp[5]; cyclic1=(GEN)bidsimp[2];
1890: cyclic2=gmael(bidp,2,2); lx1=lg(U1); lx2=lg(U2); lx=lx1+lx2-1;
1891: llx1=lg(cyclic1); llx2=lg(cyclic2);
1892: llx=llx1+llx2-1; nbgen=llx-1; U=cgetg(lx,t_MAT);
1893: if (nbgen)
1894: {
1895: cyc=diagonal(concatsp(cyclic1,cyclic2));
1896: u1u2=smithclean(smith2(cyc)); met=(GEN)u1u2[3]; c=lg(met)-1;
1897: for (j=1; j<lx1; j++)
1898: {
1899: p1=cgetg(llx,t_COL); p2=(GEN)U1[j]; U[j]=(long)p1;
1900: for (i=1; i<llx1; i++) p1[i]=p2[i];
1901: for ( ; i<llx; i++) p1[i]=zero;
1902: }
1903: for ( ; j<lx; j++)
1904: {
1905: p1=cgetg(llx,t_COL); p2=(GEN)U2[j-lx1+1]; U[j]=(long)p1;
1906: for (i=1; i<llx1; i++) p1[i]=zero;
1907: for ( ; i<llx; i++) p1[i]=p2[i-llx1+1];
1908: }
1909: y[3]=lmul((GEN)u1u2[1],U);
1910: }
1911: else
1912: {
1913: met=cgetg(1,t_MAT); for (j=1; j<lx; j++) U[j]=lgetg(1,t_COL);
1914: y[3]=(long)U; c=0;
1915: }
1916: cyc=cgetg(c+1,t_VEC); for (i=1; i<=c; i++) cyc[i]=coeff(met,i,i);
1917: y[2]=(long)cyc;
1918: y[4]=(long)vconcat((GEN)bidsimp[4],matunit);
1919: tetpil=avma; return gerepile(av,tetpil,gcopy(y));
1920: }
1921:
1922: static GEN
1923: rayclassnointern(GEN sous, GEN clh)
1924: {
1925: long lx,nc,nq,k,kk,j;
1926: GEN bidsimp,qm,sousray,cyclic,m,p2,p1;
1927:
1928: lx=lg(sous); sousray=cgetg(lx,t_VEC);
1929: for (j=1; j<lx; j++)
1930: {
1931: bidsimp=(GEN)sous[j]; qm=gmul((GEN)bidsimp[3],(GEN)bidsimp[4]);
1932: nq=lg(qm)-1; cyclic=(GEN)bidsimp[2]; nc=lg(cyclic)-1;
1933: if (lg(qm[1]) != nc+1) err(bugparier,"rayclassnolist");
1934: m=cgetg(nq+nc+1,t_MAT);
1935: for (k=1; k<=nq; k++) m[k]=qm[k];
1936: for ( ; k<=nq+nc; k++)
1937: {
1938: p2=cgetg(nc+1,t_COL); m[k]=(long)p2;
1939: for (kk=1; kk<=nc; kk++) p2[kk]=(kk==k-nq)?cyclic[kk]:zero;
1940: }
1941: p1=cgetg(3,t_VEC); p1[2]=lmul(clh,dethnf(hnf(m)));
1942: p1[1]=bidsimp[1]; sousray[j]=(long)p1;
1943: }
1944: return sousray;
1945: }
1946:
1947: static GEN
1948: rayclassnointernarch(GEN sous, GEN clh, GEN matarchunit)
1949: {
1950: long lx,nc,nq,k,kk,j,lm,lh,r1,jj,i,nba,nbarch,ii;
1951: GEN bidsimp,qm,sousray,cyclic,m,p2,p1,p1all,p3,mm,mj,qmk,matk;
1952:
1953: if (!matarchunit) return rayclassnointern(sous,clh);
1954:
1955: lm=lg(matarchunit); if (!lm) err(talker,"no units in rayclassnointernarch");
1956: r1=lg(matarchunit[1])-1; if (r1>15) err(talker,"r1>15 in rayclassnointernarch");
1957: lx=lg(sous); sousray=cgetg(lx,t_VEC);
1958: for (j=1; j<lx; j++)
1959: {
1960: bidsimp=(GEN)sous[j]; qm=gmul((GEN)bidsimp[3],(GEN)bidsimp[4]);
1961: nq=lg(qm)-1; cyclic=(GEN)bidsimp[2]; nc=lg(cyclic)-1;
1962: if (lm != nq+1) err(bugparier,"rayclassnointernarch (1)");
1963: if (lg(qm[1]) != nc+1) err(bugparier,"rayclassnointernarch (2)");
1964: m=cgetg(nq+nc+r1+1,t_MAT);
1965: for (k=1; k<=nq; k++)
1966: {
1967: p2=cgetg(nc+r1+1,t_COL); m[k]=(long)p2; qmk=(GEN)qm[k];
1968: matk=(GEN)matarchunit[k];
1969: for (kk=1; kk<=nc; kk++) p2[kk]=qmk[kk];
1970: for ( ; kk<=nc+r1; kk++) p2[kk]=matk[kk-nc];
1971: }
1972: for ( ; k<=nq+nc; k++)
1973: {
1974: p2=cgetg(nc+r1+1,t_COL); m[k]=(long)p2;
1975: for (kk=1; kk<=nc+r1; kk++) p2[kk]=(kk==k-nq)?cyclic[kk]:zero;
1976: }
1977: for ( ; k<=nq+nc+r1; k++)
1978: {
1979: p2=cgetg(nc+r1+1,t_COL); m[k]=(long)p2;
1980: for (kk=1; kk<=nc+r1; kk++) p2[kk]=(kk==k-nq)?deux:zero;
1981: }
1982: m=hnf(m);
1983: nbarch=(1<<r1); p1all=cgetg(nbarch+1,t_VEC); lh=lg(m);
1984: if (lh!=nc+r1+1) err(bugparier,"rayclassnointernarch (3)");
1985: for (k=0; k<=nbarch-1; k++)
1986: {
1987: p2=cgetg(r1+1,t_COL); kk=k; nba=0;
1988: for (jj=1; jj<=r1; jj++)
1989: {
1990: if (kk%2) { nba++; p2[jj]=un; } else p2[jj]=zero;
1991: kk>>=1;
1992: }
1993: mm=cgetg(lh,t_MAT);
1994: for (jj=1; jj<lh; jj++)
1995: {
1996: p3=cgetg(nc+nba+1,t_COL); mm[jj]=(long)p3; mj=(GEN)m[jj];
1997: for (i=1; i<=nc; i++) p3[i]=mj[i];
1998: for (ii=1; ii<=r1; ii++)
1999: if (signe(p2[ii])) p3[i++]=mj[nc+ii];
2000: }
2001: p1all[k+1]=lmul(clh,dethnf(hnf(mm)));
2002: }
2003: p1=cgetg(3,t_VEC); p1[2]=(long)p1all; p1[1]=bidsimp[1];
2004: sousray[j]=(long)p1;
2005: }
2006: return sousray;
2007: }
2008:
2009: GEN
2010: decodemodule(GEN nf, GEN fa)
2011: {
2012: long n,k,j,fauxpr,av=avma;
2013: GEN fa2,ex,id,pr;
2014:
2015: nf=checknf(nf);
2016: if (typ(fa)!=t_MAT || lg(fa)!=3)
2017: err(talker,"incorrect factorisation in decodemodule");
2018: n=lgef(nf[1])-3; id=idmat(n);
2019: fa2=(GEN)fa[1]; ex=(GEN)fa[2];
2020: for (k=1; k<lg(fa2); k++)
2021: {
2022: fauxpr=itos((GEN)fa2[k]);
2023: j=(fauxpr%n)+1; fauxpr /= n*n;
2024: pr = (GEN)primedec(nf,stoi(fauxpr))[j];
2025: id = idealmul(nf,id,idealpow(nf,pr,(GEN)ex[k]));
2026: }
2027: return gerepileupto(av,id);
2028: }
2029:
2030: /* Fait tout a partir du debut, et bound peut aller jusqu'a 2^30. Pour
2031: * l'instant ne s'occupe pas des sous-groupes. le format de sortie est le
2032: * suivant: un vecteur vext dont les composantes vint ont exactement 2^LGVINT
2033: * vraies composantes sauf le dernier qui peut etre plus court. vext[i][j]
2034: * (ou j<=2^LGVINT) doit etre compris comme la composante d'indice
2035: * I=(i-1)*2^LGVINT+j d'un grand vecteur unique V. Une telle composante
2036: * d'indice I est un vecteur indexe par tous les ideaux de norme egal a I. Si
2037: * m_0 est un tel ideal, la composante correspondante est la suivante:
2038: *
2039: * + si arch = NULL, on parcourt toutes les parties archimediennes possibles.
2040: * L'ordre des arch est l'ordre lexicographique inverse, donc [0,0,..,0],
2041: * [1,0,..,0], [0,1,..,0],... Dans ce cas: [m_0,V] ou V est un vecteur de
2042: * 2^r1 composantes, donnant pour chaque arch, le triplet [N,R1,D], ou N, R1,
2043: * D sont comme dans discrayabs sauf que D est sous forme factorisee.
2044: *
2045: * + sinon [m_0,arch,N,R1,D], ou N, R1, D sont comme ci-dessus.
2046: *
2047: * Si ramip est different de 0 et -1, ne prend que les modules sans facteur
2048: * carres ailleurs qu'au dessus de ramip. Si ramip est strictement negatif,
2049: * archsquare.
2050: */
2051: static GEN
2052: discrayabslistarchintern(GEN bnf, GEN arch, long bound, long ramip)
2053: {
2054: byteptr ptdif=diffptr;
2055: long degk,lim,av0,av,av1,tetpil,i,j,k,p2s,lfa,lp1,sqbou,cex, allarch;
2056: long ffs,fs,resp,flbou,tdi,nba, k2,karch,kka,nbarch,jjj,jj,square;
2057: long ii2,ii,ly,clhray,lfa2,ep,som,clhss,normps,normi,nbdezero,r1,R1,n,lp4,c;
2058: ulong q;
2059: GEN nf,p,z,pol,p1,p2,p3,fa,pr,normp,ideal,bidp,z2,matarchunit;
2060: GEN bigres,funits,racunit,embunit,sous,clh,sousray,raylist;
2061: GEN clhrayall,discall,faall,Id,idealrel,idealrelinit;
2062: GEN sousdisc,module,fa2,ex,fac,no1,no2,fad,fad1,fad2,fadkabs,pz;
2063: GEN arch2,dlk,disclist,bidsimp,p4,faussefa,pex,fauxpr,gprime;
2064: GEN *gptr[2];
2065:
2066: /* ce qui suit recopie d'assez pres ideallistzstarall */
2067: if (DEBUGLEVEL>2) timer2();
2068: if (bound <= 0) err(talker,"non-positive bound in discrayabslist");
2069: av0=avma; bnf = checkbnf(bnf); flbou=0;
2070: nf=(GEN)bnf[7]; bigres=(GEN)bnf[8]; pol=(GEN)nf[1]; degk=lgef(pol)-3;
2071: r1=itos(gmael(nf,2,1)); fadkabs=factor(absi((GEN)nf[3]));
2072: clh=gmael(bigres,1,1);
2073: funits = check_units(bnf,"discrayabslistarchintern");
2074: racunit=gmael(bigres,4,2);
2075:
2076: if (ramip >= 0) square = 0;
2077: else
2078: {
2079: square = 1; ramip = -ramip;
2080: if (ramip==1) ramip=0;
2081: }
2082: nba = 0; allarch = (arch==NULL);
2083: if (allarch)
2084: { arch=cgetg(r1+1,t_VEC); for (i=1; i<=r1; i++) arch[i]=un; nba=r1; }
2085: else if (gcmp0(arch))
2086: { arch=cgetg(r1+1,t_VEC); for (i=1; i<=r1; i++) arch[i]=zero; }
2087: else
2088: {
2089: if (lg(arch)!=r1+1)
2090: err(talker,"incorrect archimedean argument in discrayabslistlong");
2091: for (i=1; i<=r1; i++) if (signe(arch[i])) nba++;
2092: if (nba) module=cgetg(3,t_VEC);
2093: }
2094: p1=cgetg(3,t_VEC); p1[1]=(long)idmat(degk); p1[2]=(long)arch;
2095: bidp=zidealstarinitall(nf,p1,0);
2096: matarchunit = allarch? logunitmatrix(nf,funits,racunit,bidp): (GEN)NULL;
2097:
2098: p=cgeti(3); p[1]=evalsigne(1)|evallgef(3);
2099: sqbou=itos(racine(stoi(bound)))+1;
2100: av=avma; lim=stack_lim(av,1);
2101: z=bigcgetvec(bound); for (i=2; i<=bound; i++) putcompobig(z,i,cgetg(1,t_VEC));
2102: if (allarch) bidp=zidealstarinitall(nf,idmat(degk),0);
2103: embunit=logunitmatrix(nf,funits,racunit,bidp);
2104: p1=cgetg(2,t_VEC); putcompobig(z,1,p1); p1[1]=(long)zsimp(bidp,embunit);
2105: if (DEBUGLEVEL>=2) fprintferr("Starting zidealstarunits computations\n");
2106: for (p[2]=0; p[2]<=bound; )
2107: {
2108: if (!*ptdif) err(primer1);
2109: p[2] += *ptdif++;
2110: if (!flbou && p[2]>sqbou)
2111: {
2112: flbou=1;
2113: if (DEBUGLEVEL>=2)
2114: { fprintferr("\nStarting rayclassno computations\n"); flusherr(); }
2115: tetpil=avma; z=gerepile(av,tetpil,gcopy(z));
2116: av1=avma; raylist=bigcgetvec(bound);
2117: /* maintenant on suit rayclassnolist */
2118: for (i=1; i<=bound; i++)
2119: {
2120: sous=getcompobig(z,i);
2121: sousray=rayclassnointernarch(sous,clh,matarchunit);
2122: putcompobig(raylist,i,sousray);
2123: }
2124: tetpil=avma; raylist=gerepile(av1,tetpil,gcopy(raylist));
2125: z2=bigcgetvec(sqbou);
2126: for (i=1; i<=sqbou; i++)
2127: { p1=gcopy(getcompobig(z,i)); putcompobig(z2,i,p1); }
2128: z = z2;
2129: }
2130: fa=primedec(nf,p); lfa=lg(fa)-1;
2131: for (j=1; j<=lfa; j++)
2132: {
2133: pr=(GEN)fa[j]; normp=powgi(p,(GEN)pr[4]); cex=0;
2134: if (DEBUGLEVEL>=2) { fprintferr("%ld ",p[2]); flusherr(); }
2135: if (gcmpgs(normp,bound)<=0)
2136: {
2137: fauxpr=stoi(p[2]*degk*degk+(itos((GEN)pr[4])-1)*degk+j-1);
2138: q=p2s=itos(normp); ideal=pr;
2139: while (q <= (ulong)bound)
2140: {
2141: bidp=zidealstarinitall(nf,ideal,0);
2142: faussefa=cgetg(3,t_MAT); p1=cgetg(2,t_COL);
2143: faussefa[1]=(long)p1; p1[1]=(long)fauxpr;
2144: pex=cgetg(2,t_COL); faussefa[2]=(long)pex;
2145: cex++; pex[1]=lstoi(cex);
2146: embunit=logunitmatrix(nf,funits,racunit,bidp);
2147: for (i=q; i<=bound; i+=q)
2148: {
2149: p1=getcompobig(z,i/q); lp1=lg(p1);
2150: if (lp1>1)
2151: {
2152: p2=cgetg(lp1,t_VEC); c=0;
2153: for (k=1; k<lp1; k++)
2154: {
2155: p3=(GEN)p1[k]; if (i>q) { p4=gmael(p3,1,1); lp4=lg(p4)-1; }
2156: if (i==q || !isinvector(p4,fauxpr,lp4))
2157: {
2158: c++;
2159: p2[c]=(long)zsimpjoin(p3,bidp,faussefa,embunit);
2160: }
2161: }
2162: setlg(p2,c+1);
2163: if (c)
2164: {
2165: if (p[2]<=sqbou)
2166: {
2167: pz=getcompobig(z,i);
2168: if (lg(pz)>1) putcompobig(z,i,concatsp(pz,p2));
2169: else putcompobig(z,i,p2);
2170: }
2171: else
2172: {
2173: sousray=rayclassnointernarch(p2,clh,matarchunit);
2174: pz=getcompobig(raylist,i);
2175: if (lg(pz)>1) putcompobig(raylist,i,concatsp(pz,sousray));
2176: else putcompobig(raylist,i,sousray);
2177: }
2178: }
2179: }
2180: }
2181: if (ramip && ramip % p[2]) q=bound+1;
2182: else
2183: {
2184: pz=mulss(q,p2s);
2185: q=(gcmpgs(pz,bound)>0)?bound+1:pz[2];
2186: if (q <= (ulong)bound) ideal=idealmul(nf,ideal,pr);
2187: }
2188: }
2189: }
2190: }
2191: if (low_stack(lim, stack_lim(av,1)))
2192: {
2193: if(DEBUGMEM>1) err(warnmem,"[1]: discrayabslistarch");
2194: if (!flbou)
2195: {
2196: if (DEBUGLEVEL>2)
2197: fprintferr("avma = %ld, t(z) = %ld ",avma-bot,taille2(z));
2198: tetpil=avma; z=gerepile(av,tetpil,gcopy(z));
2199: }
2200: else
2201: {
2202: if (DEBUGLEVEL>2)
2203: fprintferr("avma = %ld, t(r) = %ld ",avma-bot,taille2(raylist));
2204: gptr[0]=&z; gptr[1]=&raylist; gerepilemany(av,gptr,2);
2205: }
2206: if (DEBUGLEVEL>2) { fprintferr("avma = %ld ",avma-bot); flusherr(); }
2207: }
2208: }
2209: if (!flbou) /* maintenant on suit rayclassnolist */
2210: {
2211: if (DEBUGLEVEL>=2)
2212: { fprintferr("\nStarting rayclassno computations\n"); flusherr(); }
2213: tetpil=avma; z=gerepile(av,tetpil,gcopy(z));
2214: av1=avma; raylist=bigcgetvec(bound);
2215: for (i=1; i<=bound; i++)
2216: {
2217: sous=getcompobig(z,i);
2218: sousray=rayclassnointernarch(sous,clh,matarchunit);
2219: putcompobig(raylist,i,sousray);
2220: }
2221: }
2222: if (DEBUGLEVEL>2)
2223: fprintferr("avma = %ld, t(r) = %ld ",avma-bot,taille2(raylist));
2224: tetpil=avma; raylist=gerepile(av,tetpil,gcopy(raylist));
2225: if (DEBUGLEVEL>2)
2226: { fprintferr("avma = %ld ",avma-bot); msgtimer("zidealstarlist"); }
2227: /* maintenant on suit discrayabslist */
2228: if (DEBUGLEVEL>=2)
2229: { fprintferr("Starting discrayabs computations\n"); flusherr(); }
2230:
2231: if (allarch) nbarch = 1<<r1;
2232: else
2233: {
2234: nbarch = 1;
2235: clhrayall = cgetg(2,t_VEC);
2236: discall = cgetg(2,t_VEC);
2237: faall = cgetg(2,t_VEC);
2238: Id = idmat(degk);
2239: }
2240: idealrelinit=cgetg(3,t_MAT);
2241: idealrelinit[1]=lgetg(1,t_COL);
2242: idealrelinit[2]=lgetg(1,t_COL);
2243: av1=avma; lim=stack_lim(av1,1);
2244: if (square) bound = sqbou-1;
2245: disclist=bigcgetvec(bound);
2246: for (ii=1; ii<=bound; ii++) putcompobig(disclist,ii,cgetg(1,t_VEC));
2247: for (ii2=1; ii2<=bound; ii2++)
2248: {
2249: ii = square? ii2*ii2: ii2;
2250: if (DEBUGLEVEL>=2 && ii%100==0) { fprintferr("%ld ",ii); flusherr(); }
2251: sous=getcompobig(raylist,ii); ly=lg(sous); sousdisc=cgetg(ly,t_VEC);
2252: putcompobig(disclist, square? ii2: ii,sousdisc);
2253: for (jj=1; jj<ly; jj++)
2254: {
2255: bidsimp=(GEN)sous[jj]; fa=(GEN)bidsimp[1]; fac=gcopy(fa);
2256: fa2=(GEN)fa[1]; ex=(GEN)fa[2]; lfa2=lg(fa2);
2257:
2258: if (allarch)
2259: {
2260: clhrayall = (GEN)bidsimp[2];
2261: discall=cgetg(nbarch+1,t_VEC);
2262: }
2263: else
2264: clhray = itos((GEN)bidsimp[2]);
2265: for (karch=0; karch<nbarch; karch++)
2266: {
2267: if (!allarch) ideal = Id;
2268: else
2269: {
2270: kka=karch; nba=0;
2271: for (jjj=1; jjj<=r1; jjj++)
2272: {
2273: if (kka%2) nba++;
2274: kka>>=1;
2275: }
2276: clhray=itos((GEN)clhrayall[karch+1]);
2277: for (k2=1,k=1; k<=r1; k++,k2<<=1)
2278: {
2279: if (karch&k2 && clhray==itos((GEN)clhrayall[karch-k2+1]))
2280: { clhray=0; goto LDISCRAY; }
2281: }
2282: }
2283: idealrel = idealrelinit;
2284: for (k=1; k<lfa2; k++)
2285: {
2286: fauxpr=(GEN)fa2[k]; ep=itos((GEN)ex[k]); ffs=itos(fauxpr);
2287: /* Hack for NeXTgcc 2.5.8 -- splitting "resp=fs%degk+1" */
2288: fs=ffs/degk; resp=fs%degk; resp++; gprime=stoi((long)(fs/degk));
2289: if (!allarch && nba)
2290: {
2291: p1=(GEN)primedec(nf,gprime)[ffs%degk+1];
2292: ideal = idealmul(nf,ideal,idealpow(nf,p1,(GEN)ex[k]));
2293: }
2294: som=0; clhss=0;
2295: normp=gpuigs(gprime,resp); normps=itos(normp); normi=ii;
2296: normp=cgetg(3,t_MAT);
2297: no1=cgetg(2,t_COL); no1[1]=(long)gprime; normp[1]=(long)no1;
2298: no2=cgetg(2,t_COL); no2[1]=lstoi(resp); normp[2]=(long)no2;
2299: for (j=1; j<=ep; j++)
2300: {
2301: if (clhss==1) som++;
2302: else
2303: {
2304: if (j<ep) { coeff(fac,k,2)=lstoi(ep-j); fad=fac; }
2305: else
2306: {
2307: fad=cgetg(3,t_MAT);
2308: fad1=cgetg(lfa2-1,t_COL); fad[1]=(long)fad1;
2309: fad2=cgetg(lfa2-1,t_COL); fad[2]=(long)fad2;
2310: for (i=1; i<k; i++)
2311: { fad1[i]=coeff(fac,i,1); fad2[i]=coeff(fac,i,2); }
2312: for ( ; i<lfa2-1; i++)
2313: { fad1[i]=coeff(fac,i+1,1); fad2[i]=coeff(fac,i+1,2); }
2314: }
2315: normi /= normps;
2316: /* Hack for NeXTgcc 2.5.8 -- using dlk as temporary variable */
2317: dlk=rayclassnolistessimp(getcompobig(raylist,normi),fad);
2318: if (allarch) dlk = (GEN)dlk[karch+1];
2319: clhss = itos(dlk);
2320: if (j==1 && clhss==clhray)
2321: {
2322: clhray=0; coeff(fac,k,2)=ex[k]; goto LDISCRAY;
2323: }
2324: som += clhss;
2325: }
2326: }
2327: coeff(fac,k,2)=ex[k];
2328: idealrel=factormul(idealrel,factorpow(normp,som));
2329: }
2330: dlk=factordivexact(factorpow(factor(stoi(ii)),clhray),idealrel);
2331: if (!allarch && nba)
2332: {
2333: module[1]=(long)ideal; arch2=gcopy(arch); module[2]=(long)arch2;
2334: nbdezero=0;
2335: for (k=1; k<=r1; k++)
2336: {
2337: if (signe(arch[k]))
2338: {
2339: arch2[k]=zero;
2340: clhss=itos(rayclassno(bnf,module));
2341: arch2[k]=un;
2342: if (clhss==clhray) { clhray=0; goto LDISCRAY; }
2343: }
2344: else nbdezero++;
2345: }
2346: }
2347: else nbdezero = r1-nba;
2348: LDISCRAY:
2349: p1=cgetg(4,t_VEC); discall[karch+1]=(long)p1;
2350: if (!clhray) p1[1]=p1[2]=p1[3]=zero;
2351: else
2352: {
2353: p3=factorpow(fadkabs,clhray); n=clhray*degk; R1=nbdezero*clhray;
2354: if (((n-R1)&3)==2)
2355: {
2356: normp=cgetg(3,t_MAT);
2357: no1=cgetg(2,t_COL); normp[1]=(long)no1; no1[1]=lstoi(-1);
2358: no2=cgetg(2,t_COL); normp[2]=(long)no2; no2[1]=un;
2359: dlk=factormul(normp,dlk);
2360: }
2361: p1[1]=lstoi(n); p1[2]=lstoi(R1); p1[3]=(long)factormul(dlk,p3);
2362: }
2363: }
2364: if (allarch)
2365: { p1 = cgetg(3,t_VEC); p1[1]=(long)fa; p1[2]=(long)discall; }
2366: else
2367: { faall[1]=(long)fa; p1 = concatsp(faall, p1); }
2368: sousdisc[jj]=(long)p1;
2369: if (low_stack(lim, stack_lim(av1,1)))
2370: {
2371: if(DEBUGMEM>1) err(warnmem,"[2]: discrayabslistarch");
2372: if (DEBUGLEVEL>2)
2373: fprintferr("avma = %ld, t(d) = %ld ",avma-bot,taille2(disclist));
2374: tetpil=avma; disclist=gerepile(av1,tetpil,gcopy(disclist));
2375: if (DEBUGLEVEL>2) { fprintferr("avma = %ld ",avma-bot); flusherr(); }
2376: }
2377: }
2378: }
2379: if (DEBUGLEVEL>2) msgtimer("discrayabs");
2380: tdi=taille2(disclist);
2381: if (DEBUGLEVEL>2)
2382: { fprintferr("avma = %ld, t(d) = %ld ",avma-bot,tdi); flusherr(); }
2383: if (tdi<avma-bot)
2384: {
2385: tetpil=avma; disclist=gerepile(av0,tetpil,gcopy(disclist));
2386: if (DEBUGLEVEL>2) { fprintferr("avma = %ld ",avma-bot); flusherr(); }
2387: }
2388: return disclist;
2389: }
2390:
2391: GEN
2392: discrayabslistarch(GEN bnf, GEN arch, long bound)
2393: { return discrayabslistarchintern(bnf,arch,bound, 0); }
2394:
2395: GEN
2396: discrayabslistlong(GEN bnf, long bound)
2397: { return discrayabslistarchintern(bnf,gzero,bound, 0); }
2398:
2399: GEN
2400: discrayabslistarchsquare(GEN bnf, GEN arch, long bound)
2401: { return discrayabslistarchintern(bnf,arch,bound, -1); }
2402:
2403: static GEN
2404: computehuv(GEN bnr,GEN id, GEN arch,long prec)
2405: {
2406: long i,nbgen, av = avma;
2407: GEN bnf,bnrnew,listgen,P,U,DC;
2408: GEN newmod=cgetg(3,t_VEC);
2409: newmod[1]=(long)id;
2410: newmod[2]=(long)arch;
2411:
2412: bnf=(GEN)bnr[1];
2413: bnrnew=buchrayall(bnf,newmod,nf_INIT,prec);
2414: listgen=gmael(bnr,5,3); nbgen=lg(listgen);
2415: P=cgetg(nbgen,t_MAT);
2416: for (i=1; i<nbgen; i++)
2417: P[i] = (long)isprincipalray(bnrnew,(GEN)listgen[i]);
2418: DC=diagonal(gmael(bnrnew,5,2));
2419: U=(GEN)hnfall(concatsp(P,DC))[2];
2420: setlg(U,nbgen); for (i=1; i<nbgen; i++) setlg(U[i], nbgen);
2421: return gerepileupto(av, hnf(concatsp(U,diagonal(gmael(bnr,5,2)))));
2422: }
2423:
2424: /* 0 if hinv*list[i] has a denominator for all i, 1 otherwise */
2425: static int
2426: hnflistdivise(GEN list,GEN h)
2427: {
2428: long av = avma, i, I = lg(list);
2429: GEN hinv = ginv(h);
2430:
2431: for (i=1; i<I; i++)
2432: if (gcmp1(denom(gmul(hinv,(GEN)list[i])))) break;
2433: avma = av; return i < I;
2434: }
2435:
2436: static GEN
2437: subgroupcond(GEN bnr, long indexbound, long prec)
2438: {
2439: long av=avma,tetpil,i,j,lgi,lp;
2440: GEN li,p1,lidet,perm,nf,bid,ideal,arch,primelist,listkernels;
2441:
2442: checkbnrgen(bnr); bid=(GEN)bnr[2];
2443: ideal=gmael(bid,1,1);
2444: arch =gmael(bid,1,2); nf=gmael(bnr,1,7);
2445: primelist=gmael(bid,3,1); lp=lg(primelist)-1;
2446: listkernels=cgetg(lp+lg(arch),t_VEC);
2447: for (i=1; i<=lp; )
2448: {
2449: p1=idealdiv(nf,ideal,(GEN)primelist[i]);
2450: listkernels[i++]=(long)computehuv(bnr,p1,arch,prec);
2451: }
2452: for (j=1; j<lg(arch); j++)
2453: if (signe((GEN)arch[j]))
2454: {
2455: p1=dummycopy(arch); p1[j]=zero;
2456: listkernels[i++]=(long)computehuv(bnr,ideal,p1,prec);
2457: }
2458: setlg(listkernels,i);
2459:
2460: li=subgrouplist(gmael(bnr,5,2),indexbound);
2461: lgi=lg(li);
2462: for (i=1,j=1; j<lgi; j++)
2463: if (!hnflistdivise(listkernels, (GEN)li[j])) li[i++] = li[j];
2464: /* sort by increasing index */
2465: lgi = i; setlg(li,i); lidet=cgetg(lgi,t_VEC);
2466: for (i=1; i<lgi; i++) lidet[i]=(long)dethnf_i((GEN)li[i]);
2467: perm = sindexsort(lidet); p1=li; li=cgetg(lgi,t_VEC);
2468: for (i=1; i<lgi; i++) li[i] = p1[perm[lgi-i]];
2469: tetpil=avma; return gerepile(av,tetpil,gcopy(li));
2470: }
2471:
2472: GEN
2473: subgrouplist0(GEN bnr, long indexbound, long all, long prec)
2474: {
2475: if (typ(bnr)!=t_VEC) err(typeer,"subgrouplist");
2476: if (lg(bnr)!=1 && typ(bnr[1])!=t_INT)
2477: {
2478: if (!all) return subgroupcond(bnr,indexbound,prec);
2479: checkbnr(bnr); bnr = gmael(bnr,5,2);
2480: }
2481: return subgrouplist(bnr,indexbound);
2482: }
2483:
2484: GEN
2485: bnrdisclist0(GEN bnf, GEN borne, GEN arch, long all)
2486: {
2487: if (typ(borne)==t_INT)
2488: {
2489: if (!arch) arch = gzero;
2490: if (all==1) { arch = NULL; all = 0; }
2491: return discrayabslistarchintern(bnf,arch,itos(borne),all);
2492: }
2493: return discrayabslist(bnf,borne);
2494: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>