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