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

Annotation of OpenXM_contrib/pari/src/basemath/base3.c, Revision 1.1.1.1

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

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