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

Annotation of OpenXM_contrib/pari/src/basemath/bibli1.c, Revision 1.1

1.1     ! maekawa     1: /********************************************************************/
        !             2: /**                                                                **/
        !             3: /**                 LLL Algorithm and close friends                **/
        !             4: /**                                                                **/
        !             5: /********************************************************************/
        !             6: /* $Id: bibli1.c,v 1.4 1999/09/24 10:51:24 karim Exp $ */
        !             7: #include "pari.h"
        !             8: #include "parinf.h"
        !             9: GEN lincomb_integral(GEN u, GEN v, GEN X, GEN Y);
        !            10:
        !            11: /* scalar product of x with himself */
        !            12: static GEN
        !            13: sqscal(GEN x)
        !            14: {
        !            15:   long i,av=avma,lx=lg(x);
        !            16:   GEN z=gzero;
        !            17:
        !            18:   for (i=1; i<lx; i++)
        !            19:     z = gadd(z, gsqr((GEN)x[i]));
        !            20:   return gerepileupto(av,z);
        !            21: }
        !            22:
        !            23: /* scalar product x . y */
        !            24: static GEN
        !            25: gscal(GEN x,GEN y)
        !            26: {
        !            27:   long i,av=avma,lx=lg(x);
        !            28:   GEN z=gzero;
        !            29:
        !            30:   for (i=1; i<lx; i++)
        !            31:     z = gadd(z, gmul((GEN)x[i],(GEN)y[i]));
        !            32:   return gerepileupto(av,z);
        !            33: }
        !            34:
        !            35: static GEN
        !            36: sqscali(GEN x)
        !            37: {
        !            38:   GEN z = gzero;
        !            39:   long i,lx=lg(x);
        !            40:
        !            41:   for (i=1; i<lx; i++)
        !            42:     z = addii(z,sqri((GEN)x[i]));
        !            43:   return z;
        !            44: }
        !            45:
        !            46: static GEN
        !            47: gscali(GEN x,GEN y)
        !            48: {
        !            49:   GEN z = gzero;
        !            50:   long i,lx=lg(x);
        !            51:
        !            52:   for (i=1; i<lx; i++)
        !            53:     z = addii(z, mulii((GEN)x[i],(GEN)y[i]));
        !            54:   return z;
        !            55: }
        !            56:
        !            57: static GEN
        !            58: lllall_trivial(GEN x, long n, long flag)
        !            59: {
        !            60:   GEN y;
        !            61:   if (!n)
        !            62:   {
        !            63:     if (flag != lll_ALL) return cgetg(1,t_MAT);
        !            64:     y=cgetg(3,t_VEC);
        !            65:     y[1]=lgetg(1,t_MAT);
        !            66:     y[2]=lgetg(1,t_MAT); return y;
        !            67:   }
        !            68:   /* here n = 1 */
        !            69:   if (gcmp0((GEN)x[1]))
        !            70:   {
        !            71:     switch(flag)
        !            72:     {
        !            73:       case lll_KER: return idmat(1);
        !            74:       case lll_IM : return cgetg(1,t_MAT);
        !            75:       default: y=cgetg(3,t_VEC);
        !            76:         y[1]=(long)idmat(1);
        !            77:         y[2]=lgetg(1,t_MAT); return y;
        !            78:     }
        !            79:   }
        !            80:   if (flag & lll_GRAM) flag ^= lll_GRAM; else x = NULL;
        !            81:   switch (flag)
        !            82:   {
        !            83:     case lll_KER: return cgetg(1,t_MAT);
        !            84:     case lll_IM : return idmat(1);
        !            85:     default: y=cgetg(3,t_VEC);
        !            86:       y[1]=lgetg(1,t_MAT);
        !            87:       y[2]=x? lcopy(x): (long)idmat(1); return y;
        !            88:   }
        !            89: }
        !            90:
        !            91: static GEN
        !            92: lllgramall_finish(GEN h,GEN fl,long flag,long n)
        !            93: {
        !            94:   long k;
        !            95:   GEN y;
        !            96:
        !            97:   k=1; while (k<=n && !fl[k]) k++;
        !            98:   switch(flag)
        !            99:   {
        !           100:     case lll_KER: setlg(h,k);
        !           101:       y = gcopy(h); break;
        !           102:
        !           103:     case lll_IM: h += k-1; h[0] = evaltyp(t_MAT)| evallg(n-k+2);
        !           104:       y = gcopy(h); break;
        !           105:
        !           106:     default: setlg(h,k); y=cgetg(3,t_VEC);
        !           107:       y[1] = lcopy(h);
        !           108:       h += k-1; h[0] = evaltyp(t_MAT)| evallg(n-k+2);
        !           109:       y[2] = lcopy(h);
        !           110:       break;
        !           111:   }
        !           112:   return y;
        !           113: }
        !           114:
        !           115: /********************************************************************/
        !           116: /**                                                                **/
        !           117: /**                          LLL with content                      **/
        !           118: /**                                                                **/
        !           119: /********************************************************************/
        !           120:
        !           121: /* real Gram matrix has coeffs X[i,j] = x[i,j]*veccon[i]*veccon[j] */
        !           122: static GEN
        !           123: lllgramintwithcontent(GEN x, GEN veccon, long flag)
        !           124: {
        !           125:   long av0=avma,av,tetpil,lx=lg(x),i,j,k,l,n,lim,kmax;
        !           126:   GEN u,u2,B,lam,q,r,h,la,bb,p1,p2,p3,p4,fl,corr,corr2,newcon;
        !           127:   GEN *gptr[8];
        !           128:
        !           129:   if (typ(x) != t_MAT) err(typeer,"lllgramintwithcontent");
        !           130:   n=lx-1; if (n<=1) return lllall_trivial(x,n,flag);
        !           131:   if (lg((GEN)x[1])!=lx) err(mattype1,"lllgramintwithcontent");
        !           132:   fl = new_chunk(lx);
        !           133:
        !           134:   av=avma; lim=stack_lim(av,1);
        !           135:   x=dummycopy(x); veccon=dummycopy(veccon);
        !           136:   B=cgetg(lx+1,t_COL); B[1]=un;
        !           137:   /* B[i+1]=B_i; le vrai B_i est B_i*prod(1,j=1,i,veccon[j]^2) */
        !           138:
        !           139:   for (i=1; i<lx; i++) { B[i+1]=zero; fl[i]=0; }
        !           140:   lam=cgetg(lx,t_MAT);
        !           141:   for (j=1; j<lx; j++)
        !           142:   { p2=cgetg(lx,t_COL); lam[j]=(long)p2; for (i=1; i<lx; i++) p2[i]=zero; }
        !           143: /* le vrai lam[i,j] est
        !           144:    lam[i,j]*veccon[i]*veccon[j]*prod(1,l=1,j-1,veccon[l]^2) */
        !           145:   k=2; h=idmat(n); kmax=1;
        !           146:   u=gcoeff(x,1,1); if (typ(u)!=t_INT) err(lllger4);
        !           147:   if (signe(u)) { B[2]=(long)u; coeff(lam,1,1)=un; fl[1]=1; }
        !           148:   else { B[2]=un; fl[1]=0; }
        !           149:   if (DEBUGLEVEL>5) { fprintferr("k = %ld",k); flusherr(); }
        !           150:   for(;;)
        !           151:   {
        !           152:     if (k>kmax)
        !           153:     {
        !           154:       kmax=k;
        !           155:       for (j=1; j<=k; j++)
        !           156:       {
        !           157:        if (j==k || fl[j])
        !           158:        {
        !           159:          u=gcoeff(x,k,j); if (typ(u)!=t_INT) err(lllger4);
        !           160:          for (i=1; i<j; i++)
        !           161:            if (fl[i])
        !           162:              u=divii(subii(mulii((GEN)B[i+1],u),mulii(gcoeff(lam,k,i),gcoeff(lam,j,i))),(GEN)B[i]);
        !           163:          if (j<k) coeff(lam,k,j)=(long)u;
        !           164:          else
        !           165:          {
        !           166:            if (signe(u)) { B[k+1]=(long)u; coeff(lam,k,k)=un; fl[k]=1; }
        !           167:            else { B[k+1]=B[k]; fl[k]=0; }
        !           168:          }
        !           169:        }
        !           170:       }
        !           171:       if (low_stack(lim, stack_lim(av,1)))
        !           172:       {
        !           173:        if(DEBUGMEM>1) err(warnmem,"[1]: lllgramintwithcontent");
        !           174:        gptr[0]=&B; gptr[1]=&lam; gptr[2]=&h;
        !           175:        gptr[3]=&x; gptr[4]=&veccon; gerepilemany(av,gptr,5);
        !           176:       }
        !           177:     }
        !           178:     u=shifti(mulii(gcoeff(lam,k,k-1),(GEN)veccon[k]),1);
        !           179:     u2=mulii((GEN)B[k],(GEN)veccon[k-1]);
        !           180:     if (cmpii(absi(u),u2)>0)
        !           181:     {
        !           182:       q=dvmdii(addii(u,u2),shifti(u2,1),&r);
        !           183:       if (signe(r)<0) q=addsi(-1,q);
        !           184:       h[k]=lsub((GEN)h[k],gmul(q,(GEN)h[k-1]));
        !           185:       newcon=mppgcd((GEN)veccon[k],(GEN)veccon[k-1]);
        !           186:       corr=divii((GEN)veccon[k],newcon); veccon[k]=(long)newcon;
        !           187:       if(!gcmp1(corr))
        !           188:       {
        !           189:        corr2=sqri(corr);
        !           190:        for (j=1; j<=n; j++)
        !           191:          coeff(x,j,k)=coeff(x,k,j)=lmulii(corr,gcoeff(x,k,j));
        !           192:        coeff(x,k,k)=lmulii(corr,gcoeff(x,k,k));
        !           193:        for (j=k; j<=kmax; j++) B[j+1]=lmulii(corr2,(GEN)B[j+1]);
        !           194:        for (i=1; i<k; i++) coeff(lam,k,i)=lmulii(corr,gcoeff(lam,k,i));
        !           195:        for (i=k+1; i<=kmax; i++)
        !           196:        {
        !           197:          coeff(lam,i,k)=lmulii(corr,gcoeff(lam,i,k));
        !           198:          for (j=k+1; j<i; j++)
        !           199:            coeff(lam,i,j)=lmulii(corr2,gcoeff(lam,i,j));
        !           200:        }
        !           201:       }
        !           202:       r=negi(mulii(q,divii((GEN)veccon[k-1],(GEN)veccon[k])));
        !           203:       p1=gcoeff(x,k,k-1);
        !           204:       for (j=1; j<=n; j++)
        !           205:        coeff(x,j,k)=coeff(x,k,j)=laddii(gcoeff(x,j,k),mulii(r,(j==k)?p1:gcoeff(x,j,k-1)));
        !           206:       coeff(x,k,k)=laddii(gcoeff(x,k,k),mulii(r,gcoeff(x,k-1,k)));
        !           207:       coeff(lam,k,k-1)=laddii(gcoeff(lam,k,k-1),mulii(r,(GEN)B[k]));
        !           208:       for (i=1; i<k-1; i++)
        !           209:        coeff(lam,k,i)=laddii(gcoeff(lam,k,i),mulii(r,gcoeff(lam,k-1,i)));
        !           210:     }
        !           211:     if (low_stack(lim, stack_lim(av,1)))
        !           212:     {
        !           213:       if(DEBUGMEM>1) err(warnmem,"[2]: lllgramintwithcontent");
        !           214:       gptr[0]=&B; gptr[1]=&lam; gptr[2]=&h;
        !           215:       gptr[3]=&x; gptr[4]=&veccon; gerepilemany(av,gptr,5);
        !           216:     }
        !           217:     p3=mulii((GEN)B[k-1],(GEN)B[k+1]);la=gcoeff(lam,k,k-1);p4=mulii(la,la);
        !           218:     p2=mulsi(100,mulii(mulii((GEN)veccon[k],(GEN)veccon[k]),addii(p3,p4)));
        !           219:     p1=mulii((GEN)veccon[k-1],(GEN)B[k]);p1=mulsi(99,mulii(p1,p1));
        !           220:     if (fl[k-1] && (cmpii(p1,p2)>0 || !fl[k]))
        !           221:     {
        !           222:       if (DEBUGLEVEL>=4 && k==n)
        !           223:        { fprintferr(" (%ld)", expi(p1)-expi(p2)); flusherr(); }
        !           224:       p1=(GEN)h[k-1]; h[k-1]=h[k]; h[k]=(long)p1;
        !           225:       p1=(GEN)x[k-1]; x[k-1]=x[k]; x[k]=(long)p1;
        !           226:       for (j=1; j<=n; j++)
        !           227:       { p1=gcoeff(x,k-1,j); coeff(x,k-1,j)=coeff(x,k,j); coeff(x,k,j)=(long)p1; }
        !           228:       p1=(GEN)veccon[k-1]; veccon[k-1]=veccon[k]; veccon[k]=(long)p1;
        !           229:       for (j=1; j<=k-2; j++)
        !           230:       { p1=gcoeff(lam,k-1,j); coeff(lam,k-1,j)=coeff(lam,k,j); coeff(lam,k,j)=(long)p1; }
        !           231:       if (fl[k])
        !           232:       {
        !           233:        for (i=k+1; i<=kmax; i++)
        !           234:        {
        !           235:          bb=gcoeff(lam,i,k);
        !           236:          coeff(lam,i,k)=ldivii(subii(mulii((GEN)B[k+1],gcoeff(lam,i,k-1)),mulii(la,bb)),(GEN)B[k]);
        !           237:          coeff(lam,i,k-1)=ldivii(addii(mulii(la,gcoeff(lam,i,k-1)),mulii((GEN)B[k-1],bb)),(GEN)B[k]);
        !           238:           if (low_stack(lim, stack_lim(av,1)))
        !           239:          {
        !           240:            if(DEBUGMEM>1) err(warnmem,"[3]: lllgramintwithcontent");
        !           241:            gptr[0]=&B; gptr[1]=&lam; gptr[2]=&h;
        !           242:            gptr[3]=&x; gptr[4]=&la; gptr[5]=&veccon; gptr[6]=&p3;
        !           243:            gptr[7]=&p4; gerepilemany(av,gptr,8);
        !           244:          }
        !           245:        }
        !           246:        B[k]=ldivii(addii(p3,p4),(GEN)B[k]);
        !           247:       }
        !           248:       else
        !           249:       {
        !           250:        if (signe(la))
        !           251:        {
        !           252:          p2=(GEN)B[k]; p1=divii(p4,p2);
        !           253:          for (i=k+1; i<=kmax; i++)
        !           254:            coeff(lam,i,k-1)=ldivii(mulii(la,gcoeff(lam,i,k-1)),p2);
        !           255:          for (j=k+1; j<kmax; j++)
        !           256:          {
        !           257:            for (i=j+1; i<=kmax; i++)
        !           258:              coeff(lam,i,j)=ldivii(mulii(p1,gcoeff(lam,i,j)),p2);
        !           259:             if (low_stack(lim, stack_lim(av,1)))
        !           260:            {
        !           261:              if(DEBUGMEM>1) err(warnmem,"[4]: lllgramintwithcontent");
        !           262:              gptr[0]=&B; gptr[1]=&lam; gptr[2]=&h;
        !           263:              gptr[3]=&x; gptr[4]=&la; gptr[5]=&veccon; gptr[6]=&p1;
        !           264:              gptr[7]=&p2; gerepilemany(av,gptr,8);
        !           265:            }
        !           266:          }
        !           267:          B[k+1]=B[k]=(long)p1;
        !           268:          for (i=k+2; i<=lx; i++)
        !           269:            B[i]=ldivii(mulii(p1,(GEN)B[i]),p2);
        !           270:        }
        !           271:        else
        !           272:        {
        !           273:          coeff(lam,k,k-1)=zero;
        !           274:          for (i=k+1; i<=kmax; i++)
        !           275:          {
        !           276:            coeff(lam,i,k)=coeff(lam,i,k-1);
        !           277:            coeff(lam,i,k-1)=zero;
        !           278:          }
        !           279:          B[k]=B[k-1]; fl[k]=1; fl[k-1]=0;
        !           280:        }
        !           281:
        !           282:         if (low_stack(lim, stack_lim(av,1)))
        !           283:        {
        !           284:          if(DEBUGMEM>1) err(warnmem,"[5]: lllgramintwithcontent");
        !           285:          gptr[0]=&B; gptr[1]=&lam; gptr[2]=&h;
        !           286:          gptr[3]=&x; gptr[4]=&veccon;
        !           287:          gerepilemany(av,gptr,5);
        !           288:        }
        !           289:       }
        !           290:       if (k>2) k--;
        !           291:       if (DEBUGLEVEL>5) { fprintferr(" %ld",k); flusherr(); }
        !           292:     }
        !           293:     else
        !           294:     {
        !           295:       for (l=k-2; l>=1; l--)
        !           296:       {
        !           297:        u=shifti(mulii(gcoeff(lam,k,l),(GEN)veccon[k]),1);
        !           298:        u2=mulii((GEN)B[l+1],(GEN)veccon[l]);
        !           299:        if (cmpii(absi(u),u2)>0)
        !           300:        {
        !           301:          q=dvmdii(addii(u,u2),shifti(u2,1),&r);
        !           302:          if (signe(r)<0) q=addsi(-1,q);
        !           303:          h[k]=lsub((GEN)h[k],gmul(q,(GEN)h[l]));
        !           304:          newcon=mppgcd((GEN)veccon[k],(GEN)veccon[l]);
        !           305:          corr=divii((GEN)veccon[k],newcon); veccon[k]=(long)newcon;
        !           306:          if(!gcmp1(corr))
        !           307:          {
        !           308:            corr2=sqri(corr);
        !           309:            for (j=1; j<=n; j++)
        !           310:              coeff(x,j,k)=coeff(x,k,j)=lmulii(corr,gcoeff(x,k,j));
        !           311:            coeff(x,k,k)=lmulii(corr,gcoeff(x,k,k));
        !           312:            for (j=k; j<=kmax; j++) B[j+1]=lmulii(corr2,(GEN)B[j+1]);
        !           313:            for (i=1; i<k; i++) coeff(lam,k,i)=lmulii(corr,gcoeff(lam,k,i));
        !           314:            for (i=k+1; i<=kmax; i++)
        !           315:            {
        !           316:              coeff(lam,i,k)=lmulii(corr,gcoeff(lam,i,k));
        !           317:              for (j=k+1; j<i; j++)
        !           318:                coeff(lam,i,j)=lmulii(corr2,gcoeff(lam,i,j));
        !           319:            }
        !           320:          }
        !           321:          r=negi(mulii(q,divii((GEN)veccon[l],(GEN)veccon[k])));
        !           322:          p1=gcoeff(x,k,l);
        !           323:          for (j=1; j<=n; j++)
        !           324:            coeff(x,j,k)=coeff(x,k,j)=laddii(gcoeff(x,j,k),mulii(r,(j==k)?p1:gcoeff(x,j,l)));
        !           325:          coeff(x,k,k)=laddii(gcoeff(x,k,k),mulii(r,gcoeff(x,l,k)));
        !           326:          coeff(lam,k,l)=laddii(gcoeff(lam,k,l),mulii(r,(GEN)B[l+1]));
        !           327:          for (i=1; i<l; i++)
        !           328:            coeff(lam,k,i)=laddii(gcoeff(lam,k,i),mulii(r,gcoeff(lam,l,i)));
        !           329:        }
        !           330:         if (low_stack(lim, stack_lim(av,1)))
        !           331:        {
        !           332:          if(DEBUGMEM>1) err(warnmem,"[6]: lllgramintwithcontent");
        !           333:          gptr[0]=&B; gptr[1]=&lam; gptr[2]=&h;
        !           334:          gptr[3]=&x; gptr[4]=&veccon; gerepilemany(av,gptr,5);
        !           335:        }
        !           336:       }
        !           337:       k++; if (DEBUGLEVEL>5) { fprintferr(" %ld",k); flusherr(); }
        !           338:       if (k>n)
        !           339:       {
        !           340:         if (DEBUGLEVEL>5) { fprintferr("\n"); flusherr(); }
        !           341:        tetpil=avma;
        !           342:        return gerepile(av0,tetpil,lllgramall_finish(h,fl,flag,n));
        !           343:       }
        !           344:     }
        !           345:     if (low_stack(lim, stack_lim(av,1)))
        !           346:     {
        !           347:       if(DEBUGMEM>1) err(warnmem,"[7]: lllgramintwithcontent");
        !           348:       gptr[0]=&B; gptr[1]=&lam; gptr[2]=&h;
        !           349:       gptr[3]=&x; gptr[4]=&veccon; gerepilemany(av,gptr,5);
        !           350:     }
        !           351:   }
        !           352: }
        !           353:
        !           354: static GEN
        !           355: lllintwithcontent(GEN x)
        !           356: {
        !           357:   long lx=lg(x),i,j,av,tetpil;
        !           358:   GEN veccon,con,xred,g;
        !           359:
        !           360:   if (typ(x) != t_MAT) err(typeer,"lllintwithcontent");
        !           361:   if (lx==1) return cgetg(1,t_MAT);
        !           362:   av=avma; veccon=cgetg(lx,t_VEC); g=cgetg(lx,t_MAT); xred=cgetg(lx,t_MAT);
        !           363:   for (j=1; j<lx; j++)
        !           364:   {
        !           365:     g[j]=lgetg(lx,t_COL); con=content((GEN)x[j]);
        !           366:     xred[j]=ldiv((GEN)x[j],con); veccon[j]=(long)con;
        !           367:   }
        !           368:   for (i=1; i<lx; i++)
        !           369:     for (j=1; j<=i; j++)
        !           370:       coeff(g,i,j)=coeff(g,j,i)=(long)gscal((GEN)xred[i],(GEN)xred[j]);
        !           371:   tetpil=avma;
        !           372:   return gerepile(av,tetpil,lllgramintwithcontent(g,veccon,2));
        !           373: }
        !           374:
        !           375: /********************************************************************/
        !           376: /**                                                                **/
        !           377: /**                          LLL ALGORITHM                         **/
        !           378: /**                                                                **/
        !           379: /********************************************************************/
        !           380: #define swap(x,y) { long _t=x; x=y; y=_t; }
        !           381: #define gswap(x,y) { GEN _t=x; x=y; y=_t; }
        !           382:
        !           383: static void
        !           384: lllupdate_int(GEN x, GEN h, GEN L, GEN B, long K, long k, long l)
        !           385: {
        !           386:   long i,lx;
        !           387:   GEN r = truedvmdii(addii(B,shifti(gcoeff(L,k,l),1)), shifti(B,1), NULL);
        !           388:   GEN *hk,*hl,*xk,*xl;
        !           389:   if (!signe(r)) return;
        !           390:   r = negi(r); lx = lg(x);
        !           391:   hk = (GEN*)h[k]; hl = (GEN*)h[l];
        !           392:   xk = (GEN*)x[k]; xl = (GEN*)x[l];
        !           393:   if (is_pm1(r))
        !           394:   {
        !           395:     if (signe(r) > 0)
        !           396:     {
        !           397:       for (i=1;i<=K;i++) hk[i]=addii(hk[i],hl[i]);
        !           398:       for (i=1;i<lx;i++) xk[i]=addii(xk[i],xl[i]);
        !           399:       for (i=1;i<lx;i++) coeff(x,k,i)=laddii(gcoeff(x,k,i),gcoeff(x,l,i));
        !           400:       for (i=1;i<l; i++) coeff(L,k,i)=laddii(gcoeff(L,k,i),gcoeff(L,l,i));
        !           401:     } else {
        !           402:       for (i=1;i<=K;i++) hk[i]=subii(hk[i],hl[i]);
        !           403:       for (i=1;i<lx;i++) xk[i]=subii(xk[i],xl[i]);
        !           404:       for (i=1;i<lx;i++) coeff(x,k,i)=lsubii(gcoeff(x,k,i),gcoeff(x,l,i));
        !           405:       for (i=1;i<l; i++) coeff(L,k,i)=lsubii(gcoeff(L,k,i),gcoeff(L,l,i));
        !           406:     }
        !           407:   } else {
        !           408:     for(i=1;i<=K;i++) hk[i]=addii(hk[i],mulii(r,hl[i]));
        !           409:     for(i=1;i<lx;i++) xk[i]=addii(xk[i],mulii(r,xl[i]));
        !           410:     for(i=1;i<lx;i++) coeff(x,k,i)=laddii(gcoeff(x,k,i),mulii(r,gcoeff(x,l,i)));
        !           411:     for(i=1;i<l;i++)  coeff(L,k,i)=laddii(gcoeff(L,k,i),mulii(r,gcoeff(L,l,i)));
        !           412:   }
        !           413:   coeff(L,k,l)=laddii(gcoeff(L,k,l),mulii(r,B));
        !           414: }
        !           415:
        !           416: static void
        !           417: lllupdate(GEN x, GEN h, GEN L, long K, long k, long l)
        !           418: {
        !           419:   long e,i,lx;
        !           420:   GEN r = grndtoi(gcoeff(L,k,l),&e);
        !           421:   GEN *hk,*hl,*xk,*xl;
        !           422:   if (DEBUGLEVEL>8)
        !           423:     fprintferr("error bits when rounding in lllgram: %ld\n",e);
        !           424:   if (!signe(r)) return;
        !           425:   r = negi(r); lx = lg(x);
        !           426:   hk = (GEN*)h[k]; hl = (GEN*)h[l];
        !           427:   xk = (GEN*)x[k]; xl = (GEN*)x[l];
        !           428:   if (is_pm1(r))
        !           429:   {
        !           430:     if (signe(r) > 0)
        !           431:     {
        !           432:       for (i=1;i<=K;i++) hk[i]=addii(hk[i],hl[i]);
        !           433:       for (i=1;i<lx;i++) xk[i]=gadd(xk[i],xl[i]);
        !           434:       for (i=1;i<lx;i++) coeff(x,k,i)=ladd(gcoeff(x,k,i),gcoeff(x,l,i));
        !           435:       for (i=1;i<l; i++) coeff(L,k,i)=ladd(gcoeff(L,k,i),gcoeff(L,l,i));
        !           436:     } else {
        !           437:       for (i=1;i<=K;i++) hk[i]=subii(hk[i],hl[i]);
        !           438:       for (i=1;i<lx;i++) xk[i]=gsub(xk[i],xl[i]);
        !           439:       for (i=1;i<lx;i++) coeff(x,k,i)=lsub(gcoeff(x,k,i),gcoeff(x,l,i));
        !           440:       for (i=1;i<l; i++) coeff(L,k,i)=lsub(gcoeff(L,k,i),gcoeff(L,l,i));
        !           441:     }
        !           442:   } else {
        !           443:     for (i=1;i<=K;i++) hk[i]=addii(hk[i],mulii(r,hl[i]));
        !           444:     for (i=1;i<lx;i++) xk[i]=gadd(xk[i],gmul(r,xl[i]));
        !           445:     for (i=1;i<lx;i++) coeff(x,k,i)=ladd(gcoeff(x,k,i),gmul(r,gcoeff(x,l,i)));
        !           446:     for (i=1;i<l; i++) coeff(L,k,i)=ladd(gcoeff(L,k,i),gmul(r,gcoeff(L,l,i)));
        !           447:   }
        !           448:   coeff(L,k,l)=ladd(gcoeff(L,k,l),r);
        !           449: }
        !           450:
        !           451: /* x integer matrix */
        !           452: GEN
        !           453: lllgramall(GEN x, long alpha, long flag)
        !           454: {
        !           455:   long av0=avma,av,tetpil,lim,lx=lg(x),i,j,k,l,n,kmax;
        !           456:   GEN u,B,L,h,la,p1,p2,p3,p4,fl, *gptr[6];
        !           457:
        !           458:   if (typ(x) != t_MAT) err(typeer,"lllgramall");
        !           459:   n=lx-1; if (n<=1) return lllall_trivial(x,n,flag);
        !           460:   if (lg((GEN)x[1])!=lx) err(mattype1,"lllgramall");
        !           461:   fl = new_chunk(lx);
        !           462:
        !           463:   av=avma; lim=stack_lim(av,1); x=dummycopy(x);
        !           464:   B=gscalcol(gun, lx);
        !           465:   L=cgetg(lx,t_MAT);
        !           466:   for (j=1; j<lx; j++)
        !           467:   {
        !           468:     for (i=1; i<lx; i++)
        !           469:       if (typ(gcoeff(x,i,j))!=t_INT) err(lllger4);
        !           470:     fl[j] = 0; L[j] = (long)zerocol(n);
        !           471:   }
        !           472:   k=2; h=idmat(n); kmax=1;
        !           473:   u=gcoeff(x,1,1);
        !           474:   if (signe(u)) { B[2]=(long)u; coeff(L,1,1)=un; fl[1]=1; } else B[2]=un;
        !           475:   if (DEBUGLEVEL>5) fprintferr("k =");
        !           476:   for(;;)
        !           477:   {
        !           478:     if (k > kmax)
        !           479:     {
        !           480:       if (DEBUGLEVEL>3) {fprintferr(" K%ld",k);flusherr();}
        !           481:       kmax = k;
        !           482:       for (j=1; j<=k; j++)
        !           483:        if (j==k || fl[j])
        !           484:        {
        !           485:           long av1 = avma;
        !           486:          u = gcoeff(x,k,j);
        !           487:          for (i=1; i<j; i++) if (fl[i])
        !           488:             u = divii(subii(mulii((GEN)B[i+1],u),
        !           489:                             mulii(gcoeff(L,k,i),gcoeff(L,j,i))),
        !           490:                       (GEN)B[i]);
        !           491:           u = gerepileuptoint(av1, u);
        !           492:          if (j<k) coeff(L,k,j)=(long)u;
        !           493:          else
        !           494:          {
        !           495:            if (signe(u)) { B[k+1]=(long)u; coeff(L,k,k)=un; fl[k]=1; }
        !           496:            else { B[k+1]=B[k]; fl[k]=0; }
        !           497:          }
        !           498:        }
        !           499:     } else if (DEBUGLEVEL>5) {fprintferr(" %ld",k); flusherr();}
        !           500:     lllupdate_int(x,h,L,(GEN)B[k],kmax,k,k-1);
        !           501:     if (fl[k-1] &&
        !           502:      (cmpii(mulsi(alpha-1,sqri((GEN)B[k])),
        !           503:             mulsi(alpha,p3=addii(mulii((GEN)B[k-1],(GEN)B[k+1]),
        !           504:                                p4=sqri(la=gcoeff(L,k,k-1))))) > 0
        !           505:       || !fl[k]))
        !           506:     {
        !           507:       if (DEBUGLEVEL>3 && k==n)
        !           508:       {
        !           509:         fprintferr(" (%ld)", expi(mulsi(alpha-1,sqri((GEN)B[k])))
        !           510:                            - expi(mulsi(alpha,p3)));
        !           511:         flusherr();
        !           512:       }
        !           513:       swap(h[k-1], h[k]);
        !           514:       swap(x[k-1], x[k]);
        !           515:       for (j=1; j<=n; j++)  swap(coeff(x,k-1,j), coeff(x,k,j));
        !           516:       for (j=1; j<k-1; j++) swap(coeff(L,k-1,j), coeff(L,k,j))
        !           517:       if (fl[k])
        !           518:       {
        !           519:         GEN Bk = (GEN)B[k];
        !           520:         long av1 = avma;
        !           521:        for (i=k+1; i<=kmax; i++)
        !           522:        {
        !           523:          GEN bb=gcoeff(L,i,k);
        !           524:           p1 = divii(subii(mulii((GEN)B[k+1],gcoeff(L,i,k-1)),
        !           525:                            mulii(la,bb)), Bk);
        !           526:          av1=avma=coeff(L,i,k) = (long)icopy_av(p1,(GEN)av1);
        !           527:           p1 = divii(addii(mulii(la,gcoeff(L,i,k-1)),
        !           528:                            mulii((GEN)B[k-1],bb)), Bk);
        !           529:          av1=avma=coeff(L,i,k-1) = (long)icopy_av(p1,(GEN)av1);
        !           530:        }
        !           531:        B[k] = ldivii(p3,Bk);
        !           532:       }
        !           533:       else
        !           534:       {
        !           535:        if (signe(la))
        !           536:        {
        !           537:          p2=(GEN)B[k]; p1=divii(p4,p2);
        !           538:          B[k+1]=B[k]=(long)p1;
        !           539:          for (i=k+2; i<=lx; i++)
        !           540:            B[i]=ldivii(mulii(p1,(GEN)B[i]),p2);
        !           541:          for (i=k+1; i<=kmax; i++)
        !           542:            coeff(L,i,k-1)=ldivii(mulii(la,gcoeff(L,i,k-1)),p2);
        !           543:          for (j=k+1; j<kmax; j++)
        !           544:          {
        !           545:            for (i=j+1; i<=kmax; i++)
        !           546:              coeff(L,i,j)=ldivii(mulii(p1,gcoeff(L,i,j)),p2);
        !           547:            if (low_stack(lim, stack_lim(av,1)))
        !           548:            {
        !           549:              if(DEBUGMEM>1) err(warnmem,"lllgramall[1]");
        !           550:              gptr[0]=&B; gptr[1]=&L; gptr[2]=&h;
        !           551:              gptr[3]=&x; gptr[4]=&p2;
        !           552:              gerepilemany(av,gptr,5); p1=(GEN)B[k];
        !           553:            }
        !           554:          }
        !           555:        }
        !           556:        else
        !           557:        {
        !           558:          for (i=k+1; i<=kmax; i++)
        !           559:          { coeff(L,i,k)=coeff(L,i,k-1); coeff(L,i,k-1)=zero; }
        !           560:          B[k]=B[k-1]; fl[k]=1; fl[k-1]=0;
        !           561:        }
        !           562:       }
        !           563:       if (k>2) k--;
        !           564:     }
        !           565:     else
        !           566:     {
        !           567:       for (l=k-2; l; l--)
        !           568:       {
        !           569:         lllupdate_int(x,h,L,(GEN)B[l+1],kmax,k,l);
        !           570:         if (low_stack(lim, stack_lim(av,1)))
        !           571:         {
        !           572:           if(DEBUGMEM>1) err(warnmem,"lllgramall[2]");
        !           573:           gptr[0]=&B; gptr[1]=&L; gptr[2]=&h;
        !           574:           gptr[3]=&x; gerepilemany(av,gptr,4);
        !           575:         }
        !           576:       }
        !           577:       if (++k > n) break;
        !           578:     }
        !           579:     if (low_stack(lim, stack_lim(av,1)))
        !           580:     {
        !           581:       if(DEBUGMEM>1) err(warnmem,"lllgramall[3]");
        !           582:       gptr[0]=&B; gptr[1]=&L; gptr[2]=&h;
        !           583:       gptr[3]=&x; gerepilemany(av,gptr,4);
        !           584:     }
        !           585:   }
        !           586:   if (DEBUGLEVEL>3) fprintferr("\n");
        !           587:   tetpil=avma; return gerepile(av0,tetpil,lllgramall_finish(h,fl,flag,n));
        !           588: }
        !           589:
        !           590: static GEN
        !           591: lllgramall0(GEN x, long flag) { return lllgramall(x,100,flag); }
        !           592:
        !           593: static int
        !           594: pslg(GEN x)
        !           595: {
        !           596:   long tx;
        !           597:   if (gcmp0(x)) return 2;
        !           598:   tx=typ(x); return is_scalar_t(tx)? 3: lgef(x);
        !           599: }
        !           600:
        !           601: static GEN
        !           602: lllgramallgen(GEN x, long flag)
        !           603: {
        !           604:   long av0=avma,av,tetpil,lx=lg(x),tu,i,j,k,l,n,lim;
        !           605:   GEN u,B,lam,q,cq,h,la,bb,p1,p2,p3,p4,fl;
        !           606:   int ps1,ps2,flc;
        !           607:
        !           608:   if (typ(x) != t_MAT) err(typeer,"lllgramallgen");
        !           609:   n=lx-1; if (n<=1) return lllall_trivial(x,n,flag);
        !           610:   if (lg((GEN)x[1])!=lx) err(mattype1,"lllgramallgen");
        !           611:
        !           612:   fl = new_chunk(lx);
        !           613:
        !           614:   av=avma; lim=stack_lim(av,1);
        !           615:   B=cgetg(lx+1,t_COL);
        !           616:   B[1]=un; lam=cgetg(lx,t_MAT);
        !           617:   for (j=1; j<lx; j++) lam[j]=lgetg(lx,t_COL);
        !           618:   for (i=1; i<lx; i++)
        !           619:     for (j=1; j<=i; j++)
        !           620:     {
        !           621:       if (j<i && !fl[j]) coeff(lam,i,j)=coeff(lam,j,i)=zero;
        !           622:       else
        !           623:       {
        !           624:        u=gcoeff(x,i,j); tu=typ(u);
        !           625:        if (! is_scalar_t(tu) && tu != t_POL) err(lllger4);
        !           626:        for (k=1; k<j; k++)
        !           627:          if (fl[k])
        !           628:            u=gdiv(gsub( gmul((GEN)B[k+1],u),
        !           629:                          gmul(gcoeff(lam,i,k),gcoeff(lam,j,k)) ),
        !           630:                   (GEN)B[k]);
        !           631:        if (j<i) { coeff(lam,i,j)=(long)u; coeff(lam,j,i)=zero; }
        !           632:        else
        !           633:        {
        !           634:          if (!gcmp0(u)) { B[i+1]=(long)u; coeff(lam,i,i)=un; fl[i]=1; }
        !           635:          else { B[i+1]=B[i]; coeff(lam,i,i)=zero; fl[i]=0; }
        !           636:        }
        !           637:       }
        !           638:     }
        !           639:   k=2; h=idmat(n); flc=0;
        !           640:   for(;;)
        !           641:   {
        !           642:     u=gcoeff(lam,k,k-1);
        !           643:     if (pslg(u) >= pslg((GEN)B[k]))
        !           644:     {
        !           645:       q=gdeuc(u,(GEN)B[k]); cq=gdivsg(1,content(q)); q=gmul(q,cq); flc=1;
        !           646:       h[k]=lsub(gmul(cq,(GEN)h[k]),gmul(q,(GEN)h[k-1]));
        !           647:       coeff(lam,k,k-1)=lsub(gmul(cq,gcoeff(lam,k,k-1)),gmul(q,(GEN)B[k]));
        !           648:       for (i=1; i<k-1; i++)
        !           649:        coeff(lam,k,i)=lsub(gmul(cq,gcoeff(lam,k,i)),gmul(q,gcoeff(lam,k-1,i)));
        !           650:     }
        !           651:     ps1 = pslg(gsqr((GEN)B[k]));
        !           652:     p3 = gmul((GEN)B[k-1],(GEN)B[k+1]);
        !           653:     la=gcoeff(lam,k,k-1); p4 = gmul(la,gcoeff(lam,k,k-1));
        !           654:     ps2=pslg(gadd(p3,p4));
        !           655:     if (fl[k-1] && (ps1>ps2 || (ps1==ps2 && flc) || !fl[k]))
        !           656:     {
        !           657:       flc = (ps1!=ps2);
        !           658:       swap(h[k-1],h[k]);
        !           659:       for (j=1; j<=k-2; j++) swap(coeff(lam,k-1,j), coeff(lam,k,j));
        !           660:       if (fl[k])
        !           661:       {
        !           662:        for (i=k+1; i<=n; i++)
        !           663:        {
        !           664:          bb=gcoeff(lam,i,k);
        !           665:          coeff(lam,i,k)=ldiv(gsub(gmul((GEN)B[k+1],gcoeff(lam,i,k-1)),gmul(la,bb)),(GEN)B[k]);
        !           666:          coeff(lam,i,k-1)=ldiv(gadd(gmul(la,gcoeff(lam,i,k-1)),gmul((GEN)B[k-1],bb)),(GEN)B[k]);
        !           667:         }
        !           668:        B[k]=ldiv(gadd(p3,p4),(GEN)B[k]);
        !           669:       }
        !           670:       else
        !           671:       {
        !           672:        if (!gcmp0(la))
        !           673:        {
        !           674:          p2=(GEN)B[k]; p1=gdiv(p4,p2);
        !           675:          for (i=k+1; i<lx; i++)
        !           676:            coeff(lam,i,k-1)=ldiv(gmul(la,gcoeff(lam,i,k-1)),p2);
        !           677:          for (j=k+1; j<lx-1; j++)
        !           678:            for (i=j+1; i<lx; i++)
        !           679:              coeff(lam,i,j)=ldiv(gmul(p1,gcoeff(lam,i,j)),p2);
        !           680:          B[k+1]=B[k]=(long)p1;
        !           681:          for (i=k+2; i<=lx; i++)
        !           682:            B[i]=ldiv(gmul(p1,(GEN)B[i]),p2);
        !           683:         }
        !           684:        else
        !           685:        {
        !           686:          coeff(lam,k,k-1)=zero;
        !           687:          for (i=k+1; i<lx; i++)
        !           688:          { coeff(lam,i,k)=coeff(lam,i,k-1); coeff(lam,i,k-1)=zero; }
        !           689:          B[k]=B[k-1]; fl[k]=1; fl[k-1]=0;
        !           690:         }
        !           691:       }
        !           692:       if (k>2) k--;
        !           693:     }
        !           694:     else
        !           695:     {
        !           696:       for (l=k-2; l>=1; l--)
        !           697:       {
        !           698:        u=gcoeff(lam,k,l);
        !           699:        if (pslg(u)>=pslg((GEN)B[l+1]))
        !           700:        {
        !           701:          q=gdeuc(u,(GEN)B[l+1]); cq=gdivsg(1,content(q));
        !           702:           q=gmul(q,cq); flc=1;
        !           703:          h[k]=lsub(gmul(cq,(GEN)h[k]),gmul(q,(GEN)h[l]));
        !           704:          coeff(lam,k,l)=lsub(gmul(cq,gcoeff(lam,k,l)),gmul(q,(GEN)B[l+1]));
        !           705:          for (i=1; i<l; i++)
        !           706:             coeff(lam,k,i)=lsub(gmul(cq,gcoeff(lam,k,i)),gmul(q,gcoeff(lam,l,i)));
        !           707:        }
        !           708:       }
        !           709:       if (++k > n) break;
        !           710:     }
        !           711:     if (low_stack(lim, stack_lim(av,1)))
        !           712:     {
        !           713:       GEN *gptr[4];
        !           714:       if(DEBUGMEM>1) err(warnmem,"lllgramallgen");
        !           715:       gptr[0]=&B; gptr[1]=&lam; gptr[2]=&h;
        !           716:       gerepilemany(av,gptr,3);
        !           717:     }
        !           718:   }
        !           719:   tetpil=avma;
        !           720:   return gerepile(av0,tetpil,lllgramall_finish(h,fl,flag,n));
        !           721: }
        !           722:
        !           723: /* return x[k,j] - (mu.A)[j] */
        !           724: #ifdef INLINE
        !           725: INLINE
        !           726: #endif
        !           727: GEN
        !           728: get_Aj(GEN x, GEN mu, GEN A, long j, long k)
        !           729: {
        !           730:   long av,i;
        !           731:   GEN s;
        !           732:
        !           733:   if (j==1) return gcopy(gcoeff(x,k,1));
        !           734:   av = avma; s = gmul(gcoeff(mu,j,1),(GEN)A[1]);
        !           735:   for (i=2; i<j; i++) s=gadd(s,gmul(gcoeff(mu,j,i),(GEN)A[i]));
        !           736:   s=gneg(s); return gerepileupto(av, gadd(gcoeff(x,k,j),s));
        !           737: }
        !           738:
        !           739: /* x = Gram(b_i). If precision problems return NULL if flag=1, error otherwise.
        !           740:  * Quality ratio = (alpha-1)/alpha. Suggested value: alpha = 100
        !           741:  */
        !           742: GEN
        !           743: lllgramintern(GEN x, long alpha, long flag, long prec)
        !           744: {
        !           745:   GEN xinit,L,h,A,B,L1,L2,q,cst;
        !           746:   long retry = 2, av = avma,tetpil,lim,l,i,j,k,k1,lx=lg(x),n,kmax;
        !           747:
        !           748:   if (typ(x) != t_MAT) err(typeer,"lllgram");
        !           749:   n=lx-1; if (n && lg((GEN)x[1])!=lx) err(mattype1,"lllgram");
        !           750:   if (n<=1) return idmat(n);
        !           751:   lim = stack_lim(av,1); xinit=x;
        !           752:   for (k=2,j=1; j<lx; j++)
        !           753:   {
        !           754:     GEN p1=(GEN)x[j];
        !           755:     for (i=1; i<lx; i++) /* FIXME: lg <-> expo */
        !           756:       if (typ(p1[i]) == t_REAL) { l = lg((GEN)p1[i]); if (l>k) k=l; }
        !           757:   }
        !           758:   if (k == 2)
        !           759:   {
        !           760:     if (!prec) return lllgramint(x);
        !           761:     x = gmul(x, realun(prec+1));
        !           762:   }
        !           763:   else if (prec < k) prec = k;
        !           764:   h = idmat(n);
        !           765:   x = gprec_w(x, prec+1);
        !           766:
        !           767: LABLLLGRAM:
        !           768:   switch(retry--)
        !           769:   {
        !           770:     case 2: /* entry */ break;
        !           771:     case 1: /* failed already */
        !           772:       tetpil = avma; h = gcopy(h);
        !           773:       prec = (prec<<1)-2;
        !           774:       if (DEBUGLEVEL > 3) fprintferr("\n");
        !           775:       if (DEBUGLEVEL) err(warnprec,"lllgramintern",prec);
        !           776:       x = qf_base_change(gprec_w(xinit,prec),h,1);
        !           777:       {
        !           778:         GEN *gsav[2]; gsav[0]=&h; gsav[1]=&x;
        !           779:         gerepilemanysp(av, tetpil, gsav, 2);
        !           780:       }
        !           781:       if (DEBUGLEVEL) err(warner,"lllgramintern starting over");
        !           782:       break;
        !           783:     case 0: /* give up */
        !           784:       if (DEBUGLEVEL > 3) fprintferr("\n");
        !           785:       if (DEBUGLEVEL) err(warner,"lllgramintern giving up");
        !           786:       if (flag) { avma=av; return NULL; }
        !           787:       if (DEBUGLEVEL) outerr(xinit);
        !           788:       err(lllger3);
        !           789:   }
        !           790:   cst = cgetr(prec+1); affsr(alpha-1,cst);
        !           791:   cst = divrs(cst,alpha);
        !           792:
        !           793:   L=cgetg(lx,t_MAT);
        !           794:   B=cgetg(lx,t_COL);
        !           795:   A=cgetg(lx,t_VEC);
        !           796:   for (j=1; j<lx; j++)
        !           797:   {
        !           798:     L[j] = (long)zerocol(n);
        !           799:     A[j] = B[j] = zero;
        !           800:   }
        !           801:   k=2; kmax=1; B[1]=coeff(x,1,1);
        !           802:   if (gcmp0((GEN)B[1]))
        !           803:   {
        !           804:     if (flag) return NULL;
        !           805:     err(lllger3);
        !           806:   }
        !           807:   if (DEBUGLEVEL>5) fprintferr("k =");
        !           808:   for(;;)
        !           809:   {
        !           810:     if (k>kmax)
        !           811:     {
        !           812:       if (DEBUGLEVEL>3) {fprintferr(" K%ld",k);flusherr();}
        !           813:       kmax=k;
        !           814:       for (j=1; j<k; j++)
        !           815:       {
        !           816:         A[j] = (long)get_Aj(x,L,A,j,k);
        !           817:         coeff(L,k,j) = ldiv((GEN)A[j],(GEN)B[j]);
        !           818:       }
        !           819:       B[k] = (long)get_Aj(x,L,A,k,k);
        !           820:       if (gsigne((GEN)B[k]) <= 0)
        !           821:       {
        !           822:         if (kmax == 2) retry = 0;
        !           823:         goto LABLLLGRAM;
        !           824:       }
        !           825:     }
        !           826:     else if (DEBUGLEVEL>5) fprintferr(" %ld",k);
        !           827:     L1=gcoeff(L,k,k-1);
        !           828:     if (DEBUGLEVEL>9)
        !           829:     {
        !           830:       fprintferr(" %ld", gexpo(L1) - bit_accuracy(lg(L1)));
        !           831:       for (i=1; i<lx; i++)
        !           832:         fprintferr("%ld: %Z\n",i,qfeval(x,(GEN)h[i]));
        !           833:       flusherr();
        !           834:     }
        !           835:     if (2*gexpo(L1) > bit_accuracy(lg(L1)))
        !           836:     {
        !           837:       if (DEBUGLEVEL>3)
        !           838:       {
        !           839:        fprintferr("\nRecomputing Gram-Schmidt, kmax = %ld\n",kmax);
        !           840:         if (DEBUGLEVEL>9) fprintferr("Old B = %Z\n",B);
        !           841:       }
        !           842:       for (k1=1; k1<=kmax; k1++)
        !           843:       {
        !           844:        for (j=1; j<k1; j++)
        !           845:        {
        !           846:          A[j] = (long)get_Aj(x,L,A,j,k1);
        !           847:           coeff(L,k1,j) = ldiv((GEN)A[j],(GEN)B[j]);
        !           848:        }
        !           849:         B[k1] = (long)get_Aj(x,L,A,k1,k1);
        !           850:        if (gsigne((GEN)B[k1]) <= 0) goto LABLLLGRAM;
        !           851:       }
        !           852:       if (DEBUGLEVEL>9) fprintferr("New B = %Z\n",B);
        !           853:     }
        !           854:     lllupdate(x,h,L,kmax,k,k-1);
        !           855:     L1 = gcoeff(L,k,k-1);
        !           856:     L2 = gsqr(L1);
        !           857:     q = gmul((GEN)B[k-1], gsub(cst,L2));
        !           858:     if (gcmp(q,(GEN)B[k]) > 0)
        !           859:     {
        !           860:       GEN BK,BB;
        !           861:       if (DEBUGLEVEL>3 && k==kmax)
        !           862:       { fprintferr(" (%ld)",gexpo(q)-gexpo((GEN)B[k])); flusherr(); }
        !           863:       BB = gadd((GEN)B[k], gmul((GEN)B[k-1],L2));
        !           864:       if (gcmp0(BB)) goto LABLLLGRAM;
        !           865:       coeff(L,k,k-1) = ldiv(gmul(L1,(GEN)B[k-1]), BB);
        !           866:       BK = gdiv((GEN)B[k],BB);
        !           867:       B[k] = lmul((GEN)B[k-1], BK);
        !           868:       B[k-1] = (long)BB;
        !           869:       swap(h[k-1],h[k]);
        !           870:       swap(x[k-1],x[k]);
        !           871:       for (j=1; j<=n; j++)  swap(coeff(x,k-1,j), coeff(x,k,j));
        !           872:       for (j=1; j<k-1; j++) swap(coeff(L,k-1,j), coeff(L,k,j))
        !           873:       for (i=k+1; i<=kmax; i++)
        !           874:       {
        !           875:        GEN p=gcoeff(L,i,k);
        !           876:         coeff(L,i,k) = lsub(gcoeff(L,i,k-1),gmul(L1,p));
        !           877:        coeff(L,i,k-1)=ladd(gmul(BK,p), gmul(gcoeff(L,k,k-1),gcoeff(L,i,k-1)));
        !           878:       }
        !           879:       if (k>2) k--;
        !           880:     }
        !           881:     else
        !           882:     {
        !           883:       for (l=k-2; l; l--) lllupdate(x,h,L,kmax,k,l);
        !           884:       if (++k > n) break;
        !           885:     }
        !           886:     if (low_stack(lim, stack_lim(av,1)))
        !           887:     {
        !           888:       GEN *gptr[6];
        !           889:       if(DEBUGMEM>1)
        !           890:       {
        !           891:         if (DEBUGLEVEL > 3) fprintferr("\n");
        !           892:         err(warnmem,"lllgram");
        !           893:       }
        !           894:       gptr[0]=&B; gptr[1]=&L; gptr[2]=&h; gptr[3]=&A;
        !           895:       gptr[4]=&x; gptr[5]=&cst; gerepilemany(av,gptr,6);
        !           896:     }
        !           897:   }
        !           898:   if (DEBUGLEVEL>3) fprintferr("\n");
        !           899:   tetpil=avma; return gerepile(av,tetpil,gcopy(h));
        !           900: }
        !           901:
        !           902: static GEN
        !           903: lllgram_noerr(GEN x,long prec) { return lllgramintern(x,100,1,prec); }
        !           904:
        !           905: GEN
        !           906: lllgram(GEN x,long prec) { return lllgramintern(x,100,0,prec); }
        !           907:
        !           908: GEN
        !           909: qflll0(GEN x, long flag, long prec)
        !           910: {
        !           911:   switch(flag)
        !           912:   {
        !           913:     case 0: return lll(x,prec);
        !           914:     case 1: return lllint(x);
        !           915:     case 2: return lllintpartial(x);
        !           916:     case 3: return lllrat(x);
        !           917:     case 4: return lllkerim(x);
        !           918:     case 5: return lllkerimgen(x);
        !           919:     case 7: return lll1(x,prec);
        !           920:     case 8: return lllgen(x);
        !           921:     case 9: return lllintwithcontent(x);
        !           922:     default: err(flagerr,"qflll");
        !           923:   }
        !           924:   return NULL; /* not reached */
        !           925: }
        !           926:
        !           927: GEN
        !           928: qflllgram0(GEN x, long flag, long prec)
        !           929: {
        !           930:   switch(flag)
        !           931:   {
        !           932:     case 0: return lllgram(x,prec);
        !           933:     case 1: return lllgramint(x);
        !           934:     case 4: return lllgramkerim(x);
        !           935:     case 5: return lllgramkerimgen(x);
        !           936:     case 7: return lllgram1(x,prec);
        !           937:     case 8: return lllgramgen(x);
        !           938:     default: err(flagerr,"qflllgram");
        !           939:   }
        !           940:   return NULL; /* not reached */
        !           941: }
        !           942:
        !           943: /* x est la matrice d'une base b_i; retourne la matrice u (entiere
        !           944:  * unimodulaire) d'une base LLL-reduite c_i en fonction des b_i (la base
        !           945:  * reduite est c=b*u).
        !           946:  */
        !           947: static GEN
        !           948: lll_proto(GEN x, GEN f(GEN, long), long prec)
        !           949: {
        !           950:   long lx=lg(x),i,j,av,av1;
        !           951:   GEN g;
        !           952:
        !           953:   if (typ(x) != t_MAT) err(typeer,"lll_proto");
        !           954:   if (lx==1) return cgetg(1,t_MAT);
        !           955:   av=avma; g=cgetg(lx,t_MAT);
        !           956:   for (j=1; j<lx; j++) g[j]=lgetg(lx,t_COL);
        !           957:   for (i=1; i<lx; i++)
        !           958:     for (j=1; j<=i; j++)
        !           959:       coeff(g,i,j)=coeff(g,j,i)=(long)gscal((GEN)x[i],(GEN)x[j]);
        !           960:   av1=avma; x = f(g,prec);
        !           961:   if (!x) { avma=av; return NULL; }
        !           962:   return gerepile(av,av1,x);
        !           963: }
        !           964:
        !           965: GEN
        !           966: lllintern(GEN x,long flag,long prec)
        !           967: {
        !           968:   return lll_proto(x,flag? lllgram_noerr: lllgram,prec);
        !           969: }
        !           970:
        !           971: GEN
        !           972: lll(GEN x,long prec) { return lll_proto(x,lllgram,prec); }
        !           973:
        !           974: GEN
        !           975: lll1(GEN x,long prec) { return lll_proto(x,lllgram1,prec); }
        !           976:
        !           977: GEN
        !           978: lllrat(GEN x) { return lll_proto(x,lllgram,lll_ALL); }
        !           979:
        !           980: GEN
        !           981: lllint(GEN x) { return lll_proto(x,lllgramall0,lll_IM); }
        !           982:
        !           983: GEN
        !           984: lllgen(GEN x) { return lll_proto(x,lllgramallgen,lll_IM); }
        !           985:
        !           986: GEN
        !           987: lllgramgen(GEN x) { return lllgramallgen(x,lll_IM); }
        !           988:
        !           989: GEN
        !           990: lllgramkerimgen(GEN x) { return lllgramallgen(x,lll_ALL); }
        !           991:
        !           992: static GEN
        !           993: lllkerim_proto(GEN x, GEN f(GEN,long))
        !           994: {
        !           995:   long lx=lg(x), i,j,av,av1;
        !           996:   GEN g;
        !           997:
        !           998:   if (typ(x) != t_MAT) err(typeer,"lllkerim_proto");
        !           999:   if (lx==1)
        !          1000:   {
        !          1001:     g=cgetg(3,t_VEC);
        !          1002:     g[1]=lgetg(1,t_MAT);
        !          1003:     g[2]=lgetg(1,t_MAT); return g;
        !          1004:   }
        !          1005:   if (lg((GEN)x[1])==1)
        !          1006:   {
        !          1007:     g=cgetg(3,t_VEC);
        !          1008:     g[1]=(long)idmat(lx-1);
        !          1009:     g[2]=lgetg(1,t_MAT); return g;
        !          1010:   }
        !          1011:   av=avma; g=cgetg(lx,t_MAT);
        !          1012:   for (j=1; j<lx; j++) g[j]=lgetg(lx,t_COL);
        !          1013:   for (i=1; i<lx; i++)
        !          1014:     for (j=1; j<=i; j++)
        !          1015:       coeff(g,i,j)=coeff(g,j,i)=(long)gscal((GEN)x[i],(GEN)x[j]);
        !          1016:   av1=avma; return gerepile(av,av1,f(g,lll_ALL));
        !          1017: }
        !          1018:
        !          1019: GEN
        !          1020: lllkerim(GEN x) { return lllkerim_proto(x,lllgramall0); }
        !          1021:
        !          1022: GEN
        !          1023: lllkerimgen(GEN x) { return lllkerim_proto(x,lllgramallgen); }
        !          1024:
        !          1025: /* x est ici la matrice de GRAM des bi.  */
        !          1026: GEN
        !          1027: lllgram1(GEN x, long prec)
        !          1028: {
        !          1029:   GEN mu,u,B,BB,BK,p,q,r,cst,unreel,sv,mu1,mu2;
        !          1030:   long av,tetpil,lim,l,i,j,k,lx=lg(x),n,e;
        !          1031:
        !          1032:   if (typ(x) != t_MAT) err(typeer,"lllgram1");
        !          1033:   if (lg((GEN)x[1])!=lx) err(mattype1,"lllgram1"); n=lx-1;
        !          1034:   if (n<=1) return idmat(n);
        !          1035:   cst=gdivgs(stoi(99),100); /* LLL proposent 0.75 */
        !          1036:   if (prec)
        !          1037:   {
        !          1038:     unreel = realun(prec+1);
        !          1039:     x = gmul(x,unreel);
        !          1040:     cst = gmul(cst,unreel);
        !          1041:   }
        !          1042:   av=avma; lim=stack_lim(av,1);
        !          1043:   mu=gtrans(sqred(x)); B=cgetg(lx,t_COL);
        !          1044:   for (i=1,l=0; i<=n; i++)
        !          1045:   {
        !          1046:     if (gsigne((GEN)(B[i]=coeff(mu,i,i)))>0) l++;
        !          1047:     coeff(mu,i,i)=un;
        !          1048:   }
        !          1049:   if (l<n) err(lllger3);
        !          1050:
        !          1051:   u=idmat(n); k=2;
        !          1052:   do
        !          1053:   {
        !          1054:     if (!gcmp0(r=grndtoi(gcoeff(mu,k,k-1),&e)))
        !          1055:     {
        !          1056:       u[k]=lsub((GEN)u[k],gmul(r,(GEN)u[k-1]));
        !          1057:       for (j=1; j<k-1; j++)
        !          1058:        coeff(mu,k,j)=lsub(gcoeff(mu,k,j),gmul(r,gcoeff(mu,k-1,j)));
        !          1059:       mu1=(GEN)(coeff(mu,k,k-1)=lsub(gcoeff(mu,k,k-1),r));
        !          1060:     }
        !          1061:     else mu1=gcoeff(mu,k,k-1);
        !          1062:     q=gmul((GEN)B[k-1],gsub(cst,mu2=gsqr(mu1)));
        !          1063:     if (gcmp(q,(GEN)B[k])>0)
        !          1064:     {
        !          1065:       BB=gadd((GEN)B[k],gmul((GEN)B[k-1],mu2));
        !          1066:       coeff(mu,k,k-1)=ldiv(gmul(mu1,(GEN)B[k-1]),BB);
        !          1067:       B[k]=lmul((GEN)B[k-1],BK=gdiv((GEN)B[k],BB));
        !          1068:       B[k-1]=(long)BB;
        !          1069:       swap(u[k-1],u[k]);
        !          1070:       for (j=1; j<=k-2; j++) swap(coeff(mu,k-1,j), coeff(mu,k,j));
        !          1071:       for (i=k+1; i<=n; i++)
        !          1072:       {
        !          1073:        p=gcoeff(mu,i,k);
        !          1074:        coeff(mu,i,k)=lsub(gcoeff(mu,i,k-1),gmul(mu1,p));
        !          1075:        coeff(mu,i,k-1)=ladd(gmul(BK,p),gmul(gcoeff(mu,k,k-1),gcoeff(mu,i,k-1)));
        !          1076:       }
        !          1077:       if (k>2) k--;
        !          1078:     }
        !          1079:     else
        !          1080:     {
        !          1081:       for (l=k-2; l; l--)
        !          1082:       {
        !          1083:        if (!gcmp0(r=grndtoi(gcoeff(mu,k,l),&e)))
        !          1084:        {
        !          1085:          u[k]=lsub((GEN)u[k],gmul(r,(GEN)u[l]));
        !          1086:          for (j=1; j<l; j++)
        !          1087:            coeff(mu,k,j)=lsub(gcoeff(mu,k,j),gmul(r,gcoeff(mu,l,j)));
        !          1088:          coeff(mu,k,l)=lsub(gcoeff(mu,k,l),r);
        !          1089:         }
        !          1090:       }
        !          1091:       k++;
        !          1092:     }
        !          1093:     if (low_stack(lim, stack_lim(av,1)))
        !          1094:     {
        !          1095:       if(DEBUGMEM>1) err(warnmem,"lllgram1");
        !          1096:       tetpil=avma;
        !          1097:       sv=cgetg(4,t_VEC);
        !          1098:       sv[1]=lcopy(B); sv[2]=lcopy(u); sv[3]=lcopy(mu);
        !          1099:       sv=gerepile(av,tetpil,sv);
        !          1100:       B=(GEN)sv[1]; u=(GEN)sv[2]; mu=(GEN)sv[3];
        !          1101:     }
        !          1102:   }
        !          1103:   while (k<=n);
        !          1104:   tetpil=avma; return gerepile(av,tetpil,gcopy(u));
        !          1105: }
        !          1106:
        !          1107: GEN
        !          1108: lllgramint(GEN x)
        !          1109: {
        !          1110:   return lllgramall0(x,lll_IM);
        !          1111: }
        !          1112:
        !          1113: GEN
        !          1114: lllgramkerim(GEN x)
        !          1115: {
        !          1116:   return lllgramall0(x,lll_ALL);
        !          1117: }
        !          1118:
        !          1119: /*  This routine is functionally similar to lllint when all = 0.
        !          1120:  *
        !          1121:  *    The input is an integer matrix mat (not necessarily square) whose
        !          1122:  *  columns are linearly independent.  It outputs another matrix T such that
        !          1123:  *  mat * T is partially reduced.  If all = 0, the size of mat * T is the
        !          1124:  *  same as the size of mat.  If all = 1 the number of columns of mat * T
        !          1125:  *  is at most equal to its number of rows.  A matrix M is said to be
        !          1126:  *  -partially reduced- if | m1 +- m2 | >= |m1| for any two distinct
        !          1127:  *  columns m1, m2, in M.
        !          1128:  *
        !          1129:  *    This routine is designed to quickly reduce lattices in which one row
        !          1130:  *  is huge compared to the other rows.  For example, when searching for a
        !          1131:  *  polynomial of degree 3 with root a mod p, the four input vectors might
        !          1132:  *  be the coefficients of
        !          1133:  *      X^3 - (a^3 mod p), X^2 - (a^2 mod p), X - (a mod p), p.
        !          1134:  *  All four constant coefficients are O(p) and the rest are O(1). By the
        !          1135:  *  pigeon-hole principle, the coefficients of the smallest vector in the
        !          1136:  *  lattice are O(p^(1/4)), Hence significant reduction of vector lengths
        !          1137:  *  can be anticipated.
        !          1138:  *
        !          1139:  *             Peter Montgomery (July, 1994)
        !          1140:  *
        !          1141:  *  If flag = 1 complete the reduction using lllint, otherwise return
        !          1142:  *  partially reduced basis.
        !          1143:  */
        !          1144: GEN
        !          1145: lllintpartialall(GEN m, long flag)
        !          1146: {
        !          1147:   const long ncol = lg(m)-1;
        !          1148:   const long ltop1 = avma;
        !          1149:   long ncolnz;
        !          1150:   GEN tm1, tm2, mid, *gptr[4];
        !          1151:
        !          1152:   if (typ(m) != t_MAT) err(typeer,"lllintpartialall");
        !          1153:   if (ncol <= 1) return idmat(ncol);
        !          1154:
        !          1155:   {
        !          1156:     GEN dot11 = sqscali((GEN)m[1]);
        !          1157:     GEN dot22 = sqscali((GEN)m[2]);
        !          1158:     GEN dot12 = gscali((GEN)m[1], (GEN)m[2]);
        !          1159:     GEN tm  = idmat(2); /* For first two columns only */
        !          1160:
        !          1161:     int progress = 0;
        !          1162:     long npass2 = 0;
        !          1163:
        !          1164: /* Try to row reduce the first two columns of m.
        !          1165:  * Our best result so far is (first two columns of m)*tm.
        !          1166:  *
        !          1167:  * Initially tm = 2 x 2 identity matrix.
        !          1168:  * The inner products of the reduced matrix are in
        !          1169:  * dot11, dot12, dot22.
        !          1170:  */
        !          1171:     while (npass2 < 2 || progress)
        !          1172:     {
        !          1173:       GEN dot12new,q = gdivround(dot12, dot22);
        !          1174:
        !          1175:       npass2++; progress = signe(q);
        !          1176:       if (progress)
        !          1177:       {
        !          1178:        /* Conceptually replace (v1, v2) by (v1 - q*v2, v2),
        !          1179:         * where v1 and v2 represent the reduced basis for the
        !          1180:         * first two columns of the matrix.
        !          1181:         *
        !          1182:         * We do this by updating tm and the inner products.
        !          1183:         *
        !          1184:         * An improved algorithm would look only at the leading
        !          1185:         * digits of dot11, dot12, dot22.  It would use
        !          1186:         * single-precision calculations as much as possible.
        !          1187:         */
        !          1188:         q = negi(q);
        !          1189:         dot12new = addii(dot12, mulii(q, dot22));
        !          1190:         dot11 = addii(dot11, mulii(q, addii(dot12, dot12new)));
        !          1191:         dot12 = dot12new;
        !          1192:         tm[1] = (long)lincomb_integral(gun,q, (GEN)tm[1],(GEN)tm[2]);
        !          1193:       }
        !          1194:
        !          1195:       /* Interchange the output vectors v1 and v2.  */
        !          1196:       gswap(dot11,dot22); swap(tm[1],tm[2]);
        !          1197:
        !          1198:       /* Occasionally (including final pass) do garbage collection.  */
        !          1199:       if (npass2 % 8 == 0 || !progress)
        !          1200:       {
        !          1201:         gptr[0] = &dot11; gptr[1] = &dot12;
        !          1202:         gptr[2] = &dot22; gptr[3] = &tm;
        !          1203:         gerepilemany(ltop1, gptr, 4);
        !          1204:       }
        !          1205:     } /* while npass2 < 2 || progress */
        !          1206:
        !          1207:     {
        !          1208:       long icol;
        !          1209:       GEN det12 = subii(mulii(dot11, dot22), mulii(dot12, dot12));
        !          1210:
        !          1211:       tm1 = idmat(ncol);
        !          1212:       mid = cgetg(ncol+1, t_MAT);
        !          1213:       for (icol = 1; icol <= 2; icol++)
        !          1214:       {
        !          1215:         coeff(tm1,1,icol) = coeff(tm,1,icol);
        !          1216:        coeff(tm1,2,icol) = coeff(tm,2,icol);
        !          1217:         mid[icol] = (long)lincomb_integral(
        !          1218:            gcoeff(tm,1,icol),gcoeff(tm,2,icol), (GEN)m[1],(GEN)m[2]);
        !          1219:       }
        !          1220:       for (icol = 3; icol <= ncol; icol++)
        !          1221:       {
        !          1222:         GEN curcol = (GEN)m[icol];
        !          1223:        GEN dot1i = gscali((GEN)mid[1], curcol);
        !          1224:         GEN dot2i = gscali((GEN)mid[2], curcol);
        !          1225:        /* Try to solve
        !          1226:         *
        !          1227:         * ( dot11  dot12 ) (q1)    ( dot1i )
        !          1228:         * ( dot12  dot22 ) (q2)  = ( dot2i )
        !          1229:         *
        !          1230:         * Round -q1 and -q2 to the nearest integer.
        !          1231:         * Then compute curcol - q1*mid[1] - q2*mid[2].
        !          1232:         * This will be approximately orthogonal to the
        !          1233:         * first two vectors in the new basis.
        !          1234:         */
        !          1235:        GEN q1neg = subii(mulii(dot12, dot2i), mulii(dot22, dot1i));
        !          1236:         GEN q2neg = subii(mulii(dot12, dot1i), mulii(dot11, dot2i));
        !          1237:
        !          1238:         q1neg = gdivround(q1neg, det12);
        !          1239:         q2neg = gdivround(q2neg, det12);
        !          1240:         coeff(tm1, 1, icol) = ladd(gmul(q1neg, gcoeff(tm,1,1)),
        !          1241:                                   gmul(q2neg, gcoeff(tm,1,2)));
        !          1242:         coeff(tm1, 2, icol) = ladd(gmul(q1neg, gcoeff(tm,2,1)),
        !          1243:                                   gmul(q2neg, gcoeff(tm,2,2)));
        !          1244:         mid[icol] = ladd(curcol,
        !          1245:           lincomb_integral(q1neg,q2neg, (GEN)mid[1],(GEN)mid[2]));
        !          1246:       } /* for icol */
        !          1247:     } /* local block */
        !          1248:   }
        !          1249:   if (DEBUGLEVEL>4)
        !          1250:   {
        !          1251:     fprintferr("tm1 = "); outbeauterr(tm1);
        !          1252:     fprintferr("mid = "); outbeauterr(mid);
        !          1253:   }
        !          1254:   gptr[0] = &tm1; gptr[1] = &mid;
        !          1255:   gerepilemany(ltop1, gptr, 2);
        !          1256:   {
        !          1257:    /* For each pair of column vectors v and w in mid * tm2,
        !          1258:     * try to replace (v, w) by (v, v - q*w) for some q.
        !          1259:     * We compute all inner products and check them repeatedly.
        !          1260:     */
        !          1261:     const long ltop3 = avma; /* Excludes region with tm1 and mid */
        !          1262:     long icol, lim, reductions, npass = 0;
        !          1263:     GEN dotprd = cgetg(ncol+1, t_MAT);
        !          1264:
        !          1265:     tm2 = idmat(ncol);
        !          1266:     for (icol=1; icol <= ncol; icol++)
        !          1267:     {
        !          1268:       long jcol;
        !          1269:
        !          1270:       dotprd[icol] = lgetg(ncol+1,t_COL);
        !          1271:       for (jcol=1; jcol <= icol; jcol++)
        !          1272:        coeff(dotprd,jcol,icol) = coeff(dotprd,icol,jcol) =
        !          1273:           (long)gscali((GEN)mid[icol], (GEN)mid[jcol]);
        !          1274:     } /* for icol */
        !          1275:     lim = stack_lim(ltop3,1);
        !          1276:     for(;;)
        !          1277:     {
        !          1278:       reductions = 0;
        !          1279:       for (icol=1; icol <= ncol; icol++)
        !          1280:       {
        !          1281:        long ijdif, jcol, k1, k2;
        !          1282:        GEN codi, q;
        !          1283:
        !          1284:         for (ijdif=1; ijdif < ncol; ijdif++)
        !          1285:        {
        !          1286:           const long previous_avma = avma;
        !          1287:
        !          1288:           jcol = (icol + ijdif - 1) % ncol; jcol++; /* Hack for NeXTgcc 2.5.8 */
        !          1289:           k1 = (cmpii(gcoeff(dotprd,icol,icol),
        !          1290:                      gcoeff(dotprd,jcol,jcol) ) > 0)
        !          1291:                ? icol : jcol;  /* index of larger column */
        !          1292:          k2 = icol + jcol - k1;        /* index of smaller column */
        !          1293:          codi = gcoeff(dotprd,k2,k2);
        !          1294:          q = gcmp0(codi)? gzero: gdivround(gcoeff(dotprd,k1,k2), codi);
        !          1295:
        !          1296:          /* Try to subtract a multiple of column k2 from column k1.  */
        !          1297:          if (gcmp0(q)) avma = previous_avma;
        !          1298:           else
        !          1299:          {
        !          1300:            long dcol;
        !          1301:
        !          1302:            reductions++; q = negi(q);
        !          1303:            tm2[k1]=(long)
        !          1304:               lincomb_integral(gun,q, (GEN)tm2[k1], (GEN)tm2[k2]);
        !          1305:            dotprd[k1]=(long)
        !          1306:               lincomb_integral(gun,q, (GEN)dotprd[k1], (GEN)dotprd[k2]);
        !          1307:            coeff(dotprd, k1, k1) = laddii(gcoeff(dotprd,k1,k1),
        !          1308:                                           mulii(q, gcoeff(dotprd,k2,k1)));
        !          1309:            for (dcol = 1; dcol <= ncol; dcol++)
        !          1310:              coeff(dotprd,k1,dcol) = coeff(dotprd,dcol,k1);
        !          1311:          } /* if q != 0 */
        !          1312:         } /* for ijdif */
        !          1313:         if (low_stack(lim, stack_lim(ltop3,1)))
        !          1314:        {
        !          1315:           if(DEBUGMEM>1) err(warnmem,"lllintpartialall");
        !          1316:          gptr[0] = &dotprd; gptr[1] = &tm2;
        !          1317:          gerepilemany(ltop3, gptr, 2);
        !          1318:         }
        !          1319:       } /* for icol */
        !          1320:       if (!reductions) break;
        !          1321:       if (DEBUGLEVEL>4)
        !          1322:       {
        !          1323:        GEN diag_prod = dbltor(1.0);
        !          1324:        for (icol = 1; icol <= ncol; icol++)
        !          1325:          diag_prod = gmul(diag_prod, gcoeff(dotprd,icol,icol));
        !          1326:         npass++;
        !          1327:        fprintferr("npass = %ld, red. last time = %ld, diag_prod = %Z\n\n",
        !          1328:                    npass, reductions, diag_prod);
        !          1329:       }
        !          1330:     } /* for(;;)*/
        !          1331:
        !          1332:    /* Sort columns so smallest comes first in m * tm1 * tm2.
        !          1333:     * Use insertion sort.
        !          1334:     */
        !          1335:     for (icol = 1; icol < ncol; icol++)
        !          1336:     {
        !          1337:       long jcol, s = icol;
        !          1338:
        !          1339:       for (jcol = icol+1; jcol <= ncol; jcol++)
        !          1340:        if (cmpii(gcoeff(dotprd,s,s),gcoeff(dotprd,jcol,jcol)) > 0) s = jcol;
        !          1341:       if (icol != s)
        !          1342:       { /* Exchange with proper column */
        !          1343:         /* Only diagonal of dotprd is updated */
        !          1344:         swap(tm2[icol], tm2[s]);
        !          1345:         swap(coeff(dotprd,icol,icol), coeff(dotprd,s,s));
        !          1346:       }
        !          1347:     } /* for icol */
        !          1348:     icol=1;
        !          1349:     while (icol <= ncol && !signe(gcoeff(dotprd,icol,icol))) icol++;
        !          1350:     ncolnz = ncol - icol + 1;
        !          1351:   } /* local block */
        !          1352:
        !          1353:   if (flag)
        !          1354:   {
        !          1355:     if (ncolnz == lg((GEN)m[1])-1)
        !          1356:     {
        !          1357:       tm2 += (ncol-ncolnz);
        !          1358:       tm2[0]=evaltyp(t_MAT)|evallg(ncolnz+1);
        !          1359:     }
        !          1360:     else
        !          1361:     {
        !          1362:       tm1 = gmul(tm1, tm2);
        !          1363:       tm2 = lllint(gmul(m, tm1));
        !          1364:     }
        !          1365:   }
        !          1366:   if (DEBUGLEVEL>4)
        !          1367:     { fprintferr("lllintpartial output = "); outbeauterr(gmul(tm1, tm2)); }
        !          1368:   return gerepileupto(ltop1, gmul(tm1, tm2));
        !          1369: }
        !          1370:
        !          1371: GEN
        !          1372: lllintpartial(GEN mat)
        !          1373: {
        !          1374:   return lllintpartialall(mat,1);
        !          1375: }
        !          1376:
        !          1377: /********************************************************************/
        !          1378: /**                                                                **/
        !          1379: /**                   LINEAR & ALGEBRAIC DEPENDANCE                **/
        !          1380: /**                                                                **/
        !          1381: /********************************************************************/
        !          1382:
        !          1383: GEN
        !          1384: lindep0(GEN x,long bit,long prec)
        !          1385: {
        !          1386:   if (!bit) return lindep(x,prec);
        !          1387:   if (bit>0) return lindep2(x,bit);
        !          1388:   return deplin(x);
        !          1389: }
        !          1390:
        !          1391: GEN
        !          1392: lindep2(GEN x, long bit)
        !          1393: {
        !          1394:   long tx=typ(x),lx=lg(x),ly,i,j,flag,e,tetpil, av = avma;
        !          1395:   GEN re,im,p1,p2;
        !          1396:
        !          1397:   if (! is_vec_t(tx)) err(typeer,"lindep2");
        !          1398:   if (lx<=2) return cgetg(1,t_VEC);
        !          1399:   re=greal(x); im=gimag(x); flag = !gcmp0(im);
        !          1400:   if (lx == 3)
        !          1401:   { /* independant over R ? */
        !          1402:     if (gexpo(gsub(gmul((GEN)re[1],(GEN)im[2]),
        !          1403:                    gmul((GEN)re[2],(GEN)im[1]))) > - bit)
        !          1404:     {
        !          1405:       avma = av; return cgetg(1, t_VEC);
        !          1406:     }
        !          1407:   }
        !          1408:   ly = flag? lx+2: lx+1;
        !          1409:   p2=cgetg(lx,t_MAT); bit = (long) (bit/L2SL10);
        !          1410:   for (i=1; i<lx; i++)
        !          1411:   {
        !          1412:     p1=cgetg(ly,t_COL); p2[i]=(long)p1;
        !          1413:     for (j=1; j<lx; j++) p1[j]=(i==j) ? un : zero;
        !          1414:     p1[lx]=lcvtoi(gshift((GEN)re[i],bit),&e);
        !          1415:     if (flag) p1[lx+1]=lcvtoi(gshift((GEN)im[i],bit),&e);
        !          1416:   }
        !          1417:   p1=gmul(p2,lllint(p2)); p1=(GEN)p1[1];
        !          1418:   p1[0]=evaltyp(t_VEC) | evallg(lx); tetpil=avma;
        !          1419:   return gerepile(av,tetpil,gcopy(p1));
        !          1420: }
        !          1421:
        !          1422: #define quazero(x) (gcmp0(x) || (typ(x)==t_REAL && expo(x) < EXP))
        !          1423: GEN
        !          1424: lindep(GEN x, long prec)
        !          1425: {
        !          1426:   GEN *b,*be,*bn,**m,qzer;
        !          1427:   GEN c1,c2,c3,px,py,pxy,re,im,p3,p4,r,f,em;
        !          1428:   long i,j,fl,i1, lx = lg(x), tx = typ(x), n = lx-1;
        !          1429:   long av = avma, lim = stack_lim(av,1), av0,av1,tetpil;
        !          1430:   const long EXP = - bit_accuracy(prec) + 2*n;
        !          1431:
        !          1432:   if (! is_vec_t(tx)) err(typeer,"lindep");
        !          1433:   if (lx<=2) return cgetg(1,t_VEC);
        !          1434:   x = gmul(x, realun(prec));
        !          1435:   re=greal(x); im=gimag(x);
        !          1436:   if (lx == 3)
        !          1437:   { /* independant over R ? */
        !          1438:     if (gexpo(gsub(gmul((GEN)re[1],(GEN)im[2]),
        !          1439:                    gmul((GEN)re[2],(GEN)im[1]))) > - bit_accuracy(prec))
        !          1440:     {
        !          1441:       avma = av; return cgetg(1, t_VEC);
        !          1442:     }
        !          1443:   }
        !          1444:   qzer = new_chunk(lx);
        !          1445:   b = (GEN*)idmat(n);
        !          1446:   be= (GEN*)new_chunk(lx);
        !          1447:   bn= (GEN*)new_chunk(lx);
        !          1448:   m = (GEN**)new_chunk(lx);
        !          1449:   for (i=1; i<=n; i++)
        !          1450:   {
        !          1451:     bn[i]=cgetr(prec+1);
        !          1452:     be[i]=cgetg(lx,t_COL);
        !          1453:     m[i] = (GEN*)new_chunk(lx);
        !          1454:     for (j=1; j<i ; j++) m[i][j]=cgetr(prec+1);
        !          1455:     for (j=1; j<=n; j++) be[i][j]=lgetr(prec+1);
        !          1456:   }
        !          1457:   px=sqscal(re);
        !          1458:   py=sqscal(im); pxy=gscal(re,im);
        !          1459:   p3=mpsub(mpmul(px,py),gsqr(pxy));
        !          1460:   if (quazero(re)) { re=im; px=py; fl=1; } else fl=quazero(p3);
        !          1461:   av0 = av1 = avma;
        !          1462:   for (i=1; i<=n; i++)
        !          1463:   {
        !          1464:     p4 = gscal(b[i],re);
        !          1465:     if (fl) p4=gmul(gdiv(p4,px),re);
        !          1466:     else
        !          1467:     {
        !          1468:       GEN p5,p6,p7;
        !          1469:       p5=gscal(b[i],im);
        !          1470:       p6=gdiv(gsub(gmul(py,p4),gmul(pxy,p5)),p3);
        !          1471:       p7=gdiv(gsub(gmul(px,p5),gmul(pxy,p4)),p3);
        !          1472:       p4=gadd(gmul(p6,re),gmul(p7,im));
        !          1473:     }
        !          1474:     if (tx!=t_COL) p4=gtrans(p4);
        !          1475:     p4=gsub(b[i],p4);
        !          1476:     for (j=1; j<i; j++)
        !          1477:       if (qzer[j]) affrr(bn[j],m[i][j]);
        !          1478:       else
        !          1479:       {
        !          1480:         gdivz(gscal(b[i],be[j]),bn[j],m[i][j]);
        !          1481:         p4=gsub(p4,gmul(m[i][j],be[j]));
        !          1482:       }
        !          1483:     gaffect(p4,be[i]); affrr(sqscal(be[i]),bn[i]);
        !          1484:     qzer[i]=quazero(bn[i]); avma=av1;
        !          1485:   }
        !          1486:   while (qzer[n])
        !          1487:   {
        !          1488:     long e;
        !          1489:     if (DEBUGLEVEL>9)
        !          1490:     {
        !          1491:       fprintferr("qzer[%ld]=%ld\n",n,qzer[n]);
        !          1492:       for (i1=1; i1<=n; i1++)
        !          1493:        for (i=1; i<i1; i++) output(m[i1][i]);
        !          1494:     }
        !          1495:     em=bn[1]; j=1;
        !          1496:     for (i=2; i<n; i++)
        !          1497:     {
        !          1498:       p3=shiftr(bn[i],i);
        !          1499:       if (cmprr(p3,em)>0) { em=p3; j=i; }
        !          1500:     }
        !          1501:     i=j; i1=i+1;
        !          1502:     avma = av1; r = grndtoi(m[i1][i], &e);
        !          1503:     if (e >= 0) err(talker,"precision too low in lindep");
        !          1504:     r  = negi(r);
        !          1505:     p3 = lincomb_integral(gun,r, b[i1],b[i]);
        !          1506:     av1 = avma;
        !          1507:     b[i1]=b[i]; b[i]=p3; f=addir(r,m[i1][i]);
        !          1508:     for (j=1; j<i; j++)
        !          1509:       if (!qzer[j])
        !          1510:       {
        !          1511:         p3=mpadd(m[i1][j],mulir(r,m[i][j]));
        !          1512:         affrr(m[i][j],m[i1][j]); mpaff(p3,m[i][j]);
        !          1513:       }
        !          1514:     c1=addrr(bn[i1],mulrr(gsqr(f),bn[i]));
        !          1515:     if (!quazero(c1))
        !          1516:     {
        !          1517:       c2=divrr(mulrr(bn[i],f),c1); affrr(c2,m[i1][i]);
        !          1518:       c3=divrr(bn[i1],c1); mulrrz(c3,bn[i],bn[i1]);
        !          1519:       affrr(c1,bn[i]); qzer[i1]=quazero(bn[i1]); qzer[i]=0;
        !          1520:       for (j=i+2; j<=n; j++)
        !          1521:       {
        !          1522:         p3=addrr(mulrr(m[j][i1],c3),mulrr(m[j][i],c2));
        !          1523:         subrrz(m[j][i],mulrr(f,m[j][i1]), m[j][i1]);
        !          1524:         affrr(p3,m[j][i]);
        !          1525:       }
        !          1526:     }
        !          1527:     else
        !          1528:     {
        !          1529:       qzer[i1]=qzer[i]; qzer[i]=1;
        !          1530:       affrr(bn[i],bn[i1]); affrr(c1,bn[i]);
        !          1531:       for (j=i+2; j<=n; j++) affrr(m[j][i],m[j][i1]);
        !          1532:     }
        !          1533:     if (low_stack(lim, stack_lim(av,1)))
        !          1534:     {
        !          1535:       if(DEBUGMEM>1) err(warnmem,"lindep");
        !          1536:       b = (GEN*)gerepileupto(av0, gcopy((GEN)b));
        !          1537:       av1 = avma;
        !          1538:     }
        !          1539:   }
        !          1540:   p3=cgetg(lx,t_COL); p3[n]=un; for (i=1; i<n; i++) p3[i]=zero;
        !          1541:   p4 = (GEN)b; p4[0] = evaltyp(t_MAT) | evallg(lx);
        !          1542:   p4=gauss(gtrans(p4),p3); tetpil=avma;
        !          1543:   return gerepile(av,tetpil,gtrans(p4));
        !          1544: }
        !          1545:
        !          1546: GEN
        !          1547: algdep0(GEN x, long n, long bit, long prec)
        !          1548: {
        !          1549:   long tx=typ(x),av,i,k;
        !          1550:   GEN y,p1;
        !          1551:
        !          1552:   if (! is_scalar_t(tx)) err(typeer,"algdep0");
        !          1553:   if (tx==t_POLMOD) { y=forcecopy((GEN)x[1]); setvarn(y,0); return y; }
        !          1554:   if (gcmp0(x)) return gzero;
        !          1555:   if (!n) return gun;
        !          1556:
        !          1557:   av=avma; p1=cgetg(n+2,t_COL); p1[1]=un;
        !          1558:   for (i=2; i<=n+1; i++) p1[i]=lmul((GEN)p1[i-1],x);
        !          1559:
        !          1560:   p1 = bit? lindep2(p1,bit): lindep(p1,prec);
        !          1561:   if (lg(p1) < 2)
        !          1562:     err(talker,"higher degree than expected in algdep");
        !          1563:
        !          1564:   y=cgetg(n+3,t_POL);
        !          1565:   y[1] = evalsigne(1) | evalvarn(0);
        !          1566:   k=1; while (gcmp0((GEN)p1[k])) k++;
        !          1567:   for (i=0; i<=n+1-k; i++) y[i+2] = p1[k+i];
        !          1568:   normalizepol_i(y, n+4-k);
        !          1569:   y = (gsigne(leading_term(y)) > 0)? gcopy(y): gneg(y);
        !          1570:   return gerepileupto(av,y);
        !          1571: }
        !          1572:
        !          1573: GEN
        !          1574: algdep2(GEN x, long n, long bit)
        !          1575: {
        !          1576:   return algdep0(x,n,bit,0);
        !          1577: }
        !          1578:
        !          1579: GEN
        !          1580: algdep(GEN x, long n, long prec)
        !          1581: {
        !          1582:   return algdep0(x,n,0,prec);
        !          1583: }
        !          1584:
        !          1585: /********************************************************************/
        !          1586: /**                                                                **/
        !          1587: /**                   INTEGRAL KERNEL (LLL REDUCED)                **/
        !          1588: /**                                                                **/
        !          1589: /********************************************************************/
        !          1590:
        !          1591: GEN
        !          1592: matkerint0(GEN x, long flag)
        !          1593: {
        !          1594:   switch(flag)
        !          1595:   {
        !          1596:     case 0: return kerint(x);
        !          1597:     case 1: return kerint1(x);
        !          1598:     case 2: return kerint2(x);
        !          1599:     default: err(flagerr,"matkerint");
        !          1600:   }
        !          1601:   return NULL; /* not reached */
        !          1602: }
        !          1603:
        !          1604: GEN
        !          1605: kerint1(GEN x)
        !          1606: {
        !          1607:   long av=avma,tetpil;
        !          1608:   GEN p1,p2;
        !          1609:
        !          1610:   p1=matrixqz3(ker(x)); p2=lllint(p1); tetpil=avma;
        !          1611:   return gerepile(av,tetpil,gmul(p1,p2));
        !          1612: }
        !          1613:
        !          1614: GEN
        !          1615: kerint2(GEN x)
        !          1616: {
        !          1617:   long lx=lg(x), i,j,av,av1;
        !          1618:   GEN g,p1;
        !          1619:
        !          1620:   if (typ(x) != t_MAT) err(typeer,"kerint2");
        !          1621:   av=avma; g=cgetg(lx,t_MAT);
        !          1622:   for (j=1; j<lx; j++) g[j]=lgetg(lx,t_COL);
        !          1623:   for (i=1; i<lx; i++)
        !          1624:     for (j=1; j<=i; j++)
        !          1625:       coeff(g,i,j) = coeff(g,j,i) = (long)gscal((GEN)x[i],(GEN)x[j]);
        !          1626:   g=lllgramall0(g,lll_KER); p1=lllint(g);
        !          1627:   av1=avma; return gerepile(av,av1,gmul(g,p1));
        !          1628: }
        !          1629:
        !          1630: static GEN
        !          1631: lllall0(GEN x, long flag)
        !          1632: {
        !          1633:   long av0=avma,av,tetpil,lx=lg(x),i,j,k,l,n,lim,kmax;
        !          1634:   GEN u,B,L,q,r,h,la,p1,p2,p4,fl;
        !          1635:
        !          1636:   if (typ(x) != t_MAT) err(typeer,"lllall0");
        !          1637:   n=lx-1; if (n<=1) return lllall_trivial(x,n, flag | lll_GRAM);
        !          1638:   fl = new_chunk(lx);
        !          1639:
        !          1640:   av=avma; lim=stack_lim(av,1); x=dummycopy(x);
        !          1641:   B=gscalcol(gun, lx);
        !          1642:   L=cgetg(lx,t_MAT);
        !          1643:   for (k=lg(x[1]),j=1; j<lx; j++)
        !          1644:   {
        !          1645:     for (i=1; i<k; i++)
        !          1646:       if (typ(gcoeff(x,i,j))!=t_INT) err(lllger4);
        !          1647:     fl[j] = 0; L[j] = (long)zerocol(n);
        !          1648:   }
        !          1649:   k=2; h=idmat(n); kmax=1;
        !          1650:   u=sqscali((GEN)x[1]);
        !          1651:   if (signe(u)) { B[2]=(long)u; coeff(L,1,1)=un; fl[1]=1; } else B[2]=un;
        !          1652:   for(;;)
        !          1653:   {
        !          1654:     if (k > kmax)
        !          1655:     {
        !          1656:       kmax = k;
        !          1657:       for (j=1; j<=k; j++)
        !          1658:       {
        !          1659:        if (j==k || fl[j])
        !          1660:        {
        !          1661:           long av1 = avma;
        !          1662:          u=gscali((GEN)x[k],(GEN)x[j]);
        !          1663:          for (i=1; i<j; i++)
        !          1664:            if (fl[i])
        !          1665:               u = divii(subii(mulii((GEN)B[i+1],u),
        !          1666:                               mulii(gcoeff(L,k,i),gcoeff(L,j,i))),
        !          1667:                         (GEN)B[i]);
        !          1668:           u = gerepileuptoint(av1, u);
        !          1669:          if (j<k) coeff(L,k,j)=(long)u;
        !          1670:          else
        !          1671:          {
        !          1672:            if (signe(u)) { B[k+1]=(long)u; coeff(L,k,k)=un; fl[k]=1; }
        !          1673:            else { B[k+1]=B[k]; fl[k]=0; }
        !          1674:          }
        !          1675:        }
        !          1676:       }
        !          1677:     }
        !          1678:     if (fl[k-1] && !fl[k])
        !          1679:     {
        !          1680:       u = shifti(gcoeff(L,k,k-1),1);
        !          1681:       if (absi_cmp(u, (GEN)B[k]) > 0)
        !          1682:       {
        !          1683:        q = truedvmdii(addii(u,(GEN)B[k]),shifti((GEN)B[k],1), NULL);
        !          1684:         r = negi(q);
        !          1685:         h[k] = (long)lincomb_integral(gun,r, (GEN)h[k],(GEN)h[k-1]);
        !          1686:         x[k] = (long)lincomb_integral(gun,r, (GEN)x[k],(GEN)x[k-1]);
        !          1687:        coeff(L,k,k-1)=laddii(gcoeff(L,k,k-1),mulii(r,(GEN)B[k]));
        !          1688:        for (i=1; i<k-1; i++)
        !          1689:          coeff(L,k,i)=laddii(gcoeff(L,k,i),mulii(r,gcoeff(L,k-1,i)));
        !          1690:       }
        !          1691:       la=gcoeff(L,k,k-1); p4=sqri(la);
        !          1692:       swap(h[k-1], h[k]);
        !          1693:       swap(x[k-1], x[k]);
        !          1694:       for (j=1; j<k-1; j++) swap(coeff(L,k-1,j), coeff(L,k,j));
        !          1695:       if (signe(la))
        !          1696:       {
        !          1697:        p2=(GEN)B[k]; p1=divii(p4,p2);
        !          1698:        B[k+1]=B[k]=(long)p1;
        !          1699:        for (i=k+1; i<=kmax; i++)
        !          1700:          coeff(L,i,k-1)=ldivii(mulii(la,gcoeff(L,i,k-1)),p2);
        !          1701:        for (j=k+1; j<kmax; j++)
        !          1702:          for (i=j+1; i<=kmax; i++)
        !          1703:            coeff(L,i,j)=ldivii(mulii((GEN)p1,gcoeff(L,i,j)),p2);
        !          1704:        for (i=k+2; i<=kmax+1; i++)
        !          1705:          B[i]=ldivii(mulii((GEN)p1,(GEN)B[i]),p2);
        !          1706:       }
        !          1707:       else
        !          1708:       {
        !          1709:        for (i=k+1; i<=kmax; i++)
        !          1710:        { coeff(L,i,k)=coeff(L,i,k-1); coeff(L,i,k-1)=zero; }
        !          1711:        B[k]=B[k-1]; fl[k]=1; fl[k-1]=0;
        !          1712:       }
        !          1713:       if (k>2) k--;
        !          1714:     }
        !          1715:     else
        !          1716:     {
        !          1717:       for (l=k-1; l>=1; l--)
        !          1718:       {
        !          1719:         u = shifti(gcoeff(L,k,l),1);
        !          1720:        if (absi_cmp(u,(GEN)B[l+1]) > 0)
        !          1721:        {
        !          1722:          q = truedvmdii(addii(u,(GEN)B[l+1]),shifti((GEN)B[l+1],1), NULL);
        !          1723:           r = negi(q);
        !          1724:          h[k] = (long)lincomb_integral(gun,r,(GEN)h[k],(GEN)h[l]);
        !          1725:          x[k] = (long)lincomb_integral(gun,r,(GEN)x[k],(GEN)x[l]);
        !          1726:          coeff(L,k,l)=laddii(gcoeff(L,k,l),mulii(r,(GEN)B[l+1]));
        !          1727:          for (i=1; i<l; i++)
        !          1728:            coeff(L,k,i)=laddii(gcoeff(L,k,i),mulii(r,gcoeff(L,l,i)));
        !          1729:         }
        !          1730:       }
        !          1731:       if (++k > n) break;
        !          1732:     }
        !          1733:     if (low_stack(lim, stack_lim(av,1)))
        !          1734:     {
        !          1735:       GEN *gptr[4];
        !          1736:       if(DEBUGMEM>1) err(warnmem,"lllall0");
        !          1737:       gptr[0]=&B; gptr[1]=&L; gptr[2]=&h;
        !          1738:       gptr[3]=&x; gerepilemany(av,gptr,4);
        !          1739:     }
        !          1740:   }
        !          1741:   tetpil=avma;
        !          1742:   return gerepile(av0,tetpil,lllgramall_finish(h,fl,flag,n));
        !          1743: }
        !          1744:
        !          1745: GEN
        !          1746: kerint(GEN x)
        !          1747: {
        !          1748:   long av=avma,av1;
        !          1749:   GEN g,p1;
        !          1750:
        !          1751:   g=lllall0(x,lll_KER); if (lg(g)==1) return g;
        !          1752:   p1=lllint(g); av1=avma;
        !          1753:   return gerepile(av,av1,gmul(g,p1));
        !          1754: }
        !          1755:
        !          1756: /********************************************************************/
        !          1757: /**                                                                **/
        !          1758: /**                        POLRED & CO.                            **/
        !          1759: /**                                                                **/
        !          1760: /********************************************************************/
        !          1761: /* remove duplicate polynomials in y, updating a (same indexes), in place */
        !          1762: static long
        !          1763: remove_duplicates(GEN y, GEN a)
        !          1764: {
        !          1765:   long k,i, nv = lg(y), av = avma;
        !          1766:   GEN z;
        !          1767:
        !          1768:   if (nv < 2) return nv;
        !          1769:   z = new_chunk(3);
        !          1770:   z[1] = (long)y;
        !          1771:   z[2] = (long)a; (void)sort_factor(z, gcmp);
        !          1772:   for  (k=1, i=2; i<nv; i++)
        !          1773:     if (!gegal((GEN)y[i], (GEN)y[k]))
        !          1774:     {
        !          1775:       k++;
        !          1776:       a[k] = a[i];
        !          1777:       y[k] = y[i];
        !          1778:     }
        !          1779:   nv = k+1; setlg(a,nv); setlg(y,nv);
        !          1780:   avma = av; return nv;
        !          1781: }
        !          1782:
        !          1783: /* in place; make sure second non-zero coeff is negative (choose x or -x) */
        !          1784: int
        !          1785: canon_pol(GEN z)
        !          1786: {
        !          1787:   long i,s;
        !          1788:
        !          1789:   for (i=lgef(z)-2; i>=2; i-=2)
        !          1790:   {
        !          1791:     s = signe(z[i]);
        !          1792:     if (s > 0)
        !          1793:     {
        !          1794:       for (; i>=2; i-=2) z[i]=lnegi((GEN)z[i]);
        !          1795:       return -1;
        !          1796:     }
        !          1797:     if (s) return 1;
        !          1798:   }
        !          1799:   return 0;
        !          1800: }
        !          1801:
        !          1802: static GEN
        !          1803: pols_for_polred(GEN x, GEN base, GEN LLLbase, GEN *pta)
        !          1804: {
        !          1805:   long i,j, v = varn(x), n = lg(base);
        !          1806:   GEN p1,p2,p3,y, a = cgetg(n,t_VEC);
        !          1807:
        !          1808:   for (i=1; i<n; i++) a[i] = lmul(base,(GEN)LLLbase[i]);
        !          1809:   y=cgetg(n,t_VEC);
        !          1810:   for (i=1; i<n; i++)
        !          1811:   {
        !          1812:     if (DEBUGLEVEL>2) { fprintferr("i = %ld\n",i); flusherr(); }
        !          1813:     p1=(GEN)a[i]; p3=content(p1);
        !          1814:     if (gcmp1(p3)) p3 = NULL; else p1 = gdiv(p1,p3);
        !          1815:     p1 = caract2(x,p1,v);
        !          1816:     if (p3)
        !          1817:       for (p2=gun, j=lgef(p1)-2; j>=2; j--)
        !          1818:       {
        !          1819:         p2 = gmul(p2,p3); p1[j] = lmul((GEN)p1[j], p2);
        !          1820:       }
        !          1821:     p2=modulargcd(derivpol(p1),p1); p3=leading_term(p2);
        !          1822:     if (!gcmp1(p3)) p2=gdiv(p2,p3);
        !          1823:     p1 = gdiv(p1,p2);
        !          1824:     if (canon_pol(p1) < 0 && pta)
        !          1825:       a[i] = (long) gneg_i((GEN)a[i]);
        !          1826:     y[i] = (long)p1; if (DEBUGLEVEL>=4) outerr(p1);
        !          1827:   }
        !          1828:   (void)remove_duplicates(y,a);
        !          1829:   if (pta) *pta = a;
        !          1830:   return y;
        !          1831: }
        !          1832:
        !          1833: GEN
        !          1834: nf_get_T2(GEN base, GEN polr)
        !          1835: {
        !          1836:   long i,j, n = lg(base);
        !          1837:   GEN p1,p2=cgetg(n,t_MAT);
        !          1838:
        !          1839:   for (i=1; i<n; i++)
        !          1840:   {
        !          1841:     p1=cgetg(n,t_COL); p2[i]=(long)p1;
        !          1842:     for (j=1; j<n; j++)
        !          1843:       p1[j] = (long) poleval((GEN)base[i],(GEN)polr[j]);
        !          1844:   }
        !          1845:   return mulmat_real(gconj(gtrans(p2)),p2);
        !          1846: }
        !          1847:
        !          1848: /* Return the base change matrix giving the an LLL-reduced basis for the
        !          1849:  * maximal order of the nf given by x. Expressed in terms of the standard
        !          1850:  * HNF basis (as polynomials) given in base (ignored if x is an nf)
        !          1851:  */
        !          1852: GEN
        !          1853: LLL_nfbasis(GEN *ptx, GEN polr, GEN base, long prec)
        !          1854: {
        !          1855:   GEN T2,p1, x = *ptx;
        !          1856:   int totally_real,n,i,j;
        !          1857:
        !          1858:   if (typ(x) != t_POL)
        !          1859:   {
        !          1860:     p1=checknf(x); *ptx=x=(GEN)p1[1];
        !          1861:     base=(GEN)p1[7]; n=lgef(x)-3;
        !          1862:     totally_real = !signe(gmael(p1,2,2));
        !          1863:     T2=gmael(p1,5,3); if (totally_real) T2 = ground(T2);
        !          1864:   }
        !          1865:   else
        !          1866:   {
        !          1867:     n=lgef(x)-3; totally_real = (!prec || sturm(x)==n);
        !          1868:     if (!totally_real)
        !          1869:       T2 = nf_get_T2(base,polr? polr: roots(x,prec));
        !          1870:     else
        !          1871:     { /* totally real */
        !          1872:       GEN ptrace=cgetg(n+2,t_VEC);
        !          1873:       long k;
        !          1874:
        !          1875:       ptrace[2]=lstoi(n);
        !          1876:       for (k=2; k<=n; k++)
        !          1877:       { /* cf polsym */
        !          1878:        GEN y = x + (n-k+1);
        !          1879:        p1 = gmulsg(k-1,(GEN)y[2]);
        !          1880:        for (i=3; i<=k; i++)
        !          1881:          p1 = gadd(p1,gmul((GEN)y[i],(GEN)ptrace[i]));
        !          1882:        ptrace[i] = lneg(p1);
        !          1883:       }
        !          1884:       T2=cgetg(n+1,t_MAT);
        !          1885:       for (i=1; i<=n; i++)
        !          1886:       {
        !          1887:        p1=cgetg(n+1,t_COL); T2[i]=(long)p1;
        !          1888:        for (j=1; j<i ; j++) p1[j] = coeff(T2,i,j);
        !          1889:        for (   ; j<=n; j++)
        !          1890:        { /* cf quicktrace */
        !          1891:          GEN p2 = gres(gmul((GEN)base[i],(GEN)base[j]),x);
        !          1892:           GEN p3 = gzero;
        !          1893:          for (k=lgef(p2)-1; k>1; k--)
        !          1894:            p3 = gadd(p3, gmul((GEN)p2[k],(GEN)ptrace[k]));
        !          1895:          p1[j]=(long)p3;
        !          1896:        }
        !          1897:       }
        !          1898:     }
        !          1899:   }
        !          1900:   if (totally_real) return lllgramint(T2);
        !          1901:   for (i=1; ; i++)
        !          1902:   {
        !          1903:     if ((p1 = lllgramintern(T2,100,1,prec))) return p1;
        !          1904:     if (i == MAXITERPOL) err(accurer,"allpolred");
        !          1905:     prec=(prec<<1)-2;
        !          1906:     if (DEBUGLEVEL) err(warnprec,"allpolred",prec);
        !          1907:     T2=nf_get_T2(base,roots(x,prec));
        !          1908:   }
        !          1909: }
        !          1910:
        !          1911: /* x can be a polynomial, but also an nf or a bnf */
        !          1912: static GEN
        !          1913: allpolred(GEN x, GEN *pta, long code, long prec)
        !          1914: {
        !          1915:   GEN y,p1, base = NULL, polr = NULL;
        !          1916:   long av = avma;
        !          1917:
        !          1918:   if (typ(x) == t_POL)
        !          1919:   {
        !          1920:     if (!signe(x)) return gcopy(x);
        !          1921:     check_pol_int(x);
        !          1922:     if (!gcmp1(leading_term(x)))
        !          1923:       err(impl,"allpolred for nonmonic polynomials");
        !          1924:     base = allbase4(x,code,&p1,NULL); /* p1 is junk */
        !          1925:   }
        !          1926:   else
        !          1927:   {
        !          1928:     long i = lg(x);
        !          1929:     if (typ(x) == t_VEC && i<=4 && i>=3 && typ(x[1])==t_POL)
        !          1930:     { /* polynomial + integer basis */
        !          1931:       base=(GEN)x[2]; x=(GEN)x[1];
        !          1932:     }
        !          1933:   }
        !          1934:   p1 = LLL_nfbasis(&x,polr,base,prec);
        !          1935:   y = pols_for_polred(x,base,p1,pta);
        !          1936:   if (pta)
        !          1937:   {
        !          1938:     GEN *gptr[2]; gptr[0]=&y; gptr[1]=pta;
        !          1939:     gerepilemany(av,gptr,2); return y;
        !          1940:   }
        !          1941:   return gerepileupto(av,y);
        !          1942: }
        !          1943:
        !          1944: GEN
        !          1945: polred0(GEN x,long flag, GEN p, long prec)
        !          1946: {
        !          1947:   GEN y;
        !          1948:   long smll = (flag & 1);
        !          1949:
        !          1950:   if (p && !gcmp0(p)) smll=(long) p; /* factored polred */
        !          1951:   if (flag & 2) /* polred2 */
        !          1952:   {
        !          1953:     y=cgetg(3,t_MAT);
        !          1954:     y[2]=(long)allpolred(x,(GEN*)(y+1),smll,prec);
        !          1955:     return y;
        !          1956:   }
        !          1957:   return allpolred(x,NULL,smll,prec);
        !          1958: }
        !          1959:
        !          1960: GEN
        !          1961: ordred(GEN x, long prec)
        !          1962: {
        !          1963:   GEN p1,p2,p3,base;
        !          1964:   long n=lgef(x)-3,i,j,av=avma,v = varn(x),tetpil;
        !          1965:
        !          1966:   if (typ(x) != t_POL) err(typeer,"ordred");
        !          1967:   if (!signe(x)) return gcopy(x);
        !          1968:   if (!gcmp1((GEN)x[n+2])) err(impl,"ordred for nonmonic polynomials");
        !          1969:
        !          1970:   p2=roots(x,prec); p3=cgetg(n+1,t_MAT);
        !          1971:
        !          1972:   base=cgetg(n+1,t_VEC); /* power basis */
        !          1973:   for (i=1; i<=n; i++)
        !          1974:   {
        !          1975:     base[i]=lpowgs(polx[v],i-1);
        !          1976:     p1=cgetg(n+1,t_COL); p3[i]=(long)p1;
        !          1977:     for (j=1; j<=n; j++)
        !          1978:       p1[j]=lpuigs((GEN)p2[j],i-1);
        !          1979:   }
        !          1980:   p2 = mulmat_real(gconj(gtrans(p3)),p3);
        !          1981:   p1 = pols_for_polred(x,base,lllgram(p2,prec), NULL);
        !          1982:
        !          1983:   tetpil=avma; return gerepile(av,tetpil, gcopy(p1));
        !          1984: }
        !          1985:
        !          1986: GEN roots_to_pol_r1r2(GEN a, long r1, long v);
        !          1987: static GEN chk_basis_embed;
        !          1988: long chk_r1, chk_v;
        !          1989:
        !          1990: static GEN
        !          1991: init_chk(GEN nf, GEN mat, GEN bound)
        !          1992: {
        !          1993:   GEN M = gmael(nf,5,1);
        !          1994:   long n = lg(nf[7])-1, prec,prec2;
        !          1995:
        !          1996:   if (!bound)
        !          1997:   {
        !          1998:     chk_v = varn(nf[1]);
        !          1999:     chk_r1 = itos(gmael(nf,2,1));
        !          2000:     chk_basis_embed = gmul(M, mat);
        !          2001:     return gmul((GEN)nf[7],mat);
        !          2002:   }
        !          2003:
        !          2004:   /* should be [max_k C^n_k (B/k) ^ k] ^ (1/2) */
        !          2005:   bound = gsqrt(gpowgs(bound, n), 3);
        !          2006:   prec2 = (1 + (gexpo(bound) >> TWOPOTBITS_IN_LONG));
        !          2007:   if (prec2 < 0) prec2 = 0;
        !          2008:   prec = 3 + prec2;
        !          2009:   prec2= (long)nfnewprec(nf,-1);
        !          2010:   if (DEBUGLEVEL)
        !          2011:     fprintferr("init_chk: estimated prec = %ld (initially %ld)\n",
        !          2012:                  prec, prec2);
        !          2013:   if (prec > prec2) return NULL;
        !          2014:   if (prec < prec2) chk_basis_embed = gprec_w(chk_basis_embed, prec);
        !          2015:   return (GEN)prec;
        !          2016: }
        !          2017:
        !          2018: static GEN
        !          2019: checkgenerator(GEN x)
        !          2020: {
        !          2021:   long l,i,av = avma;
        !          2022:   GEN g = gmul(chk_basis_embed,x);
        !          2023:   GEN r = gneg((GEN)g[1]);
        !          2024:   long epsbit = 5 - bit_accuracy(gprecision(r));
        !          2025:
        !          2026:   l = lg(g)-1;
        !          2027:   for (i=2; i<=l; i++)
        !          2028:     if (gexpo(gadd((GEN)g[i], r)) < epsbit) { avma=av; return NULL; }
        !          2029:
        !          2030:   g = roots_to_pol_r1r2(g, chk_r1, chk_v);
        !          2031:   g = ground(g);
        !          2032:   if (lgef(modulargcd(g,derivpol(g))) > 3) { avma=av; return NULL; }
        !          2033:   if (DEBUGLEVEL>3) fprintferr("  generator: %Z\n",g);
        !          2034:   return g;
        !          2035: }
        !          2036:
        !          2037: /* no garbage collecting, done in polredabs0 */
        !          2038: static GEN
        !          2039: findmindisc(GEN nf, GEN y, GEN a, GEN phimax, long flun)
        !          2040: {
        !          2041:   long i,k, c = lg(y);
        !          2042:   GEN v,dmin,z,beta,discs = cgetg(c,t_VEC);
        !          2043:
        !          2044:   for (i=1; i<c; i++) discs[i] = labsi(discsr((GEN)y[i]));
        !          2045:   v = sindexsort(discs);
        !          2046:   k = v[1]; dmin = (GEN)discs[k]; z = (GEN)y[k]; beta = (GEN)a[k];
        !          2047:   for (i=2; i<c; i++)
        !          2048:   {
        !          2049:     k = v[i];
        !          2050:     if (!egalii((GEN)discs[k],dmin)) break;
        !          2051:     if (gpolcomp((GEN)y[k],z) < 0) { z = (GEN)y[k]; beta = (GEN)a[k]; }
        !          2052:   }
        !          2053:   if (flun & nf_RAW)
        !          2054:   {
        !          2055:     y=cgetg(3,t_VEC);
        !          2056:     y[1]=lcopy(z);
        !          2057:     y[2]=lcopy(beta);
        !          2058:   }
        !          2059:   else if (phimax)
        !          2060:   {
        !          2061:     y=cgetg(3,t_VEC);
        !          2062:     y[1]=lcopy(z);
        !          2063:     beta=polymodrecip(gmodulcp(beta,(GEN)nf[1]));
        !          2064:     y[2]=(long)poleval(phimax,beta);
        !          2065:   }
        !          2066:   else y = gcopy(z);
        !          2067:   return y;
        !          2068: }
        !          2069:
        !          2070: /* no garbage collecting, done in polredabs0 */
        !          2071: static GEN
        !          2072: storeallpols(GEN nf, GEN z, GEN a, GEN phimax, long flun)
        !          2073: {
        !          2074:   GEN p1,y,beta;
        !          2075:
        !          2076:   if (flun & nf_RAW)
        !          2077:   {
        !          2078:     long i, c = lg(z);
        !          2079:     y=cgetg(c,t_VEC);
        !          2080:     for (i=1; i<c; i++)
        !          2081:     {
        !          2082:       p1=cgetg(3,t_VEC); y[i]=(long)p1;
        !          2083:       p1[1]=lcopy((GEN)z[i]);
        !          2084:       p1[2]=lcopy((GEN)a[i]);
        !          2085:     }
        !          2086:   }
        !          2087:   else if (phimax)
        !          2088:   {
        !          2089:     long i, c = lg(z);
        !          2090:     beta = new_chunk(c);
        !          2091:     for (i=1; i<c; i++)
        !          2092:       beta[i] = (long)polymodrecip(gmodulcp((GEN)a[i],(GEN)nf[1]));
        !          2093:
        !          2094:     y=cgetg(c,t_VEC);
        !          2095:     for (i=1; i<c; i++)
        !          2096:     {
        !          2097:       p1=cgetg(3,t_VEC); y[i]=(long)p1;
        !          2098:       p1[1]=lcopy((GEN)z[i]);
        !          2099:       p1[2]=(long)poleval(phimax,(GEN)beta[i]);
        !          2100:     }
        !          2101:   }
        !          2102:   else y = gcopy(z);
        !          2103:   return y;
        !          2104: }
        !          2105:
        !          2106: GEN
        !          2107: polredabs0(GEN x, long flun, long prec)
        !          2108: {
        !          2109:   long i,nv, av = avma;
        !          2110:   GEN nf,v,y,a,phimax;
        !          2111:   GEN (*storepols)(ANYARG);
        !          2112:
        !          2113:   if ((ulong)flun >= 16) err(flagerr,"polredabs");
        !          2114:   nf = initalgall0(x,nf_SMALL|nf_REGULAR,prec);
        !          2115:   if (lg(nf) == 3)
        !          2116:   {
        !          2117:     phimax = lift_to_pol((GEN)nf[2]);
        !          2118:     nf = (GEN)nf[1];
        !          2119:   }
        !          2120:   else
        !          2121:     phimax = (flun & nf_ORIG)? polx[0]: (GEN)NULL;
        !          2122:   prec = (long)nfnewprec(nf,0);
        !          2123:
        !          2124:   nv = lgef(nf[1])==4? 1: 2;
        !          2125:   for (i=1; ; i++)
        !          2126:   {
        !          2127:     v = fincke_pohst(nf,NULL,stoi(5000),3,prec, &checkgenerator);
        !          2128:     if (v) break;
        !          2129:     if (i==MAXITERPOL) err(accurer,"polredabs0");
        !          2130:     prec = (prec<<1)-2; nf = nfnewprec(nf,prec);
        !          2131:     if (DEBUGLEVEL) err(warnprec,"polredabs0",prec);
        !          2132:   }
        !          2133:   a = (GEN)v[2];
        !          2134:   y = (GEN)v[1];
        !          2135:   nv = lg(a);
        !          2136:   for (i=1; i<nv; i++)
        !          2137:     if (canon_pol((GEN)y[i]) < 0 && phimax)
        !          2138:       a[i] = (long) gneg_i((GEN)a[i]);
        !          2139:   nv = remove_duplicates(y,a);
        !          2140:
        !          2141:   if (DEBUGLEVEL)
        !          2142:     { fprintferr("%ld minimal vectors found.\n",nv-1); flusherr(); }
        !          2143:   if (nv >= 10000) flun &= (~nf_ALL); /* should not happen */
        !          2144:   storepols = (flun & nf_ALL)? storeallpols: findmindisc;
        !          2145:
        !          2146:   if (DEBUGLEVEL) fprintferr("\n");
        !          2147:   if (nv==1)
        !          2148:   {
        !          2149:     x=(GEN)nf[1];
        !          2150:     y = cgetg(2,t_VEC); y[1]=(long)x;
        !          2151:     a = cgetg(2,t_VEC); a[1]=(long)polx[varn(x)];
        !          2152:   }
        !          2153:   return gerepileupto(av, storepols(nf,y,a,phimax,flun));
        !          2154: }
        !          2155:
        !          2156: GEN
        !          2157: polredabsall(GEN x, long flun, long prec)
        !          2158: {
        !          2159:   return polredabs0(x, flun | nf_ALL, prec);
        !          2160: }
        !          2161:
        !          2162: GEN
        !          2163: polredabs(GEN x, long prec)
        !          2164: {
        !          2165:   return polredabs0(x,nf_REGULAR,prec);
        !          2166: }
        !          2167:
        !          2168: GEN
        !          2169: polredabs2(GEN x, long prec)
        !          2170: {
        !          2171:   return polredabs0(x,nf_ORIG,prec);
        !          2172: }
        !          2173:
        !          2174: GEN
        !          2175: polredabsnored(GEN x, long prec)
        !          2176: {
        !          2177:   return polredabs0(x,nf_NORED,prec);
        !          2178: }
        !          2179:
        !          2180: GEN
        !          2181: polred(GEN x, long prec)
        !          2182: {
        !          2183:   return allpolred(x,(GEN*)0,0,prec);
        !          2184: }
        !          2185:
        !          2186: GEN
        !          2187: smallpolred(GEN x, long prec)
        !          2188: {
        !          2189:   return allpolred(x,(GEN*)0,1,prec);
        !          2190: }
        !          2191:
        !          2192: GEN
        !          2193: factoredpolred(GEN x, GEN p, long prec)
        !          2194: {
        !          2195:   return allpolred(x,(GEN*)0,(long)p,prec);
        !          2196: }
        !          2197:
        !          2198: GEN
        !          2199: polred2(GEN x, long prec)
        !          2200: {
        !          2201:   GEN y=cgetg(3,t_MAT);
        !          2202:
        !          2203:   y[2]= (long) allpolred(x,(GEN*)(y+1),0,prec);
        !          2204:   return y;
        !          2205: }
        !          2206:
        !          2207: GEN
        !          2208: smallpolred2(GEN x, long prec)
        !          2209: {
        !          2210:   GEN y=cgetg(3,t_MAT);
        !          2211:
        !          2212:   y[2]= (long) allpolred(x,(GEN*)(y+1),1,prec);
        !          2213:   return y;
        !          2214: }
        !          2215:
        !          2216: GEN
        !          2217: factoredpolred2(GEN x, GEN p, long prec)
        !          2218: {
        !          2219:   GEN y=cgetg(3,t_MAT);
        !          2220:
        !          2221:   y[2]= (long) allpolred(x,(GEN*)(y+1),(long)p,prec);
        !          2222:   return y;
        !          2223: }
        !          2224:
        !          2225: GEN makebasis(GEN nf,GEN pol);
        !          2226: /* relative polredabs. Returns
        !          2227:  * flag = 0: relative polynomial
        !          2228:  * flag = 1: relative polynomial + element
        !          2229:  * flag = 2: absolute polynomial */
        !          2230: GEN
        !          2231: rnfpolredabs(GEN nf, GEN relpol, long flag, long prec)
        !          2232: {
        !          2233:   GEN p1,bpol,rnf,elt,pol;
        !          2234:   long va, av = avma;
        !          2235:
        !          2236:   if (typ(relpol)!=t_POL) err(typeer,"rnfpolredabs");
        !          2237:   nf=checknf(nf); va = varn(relpol);
        !          2238:   if (DEBUGLEVEL>1) timer2();
        !          2239:   p1 = makebasis(nf, unifpol(nf,relpol,1));
        !          2240:   rnf = (GEN)p1[3];
        !          2241:   if (DEBUGLEVEL>1)
        !          2242:   {
        !          2243:     msgtimer("absolute basis");
        !          2244:     fprintferr("original absolute generator: %Z\n",p1[1]);
        !          2245:   }
        !          2246:   p1 = polredabs0(p1, nf_RAW | nf_NORED, prec);
        !          2247:   bpol = (GEN)p1[1];
        !          2248:   if (DEBUGLEVEL>1) fprintferr("reduced absolute generator: %Z\n",bpol);
        !          2249:   if (flag==2) return gerepileupto(av,bpol);
        !          2250:
        !          2251:   elt = rnfelementabstorel(rnf,(GEN)p1[2]);
        !          2252:   p1=cgetg(3,t_VEC);
        !          2253: #if 1
        !          2254:   pol = rnfcharpoly(nf,relpol,elt,va);
        !          2255: #else
        !          2256: {
        !          2257:   long i;
        !          2258:   p1=(GEN)nffactor(nf,bpol)[1];
        !          2259:   for (i=lg(p1)-1; i; i--)
        !          2260:     if(gcmp0(gsubst((GEN)p1[i],va,elt))) { pol=(GEN)p1[i]; break; }
        !          2261:   if (!i) err(bugparier,"rnfpolredabs (pol not found)");
        !          2262: }
        !          2263: #endif
        !          2264:
        !          2265:   if (!flag) p1 = pol;
        !          2266:   else
        !          2267:   {
        !          2268:     p1[1]=(long)pol;
        !          2269:     p1[2]=(long)polymodrecip(elt);
        !          2270:   }
        !          2271:   return gerepileupto(av,p1);
        !          2272: }
        !          2273:
        !          2274: /********************************************************************/
        !          2275: /**                                                                **/
        !          2276: /**                              MINIM                             **/
        !          2277: /**                                                                **/
        !          2278: /********************************************************************/
        !          2279: long addcolumntomatrix(long *V,long n,long r,GEN *INVP,long *L);
        !          2280: GEN gmul_mat_smallvec(GEN x, GEN y, long hx, long ly);
        !          2281:
        !          2282: /* Minimal vectors for the integral definite quadratic form: a.
        !          2283:  * Result u:
        !          2284:  *   u[1]= Number of vectors of square norm <= BORNE
        !          2285:  *   u[2]= maximum norm found
        !          2286:  *   u[3]= list of vectors found (at most STOCKMAX)
        !          2287:  *
        !          2288:  *  If BORNE = gzero: Minimal non-zero vectors.
        !          2289:  *  flag = min_ALL,   as above
        !          2290:  *  flag = min_FIRST, exits when first suitable vector is found.
        !          2291:  *  flag = min_PERF,  only compute rank of the family of v.v~ (v min.)
        !          2292:  */
        !          2293: static GEN
        !          2294: minim00(GEN a, GEN BORNE, GEN STOCKMAX, long flag)
        !          2295: {
        !          2296:   GEN res,p1,u,r,liste,gnorme,gnorme_max,invp,V, *gptr[2];
        !          2297:   long n = lg(a), av0 = avma, av1,av,tetpil,lim, i,j,k,s,maxrank,*x;
        !          2298:   double p,borne,*v,*y,*z,**q, eps = 0.000001;
        !          2299:
        !          2300:   switch(flag)
        !          2301:   {
        !          2302:     case min_FIRST: res = cgetg(3,t_VEC); break;
        !          2303:     case min_ALL: res = cgetg(4,t_VEC);
        !          2304:   }
        !          2305:   av=avma;
        !          2306:
        !          2307:   x = (long*)    new_chunk(n);
        !          2308:   q = (double**) new_chunk(n);
        !          2309:
        !          2310:   /* correct alignment for the following */
        !          2311:   s = avma % sizeof(double); avma -= s;
        !          2312:   if (avma<bot) err(errpile);
        !          2313:
        !          2314:   s = (n * sizeof(double))/sizeof(long);
        !          2315:   y = (double*) new_chunk(s);
        !          2316:   z = (double*) new_chunk(s);
        !          2317:   v = (double*) new_chunk(s);
        !          2318:   for (j=1; j<n; j++) q[j] = (double*) new_chunk(s);
        !          2319:   av1=avma;
        !          2320:
        !          2321:   u = lllgramint(a); a = qf_base_change(a,u,1);
        !          2322:   if (lg(a) != n)
        !          2323:     err(talker,"not a definite form in minim00");
        !          2324:
        !          2325:   n--;
        !          2326:   a = gmul(a, realun(DEFAULTPREC)); r = sqred1(a);
        !          2327:   if (DEBUGLEVEL>4) { fprintferr("minim: r = "); outerr(r); }
        !          2328:   for (j=1; j<=n; j++)
        !          2329:   {
        !          2330:     v[j] = rtodbl(gcoeff(r,j,j));
        !          2331:     for (i=1; i<j; i++) q[i][j] = rtodbl(gcoeff(r,i,j));
        !          2332:   }
        !          2333:
        !          2334:   if (flag==min_PERF || gcmp0(BORNE))
        !          2335:   {
        !          2336:     double c, b = rtodbl(gcoeff(a,1,1));
        !          2337:
        !          2338:     for (i=2; i<=n; i++)
        !          2339:       { c=rtodbl(gcoeff(a,i,i)); if (c<b) b=c; }
        !          2340:     borne = b+eps;
        !          2341:     BORNE = ground(dbltor(borne));
        !          2342:     gnorme_max = NULL;
        !          2343:   }
        !          2344:   else
        !          2345:   {
        !          2346:     BORNE = gfloor(BORNE);
        !          2347:     borne = gtodouble(BORNE)+eps;
        !          2348:     gnorme_max = gzero;
        !          2349:   }
        !          2350:
        !          2351:   switch(flag)
        !          2352:   {
        !          2353:     case min_ALL:
        !          2354:       maxrank=itos(STOCKMAX);
        !          2355:       liste = new_chunk(1+maxrank);
        !          2356:       break;
        !          2357:     case min_PERF:
        !          2358:       BORNE = gerepileupto(av1,BORNE);
        !          2359:       maxrank = (n*(n+1))>>1;
        !          2360:       liste = new_chunk(1+maxrank); V = new_chunk(1+maxrank);
        !          2361:       for (i=1; i<=maxrank; i++) liste[i]=0;
        !          2362:   }
        !          2363:
        !          2364:   s=0; av1=avma; lim = stack_lim(av1,1);
        !          2365:   k = n; y[n] = z[n] = 0;
        !          2366:   x[n] = (long) sqrt(borne/v[n]+eps);
        !          2367:   if (flag == min_PERF) invp = idmat(maxrank);
        !          2368:   for(;;)
        !          2369:   {
        !          2370:     do
        !          2371:     {
        !          2372:       if (k>1)
        !          2373:       {
        !          2374:        k--; z[k]=0;
        !          2375:        for (j=k+1; j<=n; j++) z[k] += q[k][j]*x[j];
        !          2376:        p = x[k+1]+z[k+1];
        !          2377:        y[k] = y[k+1] + p*p*v[k+1];
        !          2378:        x[k] = (long) floor(sqrt((borne-y[k]+eps)/v[k])-z[k]);
        !          2379:       }
        !          2380:       for(;;)
        !          2381:       {
        !          2382:        p=x[k]+z[k];
        !          2383:        if (y[k] + p*p*v[k] <= borne+eps) break;
        !          2384:        k++; x[k]--;
        !          2385:       }
        !          2386:     }
        !          2387:     while (k>1);
        !          2388:     if (! x[1] && y[1]<=eps) break;
        !          2389:     p = x[1]+z[1]; gnorme = ground( dbltor(y[1]+ p*p*v[1]) );
        !          2390:     if (gnorme_max)
        !          2391:       { if (gcmp(gnorme,gnorme_max) > 0) gnorme_max=gnorme; }
        !          2392:     else
        !          2393:     {
        !          2394:       if (gcmp(gnorme,BORNE) < 0)
        !          2395:       {
        !          2396:        borne=gtodouble(gnorme); s=0;
        !          2397:         affii(gnorme,BORNE); avma=av1;
        !          2398:        if (flag == min_PERF) invp = idmat(maxrank);
        !          2399:       }
        !          2400:     }
        !          2401:
        !          2402:     switch(flag)
        !          2403:     {
        !          2404:       case min_ALL:
        !          2405:         s++;
        !          2406:         if (s<=maxrank)
        !          2407:         {
        !          2408:           p1 = new_chunk(n+1); liste[s] = (long) p1;
        !          2409:           for (i=1; i<=n; i++) p1[i] = x[i];
        !          2410:         }
        !          2411:         break;
        !          2412:
        !          2413:       case min_FIRST:
        !          2414:         if (! gnorme_max || gcmp(gnorme,BORNE)>0) break;
        !          2415:
        !          2416:         tetpil=avma; gnorme = icopy(gnorme); r = gmul_mat_smallvec(r,x,n,n);
        !          2417:         gptr[0]=&gnorme; gptr[1]=&r; gerepilemanysp(av,tetpil,gptr,2);
        !          2418:         res[1]=(long)gnorme;
        !          2419:         res[2]=(long)r; return res;
        !          2420:
        !          2421:       case min_PERF:
        !          2422:       {
        !          2423:         long av2=avma, I=1, newran;
        !          2424:
        !          2425:         for (i=1; i<=n; i++)
        !          2426:           for (j=i; j<=n; j++,I++) V[I] = x[i]*x[j];
        !          2427:         newran = addcolumntomatrix(V,maxrank,s,&invp,liste);
        !          2428:         if (newran == s)
        !          2429:         {
        !          2430:           avma=av2;
        !          2431:           if (DEBUGLEVEL>1) { fprintferr("."); flusherr(); }
        !          2432:         }
        !          2433:         else
        !          2434:         {
        !          2435:           if (DEBUGLEVEL>1) { fprintferr("*"); flusherr(); }
        !          2436:           s = newran;
        !          2437:           if (s == maxrank)
        !          2438:           {
        !          2439:             if (DEBUGLEVEL>1) { fprintferr("\n"); flusherr(); }
        !          2440:             avma=av0; return stoi(s);
        !          2441:           }
        !          2442:
        !          2443:           if (low_stack(lim, stack_lim(av1,1)))
        !          2444:           {
        !          2445:             if(DEBUGMEM>1) err(warnmem,"minim00");
        !          2446:             if (DEBUGLEVEL>1)
        !          2447:             {
        !          2448:               fprintferr("\ngerepile in qfperfection. rank>=%ld\n",s);
        !          2449:               flusherr();
        !          2450:             }
        !          2451:             tetpil=avma; invp = gerepile(av1,tetpil,gcopy(invp));
        !          2452:           }
        !          2453:         }
        !          2454:       }
        !          2455:     }
        !          2456:     x[1]--;
        !          2457:   }
        !          2458:   switch(flag)
        !          2459:   {
        !          2460:     case min_FIRST:
        !          2461:       avma=av0; return cgetg(1,t_VEC);
        !          2462:     case min_PERF:
        !          2463:       if (DEBUGLEVEL>1) { fprintferr("\n"); flusherr(); }
        !          2464:       avma=av0; return stoi(s);
        !          2465:   }
        !          2466:   k = min(s,maxrank);
        !          2467:
        !          2468:   tetpil = avma; p1=cgetg(k+1,t_MAT);
        !          2469:   for (j=1; j<=k; j++)
        !          2470:     p1[j] = (long) gmul_mat_smallvec(u,(GEN)liste[j],n,n);
        !          2471:   liste = p1;
        !          2472:   r = gnorme_max? gnorme_max: BORNE;
        !          2473:
        !          2474:   r=icopy(r); gptr[0]=&r; gptr[1]=&liste;
        !          2475:   gerepilemanysp(av,tetpil,gptr,2);
        !          2476:   res[1]=lstoi(s<<1);
        !          2477:   res[2]=(long)r;
        !          2478:   res[3]=(long)liste; return res;
        !          2479: }
        !          2480:
        !          2481: GEN
        !          2482: minim0(GEN a, GEN borne, GEN stockmax, long flag, long prec)
        !          2483: {
        !          2484:   switch(flag)
        !          2485:   {
        !          2486:     case 0: return minim00(a,borne,stockmax,min_ALL);
        !          2487:     case 1: return minim00(a,borne,gzero   ,min_FIRST);
        !          2488:     case 2: return fincke_pohst(a,borne,stockmax,0,prec,NULL);
        !          2489:     default: err(flagerr,"qfminim");
        !          2490:   }
        !          2491:   return NULL; /* not reached */
        !          2492: }
        !          2493:
        !          2494: GEN
        !          2495: minim(GEN a, GEN borne, GEN stockmax)
        !          2496: {
        !          2497:   return minim00(a,borne,stockmax,min_ALL);
        !          2498: }
        !          2499:
        !          2500: GEN
        !          2501: minim2(GEN a, GEN borne, GEN stockmax)
        !          2502: {
        !          2503:   return minim00(a,borne,stockmax,min_FIRST);
        !          2504: }
        !          2505:
        !          2506: GEN
        !          2507: perf(GEN a)
        !          2508: {
        !          2509:   return minim00(a,gzero,gzero,min_PERF);
        !          2510: }
        !          2511:
        !          2512: /* programme general pour les formes quadratiques definies positives
        !          2513:  * quelconques (a coeffs reels). On doit avoir BORNE != 0; on n'entre dans
        !          2514:  * cette fonction qu'a partir de fincke_pohst (la reduction LLL n'est donc
        !          2515:  * pas faite ici). Si flag >= 2, on s'arrete des que stockmax est atteint.
        !          2516:  * Si flag&1 == 1, pas d'erreur dans sqred1intern. */
        !          2517: static GEN
        !          2518: smallvectors(GEN a, GEN BORNE, GEN STOCKMAX, long flag, long prec,
        !          2519:              GEN (*check)(GEN))
        !          2520: {
        !          2521:   long av = avma,av1,av2,lim,N,n,i,j,k,s,stockmax,epsbit,checkcnt = 0;
        !          2522:   GEN u,S,x,y,z,v,q,norme1,normax1,borne1,borne2,eps,p1,alpha,norms;
        !          2523:
        !          2524:   N=lg(a); n=N-1; stockmax=itos(STOCKMAX);
        !          2525:   if (DEBUGLEVEL)
        !          2526:     fprintferr("smallvectors looking for norm <= %Z\n",gprec_w(BORNE,3));
        !          2527:
        !          2528:   lim=stack_lim(av,1); q=sqred1intern(a,flag&1);
        !          2529:   if (q == NULL) { avma=av; return NULL; }
        !          2530:   if (DEBUGLEVEL>5) fprintferr("q = %Z",q);
        !          2531:   epsbit = bit_accuracy(prec) >> 1;
        !          2532:   eps=realun(prec); setexpo(eps,-epsbit);
        !          2533:   alpha = dbltor(0.95);
        !          2534:   normax1=gzero;
        !          2535:   borne1=gadd(BORNE,eps);
        !          2536:   borne2=mpmul(borne1,alpha);
        !          2537:   v=cgetg(N,t_VEC);
        !          2538:
        !          2539:   av2=avma;
        !          2540:   S = cgetg(stockmax+1,t_MAT);
        !          2541:   norms = cgetg(stockmax+1,t_VEC);
        !          2542:   x=cgetg(N,t_COL);
        !          2543:   y=cgetg(N,t_COL);
        !          2544:   z=cgetg(N,t_COL);
        !          2545:   for (i=1; i<N; i++) { v[i] = coeff(q,i,i); x[i]=y[i]=z[i] = zero; }
        !          2546:
        !          2547:   x[n] = lmpent(mpsqrt(gdiv(borne1,(GEN)v[n])));
        !          2548:   if (DEBUGLEVEL>3) { fprintferr("\nx[%ld] = %Z\n",n,x[n]); flusherr(); }
        !          2549:
        !          2550:   s=0; k=n;
        !          2551:   for(;;)
        !          2552:   {
        !          2553:     do
        !          2554:     {
        !          2555:       int fl=0;
        !          2556:       if (k>1)
        !          2557:       {
        !          2558:         av1=avma; k--;
        !          2559:         p1 = mpmul(gcoeff(q,k,k+1),(GEN)x[k+1]);
        !          2560:        for (j=k+2; j<N; j++)
        !          2561:          p1 = mpadd(p1, mpmul(gcoeff(q,k,j),(GEN)x[j]));
        !          2562:         z[k] = lpileupto(av1,p1);
        !          2563:
        !          2564:         av1=avma;
        !          2565:        p1 = gsqr(mpadd((GEN)x[k+1],(GEN)z[k+1]));
        !          2566:        y[k] = lpileupto(av1, mpadd((GEN)y[k+1], mpmul(p1,(GEN)v[k+1])));
        !          2567:
        !          2568:         av1=avma;
        !          2569:        p1 = mpsub(borne1, (GEN)y[k]);
        !          2570:        if (signe(p1) < 0) { avma=av1; fl = 1; }
        !          2571:         else
        !          2572:         {
        !          2573:           p1 = mpadd(eps,mpsub(mpsqrt(gdiv(p1,(GEN)v[k])), (GEN)z[k]));
        !          2574:           avma=av1; x[k] = lmpent(p1); /* safe */
        !          2575:         }
        !          2576:       }
        !          2577:       else if (check)
        !          2578:       { /* don't waste time on the [x,0,...0] */
        !          2579:         for (i=k+1; i<N; i++)
        !          2580:           if (signe(x[i])) break;
        !          2581:         if (i == N && signe(x[1])) x[1] = un;
        !          2582:       }
        !          2583:       for(;;)
        !          2584:       {
        !          2585:         av1=avma;
        !          2586:        if (!fl)
        !          2587:        {
        !          2588:          p1 = mpmul((GEN)v[k], gsqr(mpadd((GEN)x[k],(GEN)z[k])));
        !          2589:          if (mpcmp(mpsub(mpadd(p1,(GEN)y[k]), borne1),
        !          2590:                    gmul2n(mpabs(p1),-epsbit)) <= 0) { avma=av1; break; }
        !          2591:        }
        !          2592:         avma=av1; k++; fl=0;
        !          2593:         x[k]=laddis((GEN)x[k],-1);
        !          2594:       }
        !          2595:       if (low_stack(lim, stack_lim(av,1)))
        !          2596:       {
        !          2597:        GEN *gptr[8];
        !          2598:         int a = 4;
        !          2599:        if(DEBUGMEM>1) err(warnmem,"smallvectors");
        !          2600:        gptr[0]=&x; gptr[1]=&y; gptr[2]=&z; gptr[3]=&normax1;
        !          2601:        if (stockmax)
        !          2602:         {
        !          2603:           for (i=s+1; i<=stockmax; i++) S[i]=zero;
        !          2604:           gptr[4]=&S; a++;
        !          2605:         }
        !          2606:         if (check)
        !          2607:         {
        !          2608:           gptr[5]=&borne1; gptr[6]=&borne2; gptr[7]=&norms;
        !          2609:           for (i=s+1; i<=stockmax; i++) norms[i]=zero;
        !          2610:           a+=3;
        !          2611:         }
        !          2612:        gerepilemany(av2,gptr,a);
        !          2613:       }
        !          2614:       if (DEBUGLEVEL>3)
        !          2615:       {
        !          2616:        if (DEBUGLEVEL>5) fprintferr("%ld ",k);
        !          2617:        if (k==n) fprintferr("\nx[%ld] = %Z\n",n,x[n]);
        !          2618:        flusherr();
        !          2619:       }
        !          2620:     }
        !          2621:     while (k>1);
        !          2622:     if (!signe(x[1]) && gexpo((GEN)y[1]) <= -epsbit) break;
        !          2623:
        !          2624:     av1=avma; p1 = gsqr(mpadd((GEN)x[1],(GEN)z[1]));
        !          2625:     norme1 = mpadd((GEN)y[1], mpmul(p1, (GEN)v[1]));
        !          2626:     if (mpcmp(norme1,borne1) > 0) avma=av1;
        !          2627:     else
        !          2628:     {
        !          2629:       norme1 = gerepileupto(av1,norme1);
        !          2630:       if (check)
        !          2631:       {
        !          2632:         if (checkcnt < 5 && mpcmp(norme1, borne2) < 0)
        !          2633:         {
        !          2634:           if (check(x))
        !          2635:           {
        !          2636:             borne1 = mpadd(norme1,eps);
        !          2637:             borne2 = mpmul(borne1,alpha);
        !          2638:             s = 0; checkcnt = 0;
        !          2639:           }
        !          2640:           else { checkcnt++ ; goto CONTINUE; }
        !          2641:         }
        !          2642:       }
        !          2643:       else if (mpcmp(norme1,normax1) > 0) normax1=norme1;
        !          2644:       if (++s <= stockmax)
        !          2645:       {
        !          2646:         norms[s] = (long)norme1;
        !          2647:         p1 = cgetg(N,t_COL); S[s] = (long)p1;
        !          2648:        for (i=1; i<N; i++) p1[i]=x[i];
        !          2649:         if (s == stockmax && (flag&2) && check)
        !          2650:         {
        !          2651:           long av1 = avma;
        !          2652:           GEN per = sindexsort(norms);
        !          2653:           if (DEBUGLEVEL) fprintferr("sorting...\n");
        !          2654:           for (i=1; i<=s; i++)
        !          2655:           {
        !          2656:             long k = per[i];
        !          2657:             if (check((GEN)S[k]))
        !          2658:             {
        !          2659:               S[1] = S[k]; avma = av1;
        !          2660:               borne1 = mpadd(norme1,eps);
        !          2661:               borne2 = mpmul(borne1,alpha);
        !          2662:               s = 1; checkcnt = 0; break;
        !          2663:             }
        !          2664:           }
        !          2665:           if (checkcnt) s = 0;
        !          2666:         }
        !          2667:       }
        !          2668:     }
        !          2669: CONTINUE:
        !          2670:     x[k] = laddis((GEN)x[k],-1);
        !          2671:   }
        !          2672:   if (s<stockmax) stockmax = s;
        !          2673:   if (check)
        !          2674:   {
        !          2675:     GEN per, alph,pols,p;
        !          2676:     if (DEBUGLEVEL) fprintferr("final sort & check...\n");
        !          2677:     setlg(norms,s+1); per = sindexsort(norms);
        !          2678:     alph = cgetg(s+1,t_VEC);
        !          2679:     pols = cgetg(s+1,t_VEC);
        !          2680:     for (j=0,i=1; i<=s; i++)
        !          2681:     {
        !          2682:       long k = per[i];
        !          2683:       if (j && mpcmp((GEN)norms[k], borne1) > 0) break;
        !          2684:       if ((p = check((GEN)S[k])))
        !          2685:       {
        !          2686:         if (!j) borne1 = gadd((GEN)norms[k],eps);
        !          2687:         j++; pols[j]=(long)p; alph[j]=S[k];
        !          2688:       }
        !          2689:     }
        !          2690:     u = cgetg(3,t_VEC);
        !          2691:     setlg(pols,j+1); u[1] = (long)pols;
        !          2692:     setlg(alph,j+1); u[2] = (long)alph; return u;
        !          2693:   }
        !          2694:   u=cgetg(4,t_VEC);
        !          2695:   u[1]=lstoi(s<<1);
        !          2696:   u[2]=(long)normax1; setlg(S,stockmax+1);
        !          2697:   u[3]=(long)S; return u;
        !          2698: }
        !          2699:
        !          2700: /* return T2 norm of the polynomial defining nf */
        !          2701: static GEN
        !          2702: get_Bnf(GEN nf)
        !          2703: {
        !          2704:   GEN p = gzero, r = (GEN)nf[6];
        !          2705:   long i, r1 = itos(gmael(nf,2,1)), ru = lg(r)-1;
        !          2706:   for (i=ru; i>0; i--)
        !          2707:   {
        !          2708:     if (i == r1) p = gmul2n(p, 1);
        !          2709:     p = gadd(p, gnorm((GEN)r[i]));
        !          2710:   }
        !          2711:   if (i == r1) p = gmul2n(p, 1);
        !          2712:   return p;
        !          2713: }
        !          2714:
        !          2715: /* solve x~.a.x <= borne, a > 0. If check is non-NULL keep x only if check(x).
        !          2716:  * flag = 1, return NULL in case of precision problems (sqred1 or lllgram)
        !          2717:  *   raise an error otherwse.
        !          2718:  * flag = 2, return as soon as stockmax vectors found.
        !          2719:  * flag = 3, corresponds to 1+2 */
        !          2720: GEN
        !          2721: fincke_pohst(GEN a,GEN bound,GEN stockmax,long flag, long prec,
        !          2722:              GEN (*check)(GEN))
        !          2723: {
        !          2724:   long pr,av=avma,i,j,n;
        !          2725:   GEN B,nf,r,rinvtrans,v,v1,u,s,res,z,vnorm,sperm,perm,uperm,basis,gram;
        !          2726:
        !          2727:   if (DEBUGLEVEL>2) { fprintferr("entering fincke_pohst\n"); flusherr(); }
        !          2728:   if (typ(a) == t_VEC) { nf = a; a = gmael(nf,5,3); } else nf = NULL;
        !          2729:   pr = gprecision(a);
        !          2730:   if (pr) prec = pr; else a = gmul(a,realun(prec));
        !          2731:   if (DEBUGLEVEL>2) fprintferr("first LLL: prec = %ld\n", prec);
        !          2732:   v1 = lllgramintern(a,4,flag&1, (prec<<1)-2);
        !          2733:   if (v1 == NULL) goto PRECPB;
        !          2734:   r = qf_base_change(a,v1,1);
        !          2735:   r = sqred1intern(r,flag&1);
        !          2736:   if (r == NULL) goto PRECPB;
        !          2737:
        !          2738:   n = lg(a);
        !          2739:   for (i=1; i<n; i++)
        !          2740:   {
        !          2741:     GEN p1 = gsqrt(gcoeff(r,i,i), prec);
        !          2742:     coeff(r,i,i)=(long)p1;
        !          2743:     for (j=i+1; j<n; j++)
        !          2744:       coeff(r,i,j) = lmpmul(p1, gcoeff(r,i,j));
        !          2745:   }
        !          2746:   /* now r~ * r = a in LLL basis */
        !          2747:   rinvtrans = gtrans(invmat(r));
        !          2748:   if (DEBUGLEVEL>2)
        !          2749:     fprintferr("final LLL: prec = %ld, precision(rinvtrans) = %ld\n",
        !          2750:                 prec,gprecision(rinvtrans));
        !          2751:   v = lllintern(rinvtrans,flag&1, (gprecision(rinvtrans)<<1)-2);
        !          2752:   if (v == NULL) goto PRECPB;
        !          2753:   rinvtrans = gmul(rinvtrans,v);
        !          2754:
        !          2755:   u = invmat(gtrans(v)); s = gmul(r,u);
        !          2756:   u = gmul(v1, u);
        !          2757:   vnorm=cgetg(n,t_VEC);
        !          2758:   for (j=1; j<n; j++) vnorm[j] = lnorml2((GEN)rinvtrans[j]);
        !          2759:   perm = sindexsort(vnorm);
        !          2760:   sperm = cgetg(n,t_MAT);
        !          2761:   uperm = cgetg(n,t_MAT);
        !          2762:   for (i=1; i<n; i++) { uperm[n-i] = u[perm[i]]; sperm[n-i] = s[perm[i]]; }
        !          2763:
        !          2764:   gram = gram_matrix(sperm);
        !          2765:   B = gcoeff(gram,n-1,n-1);
        !          2766:   if (gexpo(B) >= bit_accuracy(lg(B)-2)) goto PRECPB;
        !          2767:
        !          2768:   if (check && nf) basis = init_chk(nf,uperm,NULL);
        !          2769:   if (!bound)
        !          2770:   { /* polred */
        !          2771:     GEN x = cgetg(n,t_COL);
        !          2772:
        !          2773:     if (nf) bound = get_Bnf(nf);
        !          2774:     for (j=1; j<n; j++) x[j]=zero;
        !          2775:     for (j=2; j<n; j++)
        !          2776:     {
        !          2777:       x[j]=un; B = gcoeff(gram,j,j);
        !          2778:       if (!bound || mpcmp(B,bound) < 0)
        !          2779:         if (!check || check(x)) bound = B;
        !          2780:       x[j]=zero;
        !          2781:     }
        !          2782:   }
        !          2783:
        !          2784:   if (DEBUGLEVEL>2) {fprintferr("entering smallvectors\n"); flusherr();}
        !          2785:   if (check && nf)
        !          2786:     if (! (prec = (long)init_chk(nf,uperm,bound))) goto PRECPB;
        !          2787:   i = check? 2: 1; if (i == n) i--;
        !          2788:   for (   ; i<n; i++)
        !          2789:   {
        !          2790:     res = smallvectors(gram,bound? bound: gceil(gcoeff(gram,i,i)),
        !          2791:                        stockmax,flag,prec,check);
        !          2792:     if (!res) goto PRECPB;
        !          2793:     if (!check || lg(res[2]) > 1) break;
        !          2794:     if (DEBUGLEVEL>2) fprintferr("  i = %ld failed\n",i);
        !          2795:   }
        !          2796:   if (check)
        !          2797:   {
        !          2798:     GEN p1 = (GEN)res[2];
        !          2799:     for (i=1; i<lg(p1); i++) p1[i] = lmul(basis, (GEN)p1[i]);
        !          2800:     return res;
        !          2801:   }
        !          2802:
        !          2803:   if (DEBUGLEVEL>2) {fprintferr("leaving fincke_pohst\n"); flusherr();}
        !          2804:   z=cgetg(4,t_VEC);
        !          2805:   z[1]=lcopy((GEN)res[1]);
        !          2806:   z[2]=pr? lcopy((GEN)res[2]) : lround((GEN)res[2]);
        !          2807:   z[3]=lmul(uperm, (GEN)res[3]); return gerepileupto(av,z);
        !          2808: PRECPB:
        !          2809:   if (!(flag & 1))
        !          2810:     err(talker,"not a positive definite form in fincke_pohst");
        !          2811:   avma = av; return NULL;
        !          2812: }

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