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

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

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

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