Annotation of OpenXM_contrib/pari-2.2/src/modules/kummer.c, Revision 1.1.1.1
1.1 noro 1: /* $Id: kummer.c,v 1.17 2001/10/01 12:11:33 karim Exp $
2:
3: Copyright (C) 2000 The PARI group.
4:
5: This file is part of the PARI/GP package.
6:
7: PARI/GP is free software; you can redistribute it and/or modify it under the
8: terms of the GNU General Public License as published by the Free Software
9: Foundation. It is distributed in the hope that it will be useful, but WITHOUT
10: ANY WARRANTY WHATSOEVER.
11:
12: Check the License for details. You should have received a copy of it, along
13: with the package; see the file 'COPYING'. If not, write to the Free Software
14: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
15:
16: /*******************************************************************/
17: /* */
18: /* KUMMER EXTENSIONS */
19: /* */
20: /*******************************************************************/
21: #include "pari.h"
22: extern GEN check_and_build_cycgen(GEN bnf);
23: extern GEN get_arch_real(GEN nf,GEN x,GEN *emb,long prec);
24: extern GEN vecmul(GEN x, GEN y);
25: extern GEN vecinv(GEN x);
26: extern GEN T2_from_embed_norm(GEN x, long r1);
27: extern GEN pol_to_vec(GEN x, long N);
28: extern GEN famat_to_nf(GEN nf, GEN f);
29:
30: static long rc,ell,degK,degKz,m,d,vnf,dv;
31: static GEN matexpoteta1,nf,raycyc,polnf;
32: static GEN bnfz,nfz,U,uu,gell,cyc,gencyc,vecalpha,R,g;
33: static GEN listmod,listprSp,listbid,listunif,listellrank;
34: static GEN listbidsup,listellranksup,vecw;
35:
36: /* row vector B x matrix T : c_j=prod_i (b_i^T_ij) */
37: static GEN
38: groupproduct(GEN B, GEN T)
39: {
40: long lB,lT,i,j;
41: GEN c,p1;
42:
43: lB=lg(B)-1;
44: lT=lg(T)-1;
45: c=cgetg(lT+1,t_VEC);
46: for (j=1; j<=lT; j++)
47: {
48: p1=gun;
49: for (i=1; i<=lB; i++) p1=gmul(p1,gpui((GEN)B[i],gcoeff(T,i,j),0));
50: c[j]=(long)p1;
51: }
52: return c;
53: }
54:
55: static GEN
56: grouppows(GEN B, long ex)
57: {
58: long lB = lg(B),j;
59: GEN c;
60:
61: c = cgetg(lB,t_VEC);
62: for (j=1; j<lB; j++) c[j] = lpowgs((GEN)B[j], ex);
63: return c;
64: }
65:
66: static int
67: ok_x(GEN X, GEN arch, GEN vecmunit2, GEN msign)
68: {
69: long i, l = lg(vecmunit2);
70: GEN p1;
71: for (i=1; i<l; i++)
72: {
73: p1 = FpV_red(gmul((GEN)vecmunit2[i], X), gell);
74: if (gcmp0(p1)) return 0;
75: }
76: p1 = lift(gmul(msign,X)); settyp(p1,t_VEC);
77: return gegal(p1, arch);
78: }
79:
80: static GEN
81: get_listx(GEN arch,GEN msign,GEN munit,GEN vecmunit2,long ell,long lSp,long nbvunit)
82: {
83: GEN kermat,p2,X,y, listx = cgetg(1,t_VEC);
84: long i,j,cmpt,lker;
85:
86: kermat = FpM_ker(munit,gell); lker=lg(kermat)-1;
87: if (!lker) return listx;
88: y = cgetg(lker,t_VECSMALL);
89: for (i=1; i<lker; i++) y[i] = 0;
90: for(;;)
91: {
92: p2 = cgetg(2,t_VEC);
93: X = (GEN)kermat[lker];
94: for (j=1; j<lker; j++) X = gadd(X, gmulsg(y[j],(GEN)kermat[j]));
95: X = FpV_red(X, gell);
96: cmpt = 0; for (j=1; j<=lSp; j++) if (gcmp0((GEN)X[j+nbvunit])) cmpt++;
97: if (!cmpt)
98: {
99: if (ok_x(X, arch, vecmunit2, msign))
100: { p2[1] = (long)X; listx = concatsp(listx,p2); }
101: }
102: if (!lSp)
103: {
104: j = 1; while (j<lker && !y[j]) j++;
105: if (j<lker && y[j] == 1)
106: {
107: X = gsub(X,(GEN)kermat[lker]);
108: if (ok_x(X, arch, vecmunit2, msign))
109: { p2[1] = (long)X; listx = concatsp(listx,p2); }
110: }
111: }
112: i = lker;
113: do
114: {
115: i--; if (!i) return listx;
116: if (i < lker-1) y[i+1] = 0;
117: y[i]++;
118: }
119: while (y[i] >= ell);
120: }
121: }
122:
123: static GEN
124: reducealpha(GEN nf,GEN x,GEN gell)
125: /* etant donne un nombre algebrique x du corps nf -- non necessairement
126: entier -- calcule un entier algebrique de la forme x*g^gell */
127: {
128: long tx=typ(x),i;
129: GEN den,fa,fac,ep,p1,y;
130:
131: nf = checknf(nf);
132: if (tx==t_POL || tx==t_POLMOD) y = algtobasis(nf,x);
133: else { y = x; x = basistoalg(nf,y); }
134: den = denom(y);
135: if (gcmp1(den)) return x;
136: fa = decomp(den); fac = (GEN)fa[1];ep = (GEN)fa[2];
137: p1 = gun;
138: for (i=1; i<lg(fac); i++)
139: p1 = mulii(p1, powgi((GEN)fac[i], gceil(gdiv((GEN)ep[i],gell))));
140: return gmul(powgi(p1, gell), x);
141: }
142:
143: long
144: ellrank(GEN cyc, long ell)
145: {
146: long i;
147: for (i=1; i<lg(cyc); i++)
148: if (smodis((GEN)cyc[i],ell)) break;
149: return i-1;
150: }
151:
152: static GEN
153: no_sol(long all, int i)
154: {
155: if (!all) err(talker,"bug%d in kummer",i);
156: return cgetg(1,t_VEC);
157: }
158:
159: static void
160: _append(GEN x, GEN t)
161: {
162: long l = lg(x); x[l] = (long)t; setlg(x, l+1);
163: }
164:
165: /* si all!=0, donne toutes les equations correspondant a un sousgroupe
166: de determinant all (i.e. de degre all) */
167: static GEN
168: rnfkummersimple(GEN bnr, GEN subgroup, long all)
169: {
170: long r1,degnf,ell,j,i,l;
171: long nbgenclK,lSml2,lSl,lSp,rc,nbvunit;
172: long lastbid,nbcol,nblig,k,llistx,e,vp,vd;
173:
174: GEN bnf,nf,classgroup,cyclic,bid,ideal,arch,cycgen,gell,p1,p2,p3;
175: GEN cyclicK,genK,listgamma,listalpha,fa,prm,expom,Sm,Sml1,Sml2,Sl,ESml2;
176: GEN p,factell,Sp,vecbeta,matexpo,vunit,id,pr,vsml2,vecalpha0;
177: GEN cycpro,munit,vecmunit2,msign,archartif,listx,listal,listg,listgamma0;
178: GEN vecbeta0;
179:
180: checkbnrgen(bnr);
181: bnf = (GEN)bnr[1];
182: nf = (GEN)bnf[7]; r1 = nf_get_r1(nf);
183: polnf = (GEN)nf[1]; vnf = varn(polnf); degnf = degpol(polnf);
184: if (vnf==0) err(talker,"main variable in kummer must not be x");
185:
186: p1 = conductor(bnr,all ? gzero : subgroup,2);
187: bnr = (GEN)p1[2];
188: if (!all) subgroup = (GEN)p1[3];
189: classgroup = (GEN)bnr[5];
190: cyclic = (GEN)classgroup[2];
191: bid = (GEN)bnr[2];
192: ideal= gmael(bid,1,1);
193: arch = gmael(bid,1,2); /* this is the conductor */
194: if (!all && gcmp0(subgroup)) subgroup = diagonal(cyclic);
195: gell = all? stoi(all): det(subgroup);
196: ell = itos(gell);
197:
198: cyclicK= gmael3(bnf,8,1,2); rc = ellrank(cyclicK,ell);
199: genK = gmael3(bnf,8,1,3); nbgenclK = lg(genK)-1;
200: listgamma0=cgetg(nbgenclK+1,t_VEC);
201: listgamma=cgetg(nbgenclK+1,t_VEC);
202: vecalpha0=cgetg(rc+1,t_VEC);
203: listalpha=cgetg(rc+1,t_VEC);
204: cycgen = check_and_build_cycgen(bnf);
205: p1 = gmul(gell,ideal);
206: for (i=1; i<=rc; i++)
207: {
208: p3 = basistoalg(nf,idealcoprime(nf,(GEN)genK[i],p1));
209: p2 = basistoalg(nf, famat_to_nf(nf, (GEN)cycgen[i]));
210: listgamma[i] = listgamma0[i] = linv(p3);
211: vecalpha0[i] = (long)p2;
212: listalpha[i] = lmul((GEN)vecalpha0[i], powgi(p3,(GEN)cyclicK[i]));
213: }
214: for ( ; i<=nbgenclK; i++)
215: {
216: long k;
217: p3 = basistoalg(nf,idealcoprime(nf,(GEN)genK[i],p1));
218: p2 = basistoalg(nf, famat_to_nf(nf, (GEN)cycgen[i]));
219: k = itos(mpinvmod((GEN)cyclicK[i], gell));
220: p2 = gpowgs(p2,k);
221: listgamma0[i]= (long)p2;
222: listgamma[i] = lmul(p2, gpowgs(p3, k * itos((GEN)cyclicK[i]) - 1));
223: }
224: fa = (GEN)bid[3];
225: prm = (GEN)fa[1];
226: expom = (GEN)fa[2]; l = lg(prm);
227: Sm = cgetg(l,t_VEC); setlg(Sm,1);
228: Sml1= cgetg(l,t_VEC); setlg(Sml1,1);
229: Sml2= cgetg(l,t_VEC); setlg(Sml2,1);
230: Sl = cgetg(l+degnf,t_VEC); setlg(Sl,1);
231: ESml2=cgetg(l,t_VECSMALL); setlg(ESml2,1);
232: for (i=1; i<l; i++)
233: {
234: pr = (GEN)prm[i]; p = (GEN)pr[1]; e = itos((GEN)pr[3]);
235: vp = itos((GEN)expom[i]);
236: if (!egalii(p,gell))
237: {
238: if (vp != 1) return no_sol(all,1);
239: _append(Sm, pr);
240: }
241: else
242: {
243: vd = (vp-1)*(ell-1)-ell*e;
244: if (vd > 0) return no_sol(all,4);
245: if (vd==0)
246: _append(Sml1, pr);
247: else
248: {
249: if (vp==1) return no_sol(all,2);
250: _append(Sml2, pr);
251: _append(ESml2,(GEN)vp);
252: }
253: }
254: }
255: factell = primedec(nf,gell); l = lg(factell);
256: for (i=1; i<l; i++)
257: {
258: pr = (GEN)factell[i];
259: if (!idealval(nf,ideal,pr)) _append(Sl, pr);
260: }
261: lSml2=lg(Sml2)-1; lSl=lg(Sl)-1;
262: Sp = concatsp(Sm,Sml1); lSp = lg(Sp)-1;
263: vecbeta = cgetg(lSp+1,t_VEC); matexpo=cgetg(lSp+1,t_MAT);
264: vecbeta0= cgetg(lSp+1,t_VEC);
265: for (j=1; j<=lSp; j++)
266: {
267: p1=isprincipalgenforce(bnf,(GEN)Sp[j]);
268: p2=basistoalg(nf,(GEN)p1[2]);
269: for (i=1; i<=rc; i++)
270: p2 = gmul(p2, powgi((GEN)listgamma[i],gmael(p1,1,i)));
271: p3 = p2;
272: for ( ; i<=nbgenclK; i++)
273: {
274: p2 = gmul(p2, powgi((GEN)listgamma[i],gmael(p1,1,i)));
275: p3 = gmul(p3, powgi((GEN)listgamma0[i],gmael(p1,1,i)));
276: }
277: matexpo[j]=(long)p1[1];
278: vecbeta[j]=(long)p2; /* attention, ceci sont les beta modifies */
279: vecbeta0[j]=(long)p3;
280: }
281: listg = gmodulcp(concatsp(gmael(bnf,8,5),gmael3(bnf,8,4,2)),polnf);
282: vunit = concatsp(listg, listalpha);
283: nbvunit=lg(vunit)-1;
284: id=idmat(degnf);
285: for (i=1; i<=lSl; i++)
286: {
287: pr = (GEN)Sl[i]; e = itos((GEN)pr[3]);
288: id = idealmul(nf, id, idealpows(nf,pr,(ell*e)/(ell-1)));
289: }
290: vsml2=cgetg(lSml2+1,t_VEC);
291: for (i=1; i<=lSml2; i++)
292: {
293: pr = (GEN)Sml2[i]; e = itos((GEN)pr[3]);
294: p1=idealpows(nf,pr, (e*ell)/(ell-1) + 1 - ESml2[i]);
295: id = idealmul(nf,id,p1);
296: p2 = idealmul(nf,p1,pr);
297: p3 = zidealstarinitgen(nf,p2);
298: vsml2[i] = (long)p3;
299: cycpro = gmael(p3,2,2); l = lg(cycpro)-1;
300: if (! gdivise((GEN)cycpro[l],gell)) err(talker,"bug5 in kummer");
301: }
302: bid = zidealstarinitgen(nf,id);
303: lastbid = ellrank(gmael(bid,2,2), ell);
304: nbcol=nbvunit+lSp; nblig=lastbid+rc;
305: munit=cgetg(nbcol+1,t_MAT); vecmunit2=cgetg(lSml2+1,t_VEC);
306: msign=cgetg(nbcol+1,t_MAT);
307: for (k=1; k<=lSml2; k++) vecmunit2[k]=lgetg(nbcol+1,t_MAT);
308: archartif=cgetg(r1+1,t_VEC); for (j=1; j<=r1; j++) archartif[j]=un;
309: for (j=1; j<=nbvunit; j++)
310: {
311: p1 = zideallog(nf,(GEN)vunit[j],bid);
312: p2 = cgetg(nblig+1,t_COL); munit[j]=(long)p2;
313: for (i=1; i<=lastbid; i++) p2[i]=p1[i];
314: for ( ; i<=nblig; i++) p2[i]=zero;
315: for (k=1; k<=lSml2; k++)
316: mael(vecmunit2,k,j) = (long)zideallog(nf,(GEN)vunit[j],(GEN)vsml2[k]);
317: msign[j] = (long)zsigne(nf,(GEN)vunit[j],archartif);
318: }
319: for (j=1; j<=lSp; j++)
320: {
321: p1 = zideallog(nf,(GEN)vecbeta[j],bid);
322: p2 = cgetg(nblig+1,t_COL); munit[j+nbvunit]=(long)p2;
323: for (i=1; i<=lastbid; i++) p2[i]=p1[i];
324: for ( ; i<=nblig; i++) p2[i]=coeff(matexpo,i-lastbid,j);
325: for (k=1; k<=lSml2; k++)
326: mael(vecmunit2,k,j+nbvunit) = (long)zideallog(nf,(GEN)vecbeta[j],(GEN)vsml2[k]);
327: msign[j+nbvunit] = (long)zsigne(nf,(GEN)vecbeta[j],archartif);
328: }
329: listx = get_listx(arch,msign,munit,vecmunit2,ell,lSp,nbvunit);
330: llistx= lg(listx);
331: listal= cgetg(llistx,t_VEC);
332: listg = concatsp(listg, concatsp(vecalpha0,vecbeta0));
333: l = lg(listg);
334: for (i=1; i<llistx; i++)
335: {
336: p1 = gun; p2 = (GEN)listx[i];
337: for (j=1; j<l; j++)
338: p1 = gmul(p1, powgi((GEN)listg[j],(GEN)p2[j]));
339: listal[i] = (long)reducealpha(nf,p1,gell);
340: }
341: /* A ce stade, tous les alpha dans la liste listal statisfont les
342: * congruences, noncongruences et signatures, et ne sont pas des puissances
343: * l-iemes donc x^l-alpha est irreductible, sa signature est correcte ainsi
344: * que son discriminant relatif. Reste a determiner son groupe de normes. */
345: if (DEBUGLEVEL) fprintferr("listalpha = %Z\n",listal);
346: p2 = cgetg(1,t_VEC);
347: for (i=1; i<llistx; i++)
348: {
349: p1 = gsub(gpuigs(polx[0],ell), (GEN)listal[i]);
350: if (all || gegal(rnfnormgroup(bnr,p1),subgroup)) p2 = concatsp(p2,p1);
351: }
352: if (all) return gcopy(p2);
353: switch(lg(p2)-1)
354: {
355: case 0: err(talker,"bug 6: no equation found in kummer");
356: case 1: break; /* OK */
357: default: fprintferr("equations = \n%Z",p2);
358: err(talker,"bug 7: more than one equation found in kummer");
359: }
360: return gcopy((GEN)p2[1]);
361: }
362:
363: static GEN
364: tauofideal(GEN id)
365: {
366: long j;
367: GEN p1,p2;
368:
369: p1=gsubst(gmul((GEN)nfz[7],id),vnf,U);
370: p2=cgetg(lg(p1),t_MAT);
371: for (j=1; j<lg(p1); j++) p2[j]=(long)algtobasis(nfz,(GEN)p1[j]);
372: return p2;
373: }
374:
375: static GEN
376: tauofprimeideal(GEN pr)
377: {
378: GEN p1 = dummycopy(pr);
379:
380: p1[2] = (long)algtobasis(nfz, gsubst(gmul((GEN)nfz[7],(GEN)pr[2]),vnf,U));
381: return gcoeff(idealfactor(nfz,prime_to_ideal(nfz,p1)),1,1);
382: }
383:
384: static long
385: isprimeidealconj(GEN pr1, GEN pr2)
386: {
387: GEN pr=pr1;
388:
389: do
390: {
391: if (gegal(pr,pr2)) return 1;
392: pr = tauofprimeideal(pr);
393: }
394: while (!gegal(pr,pr1));
395: return 0;
396: }
397:
398: static long
399: isconjinprimelist(GEN listpr, GEN pr2)
400: {
401: long ll=lg(listpr)-1,i;
402:
403: for (i=1; i<=ll; i++)
404: if (isprimeidealconj((GEN)listpr[i],pr2)) return 1;
405: return 0;
406: }
407:
408: static void
409: computematexpoteta1(GEN A1, GEN R)
410: {
411: long j;
412: GEN Aj = polun[vnf];
413: matexpoteta1 = cgetg(degK+1,t_MAT);
414: for (j=1; j<=degK; j++)
415: {
416: matexpoteta1[j] = (long)pol_to_vec(Aj, degKz);
417: if (j<degK) Aj = gmod(gmul(Aj,A1), R);
418: }
419: }
420:
421: static GEN
422: downtoK(GEN x)
423: {
424: long i;
425: GEN p2,p3;
426:
427: p2 = inverseimage(matexpoteta1, pol_to_vec(lift(x), degKz));
428: if (lg(p2)==1) err(talker,"not an element of K in downtoK");
429: p3 = (GEN)p2[degK];
430: for (i=degK-1; i; i--) p3 = gadd((GEN)p2[i],gmul(polx[vnf],p3));
431: return gmodulcp(p3,polnf);
432: }
433:
434: static GEN
435: tracetoK(GEN x)
436: {
437: long i;
438: GEN p1,p2;
439:
440: p1=x; p2=x;
441: for (i=1; i<=m-1; i++)
442: {
443: p1=gsubst(lift(p1),vnf,U);
444: p2=gadd(p2,p1);
445: }
446: return downtoK(p2);
447: }
448:
449: static GEN
450: normtoK(GEN x)
451: {
452: long i;
453: GEN p1,p2;
454:
455: p1=x; p2=x;
456: for (i=1; i<=m-1; i++)
457: {
458: p1=gsubst(lift(p1),vnf,U);
459: p2=gmul(p2,p1);
460: }
461: return downtoK(p2);
462: }
463:
464: static GEN
465: computepolrel(void)
466: {
467: long i,j;
468: GEN p1,p2;
469:
470: p1=gun; p2=gmodulcp(polx[vnf],R);
471: for (i=0; i<=m-1; i++)
472: {
473: p1=gmul(p1,gsub(polx[0],p2));
474: if (i<m-1) p2=gsubst(lift(p2),vnf,U);
475: }
476: for (j=2; j<=m+2; j++) p1[j]=(long)downtoK((GEN)p1[j]);
477: return p1;
478: }
479:
480: /* alg. 5.2.15. with remark */
481: static GEN
482: isprincipalell(GEN id)
483: {
484: long i, l = lg(vecalpha);
485: GEN y,logdisc,be;
486:
487: y = isprincipalgenforce(bnfz,id);
488: logdisc = (GEN)y[1];
489: be = basistoalg(bnfz,(GEN)y[2]);
490: for (i=rc+1; i<l; i++)
491: be = gmul(be, powgi((GEN)vecalpha[i], modii(mulii((GEN)logdisc[i],(GEN)uu[i]),gell)));
492: y = cgetg(3,t_VEC);
493: y[1]=(long)logdisc; setlg(logdisc,rc+1);
494: y[2]=(long)be;
495: return y;
496: }
497:
498: /* alg. 5.3.11. */
499: static GEN
500: isvirtualunit(GEN v)
501: {
502: long llist,i,j,ex, l = lg(vecalpha);
503: GEN p1,listex,listpr,q,ga,eps,vecy,logdisc;
504:
505: p1=idealfactor(nfz,v);
506: listpr = (GEN)p1[1]; llist = lg(listpr)-1;
507: listex = (GEN)p1[2]; q = idmat(degKz);
508: for (i=1; i<=llist; i++)
509: {
510: ex = itos((GEN)listex[i]);
511: if (ex%ell) err(talker,"not a virtual unit in isvirtualunit");
512: q = idealmul(nfz,q, idealpows(nfz,(GEN)listpr[i], ex/ell));
513: }
514: /* q^ell = (v) */
515: p1 = isprincipalgenforce(bnfz,q);
516: logdisc = (GEN)p1[1];
517: ga = basistoalg(nfz,(GEN)p1[2]);
518: for (j=rc+1; j<l; j++)
519: ga = gmul(ga, powgi((GEN)vecalpha[j],divii((GEN)logdisc[j],(GEN)cyc[j])));
520: eps = gpuigs(ga,ell);
521: vecy = cgetg(rc+1,t_COL);
522: for (j=1; j<=rc; j++)
523: {
524: vecy[j] = (long)divii((GEN)logdisc[j], divii((GEN)cyc[j],gell));
525: eps = gmul(eps, powgi((GEN)vecalpha[j],(GEN)vecy[j]));
526: }
527: eps = gdiv(v,eps);
528: p1 = cgetg(3,t_VEC);
529: p1[1] = (long)concatsp(vecy, lift(isunit(bnfz,eps)));
530: p1[2] = (long)ga;
531: return p1;
532: }
533:
534: static GEN
535: lifttokz(GEN id, GEN A1)
536: {
537: long i,j;
538: GEN p1,p2,p3;
539:
540: p1=gsubst(gmul((GEN)nf[7],id),vnf,A1);
541: p2=gmodulcp((GEN)nfz[7],R);
542: p3=cgetg(degK*degKz+1,t_MAT);
543: for (i=1; i<=degK; i++)
544: for (j=1; j<=degKz; j++)
545: p3[(i-1)*degKz+j]=(long)algtobasis(nfz,gmul((GEN)p1[i],(GEN)p2[j]));
546: return hnfmod(p3,detint(p3));
547: }
548:
549: static GEN
550: steinitzaux(GEN id, GEN polrel)
551: {
552: long i,j;
553: GEN p1,p2,p3,vecid,matid,pseudomat,pid;
554:
555: p1=gsubst(gmul((GEN)nfz[7],id),vnf,polx[0]);
556: for (j=1; j<=degKz; j++)
557: p1[j]=(long)gmod((GEN)p1[j],polrel);
558: p2=cgetg(degKz+1,t_MAT);
559: for (j=1; j<=degKz; j++)
560: {
561: p3=cgetg(m+1,t_COL); p2[j]=(long)p3;
562: for (i=1; i<=m; i++) p3[i]=(long)algtobasis(nf,truecoeff((GEN)p1[j],i-1));
563: }
564: vecid=cgetg(degKz+1,t_VEC); matid=idmat(degK);
565: for (j=1; j<=degKz; j++) vecid[j]=(long)matid;
566: pseudomat=cgetg(3,t_VEC);
567: pseudomat[1]=(long)p2; pseudomat[2]=(long)vecid;
568: pid=(GEN)nfhermite(nf,pseudomat)[2];
569: p1=matid;
570: for (j=1; j<=m; j++) p1=idealmul(nf,p1,(GEN)pid[j]);
571: return p1;
572: }
573:
574: static GEN
575: normrelz(GEN id, GEN polrel, GEN steinitzZk)
576: {
577: GEN p1 = steinitzaux(idealhermite(nfz, id), polrel);
578: return idealdiv(nf,p1,steinitzZk);
579: }
580:
581: static GEN
582: invimsubgroup(GEN bnrz, GEN bnr, GEN subgroup)
583: {
584: long l,j;
585: GEN g,Plog,raycycz,rayclgpz,genraycycz,U,polrel,steinitzZk;
586:
587: polrel = computepolrel();
588: steinitzZk = steinitzaux(idmat(degKz), polrel);
589: rayclgpz = (GEN)bnrz[5];
590: raycycz = (GEN)rayclgpz[2]; l=lg(raycycz);
591: genraycycz= (GEN)rayclgpz[3];
592: Plog = cgetg(l,t_MAT);
593: for (j=1; j<l; j++)
594: {
595: g = normrelz((GEN)genraycycz[j],polrel,steinitzZk);
596: Plog[j] = (long)isprincipalray(bnr, g);
597: }
598: U = (GEN)hnfall(concatsp(Plog, subgroup))[2];
599: setlg(U, l); for (j=1; j<l; j++) setlg(U[j], l);
600: return hnfmod(concatsp(U, diagonal(raycycz)), (GEN)raycycz[1]);
601: }
602:
603: static GEN
604: ideallogaux(long i, GEN al)
605: {
606: long llogli,valal;
607: GEN p1;
608:
609: valal = element_val(nfz,al,(GEN)listprSp[i]);
610: al = gmul(al,gpuigs((GEN)listunif[i],valal));
611: p1 = zideallog(nfz,al,(GEN)listbid[i]);
612: llogli = listellrank[i];
613: setlg(p1,llogli+1); return p1;
614: }
615:
616: static GEN
617: ideallogauxsup(long i, GEN al)
618: {
619: long llogli,valal;
620: GEN p1;
621:
622: valal = element_val(nfz,al,(GEN)listprSp[i]);
623: al = gmul(al,gpuigs((GEN)listunif[i],valal));
624: p1 = zideallog(nfz,al,(GEN)listbidsup[i]);
625: llogli = listellranksup[i];
626: setlg(p1,llogli+1); return p1;
627: }
628:
629: static GEN
630: vectau(GEN list)
631: {
632: long i,j,k,n;
633: GEN listz,listc,yz,yc,listfl,s, y = cgetg(3,t_VEC);
634:
635: listz = (GEN)list[1];
636: listc = (GEN)list[2]; n = lg(listz);
637: yz = cgetg(n,t_VEC); y[1] = (long)yz;
638: yc = cgetg(n,t_VEC); y[2] = (long)yc;
639: listfl=cgetg(n,t_VECSMALL); for (i=1; i<n; i++) listfl[i] = 1;
640: k = 1;
641: for (i=1; i<n; i++)
642: {
643: if (!listfl[i]) continue;
644:
645: yz[k] = listz[i];
646: s = (GEN)listc[i];
647: for (j=i+1; j<n; j++)
648: {
649: if (listfl[j] && gegal((GEN)listz[j],(GEN)listz[i]))
650: {
651: s = gadd(s,(GEN)listc[j]);
652: listfl[j] = 0;
653: }
654: }
655: yc[k] = (long)s; k++;
656: }
657: setlg(yz, k);
658: setlg(yc, k); return y;
659: }
660:
661: static GEN
662: subtau(GEN listx, GEN listy)
663: {
664: GEN y = cgetg(3,t_VEC);
665: y[1] = (long)concatsp((GEN)listx[1], (GEN)listy[1]);
666: y[2] = (long)concatsp((GEN)listx[2], gneg_i((GEN)listy[2]));
667: return vectau(y);
668: }
669:
670: static GEN
671: negtau(GEN list)
672: {
673: GEN y = cgetg(3,t_VEC);
674: y[1] = list[1];
675: y[2] = lneg((GEN)list[2]);
676: return y;
677: }
678:
679: static GEN
680: multau(GEN listx, GEN listy)
681: {
682: GEN lzx,lzy,lcx,lcy,lzz,lcz, y = cgetg(3,t_VEC);
683: long nx,ny,i,j,k;
684:
685: lzx=(GEN)listx[1]; lcx=(GEN)listx[2]; nx=lg(lzx)-1;
686: lzy=(GEN)listy[1]; lcy=(GEN)listy[2]; ny=lg(lzy)-1;
687: lzz = cgetg(nx*ny+1,t_VEC); y[1]=(long)lzz;
688: lcz = cgetg(nx*ny+1,t_VEC); y[2]=(long)lcz;
689: k = 0;
690: for (i=1; i<=nx; i++)
691: for (j=1; j<=ny; j++)
692: {
693: k++;
694: lzz[k] = ladd((GEN)lzx[i],(GEN)lzy[j]);
695: lcz[k] = lmul((GEN)lcx[i],(GEN)lcy[j]);
696: }
697: return vectau(y);
698: }
699:
700: static GEN
701: mulpoltau(GEN poltau, GEN list)
702: {
703: long i,j;
704: GEN y;
705:
706: j = lg(poltau)-2;
707: y = cgetg(j+3,t_VEC);
708: y[1] = (long)negtau(multau(list,(GEN)poltau[1]));
709: for (i=2; i<=j+1; i++)
710: y[i] = (long)subtau((GEN)poltau[i-1],multau(list,(GEN)poltau[i]));
711: y[j+2] = poltau[j+1]; return y;
712: }
713:
714: /* th. 5.3.5. and prop. 5.3.9. */
715: static GEN
716: computepolrelbeta(GEN be)
717: {
718: long i,a,b,j;
719: GEN e,u,u1,u2,u3,p1,p2,p3,p4,zet,be1,be2,listr,s,veczi,vecci,powtaubet;
720:
721: switch (ell)
722: {
723: case 2: err(talker,"you should not be here in rnfkummer !!"); break;
724: case 3: e=normtoK(be); u=tracetoK(be);
725: return gsub(gmul(polx[0],gsub(gsqr(polx[0]),gmulsg(3,e))),gmul(e,u));
726: case 5: e=normtoK(be);
727: if (d==2)
728: {
729: u=tracetoK(gpuigs(be,3));
730: p1=gadd(gmulsg(5,gsqr(e)), gmul(gsqr(polx[0]), gsub(gsqr(polx[0]),gmulsg(5,e))));
731: return gsub(gmul(polx[0],p1),gmul(e,u));
732: }
733: else
734: {
735: be1=gsubst(lift(be),vnf,U);
736: be2=gsubst(lift(be1),vnf,U);
737: u1=tracetoK(gmul(be,be1));
738: u2=tracetoK(gmul(gmul(be,be2),gsqr(be1)));
739: u3=tracetoK(gmul(gmul(gsqr(be),gpuigs(be1,3)),be2));
740: p1=gsub(gsqr(polx[0]),gmulsg(10,e));
741: p1=gsub(gmul(polx[0],p1),gmulsg(5,gmul(e,u1)));
742: p1=gadd(gmul(polx[0],p1),gmul(gmulsg(5,e),gsub(e,u2)));
743: p1=gsub(gmul(polx[0],p1),gmul(e,u3));
744: return p1;
745: }
746: default: p1=cgetg(2,t_VEC); p2=cgetg(3,t_VEC); p3=cgetg(2,t_VEC);
747: p4=cgetg(2,t_VEC); p3[1]=zero; p4[1]=un;
748: p2[1]=(long)p3; p2[2]=(long)p4; p1[1]=(long)p2;
749: zet=gmodulcp(polx[vnf], cyclo(ell,vnf));
750: listr=cgetg(m+1,t_VEC);
751: listr[1]=un;
752: for (i=2; i<=m; i++) listr[i]=(long)modii(mulii((GEN)listr[i-1],g),gell);
753: veczi=cgetg(m+1,t_VEC);
754: for (b=0; b<m; b++)
755: {
756: s=gzero;
757: for (a=0; a<m; a++)
758: s=gadd(gmul(polx[0],s),modii(mulii((GEN)listr[b+1],(GEN)listr[a+1]),gell));
759: veczi[b+1]=(long)s;
760: }
761: for (j=0; j<ell; j++)
762: {
763: vecci=cgetg(m+1,t_VEC);
764: for (b=0; b<m; b++) vecci[b+1]=(long)gpui(zet,mulsi(j,(GEN)listr[b+1]),0);
765: p4=cgetg(3,t_VEC);
766: p4[1]=(long)veczi; p4[2]=(long)vecci;
767: p1=mulpoltau(p1,p4);
768: }
769: powtaubet=cgetg(m+1,t_VEC);
770: powtaubet[1]=(long)be;
771: for (i=2; i<=m; i++) powtaubet[i]=(long)gsubst(lift((GEN)powtaubet[i-1]),vnf,U);
772: err(impl,"difficult Kummer for ell>=7"); return gzero;
773: }
774: return NULL; /* not reached */
775: }
776:
777: static GEN
778: fix_be(GEN be, GEN u)
779: {
780: GEN e,g, nf = checknf(bnfz), fu = gmael(bnfz,8,5);
781: long i,lu;
782:
783: lu = lg(u);
784: for (i=1; i<lu; i++)
785: {
786: if (!signe(u[i])) continue;
787: e = mulsi(ell, (GEN)u[i]);
788: g = gmodulcp((GEN)fu[i],(GEN)nf[1]);
789: be = gmul(be, powgi(g, e));
790: }
791: return be;
792: }
793:
794: static GEN
795: logarch2arch(GEN x, long r1, long prec)
796: {
797: long i, lx = lg(x), tx = typ(x);
798: GEN y = cgetg(lx, tx);
799:
800: if (tx == t_MAT)
801: {
802: for (i=1; i<lx; i++) y[i] = (long)logarch2arch((GEN)x[i], r1, prec);
803: return y;
804: }
805: for (i=1; i<=r1;i++) y[i] = lexp((GEN)x[i],prec);
806: for ( ; i<lx; i++) y[i] = lexp(gmul2n((GEN)x[i],-1),prec);
807: return y;
808: }
809:
810: /* multiply be by ell-th powers of units as to find small L2-norm for new be */
811: static GEN
812: reducebetanaive(GEN be, GEN b)
813: {
814: long i,k,n,ru,r1, prec = nfgetprec(bnfz);
815: GEN z,p1,p2,nmax,c, nf = checknf(bnfz);
816:
817: if (DEBUGLEVEL) fprintferr("reduce modulo (Z_K^*)^l\n");
818: r1 = nf_get_r1(nf);
819: if (!b) b = gmul(gmael(nf,5,1), algtobasis(nf,be));
820: n = max((ell>>1), 3);
821: z = cgetg(n+1, t_VEC);
822: c = gmulgs(greal((GEN)bnfz[3]), ell);
823: c = logarch2arch(c, r1, prec); /* = embeddings of fu^ell */
824: c = gprec_w(gnorm(c), DEFAULTPREC);
825: b = gprec_w(gnorm(b), DEFAULTPREC); /* need little precision */
826: z[1] = (long)concatsp(c, vecinv(c));
827: for (k=2; k<=n; k++) z[k] = (long) vecmul((GEN)z[1], (GEN)z[k-1]);
828: nmax = T2_from_embed_norm(b, r1);
829: ru = lg(c)-1; c = zerovec(ru);
830: for(;;)
831: {
832: GEN B = NULL;
833: long besti = 0, bestk = 0;
834: for (k=1; k<=n; k++)
835: for (i=1; i<=ru; i++)
836: {
837: p1 = vecmul(b, gmael(z,k,i)); p2 = T2_from_embed_norm(p1,r1);
838: if (gcmp(p2,nmax) < 0) { B=p1; nmax=p2; besti=i; bestk = k; continue; }
839: p1 = vecmul(b, gmael(z,k,i+ru)); p2 = T2_from_embed_norm(p1,r1);
840: if (gcmp(p2,nmax) < 0) { B=p1; nmax=p2; besti=i; bestk =-k; }
841: }
842: if (!B) break;
843: b = B; c[besti] = laddis((GEN)c[besti], bestk);
844: }
845: if (DEBUGLEVEL) fprintferr("unit exponents = %Z\n",c);
846: return fix_be(be,c);
847: }
848:
849: static GEN
850: reducebeta(GEN be)
851: {
852: long j,ru, prec = nfgetprec(bnfz);
853: GEN emb,z,u,matunit, nf = checknf(bnfz);
854:
855: if (gcmp1(gnorm(be))) return reducebetanaive(be,NULL);
856: matunit = gmulgs(greal((GEN)bnfz[3]), ell); /* log. embeddings of fu^ell */
857: for (;;)
858: {
859: z = get_arch_real(nf, be, &emb, prec);
860: if (z) break;
861: prec = (prec-1)<<1;
862: if (DEBUGLEVEL) err(warnprec,"reducebeta",prec);
863: nf = nfnewprec(nf,prec);
864: }
865: z = concatsp(matunit, z);
866: u = lllintern(z, 1, prec);
867: if (!u) return reducebetanaive(be,emb); /* shouldn't occur */
868: ru = lg(u);
869: for (j=1; j<ru; j++)
870: if (smodis(gcoeff(u,ru-1,j), ell)) break; /* prime to ell */
871: u = (GEN)u[j]; /* coords on (fu^ell, be) of a small generator */
872: ru--; setlg(u, ru);
873: be = powgi(be, (GEN)u[ru]);
874: return reducebetanaive(fix_be(be, u), NULL);
875: }
876:
877: /* cf. algo 5.3.18 */
878: static GEN
879: testx(GEN bnf, GEN X, GEN module, GEN subgroup, GEN vecMsup)
880: {
881: long i,v,l,lX;
882: GEN be,polrelbe,p1;
883:
884: if (gcmp0(X)) return NULL;
885: lX = lg(X);
886: for (i=dv+1; i<lX; i++)
887: if (gcmp0((GEN)X[i])) return NULL;
888: l = lg(vecMsup);
889: for (i=1; i<l; i++)
890: if (gcmp0(FpV_red(gmul((GEN)vecMsup[i],X), gell))) return NULL;
891: be = gun;
892: for (i=1; i<lX; i++)
893: be = gmul(be, powgi((GEN)vecw[i], (GEN)X[i]));
894: if (DEBUGLEVEL>1) fprintferr("reducing beta = %Z\n",be);
895: be = reducebeta(be);
896: if (DEBUGLEVEL>1) fprintferr("beta reduced = %Z\n",be);
897: polrelbe = computepolrelbeta(be);
898: v = varn(polrelbe);
899: p1 = unifpol((GEN)bnf[7],polrelbe,0);
900: p1 = denom(gtovec(p1));
901: polrelbe = gsubst(polrelbe,v, gdiv(polx[v],p1));
902: polrelbe = gmul(polrelbe, gpowgs(p1, degpol(polrelbe)));
903: if (DEBUGLEVEL>1) fprintferr("polrelbe = %Z\n",polrelbe);
904: p1 = rnfconductor(bnf,polrelbe,0);
905: if (!gegal((GEN)p1[1],module) || !gegal((GEN)p1[3],subgroup)) return NULL;
906: return polrelbe;
907: }
908:
909: GEN
910: rnfkummer(GEN bnr, GEN subgroup, long all, long prec)
911: {
912: long i,j,l,av=avma,e,vp,vd,dK,lSl,lSp,lSl2,lSml2,dc,ru,rv,nbcol;
913: GEN p1,p2,p3,p4,wk,pr;
914: GEN bnf,rayclgp,bid,ideal,cycgen,vselmer;
915: GEN kk,clgp,fununits,torsunit,vecB,vecC,Tc,Tv,P;
916: GEN Q,Qt,idealz,gothf,factgothf,listpr,listex,factell,p,vecnul;
917: GEN M,al,K,Msup,X,finalresult,y,module,A1,A2,vecMsup;
918: GEN listmodsup,vecalphap,vecbetap,mginv,matP,ESml2,Sp,Sm,Sml1,Sml2,Sl;
919:
920: checkbnrgen(bnr);
921: wk = gmael4(bnr,1,8,4,1);
922: if (all) gell = stoi(all);
923: else
924: {
925: if (!gcmp0(subgroup)) gell = det(subgroup);
926: else gell = det(diagonal(gmael(bnr,5,2)));
927: }
928: if (gcmp1(gell)) { avma = av; return polx[varn(gmael3(bnr,1,7,1))]; }
929: if (!isprime(gell)) err(impl,"kummer for composite relative degree");
930: if (divise(wk,gell))
931: return gerepileupto(av,rnfkummersimple(bnr,subgroup,all));
932: if (all && gcmp0(subgroup))
933: err(talker,"kummer when zeta not in K requires a specific subgroup");
934: bnf = (GEN)bnr[1];
935: nf = (GEN)bnf[7];
936: polnf = (GEN)nf[1]; vnf = varn(polnf); degK = degpol(polnf);
937: if (!vnf) err(talker,"main variable in kummer must not be x");
938: /* step 7 */
939: p1 = conductor(bnr,subgroup,2);
940: /* fin step 7 */
941: bnr = (GEN)p1[2];
942: subgroup = (GEN)p1[3];
943: rayclgp = (GEN)bnr[5];
944: raycyc = (GEN)rayclgp[2];
945: bid = (GEN)bnr[2]; module=(GEN)bid[1];
946: ideal = (GEN)module[1];
947: if (gcmp0(subgroup)) subgroup = diagonal(raycyc);
948: ell = itos(gell);
949: /* step 1 of alg 5.3.5. */
950: if (DEBUGLEVEL>2) fprintferr("Step 1\n");
951:
952: p1 = (GEN)compositum2(polnf, cyclo(ell,vnf))[1];
953: R = (GEN)p1[1];
954: A1= (GEN)p1[2];
955: A2= (GEN)p1[3];
956: kk= (GEN)p1[4];
957: if (signe(leadingcoeff(R)) < 0)
958: {
959: R = gneg_i(R);
960: A1 = gmodulcp(lift(A1),R);
961: A2 = gmodulcp(lift(A2),R);
962: }
963: /* step 2 */
964: if (DEBUGLEVEL>2) fprintferr("Step 2\n");
965: degKz = degpol(R);
966: m = degKz/degK;
967: d = (ell-1)/m;
968: g = lift(gpuigs(gener(gell),d)); /* g has order m in all (Z/ell^k)^* */
969: if (gcmp1(powmodulo(g, stoi(m), stoi(ell*ell)))) g = addsi(ell,g);
970: /* step reduction of R */
971: if (degKz<=20)
972: {
973: GEN A3,A3rev;
974:
975: if (DEBUGLEVEL>2) fprintferr("Step reduction\n");
976: p1 = polredabs2(R,prec);
977: if (DEBUGLEVEL>2) fprintferr("polredabs = %Z",p1[1]);
978: R = (GEN)p1[1];
979: A3= (GEN)p1[2];
980: A1 = poleval(lift(A1), A3);
981: A2 = poleval(lift(A2), A3);
982: A3rev= polymodrecip(A3);
983: U = gadd(powgi(A2,g), gmul(kk,A1));
984: U = poleval(lift(A3rev), U);
985: }
986: else U = gadd(powgi(A2,g), gmul(kk,A1));
987: /* step 3 */
988: /* one could factor disc(R) using th. 2.1.6. */
989: if (DEBUGLEVEL>2) fprintferr("Step 3\n");
990: bnfz = bnfinit0(R,1,NULL,prec);
991: nfz = (GEN)bnfz[7];
992: clgp = gmael(bnfz,8,1);
993: cyc = (GEN)clgp[2]; rc = ellrank(cyc,ell);
994: gencyc= (GEN)clgp[3]; l = lg(cyc);
995: vecalpha=cgetg(l,t_VEC);
996: cycgen = check_and_build_cycgen(bnfz);
997: for (j=1; j<l; j++)
998: vecalpha[j] = (long)basistoalg(nfz, famat_to_nf(nfz, (GEN)cycgen[j]));
999: /* computation of the uu(j) (see remark 5.2.15.) */
1000: uu = cgetg(l,t_VEC);
1001: for (j=1; j<=rc; j++) uu[j] = zero;
1002: for ( ; j< l; j++) uu[j] = lmpinvmod((GEN)cyc[j], gell);
1003:
1004: fununits = check_units(bnfz,"rnfkummer");
1005: torsunit = gmael3(bnfz,8,4,2);
1006: ru=(degKz>>1)-1;
1007: rv=rc+ru+1;
1008: vselmer = cgetg(rv+1,t_VEC);
1009: for (j=1; j<=rc; j++) vselmer[j] = vecalpha[j];
1010: for ( ; j< rv; j++) vselmer[j] = lmodulcp((GEN)fununits[j-rc],R);
1011: vselmer[rv]=(long)gmodulcp((GEN)torsunit,R);
1012: /* step 4 */
1013: if (DEBUGLEVEL>2) fprintferr("Step 4\n");
1014: vecB=cgetg(rc+1,t_VEC);
1015: Tc=cgetg(rc+1,t_MAT);
1016: for (j=1; j<=rc; j++)
1017: {
1018: p1 = isprincipalell(tauofideal((GEN)gencyc[j]));
1019: Tc[j] = p1[1];
1020: vecB[j]= p1[2];
1021: }
1022: p1=cgetg(m,t_VEC);
1023: p1[1]=(long)idmat(rc);
1024: for (j=2; j<=m-1; j++) p1[j]=lmul((GEN)p1[j-1],Tc);
1025: p2=cgetg(rc+1,t_VEC);
1026: for (j=1; j<=rc; j++) p2[j]=un;
1027: p3=vecB;
1028: for (j=1; j<=m-1; j++)
1029: {
1030: p3 = gsubst(lift(p3),vnf,U);
1031: p4 = groupproduct(grouppows(p3,(j*d)%ell),(GEN)p1[m-j]);
1032: for (i=1; i<=rc; i++) p2[i] = lmul((GEN)p2[i],(GEN)p4[i]);
1033: }
1034: vecC=p2;
1035: /* step 5 */
1036: if (DEBUGLEVEL>2) fprintferr("Step 5\n");
1037: Tv = cgetg(rv+1,t_MAT);
1038: for (j=1; j<=rv; j++)
1039: {
1040: Tv[j] = isvirtualunit(gsubst(lift((GEN)vselmer[j]),vnf,U))[1];
1041: if (DEBUGLEVEL>2) fprintferr(" %ld\n",j);
1042: }
1043: P = FpM_ker(gsub(Tv, g), gell);
1044: dv= lg(P)-1; vecw = cgetg(dv+1,t_VEC);
1045: for (j=1; j<=dv; j++)
1046: {
1047: p1 = gun;
1048: for (i=1; i<=rv; i++) p1 = gmul(p1, powgi((GEN)vselmer[i],gcoeff(P,i,j)));
1049: vecw[j] = (long)p1;
1050: }
1051: /* step 6 */
1052: if (DEBUGLEVEL>2) fprintferr("Step 6\n");
1053: Q = FpM_ker(gsub(gtrans(Tc), g), gell);
1054: Qt = gtrans(Q); dc = lg(Q)-1;
1055: /* step 7 done above */
1056: /* step 8 */
1057: if (DEBUGLEVEL>2) fprintferr("Step 7 and 8\n");
1058: idealz=lifttokz(ideal, A1);
1059: computematexpoteta1(lift(A1), R);
1060: if (!divise(idealnorm(nf,ideal),gell)) gothf = idealz;
1061: else
1062: {
1063: GEN bnrz, subgroupz;
1064: bnrz = buchrayinitgen(bnfz,idealz);
1065: subgroupz = invimsubgroup(bnrz,bnr,subgroup);
1066: gothf = conductor(bnrz,subgroupz,0);
1067: }
1068: /* step 9 */
1069: if (DEBUGLEVEL>2) fprintferr("Step 9\n");
1070: factgothf=idealfactor(nfz,gothf);
1071: listpr = (GEN)factgothf[1];
1072: listex = (GEN)factgothf[2]; l = lg(listpr);
1073: /* step 10 and step 11 */
1074: if (DEBUGLEVEL>2) fprintferr("Step 10 and 11\n");
1075: Sm = cgetg(l,t_VEC); setlg(Sm,1);
1076: Sml1= cgetg(l,t_VEC); setlg(Sml1,1);
1077: Sml2= cgetg(l,t_VEC); setlg(Sml2,1);
1078: Sl = cgetg(l+degKz,t_VEC); setlg(Sl,1);
1079: ESml2=cgetg(l,t_VECSMALL); setlg(ESml2,1);
1080: for (i=1; i<l; i++)
1081: {
1082: pr = (GEN)listpr[i]; p = (GEN)pr[1]; e = itos((GEN)pr[3]);
1083: vp = itos((GEN)listex[i]);
1084: if (!egalii(p,gell))
1085: {
1086: if (vp != 1) { avma = av; return gzero; }
1087: if (!isconjinprimelist(Sm,pr)) _append(Sm,pr);
1088: }
1089: else
1090: {
1091: vd = (vp-1)*(ell-1)-ell*e;
1092: if (vd > 0) { avma = av; return gzero; }
1093: if (vd==0)
1094: {
1095: if (!isconjinprimelist(Sml1,pr)) _append(Sml1, pr);
1096: }
1097: else
1098: {
1099: if (vp==1) { avma = av; return gzero; }
1100: if (!isconjinprimelist(Sml2,pr))
1101: {
1102: _append(Sml2, pr);
1103: _append(ESml2,(GEN)vp);
1104: }
1105: }
1106: }
1107: }
1108: factell = primedec(nfz,gell); l = lg(factell);
1109: for (i=1; i<l; i++)
1110: {
1111: pr = (GEN)factell[i];
1112: if (!idealval(nfz,gothf,pr))
1113: if (!isconjinprimelist(Sl,pr)) _append(Sl, pr);
1114: }
1115: lSml2=lg(Sml2)-1; lSl=lg(Sl)-1; lSl2=lSml2+lSl;
1116: Sp=concatsp(Sm,Sml1); lSp=lg(Sp)-1;
1117: /* step 12 */
1118: if (DEBUGLEVEL>2) fprintferr("Step 12\n");
1119: vecbetap=cgetg(lSp+1,t_VEC);
1120: vecalphap=cgetg(lSp+1,t_VEC);
1121: matP=cgetg(lSp+1,t_MAT);
1122: for (j=1; j<=lSp; j++)
1123: {
1124: p1=isprincipalell((GEN)Sp[j]);
1125: matP[j]=p1[1];
1126: p2=gun;
1127: for (i=1; i<=rc; i++)
1128: p2 = gmul(p2, powgi((GEN)vecC[i],gmael(p1,1,i)));
1129: p3=gdiv((GEN)p1[2],p2); vecbetap[j]=(long)p3;
1130: p2=gun;
1131: for (i=0; i<m; i++)
1132: {
1133: p2 = gmul(p2, powgi(p3, powmodulo(g,stoi(m-1-i),gell)));
1134: if (i<m-1) p3=gsubst(lift(p3),vnf,U);
1135: }
1136: vecalphap[j]=(long)p2;
1137: }
1138: /* step 13 */
1139: if (DEBUGLEVEL>2) fprintferr("Step 13\n");
1140: nbcol=lSp+dv;
1141: vecw=concatsp(vecw,vecbetap);
1142: listmod=cgetg(lSl2+1,t_VEC);
1143: listunif=cgetg(lSl2+1,t_VEC);
1144: listprSp = concatsp(Sml2, Sl);
1145: for (j=1; j<=lSl2; j++)
1146: {
1147: GEN pr = (GEN)listprSp[j];
1148: long e = itos((GEN)pr[3]), z = ell * (e / (ell-1));
1149: if (j <= lSml2) z += 1 - ESml2[j];
1150: listmod[j]=(long)idealpows(nfz,pr, z);
1151: listunif[j]=(long)basistoalg(nfz,gdiv((GEN)pr[5],(GEN)pr[1]));
1152: }
1153: /* step 14 and step 15 */
1154: if (DEBUGLEVEL>2) fprintferr("Step 14 and 15\n");
1155: listbid=cgetg(lSl2+1,t_VEC);
1156: listellrank = cgetg(lSl2+1,t_VECSMALL);
1157: for (i=1; i<=lSl2; i++)
1158: {
1159: listbid[i]=(long)zidealstarinitgen(nfz,(GEN)listmod[i]);
1160: listellrank[i] = ellrank(gmael3(listbid,i,2,2), ell);
1161: }
1162: mginv = modii(mulsi(m, mpinvmod(g,gell)), gell);
1163: vecnul=cgetg(dc+1,t_COL); for (i=1; i<=dc; i++) vecnul[i]=zero;
1164: M=cgetg(nbcol+1,t_MAT);
1165: for (j=1; j<=dv; j++)
1166: {
1167: p1=cgetg(1,t_COL);
1168: al=(GEN)vecw[j];
1169: for (i=1; i<=lSl2; i++) p1 = concatsp(p1,ideallogaux(i,al));
1170: p1=gmul(mginv,p1);
1171: M[j]=(long)concatsp(p1,vecnul);
1172: }
1173: for ( ; j<=nbcol; j++)
1174: {
1175: p1=cgetg(1,t_COL);
1176: al=(GEN)vecalphap[j-dv];
1177: for (i=1; i<=lSl2; i++) p1 = concatsp(p1,ideallogaux(i,al));
1178: M[j]=(long)concatsp(p1,gmul(Qt,(GEN)matP[j-dv]));
1179: }
1180: /* step 16 */
1181: if (DEBUGLEVEL>2) fprintferr("Step 16\n");
1182: K = FpM_ker(M, gell);
1183: dK= lg(K)-1; if (!dK) { avma=av; return gzero; }
1184: /* step 17 */
1185: if (DEBUGLEVEL>2) fprintferr("Step 17\n");
1186: listmodsup=cgetg(lSml2+1,t_VEC);
1187: listbidsup=cgetg(lSml2+1,t_VEC);
1188: listellranksup=cgetg(lSml2+1,t_VECSMALL);
1189: for (i=1; i<=lSml2; i++)
1190: {
1191: listmodsup[i]=(long)idealmul(nfz,(GEN)listprSp[i],(GEN)listmod[i]);
1192: listbidsup[i]=(long)zidealstarinitgen(nfz,(GEN)listmodsup[i]);
1193: listellranksup[i] = ellrank(gmael3(listbidsup,i,2,2), ell);
1194: }
1195: vecMsup=cgetg(lSml2+1,t_VEC);
1196: for (i=1; i<=lSml2; i++)
1197: {
1198: Msup=cgetg(nbcol+1,t_MAT); vecMsup[i]=(long)Msup;
1199: for (j=1; j<=dv; j++) Msup[j]=lmul(mginv,ideallogauxsup(i,(GEN)vecw[j]));
1200: for ( ; j<=nbcol; j++) Msup[j]=(long)ideallogauxsup(i,(GEN)vecalphap[j-dv]);
1201: }
1202: /* step 18 */
1203: if (DEBUGLEVEL>2) fprintferr("Step 18\n");
1204: do
1205: {
1206: y = cgetg(dK,t_VECSMALL);
1207: for (i=1; i<dK; i++) y[i] = 0;
1208: /* step 19 */
1209: for(;;)
1210: {
1211: X = (GEN)K[dK];
1212: for (j=1; j<dK; j++) X = gadd(X, gmulsg(y[j],(GEN)K[j]));
1213: X = FpV_red(X, gell);
1214: finalresult = testx(bnf,X,module,subgroup,vecMsup);
1215: if (finalresult) return gerepilecopy(av, finalresult);
1216: /* step 20,21,22 */
1217: i = dK;
1218: do
1219: {
1220: i--; if (!i) goto DECREASE;
1221: if (i < dK-1) y[i+1] = 0;
1222: y[i]++;
1223: } while (y[i] >= ell);
1224: }
1225: DECREASE:
1226: dK--;
1227: }
1228: while (dK);
1229: avma = av; return gzero;
1230: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>