[BACK]Return to base1.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / pari-2.2 / src / basemath

Annotation of OpenXM_contrib/pari-2.2/src/basemath/base1.c, Revision 1.1.1.1

1.1       noro        1: /* $Id: base1.c,v 1.41 2001/10/01 12:11:28 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: /*                        NUMBER FIELDS                       */
                     19: /*                                                            */
                     20: /**************************************************************/
                     21: #include "pari.h"
                     22: #include "parinf.h"
                     23: GEN idealhermite_aux(GEN nf, GEN x);
                     24:
                     25: void
                     26: checkrnf(GEN rnf)
                     27: {
                     28:   if (typ(rnf)!=t_VEC) err(idealer1);
                     29:   if (lg(rnf)!=12) err(idealer1);
                     30: }
                     31:
                     32: GEN
                     33: checkbnf(GEN bnf)
                     34: {
                     35:   if (typ(bnf)!=t_VEC) err(idealer1);
                     36:   switch (lg(bnf))
                     37:   {
                     38:     case 11: return bnf;
                     39:     case 10:
                     40:       if (typ(bnf[1])==t_POL)
                     41:         err(talker,"please apply bnfinit first");
                     42:       break;
                     43:     case 7:
                     44:       return checkbnf((GEN)bnf[1]);
                     45:
                     46:     case 3:
                     47:       if (typ(bnf[2])==t_POLMOD)
                     48:         return checkbnf((GEN)bnf[1]);
                     49:   }
                     50:   err(idealer1);
                     51:   return NULL; /* not reached */
                     52: }
                     53:
                     54: GEN
                     55: checkbnf_discard(GEN bnf)
                     56: {
                     57:   GEN x = checkbnf(bnf);
                     58:   if (x != bnf && lg(bnf) == 3)
                     59:     err(warner,"non-monic polynomial. Change of variables discarded");
                     60:   return x;
                     61: }
                     62:
                     63: GEN
                     64: checknf(GEN nf)
                     65: {
                     66:   if (typ(nf)==t_POL) err(talker,"please apply nfinit first");
                     67:   if (typ(nf)!=t_VEC) err(idealer1);
                     68:   switch(lg(nf))
                     69:   {
                     70:     case 10: return nf;
                     71:     case 11: return checknf((GEN)nf[7]);
                     72:     case 7:  return checknf((GEN)nf[1]);
                     73:     case 3: if (typ(nf[2]) == t_POLMOD) return checknf((GEN)nf[1]);
                     74:   }
                     75:   err(idealer1);
                     76:   return NULL; /* not reached */
                     77: }
                     78:
                     79: void
                     80: checkbnr(GEN bnr)
                     81: {
                     82:   if (typ(bnr)!=t_VEC || lg(bnr)!=7)
                     83:     err(talker,"incorrect bigray field");
                     84:   (void)checkbnf((GEN)bnr[1]);
                     85: }
                     86:
                     87: void
                     88: checkbnrgen(GEN bnr)
                     89: {
                     90:   checkbnr(bnr);
                     91:   if (lg(bnr[5])<=3)
                     92:     err(talker,"please apply bnrinit(,,1) and not bnrinit(,)");
                     93: }
                     94:
                     95: GEN
                     96: check_units(GEN bnf, char *f)
                     97: {
                     98:   GEN nf, x;
                     99:   bnf = checkbnf(bnf); nf = checknf(bnf);
                    100:   x = (GEN)bnf[8];
                    101:   if (lg(x) < 7 || (lg(x[5]) == 1 && lg(nf[6]) > 2))
                    102:     err(talker,"missing units in %s", f);
                    103:   return (GEN)x[5];
                    104: }
                    105:
                    106: void
                    107: checkid(GEN x, long N)
                    108: {
                    109:   if (typ(x)!=t_MAT) err(idealer2);
                    110:   if (lg(x) == 1 || lg(x[1]) != N+1)
                    111:     err(talker,"incorrect matrix for ideal");
                    112: }
                    113:
                    114: void
                    115: checkbid(GEN bid)
                    116: {
                    117:   if (typ(bid)!=t_VEC || lg(bid)!=6 || lg(bid[1])!=3)
                    118:     err(talker,"incorrect bigideal");
                    119: }
                    120:
                    121: void
                    122: checkprimeid(GEN id)
                    123: {
                    124:   if (typ(id) != t_VEC || lg(id) != 6)
                    125:     err(talker,"incorrect prime ideal");
                    126: }
                    127:
                    128: void
                    129: checkprhall(GEN prhall)
                    130: {
                    131:   if (typ(prhall) != t_VEC || lg(prhall) != 3 || typ(prhall[1]) != t_MAT)
                    132:     err(talker,"incorrect prhall format");
                    133: }
                    134:
                    135: void
                    136: check_pol_int(GEN x, char *s)
                    137: {
                    138:   long k = lgef(x)-1;
                    139:   for ( ; k>1; k--)
                    140:     if (typ(x[k])!=t_INT) err(talker,"polynomial not in Z[X] in %s",s);
                    141: }
                    142:
                    143: GEN
                    144: checknfelt_mod(GEN nf, GEN x, char *s)
                    145: {
                    146:   if (!gegal((GEN)x[1],(GEN)nf[1]))
                    147:     err(talker,"incompatible modulus in %s:\n  mod = %Z,\n  nf  = %Z",
                    148:         s, x[1], nf[1]);
                    149:   return (GEN)x[2];
                    150: }
                    151:
                    152: GEN
                    153: get_primeid(GEN x)
                    154: {
                    155:   if (typ(x) != t_VEC) return NULL;
                    156:   if (lg(x) == 3) x = (GEN)x[1];
                    157:   if (lg(x) != 6 || typ(x[3]) != t_INT) return NULL;
                    158:   return x;
                    159: }
                    160:
                    161: GEN
                    162: get_bnf(GEN x, int *t)
                    163: {
                    164:   switch(typ(x))
                    165:   {
                    166:     case t_POL: *t = typ_POL;  return NULL;
                    167:     case t_QUAD: *t = typ_Q  ; return NULL;
                    168:     case t_VEC:
                    169:       switch(lg(x))
                    170:       {
                    171:         case 3:
                    172:           if (typ(x[2]) != t_POLMOD) break;
                    173:           return get_bnf((GEN)x[1],t);
                    174:         case 6 : *t = typ_QUA; return NULL;
                    175:         case 10: *t = typ_NF; return NULL;
                    176:         case 11: *t = typ_BNF; return x;
                    177:         case 7 : *t = typ_BNR;
                    178:           x = (GEN)x[1]; if (typ(x)!=t_VEC || lg(x)!=11) break;
                    179:           return x;
                    180:       }
                    181:     case t_MAT:
                    182:       if (lg(x)==2)
                    183:         switch(lg(x[1]))
                    184:         {
                    185:           case 8: case 11:
                    186:             *t = typ_CLA; return NULL;
                    187:         }
                    188:   }
                    189:   *t = typ_NULL; return NULL;
                    190: }
                    191:
                    192: GEN
                    193: get_nf(GEN x, int *t)
                    194: {
                    195:   switch(typ(x))
                    196:   {
                    197:     case t_POL : *t = typ_POL; return NULL;
                    198:     case t_QUAD: *t = typ_Q  ; return NULL;
                    199:     case t_VEC:
                    200:       switch(lg(x))
                    201:       {
                    202:         case 3:
                    203:           if (typ(x[2]) != t_POLMOD) break;
                    204:           return get_nf((GEN)x[1],t);
                    205:         case 10: *t = typ_NF; return x;
                    206:         case 11: *t = typ_BNF;
                    207:           x = (GEN)x[7]; if (typ(x)!=t_VEC || lg(x)!=10) break;
                    208:           return x;
                    209:         case 7 : *t = typ_BNR;
                    210:           x = (GEN)x[1]; if (typ(x)!=t_VEC || lg(x)!=11) break;
                    211:           x = (GEN)x[7]; if (typ(x)!=t_VEC || lg(x)!=10) break;
                    212:           return x;
                    213:         case 9 :
                    214:           x = (GEN)x[2];
                    215:           if (typ(x) == t_VEC && lg(x) == 4) *t = typ_GAL;
                    216:          return NULL;
                    217:         case 14: case 20:
                    218:           *t = typ_ELL; return NULL;
                    219:       }break;
                    220:     case t_MAT:
                    221:       if (lg(x)==2)
                    222:         switch(lg(x[1]))
                    223:         {
                    224:           case 8: case 11:
                    225:             *t = typ_CLA; return NULL;
                    226:         }
                    227:   }
                    228:   *t = typ_NULL; return NULL;
                    229: }
                    230:
                    231: /*************************************************************************/
                    232: /**                                                                    **/
                    233: /**                           GALOIS GROUP                             **/
                    234: /**                                                                    **/
                    235: /*************************************************************************/
                    236:
                    237: /* exchange elements i and j in vector x */
                    238: static GEN
                    239: transroot(GEN x, int i, int j)
                    240: {
                    241:   long k;
                    242:   x = dummycopy(x);
                    243:   k=x[i]; x[i]=x[j]; x[j]=k; return x;
                    244: }
                    245:
                    246: #define randshift (BITS_IN_RANDOM - 3)
                    247:
                    248: GEN
                    249: tschirnhaus(GEN x)
                    250: {
                    251:   long a, v = varn(x), av = avma;
                    252:   GEN u, p1 = cgetg(5,t_POL);
                    253:
                    254:   if (typ(x)!=t_POL) err(notpoler,"tschirnhaus");
                    255:   if (lgef(x) < 4) err(constpoler,"tschirnhaus");
                    256:   if (v) { u=dummycopy(x); setvarn(u,0); x=u; }
                    257:   p1[1] = evalsigne(1)|evalvarn(0)|evallgef(5);
                    258:   do
                    259:   {
                    260:     a = mymyrand() >> randshift; if (a==0) a =1; p1[4]=lstoi(a);
                    261:     a = mymyrand() >> (randshift-1); if (a>=4) a-=8; p1[3]=lstoi(a);
                    262:     a = mymyrand() >> (randshift-1); if (a>=4) a-=8; p1[2]=lstoi(a);
                    263:     u = caract2(x,p1,v); a=avma;
                    264:   }
                    265:   while (lgef(srgcd(u,derivpol(u))) > 3); /* while u not separable */
                    266:   if (DEBUGLEVEL>1)
                    267:     fprintferr("Tschirnhaus transform. New pol: %Z",u);
                    268:   avma=a; return gerepileupto(av,u);
                    269: }
                    270: #undef randshift
                    271:
                    272: int
                    273: gpolcomp(GEN p1, GEN p2)
                    274: {
                    275:   int s,j = lgef(p1)-2;
                    276:
                    277:   if (lgef(p2)-2 != j)
                    278:     err(bugparier,"gpolcomp (different degrees)");
                    279:   for (; j>=2; j--)
                    280:   {
                    281:     s = absi_cmp((GEN)p1[j], (GEN)p2[j]);
                    282:     if (s) return s;
                    283:   }
                    284:   return 0;
                    285: }
                    286:
                    287: /* assume pol in Z[X] */
                    288: GEN
                    289: primitive_pol_to_monic(GEN pol, GEN *ptlead)
                    290: {
                    291:   long i,j,n = degpol(pol);
                    292:   GEN lead,fa,e,a, POL = dummycopy(pol);
                    293:
                    294:   a = POL + 2; lead = (GEN)a[n];
                    295:   if (signe(lead) < 0) { POL = gneg_i(POL); a = POL+2; lead = negi(lead); }
                    296:   if (is_pm1(lead)) { if (ptlead) *ptlead = NULL; return POL; }
                    297:   fa = auxdecomp(lead,0); lead = gun;
                    298:   e = (GEN)fa[2]; fa = (GEN)fa[1];
                    299:   for (i=lg(e)-1; i>0;i--) e[i] = itos((GEN)e[i]);
                    300:   for (i=lg(fa)-1; i>0; i--)
                    301:   {
                    302:     GEN p = (GEN)fa[i], p1,pk,pku;
                    303:     long k = (long)ceil((double)e[i] / n);
                    304:     long d = k * n - e[i], v, j0;
                    305:     /* find d, k such that  p^d pol(x / p^k) monic */
                    306:     for (j=n-1; j>0; j--)
                    307:     {
                    308:       if (!signe(a[j])) continue;
                    309:       v = pvaluation((GEN)a[j], p, &p1);
                    310:       while (v + d < k * j) { k++; d += n; }
                    311:     }
                    312:     pk = gpowgs(p,k); j0 = d/k;
                    313:     pku = gpowgs(p,d - k*j0);
                    314:     /* a[j] *= p^(d - kj) */
                    315:     for (j=j0; j>=0; j--)
                    316:     {
                    317:       if (j < j0) pku = mulii(pku, pk);
                    318:       a[j] = lmulii((GEN)a[j], pku);
                    319:     }
                    320:     j0++;
                    321:     pku = gpowgs(p,k*j0 - d);
                    322:     /* a[j] /= p^(kj - d) */
                    323:     for (j=j0; j<=n; j++)
                    324:     {
                    325:       if (j > j0) pku = mulii(pku, pk);
                    326:       a[j] = ldivii((GEN)a[j], pku);
                    327:     }
                    328:     lead = mulii(lead, pk);
                    329:   }
                    330:   if (ptlead) *ptlead = lead; return POL;
                    331: }
                    332:
                    333: /* compute x1*x2^2 + x2*x3^2 + x3*x4^2 + x4*x1^2 */
                    334: static GEN
                    335: get_F4(GEN x)
                    336: {
                    337:   GEN p1=gzero;
                    338:   long i;
                    339:
                    340:   for (i=1; i<=4; i++)
                    341:     p1 = gadd(p1, gmul((GEN)x[i], gsqr((GEN)x[(i&3)+1])));
                    342:   return p1;
                    343: }
                    344:
                    345: GEN galoisbig(GEN x, long prec);
                    346: GEN roots_to_pol(GEN a, long v);
                    347:
                    348: GEN
                    349: galois(GEN x, long prec)
                    350: {
                    351:   long av=avma,av1,i,j,k,n,f,l,l2,e,e1,pr,ind;
                    352:   GEN x1,p1,p2,p3,p4,p5,p6,w,y,z,ee;
                    353:   static int ind5[20]={2,5,3,4, 1,3,4,5, 1,5,2,4, 1,2,3,5, 1,4,2,3};
                    354:   static int ind6[60]={3,5,4,6, 2,6,4,5, 2,3,5,6, 2,4,3,6, 2,5,3,4,
                    355:                        1,4,5,6, 1,5,3,6, 1,6,3,4, 1,3,4,5, 1,6,2,5,
                    356:                        1,2,4,6, 1,5,2,4, 1,3,2,6, 1,2,3,5, 1,4,2,3};
                    357:   if (typ(x)!=t_POL) err(notpoler,"galois");
                    358:   n=degpol(x); if (n<=0) err(constpoler,"galois");
                    359:   if (n>11) err(impl,"galois of degree higher than 11");
                    360:   x = gdiv(x,content(x));
                    361:   check_pol_int(x, "galois");
                    362:   if (gisirreducible(x) != gun)
                    363:     err(impl,"galois of reducible polynomial");
                    364:
                    365:   if (n<4)
                    366:   {
                    367:     if (n<3)
                    368:     {
                    369:       avma=av; y=cgetg(4,t_VEC);
                    370:       y[1] = (n==1)? un: deux;
                    371:       y[2]=lnegi(gun);
                    372:     }
                    373:     else /* n=3 */
                    374:     {
                    375:       f=carreparfait(discsr(x));
                    376:       avma=av; y=cgetg(4,t_VEC);
                    377:       if (f) { y[1]=lstoi(3); y[2]=un; }
                    378:       else   { y[1]=lstoi(6); y[2]=lnegi(gun); }
                    379:     }
                    380:     y[3]=un; return y;
                    381:   }
                    382:   x1 = x = primitive_pol_to_monic(x,NULL); av1=avma;
                    383:   if (n>7) return galoisbig(x,prec);
                    384:   for(;;)
                    385:   {
                    386:     switch(n)
                    387:     {
                    388:       case 4: z = cgetg(7,t_VEC);
                    389:         for(;;)
                    390:        {
                    391:          p1=roots(x,prec);
                    392:           z[1] = (long)get_F4(p1);
                    393:           z[2] = (long)get_F4(transroot(p1,1,2));
                    394:           z[3] = (long)get_F4(transroot(p1,1,3));
                    395:           z[4] = (long)get_F4(transroot(p1,1,4));
                    396:           z[5] = (long)get_F4(transroot(p1,2,3));
                    397:           z[6] = (long)get_F4(transroot(p1,3,4));
                    398:           p4 = roots_to_pol(z,0);
                    399:           p5=grndtoi(greal(p4),&e);
                    400:           e1=gexpo(gimag(p4)); if (e1>e) e=e1;
                    401:           if (e <= -10) break;
                    402:          prec = (prec<<1)-2;
                    403:        }
                    404:        p6 = modulargcd(p5, derivpol(p5));
                    405:        if (typ(p6)==t_POL && lgef(p6)>3) goto tchi;
                    406:        p2 = (GEN)factor(p5)[1];
                    407:        switch(lg(p2)-1)
                    408:        {
                    409:          case 1: f=carreparfait(discsr(x)); avma=av; y=cgetg(4,t_VEC);
                    410:            y[3]=un;
                    411:            if (f) { y[2]=un; y[1]=lstoi(12); return y; }
                    412:            y[2]=lnegi(gun); y[1]=lstoi(24); return y;
                    413:
                    414:          case 2: avma=av; y=cgetg(4,t_VEC);
                    415:            y[3]=un; y[2]=lnegi(gun); y[1]=lstoi(8); return y;
                    416:
                    417:          case 3: avma=av; y=cgetg(4,t_VEC);
                    418:            y[1]=lstoi(4); y[3]=un;
                    419:            y[2] = (lgef(p2[1])==5)? un: lnegi(gun);
                    420:            return y;
                    421:
                    422:          default: err(bugparier,"galois (bug1)");
                    423:        }
                    424:
                    425:       case 5: z = cgetg(7,t_VEC);
                    426:         ee = new_chunk(7); w = new_chunk(7);
                    427:         for(;;)
                    428:        {
                    429:           for(;;)
                    430:          {
                    431:            p1=roots(x,prec);
                    432:            for (l=1; l<=6; l++)
                    433:            {
                    434:              p2=(l==1)?p1: ((l<6)?transroot(p1,1,l): transroot(p1,2,5));
                    435:              p3=gzero;
                    436:               for (k=0,i=1; i<=5; i++,k+=4)
                    437:              {
                    438:                p5 = gadd(gmul((GEN)p2[ind5[k]],(GEN)p2[ind5[k+1]]),
                    439:                          gmul((GEN)p2[ind5[k+2]],(GEN)p2[ind5[k+3]]));
                    440:                p3 = gadd(p3, gmul(gsqr((GEN)p2[i]),p5));
                    441:              }
                    442:              w[l]=lrndtoi(greal(p3),&e);
                    443:               e1 = gexpo(gimag(p3)); if (e1>e) e=e1;
                    444:               ee[l]=e; z[l] = (long)p3;
                    445:            }
                    446:             p4 = roots_to_pol(z,0);
                    447:            p5=grndtoi(greal(p4),&e);
                    448:             e1 = gexpo(gimag(p4)); if (e1>e) e=e1;
                    449:             if (e <= -10) break;
                    450:            prec = (prec<<1)-2;
                    451:          }
                    452:          p6 = modulargcd(p5,derivpol(p5));
                    453:          if (typ(p6)==t_POL && lgef(p6)>3) goto tchi;
                    454:          p3=(GEN)factor(p5)[1];
                    455:          f=carreparfait(discsr(x));
                    456:          if (lg(p3)-1==1)
                    457:          {
                    458:            avma=av; y=cgetg(4,t_VEC); y[3]=un;
                    459:            if (f) { y[2]=un; y[1]=lstoi(60); return y; }
                    460:            else { y[2]=lneg(gun); y[1]=lstoi(120); return y; }
                    461:          }
                    462:          if (!f)
                    463:          {
                    464:            avma=av; y=cgetg(4,t_VEC);
                    465:            y[3]=un; y[2]=lneg(gun); y[1]=lstoi(20); return y;
                    466:          }
                    467:           pr = - (bit_accuracy(prec) >> 1);
                    468:           for (l=1; l<=6; l++)
                    469:            if (ee[l] <= pr && gcmp0(poleval(p5,(GEN)w[l]))) break;
                    470:          if (l>6) err(bugparier,"galois (bug4)");
                    471:          p2=(l==6)? transroot(p1,2,5):transroot(p1,1,l);
                    472:          p3=gzero;
                    473:          for (i=1; i<=5; i++)
                    474:          {
                    475:            j=(i%5)+1;
                    476:            p3=gadd(p3,gmul(gmul((GEN)p2[i],(GEN)p2[j]),
                    477:                            gsub((GEN)p2[j],(GEN)p2[i])));
                    478:          }
                    479:          p5=gsqr(p3); p4=grndtoi(greal(p5),&e);
                    480:           e1 = gexpo(gimag(p5)); if (e1>e) e=e1;
                    481:          if (e <= -10)
                    482:          {
                    483:            if (gcmp0(p4)) goto tchi;
                    484:            f=carreparfait(p4); avma=av; y=cgetg(4,t_VEC);
                    485:            y[3]=y[2]=un; y[1]=lstoi(f?5:10);
                    486:            return y;
                    487:          }
                    488:          prec=(prec<<1)-2;
                    489:        }
                    490:
                    491:       case 6: z = cgetg(7, t_VEC);
                    492:         for(;;)
                    493:        {
                    494:           for(;;)
                    495:          {
                    496:            p1=roots(x,prec);
                    497:            for (l=1; l<=6; l++)
                    498:            {
                    499:              p2=(l==1)?p1:transroot(p1,1,l);
                    500:              p3=gzero; k=0;
                    501:               for (i=1; i<=5; i++) for (j=i+1; j<=6; j++)
                    502:              {
                    503:                p5=gadd(gmul((GEN)p2[ind6[k]],(GEN)p2[ind6[k+1]]),
                    504:                        gmul((GEN)p2[ind6[k+2]],(GEN)p2[ind6[k+3]]));
                    505:                p3=gadd(p3,gmul(gsqr(gmul((GEN)p2[i],(GEN)p2[j])),p5)); k+=4;
                    506:              }
                    507:              z[l] = (long)p3;
                    508:            }
                    509:             p4=roots_to_pol(z,0);
                    510:            p5=grndtoi(greal(p4),&e);
                    511:             e1 = gexpo(gimag(p4)); if (e1>e) e=e1;
                    512:             if (e <= -10) break;
                    513:            prec=(prec<<1)-2;
                    514:          }
                    515:          p6 = modulargcd(p5,derivpol(p5));
                    516:          if (typ(p6)==t_POL && lgef(p6)>3) goto tchi;
                    517:          p2=(GEN)factor(p5)[1];
                    518:          switch(lg(p2)-1)
                    519:          {
                    520:            case 1:
                    521:               z = cgetg(11,t_VEC); ind=0;
                    522:              p3=gadd(gmul(gmul((GEN)p1[1],(GEN)p1[2]),(GEN)p1[3]),
                    523:                      gmul(gmul((GEN)p1[4],(GEN)p1[5]),(GEN)p1[6]));
                    524:               z[++ind] = (long)p3;
                    525:              for (i=1; i<=3; i++)
                    526:                for (j=4; j<=6; j++)
                    527:                {
                    528:                  p2=transroot(p1,i,j);
                    529:                  p3=gadd(gmul(gmul((GEN)p2[1],(GEN)p2[2]),(GEN)p2[3]),
                    530:                          gmul(gmul((GEN)p2[4],(GEN)p2[5]),(GEN)p2[6]));
                    531:                  z[++ind] = (long)p3;
                    532:                }
                    533:               p4 = roots_to_pol(z,0);
                    534:              p5=grndtoi(greal(p4),&e);
                    535:               e1 = gexpo(gimag(p4)); if (e1>e) e=e1;
                    536:              if (e <= -10)
                    537:              {
                    538:                p6 = modulargcd(p5,derivpol(p5));
                    539:                if (typ(p6)==t_POL && lgef(p6)>3) goto tchi;
                    540:                p2=(GEN)factor(p5)[1];
                    541:                f=carreparfait(discsr(x));
                    542:                avma=av; y=cgetg(4,t_VEC); y[3]=un;
                    543:                if (lg(p2)-1==1)
                    544:                {
                    545:                  if (f) { y[2]=un; y[1]=lstoi(360); }
                    546:                  else { y[2]=lnegi(gun); y[1]=lstoi(720); }
                    547:                }
                    548:                else
                    549:                {
                    550:                  if (f) { y[2]=un; y[1]=lstoi(36); }
                    551:                  else { y[2]=lnegi(gun); y[1]=lstoi(72); }
                    552:                }
                    553:                 return y;
                    554:              }
                    555:              prec=(prec<<1)-2; break;
                    556:
                    557:            case 2: l2=degpol(p2[1]); if (l2>3) l2=6-l2;
                    558:              switch(l2)
                    559:              {
                    560:                case 1: f=carreparfait(discsr(x));
                    561:                  avma=av; y=cgetg(4,t_VEC); y[3]=un;
                    562:                  if (f) { y[2]=un; y[1]=lstoi(60); }
                    563:                  else { y[2]=lneg(gun); y[1]=lstoi(120); }
                    564:                  return y;
                    565:                case 2: f=carreparfait(discsr(x));
                    566:                  if (f)
                    567:                  {
                    568:                    avma=av; y=cgetg(4,t_VEC);
                    569:                    y[3]=y[2]=un; y[1]=lstoi(24);
                    570:                  }
                    571:                  else
                    572:                  {
                    573:                    p3=(lgef(p2[1])==5) ? (GEN)p2[2]:(GEN)p2[1];
                    574:                    f=carreparfait(discsr(p3));
                    575:                    avma=av; y=cgetg(4,t_VEC); y[2]=lneg(gun);
                    576:                    if (f) { y[1]=lstoi(24); y[3]=deux; }
                    577:                    else { y[1]=lstoi(48); y[3]=un; }
                    578:                  }
                    579:                  return y;
                    580:                case 3: f=carreparfait(discsr((GEN)p2[1]))
                    581:                       || carreparfait(discsr((GEN)p2[2]));
                    582:                  avma=av; y=cgetg(4,t_VEC);
                    583:                  y[3]=un; y[2]=lneg(gun); y[1]=lstoi(f? 18: 36);
                    584:                  return y;
                    585:              }
                    586:            case 3:
                    587:              for (l2=1; l2<=3; l2++)
                    588:                if (lgef(p2[l2])>=6) p3=(GEN)p2[l2];
                    589:              if (lgef(p3)==6)
                    590:              {
                    591:                f=carreparfait(discsr(p3)); avma=av; y=cgetg(4,t_VEC);
                    592:                 y[2]=lneg(gun); y[1]=lstoi(f? 6: 12);
                    593:              }
                    594:              else
                    595:              {
                    596:                f=carreparfait(discsr(x)); avma=av; y=cgetg(4,t_VEC);
                    597:                if (f) { y[2]=un; y[1]=lstoi(12); }
                    598:                else { y[2]=lneg(gun); y[1]=lstoi(24); }
                    599:              }
                    600:               y[3]=un; return y;
                    601:            case 4: avma=av; y=cgetg(4,t_VEC);
                    602:              y[1]=lstoi(6); y[2]=lneg(gun); y[3]=deux; return y;
                    603:             default: err(bugparier,"galois (bug3)");
                    604:          }
                    605:        }
                    606:
                    607:       case 7: z = cgetg(36,t_VEC);
                    608:         for(;;)
                    609:        {
                    610:          ind = 0; p1=roots(x,prec); p4=gun;
                    611:          for (i=1; i<=5; i++)
                    612:            for (j=i+1; j<=6; j++)
                    613:             {
                    614:               p6 = gadd((GEN)p1[i],(GEN)p1[j]);
                    615:              for (k=j+1; k<=7; k++)
                    616:                 z[++ind] = (long) gadd(p6,(GEN)p1[k]);
                    617:             }
                    618:           p4 = roots_to_pol(z,0);
                    619:           p5 = grndtoi(greal(p4),&e);
                    620:           e1 = gexpo(gimag(p4)); if (e1>e) e=e1;
                    621:          if (e <= -10) break;
                    622:           prec = (prec<<1)-2;
                    623:        }
                    624:        p6 = modulargcd(p5,derivpol(p5));
                    625:        if (typ(p6)==t_POL && lgef(p6)>3) goto tchi;
                    626:        p2=(GEN)factor(p5)[1];
                    627:        switch(lg(p2)-1)
                    628:        {
                    629:          case 1: f=carreparfait(discsr(x)); avma=av; y=cgetg(4,t_VEC); y[3]=un;
                    630:            if (f) { y[2]=un; y[1]=lstoi(2520); }
                    631:            else { y[2]=lneg(gun); y[1]=lstoi(5040); }
                    632:            return y;
                    633:          case 2: f=degpol(p2[1]); avma=av; y=cgetg(4,t_VEC); y[3]=un;
                    634:            if (f==7 || f==28) { y[2]=un; y[1]=lstoi(168); }
                    635:            else { y[2]=lneg(gun); y[1]=lstoi(42); }
                    636:            return y;
                    637:          case 3: avma=av; y=cgetg(4,t_VEC);
                    638:            y[3]=y[2]=un; y[1]=lstoi(21); return y;
                    639:          case 4: avma=av; y=cgetg(4,t_VEC);
                    640:            y[3]=un; y[2]=lneg(gun); y[1]=lstoi(14); return y;
                    641:          case 5: avma=av; y=cgetg(4,t_VEC);
                    642:            y[3]=y[2]=un; y[1]=lstoi(7); return y;
                    643:           default: err(talker,"galois (bug2)");
                    644:        }
                    645:     }
                    646:     tchi: avma=av1; x=tschirnhaus(x1);
                    647:   }
                    648: }
                    649:
                    650: GEN
                    651: galoisapply(GEN nf, GEN aut, GEN x)
                    652: {
                    653:   long av=avma,tetpil,lx,j,N;
                    654:   GEN p,p1,y,pol;
                    655:
                    656:   nf=checknf(nf); pol=(GEN)nf[1];
                    657:   if (typ(aut)==t_POL) aut = gmodulcp(aut,pol);
                    658:   else
                    659:   {
                    660:     if (typ(aut)!=t_POLMOD || !gegal((GEN)aut[1],pol))
                    661:       err(talker,"incorrect galois automorphism in galoisapply");
                    662:   }
                    663:   switch(typ(x))
                    664:   {
                    665:     case t_INT: case t_INTMOD: case t_FRAC: case t_FRACN: case t_PADIC:
                    666:       avma=av; return gcopy(x);
                    667:
                    668:     case t_POLMOD: x = (GEN) x[2]; /* fall through */
                    669:     case t_POL:
                    670:       p1 = gsubst(x,varn(pol),aut);
                    671:       if (typ(p1)!=t_POLMOD || !gegal((GEN)p1[1],pol)) p1 = gmodulcp(p1,pol);
                    672:       return gerepileupto(av,p1);
                    673:
                    674:     case t_VEC:
                    675:       if (lg(x)==3)
                    676:       {
                    677:        y=cgetg(3,t_VEC);
                    678:        y[1]=(long)galoisapply(nf,aut,(GEN)x[1]);
                    679:         y[2]=lcopy((GEN)x[2]); return gerepileupto(av, y);
                    680:       }
                    681:       if (lg(x)!=6) err(typeer,"galoisapply");
                    682:       y=cgetg(6,t_VEC); y[1]=x[1]; y[3]=x[3]; y[4]=x[4];
                    683:       p = (GEN)x[1];
                    684:       p1=centermod(galoisapply(nf,aut,(GEN)x[2]), p);
                    685:       if (is_pm1(x[3]))
                    686:        if (ggval(subres(gmul((GEN)nf[7],p1),pol), p) > itos((GEN)x[4]))
                    687:          p1[1] =  (signe(p1[1]) > 0)? lsub((GEN)p1[1], p)
                    688:                                     : ladd((GEN)p1[1], p);
                    689:       y[2]=(long)p1;
                    690:       y[5]=(long)centermod(galoisapply(nf,aut,(GEN)x[5]), p);
                    691:       return gerepilecopy(av,y);
                    692:
                    693:     case t_COL:
                    694:       N=degpol(pol);
                    695:       if (lg(x)!=N+1) err(typeer,"galoisapply");
                    696:       p1=galoisapply(nf,aut,gmul((GEN)nf[7],x)); tetpil=avma;
                    697:       return gerepile(av,tetpil,algtobasis(nf,p1));
                    698:
                    699:     case t_MAT:
                    700:       lx=lg(x); if (lx==1) return cgetg(1,t_MAT);
                    701:       N=degpol(pol);
                    702:       if (lg(x[1])!=N+1) err(typeer,"galoisapply");
                    703:       p1=cgetg(lx,t_MAT);
                    704:       for (j=1; j<lx; j++) p1[j]=(long)galoisapply(nf,aut,(GEN)x[j]);
                    705:       if (lx==N+1) p1 = idealhermite(nf,p1);
                    706:       return gerepileupto(av,p1);
                    707:   }
                    708:   err(typeer,"galoisapply");
                    709:   return NULL; /* not reached */
                    710: }
                    711:
                    712: GEN pol_to_monic(GEN pol, GEN *lead);
                    713: int cmp_pol(GEN x, GEN y);
                    714:
                    715: GEN
                    716: get_nfpol(GEN x, GEN *nf)
                    717: {
                    718:   if (typ(x) == t_POL) { *nf = NULL; return x; }
                    719:   *nf = checknf(x); return (GEN)(*nf)[1];
                    720: }
                    721:
                    722: /* if fliso test for isomorphism, for inclusion otherwise. */
                    723: static GEN
                    724: nfiso0(GEN a, GEN b, long fliso)
                    725: {
                    726:   ulong av = avma;
                    727:   long n,m,i,vb,lx;
                    728:   GEN nfa,nfb,p1,y,la,lb;
                    729:
                    730:   a = get_nfpol(a, &nfa);
                    731:   b = get_nfpol(b, &nfb);
                    732:   if (fliso && nfa && !nfb) { p1=a; a=b; b=p1; p1=nfa; nfa=nfb; nfb=p1; }
                    733:   m=degpol(a);
                    734:   n=degpol(b); if (m<=0 || n<=0) err(constpoler,"nfiso or nfincl");
                    735:   if (fliso)
                    736:     { if (n!=m) return gzero; }
                    737:   else
                    738:     { if (n%m) return gzero; }
                    739:
                    740:   if (nfb) lb = NULL; else b = pol_to_monic(b,&lb);
                    741:   if (nfa) la = NULL; else a = pol_to_monic(a,&la);
                    742:   if (nfa && nfb)
                    743:   {
                    744:     if (fliso)
                    745:     {
                    746:       if (!gegal((GEN)nfa[2],(GEN)nfb[2])
                    747:        || !gegal((GEN)nfa[3],(GEN)nfb[3])) return gzero;
                    748:     }
                    749:     else
                    750:       if (!divise((GEN)nfb[3], gpowgs((GEN)nfa[3],n/m))) return gzero;
                    751:   }
                    752:   else
                    753:   {
                    754:     GEN da = nfa? (GEN)nfa[3]: discsr(a);
                    755:     GEN db = nfb? (GEN)nfb[3]: discsr(b);
                    756:     if (fliso)
                    757:     {
                    758:       p1=gdiv(da,db);
                    759:       if (typ(p1)==t_FRAC) p1=mulii((GEN)p1[1],(GEN)p1[2]);
                    760:       if (!gcarreparfait(p1)) { avma=av; return gzero; }
                    761:     }
                    762:     else
                    763:     {
                    764:       long q=n/m;
                    765:       GEN fa=factor(da), ex=(GEN)fa[2];
                    766:       fa=(GEN)fa[1]; lx=lg(fa);
                    767:       for (i=1; i<lx; i++)
                    768:         if (mod2((GEN)ex[i]) && !divise(db,gpowgs((GEN)fa[i],q)))
                    769:           { avma=av; return gzero; }
                    770:     }
                    771:   }
                    772:   a = dummycopy(a); setvarn(a,0);
                    773:   b = dummycopy(b); vb=varn(b);
                    774:   if (nfb)
                    775:   {
                    776:     if (vb == 0) nfb = gsubst(nfb, 0, polx[MAXVARN]);
                    777:     y = lift_intern(nfroots(nfb,a));
                    778:   }
                    779:   else
                    780:   {
                    781:     if (vb == 0) setvarn(b, fetch_var());
                    782:     y = (GEN)polfnf(a,b)[1]; lx = lg(y);
                    783:     for (i=1; i<lx; i++)
                    784:     {
                    785:       if (lgef(y[i]) != 4) { setlg(y,i); break; }
                    786:       y[i] = (long)gneg_i(lift_intern(gmael(y,i,2)));
                    787:     }
                    788:     y = gen_sort(y, 0, cmp_pol);
                    789:     settyp(y, t_VEC);
                    790:     if (vb == 0) delete_var();
                    791:   }
                    792:   lx = lg(y); if (lx==1) { avma=av; return gzero; }
                    793:   for (i=1; i<lx; i++)
                    794:   {
                    795:     p1 = (GEN)y[i];
                    796:     if (typ(p1) == t_POL) setvarn(p1, vb); else p1 = scalarpol(p1, vb);
                    797:     if (lb) p1 = poleval(p1, gmul(polx[vb],lb));
                    798:     y[i] = la? ldiv(p1,la): (long)p1;
                    799:   }
                    800:   return gerepilecopy(av,y);
                    801: }
                    802:
                    803: GEN
                    804: nfisisom(GEN a, GEN b)
                    805: {
                    806:   return nfiso0(a,b,1);
                    807: }
                    808:
                    809: GEN
                    810: nfisincl(GEN a, GEN b)
                    811: {
                    812:   return nfiso0(a,b,0);
                    813: }
                    814:
                    815: /*************************************************************************/
                    816: /**                                                                    **/
                    817: /**                           INITALG                                  **/
                    818: /**                                                                    **/
                    819: /*************************************************************************/
                    820: extern GEN LLL_nfbasis(GEN *x, GEN polr, GEN base, long prec);
                    821: extern GEN eleval(GEN f,GEN h,GEN a);
                    822: extern int canon_pol(GEN z);
                    823: extern GEN mat_to_vecpol(GEN x, long v);
                    824: extern GEN vecpol_to_mat(GEN v, long n);
                    825:
                    826: /* For internal use. compute trace(x mod pol), sym=polsym(pol,deg(pol)-1) */
                    827: GEN
                    828: quicktrace(GEN x, GEN sym)
                    829: {
                    830:   GEN p1 = gzero;
                    831:   long i;
                    832:
                    833:   if (signe(x))
                    834:   {
                    835:     sym--;
                    836:     for (i=lgef(x)-1; i>1; i--)
                    837:       p1 = gadd(p1, gmul((GEN)x[i],(GEN)sym[i]));
                    838:   }
                    839:   return p1;
                    840: }
                    841:
                    842: /* T = trace(w[i]), x = sum x[i] w[i], x[i] integer */
                    843: static GEN
                    844: trace_col(GEN x, GEN T)
                    845: {
                    846:   ulong av = avma;
                    847:   GEN t = gzero;
                    848:   long i, l = lg(x);
                    849:
                    850:   t = mulii((GEN)x[1],(GEN)T[1]);
                    851:   for (i=2; i<l; i++)
                    852:     if (signe(x[i])) t = addii(t, mulii((GEN)x[i],(GEN)T[i]));
                    853:   return gerepileuptoint(av, t);
                    854: }
                    855:
                    856: /* Seek a new, simpler, polynomial pol defining the same number field as
                    857:  * x (assumed to be monic at this point).
                    858:  * *ptx   receives pol
                    859:  * *ptdx  receives disc(pol)
                    860:  * *ptrev expresses the new root in terms of the old one.
                    861:  * base updated in place.
                    862:  * prec = 0 <==> field is totally real
                    863:  */
                    864: static void
                    865: nfinit_reduce(long flag, GEN *px, GEN *pdx, GEN *prev, GEN *pbase, long prec)
                    866: {
                    867:   GEN chbas,a,phimax,dxn,s,sn,p1,p2,p3,polmax,rev,polr;
                    868:   GEN x = *px, dx = *pdx, base = *pbase;
                    869:   long i,j,nmax,numb,flc,v=varn(x), n=lg(base)-1;
                    870:
                    871:   if (n == 1)
                    872:   {
                    873:     *px = gsub(polx[v],gun); *pdx = gun;
                    874:     *prev = polymodrecip(gmodulcp(gun, x)); return;
                    875:   }
                    876:   polr = prec? roots(x, prec): NULL;
                    877:   if (polr)
                    878:     for (s=gzero,i=1; i<=n; i++) s = gadd(s,gnorm((GEN)polr[i]));
                    879:   else
                    880:     s = subii(sqri((GEN)x[n+1]), shifti((GEN)x[n],1));
                    881:
                    882:   chbas = LLL_nfbasis(&x,polr,base,prec);
                    883:   if (DEBUGLEVEL) msgtimer("LLL basis");
                    884:
                    885:   phimax=polx[v]; polmax=dummycopy(x);
                    886:   nmax=(flag & nf_PARTIAL)?min(n,3):n;
                    887:
                    888:   for (numb=0,i=2; i<=nmax || (!numb && i<=n); i++)
                    889:   { /* cf pols_for_polred */
                    890:     if (DEBUGLEVEL>2) { fprintferr("i = %ld\n",i); flusherr(); }
                    891:     p1 = a = gmul(base,(GEN)chbas[i]); p3=content(p1);
                    892:     if (gcmp1(p3)) p3 = NULL; else p1 = gdiv(p1,p3);
                    893:     p1 = caract2(x,p1,v);
                    894:     if (p3)
                    895:       for (p2=gun, j=lgef(p1)-2; j>=2; j--)
                    896:       {
                    897:         p2 = gmul(p2,p3); p1[j] = lmul((GEN)p1[j], p2);
                    898:       }
                    899:     p2 = modulargcd(derivpol(p1),p1);
                    900:     if (lgef(p2) > 3) continue;
                    901:
                    902:     if (DEBUGLEVEL>3) outerr(p1);
                    903:     dxn=discsr(p1); flc=absi_cmp(dxn,dx); numb++;
                    904:     if (flc>0) continue;
                    905:
                    906:     if (polr)
                    907:       for (sn=gzero,j=1; j<=n; j++)
                    908:         sn = gadd(sn,gnorm(poleval(a,(GEN)polr[j])));
                    909:     else
                    910:       sn = subii(sqri((GEN)p1[n+1]), shifti((GEN)p1[n],1));
                    911:     if (flc>=0)
                    912:     {
                    913:       flc=gcmp(sn,s);
                    914:       if (flc>0 || (!flc && gpolcomp(p1,polmax) >= 0)) continue;
                    915:     }
                    916:     dx=dxn; s=sn; polmax=p1; phimax=a;
                    917:   }
                    918:   if (!numb)
                    919:   {
                    920:     if (gisirreducible(x)!=gun) err(redpoler,"nfinit_reduce");
                    921:     err(talker,"you have found a counter-example to a conjecture, "
                    922:                "please send us\nthe polynomial as soon as possible");
                    923:   }
                    924:   if (phimax == polx[v]) /* no improvement */
                    925:     rev = gmodulcp(phimax,x);
                    926:   else
                    927:   {
                    928:     if (canon_pol(polmax) < 0) phimax = gneg_i(phimax);
                    929:     if (DEBUGLEVEL>1) fprintferr("polmax = %Z\n",polmax);
                    930:     p2 = gmodulcp(phimax,x); rev = polymodrecip(p2);
                    931:     a = base; base = cgetg(n+1,t_VEC);
                    932:     p1 = (GEN)rev[2];
                    933:     for (i=1; i<=n; i++)
                    934:       base[i] = (long)eleval(polmax, (GEN)a[i], p1);
                    935:     p1 = vecpol_to_mat(base,n); p2=denom(p1); p1=gmul(p2,p1);
                    936:     p1 = gdiv(hnfmodid(p1,p2), p2);
                    937:     base = mat_to_vecpol(p1,v);
                    938:   }
                    939:   *px=polmax; *pdx=dx; *prev=rev; *pbase = base;
                    940: }
                    941:
                    942: /* pol belonging to Z[x], return a monic polynomial generating the same field
                    943:  * as pol (x-> ax+b)) set lead = NULL if pol was monic (after dividing
                    944:  * by the content), and to to leading coeff otherwise.
                    945:  * No garbage collecting done.
                    946:  */
                    947: GEN
                    948: pol_to_monic(GEN pol, GEN *lead)
                    949: {
                    950:   long n = lgef(pol)-1;
                    951:   GEN p1;
                    952:
                    953:   if (n==1 || gcmp1((GEN)pol[n])) { *lead = NULL; return pol; }
                    954:
                    955:   p1=content(pol); if (!gcmp1(p1)) pol = gdiv(pol,p1);
                    956:   return primitive_pol_to_monic(pol,lead);
                    957: }
                    958:
                    959: /* NB: TI integral, det(TI) = d_K, ideal/dideal = codifferent */
                    960: GEN
                    961: make_MDI(GEN nf, GEN TI, GEN *ideal, GEN *dideal)
                    962: {
                    963:   GEN c = content(TI);
                    964:   GEN p1;
                    965:
                    966:   *dideal = divii((GEN)nf[3], c);
                    967:   *ideal = p1 = hnfmodid(gdiv(TI,c), *dideal);
                    968:   return gmul(c, ideal_two_elt(nf, p1));
                    969: }
                    970:
                    971: /* [bas[i]/den[i]]= integer basis. roo = real part of the roots */
                    972: GEN
                    973: make_M(GEN basden,GEN roo)
                    974: {
                    975:   GEN p1,d,M, bas=(GEN)basden[1], den=(GEN)basden[2];
                    976:   long i,j, ru = lg(roo), n = lg(bas);
                    977:   M = cgetg(n,t_MAT);
                    978:   for (j=1; j<n; j++)
                    979:   {
                    980:     p1=cgetg(ru,t_COL); M[j]=(long)p1;
                    981:     for (i=1; i<ru; i++)
                    982:       p1[i]=(long)poleval((GEN)bas[j],(GEN)roo[i]);
                    983:   }
                    984:   if (den)
                    985:   {
                    986:     long prec = precision((GEN)roo[1]);
                    987:     GEN invd,rd = cgetr(prec+1);
                    988:     for (j=1; j<n; j++)
                    989:     {
                    990:       d = (GEN)den[j]; if (!d) continue;
                    991:       p1 = (GEN)M[j]; affir(d,rd); invd = ginv(rd);
                    992:       for (i=1; i<ru; i++) p1[i] = lmul((GEN)p1[i], invd);
                    993:     }
                    994:   }
                    995:   if (DEBUGLEVEL>4) msgtimer("matrix M");
                    996:   return M;
                    997: }
                    998:
                    999: GEN
                   1000: make_MC(long r1,GEN M)
                   1001: {
                   1002:   long i,j,av,tetpil, n = lg(M), ru = lg(M[1]);
                   1003:   GEN p1,p2,MC=cgetg(ru,t_MAT);
                   1004:
                   1005:   for (j=1; j<ru; j++)
                   1006:   {
                   1007:     p1=cgetg(n,t_COL); MC[j]=(long)p1;
                   1008:     for (i=1; i<n; i++)
                   1009:     {
                   1010:       av=avma; p2=gconj(gcoeff(M,j,i)); tetpil=avma;
                   1011:       p1[i] = (j<=r1)? (long)p2: lpile(av,tetpil,gmul2n(p2,1));
                   1012:     }
                   1013:   }
                   1014:   if (DEBUGLEVEL>4) msgtimer("matrix MC");
                   1015:   return MC;
                   1016: }
                   1017:
                   1018: GEN
                   1019: get_roots(GEN x,long r1,long ru,long prec)
                   1020: {
                   1021:   GEN roo = (typ(x)==t_VEC)? dummycopy(x): roots(x,prec);
                   1022:   long i;
                   1023:
                   1024:   for (i=1; i<=r1; i++) roo[i]=lreal((GEN)roo[i]);
                   1025:   for (   ; i<=ru; i++) roo[i]=roo[(i<<1)-r1];
                   1026:   roo[0]=evaltyp(t_VEC)|evallg(ru+1); return roo;
                   1027: }
                   1028:
                   1029: /* assume lg(nf) > 3 && typ(nf) = container [hopefully a genuine nf] */
                   1030: long
                   1031: nf_get_r1(GEN nf)
                   1032: {
                   1033:   GEN x = (GEN)nf[2];
                   1034:   if (typ(x) != t_VEC || lg(x) != 3 || typ(x[1]) != t_INT)
                   1035:     err(talker,"false nf in nf_get_r1");
                   1036:   return itos((GEN)x[1]);
                   1037: }
                   1038: long
                   1039: nf_get_r2(GEN nf)
                   1040: {
                   1041:   GEN x = (GEN)nf[2];
                   1042:   if (typ(x) != t_VEC || lg(x) != 3 || typ(x[2]) != t_INT)
                   1043:     err(talker,"false nf in nf_get_r2");
                   1044:   return itos((GEN)x[2]);
                   1045: }
                   1046:
                   1047: extern GEN mulmat_pol(GEN A, GEN x);
                   1048:
                   1049: static GEN
                   1050: get_T(GEN mul, GEN x, GEN bas, GEN den)
                   1051: {
                   1052:   long i,j,n = lg(bas)-1;
                   1053:   GEN tr,T,T1,sym;
                   1054:   T = cgetg(n+1,t_MAT);
                   1055:   T1 = cgetg(n+1,t_COL);
                   1056:   sym = polsym(x, n-1);
                   1057:
                   1058:   T1[1]=lstoi(n);
                   1059:   for (i=2; i<=n; i++)
                   1060:   {
                   1061:     tr = quicktrace((GEN)bas[i], sym);
                   1062:     if (den && den[i]) tr = diviiexact(tr,(GEN)den[i]);
                   1063:     T1[i] = (long)tr; /* tr(w[i]) */
                   1064:   }
                   1065:   T[1] = (long)T1;
                   1066:   for (i=2; i<=n; i++)
                   1067:   {
                   1068:     T[i] = lgetg(n+1,t_COL); coeff(T,1,i) = T1[i];
                   1069:     for (j=2; j<=i; j++)
                   1070:       coeff(T,i,j) = coeff(T,j,i) = (long)trace_col((GEN)mul[j+(i-1)*n], T1);
                   1071:   }
                   1072:   return T;
                   1073: }
                   1074:
                   1075: /* return [bas[i]*denom(bas[i]), denom(bas[i])], denom 1 is given as NULL */
                   1076: GEN
                   1077: get_bas_den(GEN bas)
                   1078: {
                   1079:   GEN z,d,den, dbas = dummycopy(bas);
                   1080:   long i, c = 0, l = lg(bas);
                   1081:   den = cgetg(l,t_VEC);
                   1082:   for (i=1; i<l; i++)
                   1083:   {
                   1084:     d = denom(content((GEN)dbas[i]));
                   1085:     if (is_pm1(d)) d = NULL; else { dbas[i] = lmul((GEN)dbas[i],d); c++; }
                   1086:     den[i] = (long)d;
                   1087:   }
                   1088:   if (!c) den = NULL; /* power basis */
                   1089:   z = cgetg(3,t_VEC);
                   1090:   z[1] = (long)dbas;
                   1091:   z[2] = (long)den; return z;
                   1092: }
                   1093:
                   1094: /* allow x or y = NULL (act as 1) */
                   1095: static GEN
                   1096: _mulii(GEN x, GEN y)
                   1097: {
                   1098:   if (!x) return y;
                   1099:   if (!y) return x;
                   1100:   return mulii(x,y);
                   1101: }
                   1102:
                   1103: GEN
                   1104: get_mul_table(GEN x,GEN basden,GEN invbas,GEN *T)
                   1105: {
                   1106:   long i,j, n = degpol(x);
                   1107:   GEN z,d, mul = cgetg(n*n+1,t_MAT), bas=(GEN)basden[1], den=(GEN)basden[2];
                   1108:
                   1109:   for (j=1; j<=n*n; j++) mul[j]=lgetg(n+1,t_COL);
                   1110:   for (i=1; i<=n; i++)
                   1111:     for (j=i; j<=n; j++)
                   1112:     {
                   1113:       ulong av = avma;
                   1114:       z = gres(gmul((GEN)bas[j],(GEN)bas[i]), x);
                   1115:       z = mulmat_pol(invbas, z); /* integral column */
                   1116:       if (den)
                   1117:       {
                   1118:         d = _mulii((GEN)den[i], (GEN)den[j]);
                   1119:         if (d) z = gdivexact(z, d);
                   1120:       }
                   1121:       mul[j+(i-1)*n] = mul[i+(j-1)*n] = lpileupto(av,z);
                   1122:     }
                   1123:   if (T) *T = get_T(mul,x,bas,den);
                   1124:   return mul;
                   1125: }
                   1126:
                   1127: /* fill mat = nf[5], as well as nf[8] and nf[9]
                   1128:  * If (small) only compute a subset (use dummy 0s for the rest) */
                   1129: void
                   1130: get_nf_matrices(GEN nf, long small)
                   1131: {
                   1132:   GEN x=(GEN)nf[1],dK=(GEN)nf[3],index=(GEN)nf[4],ro=(GEN)nf[6],bas=(GEN)nf[7];
                   1133:   GEN basden,mul,invbas,M,MC,T,MDI,D,TI,A,dA,mat;
                   1134:   long r1 = nf_get_r1(nf), n = lg(bas)-1;
                   1135:
                   1136:   mat = cgetg(small? 4: 8,t_VEC); nf[5] = (long)mat;
                   1137:   basden = get_bas_den(bas);
                   1138:   M = make_M(basden,ro);
                   1139:   MC = make_MC(r1,M);
                   1140:   mat[1]=(long)M;
                   1141:   mat[3]=(long)mulmat_real(MC,M);
                   1142:   if (small) { nf[8]=nf[9]=mat[2]=zero; return; }
                   1143:
                   1144:   invbas = QM_inv(vecpol_to_mat(bas,n), gun);
                   1145:   mul = get_mul_table(x,basden,invbas,&T);
                   1146:   if (DEBUGLEVEL) msgtimer("mult. table");
                   1147:
                   1148:   nf[8]=(long)invbas;
                   1149:   nf[9]=(long)mul;
                   1150:
                   1151:   TI = ZM_inv(T, dK); /* dK T^-1 */
                   1152:   MDI = make_MDI(nf,TI, &A, &dA);
                   1153:   mat[6]=(long)TI;
                   1154:   mat[7]=(long)MDI; /* needed in idealinv below */
                   1155:   if (is_pm1(index))
                   1156:     D = idealhermite_aux(nf, derivpol(x));
                   1157:   else
                   1158:     D = gmul(dA, idealinv(nf, A));
                   1159:   mat[2]=(long)MC;
                   1160:   mat[4]=(long)T;
                   1161:   mat[5]=(long)D;
                   1162:   if (DEBUGLEVEL) msgtimer("matrices");
                   1163: }
                   1164:
                   1165: /* Initialize the number field defined by the polynomial x (in variable v)
                   1166:  * flag & nf_REGULAR
                   1167:  *    regular behaviour.
                   1168:  * flag & nf_SMALL
                   1169:  *    compute only nf[1] (pol), nf[2] (signature), nf[5][3] (T2) and
                   1170:  *    nf[7] (integer basis), the other components are filled with gzero.
                   1171:  * flag & nf_REDUCE
                   1172:  *    try a polred first.
                   1173:  * flag & nf_PARTIAL
                   1174:  *    do a partial polred, not a polredabs
                   1175:  * flag & nf_ORIG
                   1176:  *    do a polred and return [nfinit(x),Mod(a,red)], where
                   1177:  *    Mod(a,red)=Mod(v,x) (i.e return the base change).
                   1178:  */
                   1179:
                   1180: /* here x can be a polynomial, an nf or a bnf */
                   1181: GEN
                   1182: initalgall0(GEN x, long flag, long prec)
                   1183: {
                   1184:   GEN lead = NULL,nf,ro,bas,mat,rev,dK,dx,index,res;
                   1185:   long av=avma,n,i,r1,r2,ru,PRECREG;
                   1186:
                   1187:   if (DEBUGLEVEL) timer2();
                   1188:   if (typ(x)==t_POL)
                   1189:   {
                   1190:     n=degpol(x); if (n<=0) err(constpoler,"initalgall0");
                   1191:     check_pol_int(x,"initalg");
                   1192:     if (gisirreducible(x) == gzero) err(redpoler,"nfinit");
                   1193:     if (!gcmp1((GEN)x[n+2]))
                   1194:     {
                   1195:       x = pol_to_monic(x,&lead);
                   1196:       if (!(flag & nf_SMALL))
                   1197:       {
                   1198:         if (!(flag & nf_REDUCE))
                   1199:           err(warner,"non-monic polynomial. Result of the form [nf,c]");
                   1200:         flag = flag | nf_REDUCE | nf_ORIG;
                   1201:       }
                   1202:     }
                   1203:     bas = allbase4(x,0,&dK,NULL);
                   1204:     if (DEBUGLEVEL) msgtimer("round4");
                   1205:     dx = discsr(x); r1 = sturm(x);
                   1206:   }
                   1207:   else
                   1208:   {
                   1209:     i = lg(x);
                   1210:     if (typ(x) == t_VEC && i<=4 && i>=3 && typ(x[1])==t_POL)
                   1211:     { /* polynomial + integer basis */
                   1212:       bas=(GEN)x[2]; x=(GEN)x[1]; n=degpol(x);
                   1213:       if (typ(bas) == t_MAT) { mat = bas; bas = mat_to_vecpol(mat,varn(x)); }
                   1214:       else mat = vecpol_to_mat(bas,n);
                   1215:       dx = discsr(x); r1 = sturm(x);
                   1216:       dK = gmul(dx, gsqr(det2(mat)));
                   1217:     }
                   1218:     else
                   1219:     {
                   1220:       nf=checknf(x);
                   1221:       bas=(GEN)nf[7]; x=(GEN)nf[1]; n=degpol(x);
                   1222:       dK=(GEN)nf[3]; dx=mulii(dK, sqri((GEN)nf[4]));
                   1223:       r1 = nf_get_r1(nf);
                   1224:     }
                   1225:     bas[1]=lpolun[varn(x)]; /* it may be gun => SEGV later */
                   1226:   }
                   1227:   r2=(n-r1)>>1; ru=r1+r2;
                   1228:   PRECREG = prec + (expi(dK)>>(TWOPOTBITS_IN_LONG+1))
                   1229:                  + (long)((sqrt((double)n)+3) / sizeof(long) * 4);
                   1230:   rev = NULL;
                   1231:   if (flag & nf_REDUCE)
                   1232:   {
                   1233:     nfinit_reduce(flag, &x, &dx, &rev, &bas, r1==n? 0: prec);
                   1234:     if (DEBUGLEVEL) msgtimer("polred");
                   1235:   }
                   1236:   if (!carrecomplet(divii(dx,dK),&index))
                   1237:     err(bugparier,"nfinit (incorrect discriminant)");
                   1238:
                   1239:   ro=get_roots(x,r1,ru,PRECREG);
                   1240:   if (DEBUGLEVEL) msgtimer("roots");
                   1241:
                   1242:   nf=cgetg(10,t_VEC);
                   1243:   nf[1]=(long)x;
                   1244:   nf[2]=lgetg(3,t_VEC);
                   1245:   mael(nf,2,1)=lstoi(r1);
                   1246:   mael(nf,2,2)=lstoi(r2);
                   1247:   nf[3]=(long)dK;
                   1248:   nf[4]=(long)index;
                   1249:   nf[6]=(long)ro;
                   1250:   nf[7]=(long)bas;
                   1251:   get_nf_matrices(nf, flag & nf_SMALL);
                   1252:
                   1253:   if (flag & nf_ORIG)
                   1254:   {
                   1255:     if (!rev) err(talker,"bad flag in initalgall0");
                   1256:     res = cgetg(3,t_VEC);
                   1257:     res[1]=(long)nf; nf = res;
                   1258:     res[2]=lead? ldiv(rev,lead): (long)rev;
                   1259:   }
                   1260:   return gerepilecopy(av, nf);
                   1261: }
                   1262:
                   1263: GEN
                   1264: initalgred(GEN x, long prec)
                   1265: {
                   1266:   return initalgall0(x,nf_REDUCE,prec);
                   1267: }
                   1268:
                   1269: GEN
                   1270: initalgred2(GEN x, long prec)
                   1271: {
                   1272:   return initalgall0(x,nf_REDUCE|nf_ORIG,prec);
                   1273: }
                   1274:
                   1275: GEN
                   1276: nfinit0(GEN x, long flag,long prec)
                   1277: {
                   1278:   switch(flag)
                   1279:   {
                   1280:     case 0:
                   1281:     case 1: return initalgall0(x,nf_REGULAR,prec);
                   1282:     case 2: return initalgall0(x,nf_REDUCE,prec);
                   1283:     case 3: return initalgall0(x,nf_REDUCE|nf_ORIG,prec);
                   1284:     case 4: return initalgall0(x,nf_REDUCE|nf_PARTIAL,prec);
                   1285:     case 5: return initalgall0(x,nf_REDUCE|nf_ORIG|nf_PARTIAL,prec);
                   1286:     case 6: return initalgall0(x,nf_SMALL,prec);
                   1287:     default: err(flagerr,"nfinit");
                   1288:   }
                   1289:   return NULL; /* not reached */
                   1290: }
                   1291:
                   1292: GEN
                   1293: initalg(GEN x, long prec)
                   1294: {
                   1295:   return initalgall0(x,nf_REGULAR,prec);
                   1296: }
                   1297:
                   1298: /* assume x a bnr/bnf/nf */
                   1299: long
                   1300: nfgetprec(GEN x)
                   1301: {
                   1302:   GEN nf = checknf(x), ro = (GEN)nf[6];
                   1303:   return (typ(ro)==t_VEC)?precision((GEN)ro[1]): DEFAULTPREC;
                   1304: }
                   1305:
                   1306: GEN
                   1307: nfnewprec(GEN nf, long prec)
                   1308: {
                   1309:   long av=avma,r1,r2,ru,n;
                   1310:   GEN y,pol,ro,basden,MC,mat,M;
                   1311:
                   1312:   if (typ(nf) != t_VEC) err(talker,"incorrect nf in nfnewprec");
                   1313:   if (lg(nf) == 11) return bnfnewprec(nf,prec);
                   1314:   if (lg(nf) ==  7) return bnrnewprec(nf,prec);
                   1315:   (void)checknf(nf);
                   1316:   y = dummycopy(nf);
                   1317:   pol=(GEN)nf[1]; n=degpol(pol);
                   1318:   r1 = nf_get_r1(nf);
                   1319:   r2 = (n - r1) >> 1; ru = r1+r2;
                   1320:   mat=dummycopy((GEN)nf[5]);
                   1321:   ro=get_roots(pol,r1,ru,prec);
                   1322:   y[5]=(long)mat;
                   1323:   y[6]=(long)ro;
                   1324:   basden = get_bas_den((GEN)nf[7]);
                   1325:   M = make_M(basden,ro);
                   1326:   MC = make_MC(r1,M);
                   1327:   mat[1]=(long)M;
                   1328:   if (typ(nf[8]) != t_INT) mat[2]=(long)MC; /* not a small nf */
                   1329:   mat[3]=(long)mulmat_real(MC,M);
                   1330:   return gerepilecopy(av, y);
                   1331: }
                   1332:
                   1333: static long
                   1334: nf_pm1(GEN y)
                   1335: {
                   1336:   long i,l;
                   1337:
                   1338:   if (!is_pm1(y[1])) return 0;
                   1339:   l = lg(y);
                   1340:   for (i=2; i<l; i++)
                   1341:     if (signe(y[i])) return 0;
                   1342:   return signe(y[1]);
                   1343:
                   1344: }
                   1345:
                   1346: static GEN
                   1347: is_primitive_root(GEN nf, GEN fa, GEN x, long w)
                   1348: {
                   1349:   GEN y, exp = stoi(2), pp = (GEN)fa[1];
                   1350:   long i,p, l = lg(pp);
                   1351:
                   1352:   for (i=1; i<l; i++)
                   1353:   {
                   1354:     p = itos((GEN)pp[i]);
                   1355:     exp[2] = w / p; y = element_pow(nf,x,exp);
                   1356:     if (nf_pm1(y) > 0) /* y = 1 */
                   1357:     {
                   1358:       if (p!=2 || !gcmp1(gcoeff(fa,i,2))) return NULL;
                   1359:       x = gneg_i(x);
                   1360:     }
                   1361:   }
                   1362:   return x;
                   1363: }
                   1364:
                   1365: GEN
                   1366: rootsof1(GEN nf)
                   1367: {
                   1368:   ulong av;
                   1369:   long N,k,i,ws,prec;
                   1370:   GEN algun,p1,y,R1,d,list,w;
                   1371:
                   1372:   y=cgetg(3,t_VEC); av=avma; nf=checknf(nf);
                   1373:   R1=gmael(nf,2,1); algun=gmael(nf,8,1);
                   1374:   if (signe(R1))
                   1375:   {
                   1376:     y[1]=deux;
                   1377:     y[2]=lneg(algun); return y;
                   1378:   }
                   1379:   N=degpol(nf[1]); prec=gprecision((GEN)nf[6]);
                   1380: #ifdef LONG_IS_32BIT
                   1381:   if (prec < 10) prec = 10;
                   1382: #else
                   1383:   if (prec < 6) prec = 6;
                   1384: #endif
                   1385:   for (i=1; ; i++)
                   1386:   {
                   1387:     p1 = fincke_pohst(nf,stoi(N),1000,1,prec,NULL);
                   1388:     if (p1) break;
                   1389:     if (i == MAXITERPOL) err(accurer,"rootsof1");
                   1390:     prec=(prec<<1)-2;
                   1391:     if (DEBUGLEVEL) err(warnprec,"rootsof1",prec);
                   1392:     nf=nfnewprec(nf,prec);
                   1393:   }
                   1394:   if (itos(ground((GEN)p1[2])) != N) err(bugparier,"rootsof1 (bug1)");
                   1395:   w=(GEN)p1[1]; ws = itos(w);
                   1396:   if (ws == 2)
                   1397:   {
                   1398:     y[1]=deux; avma=av;
                   1399:     y[2]=lneg(algun); return y;
                   1400:   }
                   1401:
                   1402:   d = decomp(w); list = (GEN)p1[3]; k = lg(list);
                   1403:   for (i=1; i<k; i++)
                   1404:   {
                   1405:     p1 = (GEN)list[i];
                   1406:     p1 = is_primitive_root(nf,d,p1,ws);
                   1407:     if (p1)
                   1408:     {
                   1409:       y[2]=lpilecopy(av,p1);
                   1410:       y[1]=lstoi(ws); return y;
                   1411:     }
                   1412:   }
                   1413:   err(bugparier,"rootsof1");
                   1414:   return NULL; /* not reached */
                   1415: }
                   1416:
                   1417: /*******************************************************************/
                   1418: /*                                                                 */
                   1419: /*                     DEDEKIND ZETA FUNCTION                      */
                   1420: /*                                                                 */
                   1421: /*******************************************************************/
                   1422:
                   1423: ulong smulss(ulong x, ulong y, ulong *rem);
                   1424:
                   1425: static GEN
                   1426: dirzetak0(GEN nf, long N0)
                   1427: {
                   1428:   GEN vect,p1,pol,disc,c,c2;
                   1429:   long av=avma,i,j,k,limk,lx;
                   1430:   ulong q,p,rem;
                   1431:   byteptr d=diffptr;
                   1432:   long court[] = {evaltyp(t_INT)|m_evallg(3), evalsigne(1)|evallgefint(3),0};
                   1433:
                   1434:   pol=(GEN)nf[1]; disc=(GEN)nf[4];
                   1435:   c  = (GEN) gpmalloc((N0+1)*sizeof(long));
                   1436:   c2 = (GEN) gpmalloc((N0+1)*sizeof(long));
                   1437:   c2[0]=c[0]=evaltyp(t_VEC) | evallg(N0+1);
                   1438:   c2[1]=c[1]=1; for (i=2; i<=N0; i++) c[i]=0;
                   1439:   court[2] = 0;
                   1440:
                   1441:   while (court[2]<=N0)
                   1442:   {
                   1443:     court[2] += *d++; if (! *d) err(primer1);
                   1444:     if (smodis(disc,court[2])) /* court does not divide index */
                   1445:       { vect = (GEN) simplefactmod(pol,court)[1]; lx=lg(vect); }
                   1446:     else
                   1447:     {
                   1448:       p1=primedec(nf,court); lx=lg(p1); vect=cgetg(lx,t_COL);
                   1449:       for (i=1; i<lx; i++) vect[i]=mael(p1,i,4);
                   1450:     }
                   1451:     for (j=1; j<lx; j++)
                   1452:     {
                   1453:       p1=powgi(court, (GEN)vect[j]); /* p1 = court^f */
                   1454:       if (cmpis(p1,N0) <= 0)
                   1455:       {
                   1456:         q=p=p1[2]; limk=N0/q;
                   1457:         for (k=2; k<=N0; k++) c2[k]=c[k];
                   1458:         while (q<=(ulong)N0)
                   1459:         {
                   1460:           for (k=1; k<=limk; k++) c2[k*q] += c[k];
                   1461:           q = smulss(q,p,&rem);
                   1462:           if (rem) break;
                   1463:           limk /= p;
                   1464:         }
                   1465:         p1=c; c=c2; c2=p1;
                   1466:       }
                   1467:     }
                   1468:     avma=av;
                   1469:     if (DEBUGLEVEL>6) fprintferr(" %ld",court[2]);
                   1470:   }
                   1471:   if (DEBUGLEVEL>6) { fprintferr("\n"); flusherr(); }
                   1472:   free(c2); return c;
                   1473: }
                   1474:
                   1475: GEN
                   1476: dirzetak(GEN nf, GEN b)
                   1477: {
                   1478:   GEN z,c;
                   1479:   long i;
                   1480:
                   1481:   if (typ(b)!=t_INT) err(talker,"not an integer type in dirzetak");
                   1482:   if (signe(b)<=0) return cgetg(1,t_VEC);
                   1483:   nf = checknf(nf);
                   1484:   if (is_bigint(b)) err(talker,"too many terms in dirzetak");
                   1485:   c = dirzetak0(nf,itos(b));
                   1486:   i = lg(c); z=cgetg(i,t_VEC);
                   1487:   for (i-- ; i; i--) z[i]=lstoi(c[i]);
                   1488:   free(c); return z;
                   1489: }
                   1490:
                   1491: GEN
                   1492: initzeta(GEN pol, long prec)
                   1493: {
                   1494:   GEN nfz,nf,alpha,beta,mu,gr1,gr2,gru,p1,p2,cst,A0,c0,c1,c2,eps,coef;
                   1495:   GEN limx,bnf,resi,zet,C,coeflog,racpi,aij,tabj,colzero, *tabcstn, *tabcstni;
                   1496:   GEN c_even,ck_even,c_odd,ck_odd,serie_even,serie_odd,serie_exp,Pi;
                   1497:   long N0,imin,imax,r1,r2,ru,R,N,i,j,k,n, av,av2,tetpil;
                   1498:   long court[] = {evaltyp(t_INT)|m_evallg(3), evalsigne(1)|evallgefint(3),0};
                   1499:   stackzone *zone, *zone0, *zone1;
                   1500:
                   1501:   /*************** Calcul du residu et des constantes ***************/
                   1502:   eps=gmul2n(gun,-bit_accuracy(prec)-6); p1=dbltor(0.5);
                   1503:   nfz=cgetg(10,t_VEC);
                   1504:   bnf=buchinit(pol,p1,p1,prec+1); prec=(prec<<1)-1;
                   1505:   bnf = checkbnf_discard(bnf);
                   1506:   Pi = mppi(prec); racpi=gsqrt(Pi,prec);
                   1507:
                   1508:   /* Nb de classes et regulateur */
                   1509:   nf=(GEN)bnf[7]; N=degpol(nf[1]);
                   1510:   r1 = nf_get_r1(nf); r2 = (N-r1)>>1;
                   1511:   gr1=gmael(nf,2,1); gr2=gmael(nf,2,2);
                   1512:   ru=r1+r2; R=ru+2;
                   1513:   av=avma; p1=(GEN)bnf[8]; p2 = gmul(gmul2n(gmael(p1,1,1),r1), (GEN)p1[2]);
                   1514:   tetpil = avma; resi=gerepile(av,tetpil,gdiv(p2, gmael(p1,4,1)));
                   1515:
                   1516:   /* Calcul de N0 */
                   1517:   cst = cgetr(prec); av = avma;
                   1518:   mu = gadd(gmul2n(gr1,-1),gr2);
                   1519:   alpha = gmul2n(stoi(ru+1),-1);
                   1520:   beta = gpui(gdeux,gmul2n(gr1,-1),DEFAULTPREC);
                   1521:   A0 = gmul2n(gpowgs(mu,R),r1);
                   1522:   A0 = gmul(A0,gpowgs(gmul2n(Pi,1),1-ru));
                   1523:   A0 = gsqrt(A0,DEFAULTPREC);
                   1524:
                   1525:   c1 = gmul(mu,gpui(beta,ginv(mu),DEFAULTPREC));
                   1526:   c0 = gdiv(gmul(A0,gpowgs(gmul2n(Pi,1),ru-1)),mu);
                   1527:   c0 = gmul(c0,gpui(c1,gneg_i(alpha),DEFAULTPREC));
                   1528:   c2 = gdiv(alpha,mu);
                   1529:
                   1530:   p1 = glog(gdiv(c0,eps),DEFAULTPREC);
                   1531:   limx = gdiv(gsub(glog(p1,DEFAULTPREC),glog(c1,DEFAULTPREC)),
                   1532:               gadd(c2,gdiv(p1,mu)));
                   1533:   limx = gmul(gpui(gdiv(c1,p1),mu,DEFAULTPREC),
                   1534:               gadd(gun,gmul(alpha,limx)));
                   1535:   p1 = gsqrt(absi((GEN)nf[3]),prec);
                   1536:   p2 = gmul2n(gpowgs(racpi,N),r2);
                   1537:   gaffect(gdiv(p1,p2), cst);
                   1538:
                   1539:   av = avma; p1 = gfloor(gdiv(cst,limx)); N0 = p1[2];
                   1540:   if (is_bigint(p1) || N0 > 10000000)
                   1541:     err(talker,"discriminant too large for initzeta, sorry");
                   1542:   if (DEBUGLEVEL>=2)
                   1543:     { fprintferr("\ninitzeta:\nN0 = %ld\n",N0); flusherr(); timer2(); }
                   1544:
                   1545:   /* Calcul de imax */
                   1546:
                   1547:   imin=1; imax=1400;
                   1548:   p1 = gmul(gpowgs(gmul2n(racpi,1),r2),gpowgs(stoi(5),r1));
                   1549:   p1 = gdiv(p1,gmul(gmul(gsqrt(limx,DEFAULTPREC),gmul2n(eps,4)),
                   1550:                          gpowgs(racpi,3)));
                   1551:   while (imax-imin >= 4)
                   1552:   {
                   1553:     long itest = (imax+imin)>>1;
                   1554:     p2 = gmul(gpowgs(mpfactr(itest,DEFAULTPREC),r2),gpowgs(limx,itest));
                   1555:     p2 = gmul(p2,gpowgs(mpfactr(itest/2,DEFAULTPREC),r1));
                   1556:     if (gcmp(p2,p1) >= 0) imax=itest; else imin=itest;
                   1557:   }
                   1558:   imax -= (imax & 1); avma = av;
                   1559:   if (DEBUGLEVEL>=2) { fprintferr("imax = %ld\n",imax); flusherr(); }
                   1560:   /* Tableau des i/cst (i=1 a N0) */
                   1561:
                   1562:   i = prec*N0;
                   1563:   zone  = switch_stack(NULL,i + 2*(N0+1) + 6*prec);
                   1564:   zone1 = switch_stack(NULL,2*i);
                   1565:   zone0 = switch_stack(NULL,2*i);
                   1566:   switch_stack(zone,1);
                   1567:   tabcstn  = (GEN*) cgetg(N0+1,t_VEC);
                   1568:   tabcstni = (GEN*) cgetg(N0+1,t_VEC);
                   1569:   p1 = ginv(cst);
                   1570:   for (i=1; i<=N0; i++) { tabcstni[i] = gun; tabcstn[i] = mulsr(i,p1); }
                   1571:   switch_stack(zone,0);
                   1572:
                   1573:   /********** Calcul des coefficients a(i,j) independants de s **********/
                   1574:
                   1575:   zet=cgetg(R,t_VEC); zet[1] = lmpeuler(prec);
                   1576:   for (i=2; i<R; i++) zet[i] = (long)gzeta(stoi(i),prec);
                   1577:
                   1578:   aij=cgetg(imax+1,t_VEC);
                   1579:   for (i=1; i<=imax; i++) aij[i] = lgetg(R,t_VEC);
                   1580:
                   1581:   c_even = realun(prec);
                   1582:   c_even = gmul2n(c_even,r1);
                   1583:   c_odd = gmul(c_even,gpowgs(racpi,r1));
                   1584:   if (ru&1) c_odd=gneg_i(c_odd);
                   1585:   ck_even=cgetg(R,t_VEC); ck_odd=cgetg(r2+2,t_VEC);
                   1586:   for (k=1; k<R; k++)
                   1587:   {
                   1588:     ck_even[k]=lmul((GEN)zet[k],gadd(gr2,gmul2n(gr1,-k)));
                   1589:     if (k&1) ck_even[k]=lneg((GEN)ck_even[k]);
                   1590:   }
                   1591:   gru=stoi(ru);
                   1592:   for (k=1; k<=r2+1; k++)
                   1593:   {
                   1594:     ck_odd[k]=lmul((GEN)zet[k], gsub(gru, gmul2n(gr1,-k)));
                   1595:     if (k&1) ck_odd[k]=lneg((GEN)ck_odd[k]);
                   1596:     ck_odd[k]=ladd(gru,(GEN)ck_odd[k]);
                   1597:   }
                   1598:   ck_odd[1]=lsub((GEN)ck_odd[1],gmul(gr1,glog(gdeux,prec)));
                   1599:   serie_even =cgetg(ru+3,t_SER); serie_odd=cgetg(r2+3,t_SER);
                   1600:   serie_even[1] = serie_odd[1] = evalsigne(1)+evalvalp(1);
                   1601:   i=0;
                   1602:
                   1603:   while (i<imax/2)
                   1604:   {
                   1605:     for (k=1; k<R; k++)
                   1606:       serie_even[k+1]=ldivgs((GEN)ck_even[k],k);
                   1607:     serie_exp=gmul(c_even,gexp(serie_even,0));
                   1608:     p1=(GEN)aij[2*i+1];
                   1609:     for (j=1; j<R; j++) p1[j]=serie_exp[ru+3-j];
                   1610:
                   1611:     for (k=1; k<=r2+1; k++)
                   1612:       serie_odd[k+1]=ldivgs((GEN)ck_odd[k],k);
                   1613:     serie_exp=gmul(c_odd,gexp(serie_odd,0));
                   1614:     p1=(GEN)aij[2*i+2];
                   1615:     for (j=1; j<=r2+1; j++) p1[j]=serie_exp[r2+3-j];
                   1616:     for (   ; j<R; j++) p1[j]=zero;
                   1617:     i++;
                   1618:
                   1619:     c_even = gdiv(c_even,gmul(gpowgs(stoi(i),ru),gpowgs(stoi(2*i-1),r2)));
                   1620:     c_odd  = gdiv(c_odd, gmul(gpowgs(stoi(i),r2),gpowgs(stoi(2*i+1),ru)));
                   1621:     c_even = gmul2n(c_even,-r2);
                   1622:     c_odd  = gmul2n(c_odd,r1-r2);
                   1623:     if (r1&1) { c_even=gneg_i(c_even); c_odd=gneg_i(c_odd); }
                   1624:     p1 = gr2; p2 = gru;
                   1625:     for (k=1; k<R; k++)
                   1626:     {
                   1627:       p1=gdivgs(p1,2*i-1); p2=gdivgs(p2,2*i);
                   1628:       ck_even[k] = ladd((GEN)ck_even[k], gadd(p1,p2));
                   1629:     }
                   1630:     p1 = gru; p2 = gr2;
                   1631:     for (k=1; k<=r2+1; k++)
                   1632:     {
                   1633:       p1=gdivgs(p1,2*i+1); p2=gdivgs(p2,2*i);
                   1634:       ck_odd[k] = ladd((GEN)ck_odd[k], gadd(p1,p2));
                   1635:     }
                   1636:   }
                   1637:   aij=gerepilecopy(av,aij);
                   1638:   if (DEBUGLEVEL>=2) msgtimer("a(i,j)");
                   1639:   p1=cgetg(5,t_VEC);
                   1640:   p1[1]=lstoi(r1); p1[2]=lstoi(r2); p1[3]=lstoi(imax); p1[4]=(long)bnf;
                   1641:   nfz[1]=(long)p1;
                   1642:   nfz[2]=(long)resi;
                   1643:   nfz[5]=(long)cst;
                   1644:   nfz[6]=llog(cst,prec);
                   1645:   nfz[7]=(long)aij;
                   1646:
                   1647:   /************* Calcul du nombre d'ideaux de norme donnee *************/
                   1648:   coef = dirzetak0(nf,N0); tabj = cgetg(N0+1,t_MAT);
                   1649:   if (DEBUGLEVEL>=2) msgtimer("coef");
                   1650:   colzero=cgetg(ru+2,t_COL); for (j=1; j<=ru+1; j++) colzero[j]=zero;
                   1651:   for (i=1; i<=N0; i++)
                   1652:     if (coef[i])
                   1653:     {
                   1654:       GEN t = cgetg(ru+2,t_COL);
                   1655:       p1 = glog((GEN)tabcstn[i],prec); setsigne(p1, -signe(p1));
                   1656:       t[1] = lstoi(coef[i]); t[2] = lmul((GEN)t[1],p1);
                   1657:       for (j=2; j<=ru; j++)
                   1658:       {
                   1659:         long av2 = avma; p2 = gmul((GEN)t[j],p1);
                   1660:         t[j+1] = (long)gerepileuptoleaf(av2, divrs(p2,j));
                   1661:       }
                   1662:       /* tabj[n,j]=coef(n)*ln(c/n)^(j-1)/(j-1)! */
                   1663:       tabj[i] = (long)t;
                   1664:     }
                   1665:     else tabj[i]=(long)colzero;
                   1666:   if (DEBUGLEVEL>=2) msgtimer("a(n)");
                   1667:
                   1668:   coeflog=cgetg(N0+1,t_VEC); coeflog[1]=zero;
                   1669:   for (i=2; i<=N0; i++)
                   1670:     if (coef[i])
                   1671:     {
                   1672:       court[2]=i; p1=glog(court,prec);
                   1673:       setsigne(p1,-1); coeflog[i]=(long)p1;
                   1674:     }
                   1675:     else coeflog[i] = zero;
                   1676:   if (DEBUGLEVEL>=2) msgtimer("log(n)");
                   1677:
                   1678:   nfz[3]=(long)tabj;
                   1679:   p1 = cgetg(N0+1,t_VECSMALL);
                   1680:   for (i=1; i<=N0; i++) p1[i] = coef[i];
                   1681:   nfz[8]=(long)p1;
                   1682:   nfz[9]=(long)coeflog;
                   1683:
                   1684:   /******************** Calcul des coefficients Cik ********************/
                   1685:
                   1686:   C = cgetg(ru+1,t_MAT);
                   1687:   for (k=1; k<=ru; k++) C[k] = lgetg(imax+1,t_COL);
                   1688:   av2 = avma;
                   1689:   for (i=1; i<=imax; i++)
                   1690:   {
                   1691:     stackzone *z;
                   1692:     for (k=1; k<=ru; k++)
                   1693:     {
                   1694:       p1 = NULL;
                   1695:       for (n=1; n<=N0; n++)
                   1696:         if (coef[n])
                   1697:           for (j=1; j<=ru-k+1; j++)
                   1698:           {
                   1699:             p2 = gmul(tabcstni[n],
                   1700:                       gmul(gmael(aij,i,j+k), gmael(tabj,n,j)));
                   1701:             p1 = p1? gadd(p1,p2): p2;
                   1702:           }
                   1703:       coeff(C,i,k) = p1? (long)gerepileupto(av2,p1): zero;
                   1704:       av2 = avma;
                   1705:     }
                   1706:     /* use a parallel stack */
                   1707:     z = i&1? zone1: zone0;
                   1708:     switch_stack(z, 1);
                   1709:     for (n=1; n<=N0; n++)
                   1710:       if (coef[n]) tabcstni[n] = mpmul(tabcstni[n],tabcstn[n]);
                   1711:     /* come back */
                   1712:     switch_stack(z, 0);
                   1713:   }
                   1714:   nfz[4] = (long) C;
                   1715:   if (DEBUGLEVEL>=2) msgtimer("Cik");
                   1716:   gunclone(aij);
                   1717:   free((void*)zone); free((void*)zone1); free((void*)zone0);
                   1718:   free((void*)coef); return nfz;
                   1719: }
                   1720:
                   1721: GEN
                   1722: gzetakall(GEN nfz, GEN s, long flag, long prec2)
                   1723: {
                   1724:   GEN resi,C,cst,cstlog,coeflog,cs,coef;
                   1725:   GEN lambd,gammas,gammaunmoins,gammas2,gammaunmoins2,var1,var2;
                   1726:   GEN p1,unmoins,gexpro,gar,val,valm,valk,valkm;
                   1727:   long ts = typ(s), r1,r2,ru,imax,i,j,k,N0,sl,prec,bigprec, av = avma;
                   1728:
                   1729:   if (typ(nfz)!=t_VEC || lg(nfz)!=10 || typ(nfz[1]) != t_VEC)
                   1730:     err(talker,"not a zeta number field in zetakall");
                   1731:   if (! is_intreal_t(ts) && ts != t_COMPLEX && ! is_frac_t(ts))
                   1732:     err(typeer,"gzetakall");
                   1733:   resi=(GEN)nfz[2]; C=(GEN)nfz[4]; cst=(GEN)nfz[5];
                   1734:   cstlog=(GEN)nfz[6]; coef=(GEN)nfz[8]; coeflog=(GEN)nfz[9];
                   1735:   r1   = itos(gmael(nfz,1,1));
                   1736:   r2   = itos(gmael(nfz,1,2)); ru = r1+r2;
                   1737:   imax = itos(gmael(nfz,1,3)); N0 = lg(coef)-1;
                   1738:   bigprec = precision(cst); prec = prec2+1;
                   1739:
                   1740:   if (ts==t_COMPLEX && gcmp0(gimag(s))) { s=greal(s); ts = typ(s); }
                   1741:   if (ts==t_REAL && !signe(gfrac(s))) { s=mptrunc(s); ts = t_INT; }
                   1742:   if (ts==t_INT)
                   1743:   {
                   1744:     sl=itos(s);
                   1745:     if (sl==1) err(talker,"s = 1 is a pole (gzetakall)");
                   1746:     if (sl==0)
                   1747:     {
                   1748:       avma = av;
                   1749:       if (flag) err(talker,"s = 0 is a pole (gzetakall)");
                   1750:       if (ru == 1) return gneg(r1? ghalf: resi);
                   1751:       return gzero;
                   1752:     }
                   1753:     if (sl<0 && (r2 || !odd(sl)))
                   1754:     {
                   1755:       if (!flag) return gzero;
                   1756:       s = subsi(1,s); sl = 1-sl;
                   1757:     }
                   1758:     unmoins=subsi(1,s);
                   1759:     lambd = gdiv(resi, mulis(s,sl-1));
                   1760:     gammas2=ggamma(gmul2n(s,-1),prec);
                   1761:     gar=gpowgs(gammas2,r1);
                   1762:     cs=gexp(gmul(cstlog,s),prec);
                   1763:     val=s; valm=unmoins;
                   1764:     if (sl < 0) /* r2 = 0 && odd(sl) */
                   1765:     {
                   1766:       gammaunmoins2=ggamma(gmul2n(unmoins,-1),prec);
                   1767:       var1=var2=gun;
                   1768:       for (i=2; i<=N0; i++)
                   1769:        if (coef[i])
                   1770:        {
                   1771:           gexpro=gexp(gmul((GEN)coeflog[i],s),bigprec);
                   1772:          var1 = gadd(var1,gmulsg(coef[i],gexpro));
                   1773:          var2 = gadd(var2,gdivsg(coef[i],gmulsg(i,gexpro)));
                   1774:        }
                   1775:       lambd=gadd(lambd,gmul(gmul(var1,cs),gar));
                   1776:       lambd=gadd(lambd,gmul(gmul(var2,gdiv(cst,cs)),
                   1777:                            gpowgs(gammaunmoins2,r1)));
                   1778:       for (i=1; i<=imax; i+=2)
                   1779:       {
                   1780:        valk  = val;
                   1781:         valkm = valm;
                   1782:        for (k=1; k<=ru; k++)
                   1783:        {
                   1784:           p1 = gcoeff(C,i,k);
                   1785:          lambd = gsub(lambd,gdiv(p1,valk )); valk  = mulii(val,valk);
                   1786:          lambd = gsub(lambd,gdiv(p1,valkm)); valkm = mulii(valm,valkm);
                   1787:        }
                   1788:        val  = addis(val, 2);
                   1789:         valm = addis(valm,2);
                   1790:       }
                   1791:     }
                   1792:     else
                   1793:     {
                   1794:       GEN tabj=(GEN)nfz[3], aij=(GEN)nfz[7];
                   1795:
                   1796:       gar = gmul(gar,gpowgs(ggamma(s,prec),r2));
                   1797:       var1=var2=gzero;
                   1798:       for (i=1; i<=N0; i++)
                   1799:        if (coef[i])
                   1800:        {
                   1801:          gexpro=gexp(gmul((GEN)coeflog[i],s),bigprec);
                   1802:          var1 = gadd(var1,gmulsg(coef[i],gexpro));
                   1803:           if (sl <= imax)
                   1804:           {
                   1805:             p1=gzero;
                   1806:             for (j=1; j<=ru+1; j++)
                   1807:               p1 = gadd(p1, gmul(gmael(aij,sl,j), gmael(tabj,i,j)));
                   1808:             var2=gadd(var2,gdiv(p1,gmulsg(i,gexpro)));
                   1809:           }
                   1810:        }
                   1811:       lambd=gadd(lambd,gmul(gmul(var1,cs),gar));
                   1812:       lambd=gadd(lambd,gmul(var2,gdiv(cst,cs)));
                   1813:       for (i=1; i<=imax; i++)
                   1814:       {
                   1815:        valk  = val;
                   1816:         valkm = valm;
                   1817:         if (i == sl)
                   1818:           for (k=1; k<=ru; k++)
                   1819:           {
                   1820:             p1 = gcoeff(C,i,k);
                   1821:             lambd = gsub(lambd,gdiv(p1,valk)); valk = mulii(val,valk);
                   1822:           }
                   1823:         else
                   1824:        for (k=1; k<=ru; k++)
                   1825:        {
                   1826:             p1 = gcoeff(C,i,k);
                   1827:             lambd = gsub(lambd,gdiv(p1,valk )); valk  = mulii(val,valk);
                   1828:             lambd = gsub(lambd,gdiv(p1,valkm)); valkm = mulii(valm,valkm);
                   1829:        }
                   1830:        val  = addis(val,1);
                   1831:         valm = addis(valm,1);
                   1832:       }
                   1833:     }
                   1834:   }
                   1835:   else
                   1836:   {
                   1837:     GEN Pi = mppi(prec);
                   1838:     if (is_frac_t(ts))
                   1839:       s = gmul(s, realun(bigprec));
                   1840:     else
                   1841:       s = gprec_w(s, bigprec);
                   1842:
                   1843:     unmoins = gsub(gun,s);
                   1844:     lambd = gdiv(resi,gmul(s,gsub(s,gun)));
                   1845:     gammas = ggamma(s,prec);
                   1846:     gammas2= ggamma(gmul2n(s,-1),prec);
                   1847:     gar = gmul(gpowgs(gammas,r2),gpowgs(gammas2,r1));
                   1848:     cs = gexp(gmul(cstlog,s),prec);
                   1849:     var1 = gmul(Pi,s);
                   1850:     gammaunmoins = gdiv(Pi,gmul(gsin(var1,prec),gammas));
                   1851:     gammaunmoins2= gdiv(gmul(gmul(gsqrt(Pi,prec),gpui(gdeux,gsub(s,gun),prec)),
                   1852:                              gammas2),
                   1853:                         gmul(gcos(gmul2n(var1,-1),prec),gammas));
                   1854:     var1 = var2 = gun;
                   1855:     for (i=2; i<=N0; i++)
                   1856:       if (coef[i])
                   1857:       {
                   1858:         gexpro = gexp(gmul((GEN)coeflog[i],s),bigprec);
                   1859:        var1 = gadd(var1,gmulsg(coef[i], gexpro));
                   1860:        var2 = gadd(var2,gdivsg(coef[i], gmulsg(i,gexpro)));
                   1861:       }
                   1862:     lambd = gadd(lambd,gmul(gmul(var1,cs),gar));
                   1863:     lambd = gadd(lambd,gmul(gmul(gmul(var2,gdiv(cst,cs)),
                   1864:                                 gpowgs(gammaunmoins,r2)),
                   1865:                             gpowgs(gammaunmoins2,r1)));
                   1866:     val  = s;
                   1867:     valm = unmoins;
                   1868:     for (i=1; i<=imax; i++)
                   1869:     {
                   1870:       valk  = val;
                   1871:       valkm = valm;
                   1872:       for (k=1; k<=ru; k++)
                   1873:       {
                   1874:         p1 = gcoeff(C,i,k);
                   1875:        lambd = gsub(lambd,gdiv(p1,valk )); valk  = gmul(val, valk);
                   1876:        lambd = gsub(lambd,gdiv(p1,valkm)); valkm = gmul(valm,valkm);
                   1877:       }
                   1878:       if (r2)
                   1879:       {
                   1880:        val  = gadd(val, gun);
                   1881:         valm = gadd(valm,gun);
                   1882:       }
                   1883:       else
                   1884:       {
                   1885:        val  = gadd(val, gdeux);
                   1886:         valm = gadd(valm,gdeux); i++;
                   1887:       }
                   1888:     }
                   1889:   }
                   1890:   if (!flag) lambd = gdiv(lambd,gmul(gar,cs)); /* zetak */
                   1891:   return gerepileupto(av, gprec_w(lambd, prec2));
                   1892: }
                   1893:
                   1894: GEN
                   1895: gzetak(GEN nfz, GEN s, long prec)
                   1896: {
                   1897:   return gzetakall(nfz,s,0,prec);
                   1898: }
                   1899:
                   1900: GEN
                   1901: glambdak(GEN nfz, GEN s, long prec)
                   1902: {
                   1903:   return gzetakall(nfz,s,1,prec);
                   1904: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>