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

Annotation of OpenXM_contrib/pari-2.2/src/modules/aprcl.c, Revision 1.1

1.1     ! noro        1: /* $Id: aprcl.c,v 1.23 2002/07/15 13:26:20 karim Exp $
        !             2:
        !             3: Copyright (C) 2000  The PARI group.
        !             4:
        !             5: This file is part of the PARI/GP package.
        !             6:
        !             7: PARI/GP is free software; you can redistribute it and/or modify it under the
        !             8: terms of the GNU General Public License as published by the Free Software
        !             9: Foundation. It is distributed in the hope that it will be useful, but WITHOUT
        !            10: ANY WARRANTY WHATSOEVER.
        !            11:
        !            12: Check the License for details. You should have received a copy of it, along
        !            13: with the package; see the file 'COPYING'. If not, write to the Free Software
        !            14: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
        !            15:
        !            16: /*******************************************************************/
        !            17: /*                                                                 */
        !            18: /*                    THE APRCL PRIMALITY TEST                     */
        !            19: /*                                                                 */
        !            20: /*******************************************************************/
        !            21: #include "pari.h"
        !            22:
        !            23: static ulong kglob,ctglob,NBITSN,sgtaut,sgt6,sgtjac;
        !            24: static int isinstep5,ishack;
        !            25: static GEN *tabaall,*tabtall,*tabcyc,tabE,tabTH,tabeta,*tabmatvite,*tabmatinvvite,globfa,tabfaq,tabj,sgt,ctsgt,tabavite,tabpkvite,errfill;
        !            26: #define pkfalse (ishack ? 1 : pk)
        !            27: #define dotime (DEBUGLEVEL>=3)
        !            28:
        !            29: typedef struct red_t {
        !            30:   long n;
        !            31:   GEN C; /* polcyclo(n) */
        !            32:   GEN N; /* prime we are certifying */
        !            33:   GEN (*red)(GEN x, struct red_t *);
        !            34: } red_t;
        !            35:
        !            36: /* powering t_POLMOD mod N, flexible window */
        !            37:
        !            38: static GEN
        !            39: makepoldeg1(GEN c, GEN d)
        !            40: {
        !            41:   GEN res;
        !            42:   if (signe(c)) {
        !            43:     res = cgetg(4,t_POL); res[1] = evalsigne(1)|evallgef(4);
        !            44:     res[2] = (long)d; res[3] = (long)c;
        !            45:   } else if (signe(d)) {
        !            46:     res = cgetg(3,t_POL); res[1] = evalsigne(1)|evallgef(3);
        !            47:     res[2] = (long)d;
        !            48:   } else {
        !            49:     res = cgetg(2,t_POL); res[1] = evalsigne(0)|evallgef(2);
        !            50:   }
        !            51:   return res;
        !            52: }
        !            53:
        !            54: /* T mod polcyclo(p), assume deg(T) < 2p */
        !            55: static GEN
        !            56: red_mod_cyclo(GEN T, long p)
        !            57: {
        !            58:   long i, d;
        !            59:   GEN y, *z;
        !            60:
        !            61:   d = degpol(T) - p; /* < p */
        !            62:   if (d <= -2) return T;
        !            63:
        !            64:   /* reduce mod (x^p - 1) */
        !            65:   y = dummycopy(T); z = (GEN*)(y+2);
        !            66:   for (i = 0; i<=d; i++) z[i] = addii(z[i], z[i+p]);
        !            67:
        !            68:   /* reduce mod x^(p-1) + ... + 1 */
        !            69:   d = p-1;
        !            70:   if (signe(z[d]))
        !            71:     for (i=0; i<d; i++) z[i] = subii(z[i], z[d]);
        !            72:   return normalizepol_i(y, d+2);
        !            73: }
        !            74:
        !            75: /* x t_VECSMALL, n > 0. Return x mod polcyclo(2^n) = (x^(2^(n-1)) + 1). DESTROY x */
        !            76: static GEN
        !            77: u_red_mod_cyclo2n(GEN x, int n)
        !            78: {
        !            79:   long i, pow2 = 1<<(n-1);
        !            80:   GEN z;
        !            81:
        !            82:   for (i = lg(x)-1; i>pow2; i--) x[i-pow2] -= x[i];
        !            83:   for (; i>0; i--)
        !            84:     if (x[i]) break;
        !            85:   i += 2;
        !            86:   z = cgetg(i, t_POL); z[1] = evalsigne(1)|evallgef(i);
        !            87:   for (i--; i>=2; i--) z[i] = lstoi(x[i-1]);
        !            88:   return z;
        !            89: }
        !            90: /* x t_POL, n > 0. Return x mod polcyclo(2^n) = (x^(2^(n-1)) + 1). DESTROY x */
        !            91: static GEN
        !            92: red_mod_cyclo2n(GEN x, int n)
        !            93: {
        !            94:   long i, pow2 = 1<<(n-1);
        !            95:
        !            96:   for (i = lgef(x)-1; i>pow2+1; i--)
        !            97:     if (signe(x[i])) x[i-pow2] = lsubii((GEN)x[i-pow2], (GEN)x[i]);
        !            98:   for (; i>1; i--)
        !            99:     if (signe(x[i])) break;
        !           100:   i += 1; setlgef(x,i);
        !           101:   return x;
        !           102: }
        !           103:
        !           104: /* x a non-zero VECSMALL */
        !           105: static GEN
        !           106: smallpolrev(GEN x)
        !           107: {
        !           108:   long i,j, lx = lg(x);
        !           109:   GEN y;
        !           110:
        !           111:   while (lx-- && x[lx]==0) /* empty */;
        !           112:   i = lx+2; y = cgetg(i,t_POL);
        !           113:   y[1] = evallgef(i) | evalsigne(1);
        !           114:   for (j=2; j<i; j++) y[j] = lstoi(x[j-1]);
        !           115:   return y;
        !           116: }
        !           117:
        !           118: /* x polynomial in t_VECSMALL form, T t_POL return x mod T */
        !           119: static GEN
        !           120: u_red(GEN x, GEN T)
        !           121: {
        !           122:   return gres(smallpolrev(x), T);
        !           123: }
        !           124:
        !           125: /* special case R->C = polcyclo(p) */
        !           126: static GEN
        !           127: _red2(GEN x, red_t *R) {
        !           128:   return FpX_red(red_mod_cyclo(x, R->n), R->N);
        !           129: }
        !           130: static GEN
        !           131: _red(GEN x, red_t *R) {
        !           132:   return FpX_red(gres(x, R->C), R->N);
        !           133: }
        !           134:
        !           135: static GEN
        !           136: _redsimple(GEN x, red_t *R) {
        !           137:   return modii(x, R->N);
        !           138: }
        !           139:
        !           140: static GEN
        !           141: sqrmod(GEN x, red_t *R) {
        !           142:   return R->red(gsqr(x), R);
        !           143: }
        !           144:
        !           145: static GEN
        !           146: sqrconst(GEN pol, red_t *R)
        !           147: {
        !           148:   GEN p1 = cgetg(3,t_POL);
        !           149:   p1[2] = (long)modii(sqri((GEN)pol[2]), R->N);
        !           150:   p1[1] = pol[1]; return p1;
        !           151: }
        !           152:
        !           153: /* pol^2 mod (x^2+x+1, N) */
        !           154: static GEN
        !           155: sqrmod3(GEN pol, red_t *R)
        !           156: {
        !           157:   GEN a,b,bma,A,B;
        !           158:   long lv=lgef(pol);
        !           159:
        !           160:   if (lv==2) return pol;
        !           161:   if (lv==3) return sqrconst(pol, R);
        !           162:   a = (GEN)pol[3];
        !           163:   b = (GEN)pol[2]; bma = subii(b,a);
        !           164:   A = modii(mulii(a,addii(b,bma)), R->N);
        !           165:   B = modii(mulii(bma,addii(a,b)), R->N);
        !           166:   return makepoldeg1(A,B);
        !           167: }
        !           168:
        !           169: /* pol^2 mod (x^2+1,N) */
        !           170: static GEN
        !           171: sqrmod4(GEN pol, red_t *R)
        !           172: {
        !           173:   GEN a,b,A,B;
        !           174:   long lv=lgef(pol);
        !           175:
        !           176:   if (lv==2) return pol;
        !           177:   if (lv==3) return sqrconst(pol, R);
        !           178:   a = (GEN)pol[3];
        !           179:   b = (GEN)pol[2];
        !           180:   A = modii(mulii(a, shifti(b,1)), R->N);
        !           181:   B = modii(mulii(subii(b,a),addii(b,a)), R->N);
        !           182:   return makepoldeg1(A,B);
        !           183: }
        !           184:
        !           185: /* pol^2 mod (polcyclo(5),N) */
        !           186: static GEN
        !           187: sqrmod5(GEN pol, red_t *R)
        !           188: {
        !           189:   GEN c2,b,c,d,A,B,C,D;
        !           190:   long lv=lgef(pol);
        !           191:
        !           192:   if (lv==2) return pol;
        !           193:   if (lv==3) return sqrconst(pol, R);
        !           194:   b = (GEN)pol[4];
        !           195:   c = (GEN)pol[3]; c2 = shifti(c,1);
        !           196:   d = (GEN)pol[2];
        !           197:   if (lv==4)
        !           198:   {
        !           199:     A = mulii(b, subii(c2,b));
        !           200:     B = addii(sqri(c), mulii(b, subii(shifti(d,1),b)));
        !           201:     C = subii(mulii(c2,d), sqri(b));
        !           202:     D = mulii(subii(d,b), addii(d,b));
        !           203:   }
        !           204:   else
        !           205:   {
        !           206:     GEN a = (GEN)pol[5], a2 = shifti(a,1);
        !           207:     /* 2a(d - c) + b(2c - b) */
        !           208:     A = addii(mulii(a2, subii(d,c)), mulii(b, subii(c2,b)));
        !           209:     /* c(c - 2a) + b(2d - b) */
        !           210:     B = addii(mulii(c, subii(c,a2)), mulii(b, subii(shifti(d,1),b)));
        !           211:     /* (a-b)(a+b) + 2c(d - a) */
        !           212:     C = addii(mulii(subii(a,b),addii(a,b)), mulii(c2,subii(d,a)));
        !           213:     /* 2a(b - c) + (d-b)(d+b) */
        !           214:     D = addii(mulii(a2, subii(b,c)), mulii(subii(d,b), addii(d,b)));
        !           215:   }
        !           216:   A = modii(A, R->N);
        !           217:   B = modii(B, R->N);
        !           218:   C = modii(C, R->N);
        !           219:   D = modii(D, R->N);
        !           220:   return coefs_to_pol(4,A,B,C,D);
        !           221: }
        !           222:
        !           223: static GEN
        !           224: _mul(GEN x, GEN y, red_t *R) {
        !           225:   return R->red(gmul(x,y), R);
        !           226: }
        !           227:
        !           228: static GEN
        !           229: _powpolmod(int pk, GEN jac, red_t *R, GEN (*_sqr)(GEN, red_t *))
        !           230: {
        !           231:   const GEN taba = tabaall[pkfalse];
        !           232:   const GEN tabt = tabtall[pkfalse];
        !           233:   const int efin = lg(taba)-1;
        !           234:   GEN res,pol2, *vz;
        !           235:   int lv,tf,f,i;
        !           236:   gpmem_t av;
        !           237:
        !           238:   lv = 1 << (kglob-1);
        !           239:   vz = (GEN*)cgetg(lv+1,t_VEC);
        !           240:   res = lift(jac); pol2 = _sqr(res, R);
        !           241:   vz[1] = res;
        !           242:   for (i=2; i<=lv; i++) vz[i] = _mul(vz[i-1],pol2, R);
        !           243:   av = avma;
        !           244:   for (f=efin; f>=1; f--)
        !           245:   {
        !           246:     res = f==efin ? vz[taba[f]]
        !           247:                   : _mul(vz[taba[f]],res, R);
        !           248:     tf = tabt[f];
        !           249:     for (i=1; i<=tf; i++) res = _sqr(res, R);
        !           250:     if ((f&7) == 0) res = gerepilecopy(av, res);
        !           251:   }
        !           252:   return res;
        !           253: }
        !           254:
        !           255: static GEN
        !           256: _powpolmodsimple(red_t *R, int pk, GEN jac)
        !           257: {
        !           258:   GEN vres,w,wpow,wnew,ma;
        !           259:   long lvres;
        !           260:   int ph,j;
        !           261:
        !           262:   vres = gtovec(lift(jac)); settyp(vres,t_COL);
        !           263:   lvres = lg(vres);
        !           264:   ma = tabmatvite[pkfalse]; ph = lg(ma);
        !           265:   w = cgetg(lvres,t_MAT);
        !           266:   for (j=1; j<lvres; j++) w[j] = ma[j+ph-lvres];
        !           267:   w = gmul(w,vres);
        !           268:   R->red = &_redsimple;
        !           269:   wpow = cgetg(ph,t_COL);
        !           270:   for (j=1; j<ph; j++) wpow[j] = (long)_powpolmod(pk,(GEN)w[j],R,&sqrmod);
        !           271:   wnew = lift(gmul(tabmatinvvite[pkfalse],wpow));
        !           272:   return gtopoly(wnew,0);
        !           273: }
        !           274:
        !           275: GEN
        !           276: powpolmod(red_t *R, int k, int pk, GEN jac)
        !           277: {
        !           278:   GEN (*_sqr)(GEN, red_t *);
        !           279:
        !           280:   if (!gcmp0(tabmatvite[pkfalse])) return _powpolmodsimple(R, pk, jac);
        !           281:   if (pk == 3) {
        !           282:     R->red = &_red; _sqr = &sqrmod3;
        !           283:   } else if (pk == 4) {
        !           284:     R->red = &_red; _sqr = &sqrmod4;
        !           285:   } else if (pk == 5) {
        !           286:     R->red = &_red; _sqr = &sqrmod5;
        !           287:   } else if (k == 1 && pk >= 7) {
        !           288:     R->n = pk;
        !           289:     R->red = &_red2; _sqr = &sqrmod;
        !           290:   } else {
        !           291:     R->red = &_red; _sqr = &sqrmod;
        !           292:   }
        !           293:   return _powpolmod(pk, jac, R, _sqr);
        !           294: }
        !           295:
        !           296: static GEN
        !           297: e(ulong t)
        !           298: {
        !           299:   GEN fa,pr,ex,s;
        !           300:   ulong nbd,m,k,d;
        !           301:   int lfa,i,j;
        !           302:
        !           303:   fa = decomp(stoi(t));
        !           304:   pr = (GEN)fa[1]; settyp(pr, t_VECSMALL);
        !           305:   ex = (GEN)fa[2]; settyp(ex, t_VECSMALL); lfa = lg(pr);
        !           306:   nbd = 1;
        !           307:   for (i=1; i<lfa; i++)
        !           308:   {
        !           309:     ex[i] = itos((GEN)ex[i]) + 1;
        !           310:     pr[i] = itos((GEN)pr[i]);
        !           311:     nbd *= ex[i];
        !           312:   }
        !           313:   s = gdeux; /* nbd = number of divisors */
        !           314:   for (k=0; k<nbd; k++)
        !           315:   {
        !           316:     m = k; d = 1;
        !           317:     for (j=1; m; j++)
        !           318:     {
        !           319:       d *= u_pow(pr[j], m % ex[j]);
        !           320:       m /= ex[j];
        !           321:     }
        !           322:     /* d runs through the divisors of t */
        !           323:     if (isprime(stoi(++d))) s = muliu(s, u_pow(d, 1 + u_val(t,d)));
        !           324:   }
        !           325:   return s;
        !           326: }
        !           327:
        !           328: static ulong
        !           329: compt(GEN N)
        !           330: {
        !           331:   gpmem_t av0 = avma;
        !           332:   ulong Bint,t;
        !           333:   GEN B;
        !           334:
        !           335:   B = mulsr(100, divrr(glog(N,DEFAULTPREC), dbltor(log(10.))));
        !           336:   Bint = itos(gceil(B));
        !           337:   avma = av0;
        !           338:   /* Bint < [200*log_10 e(t)] ==> return t. For e(t) < 10^529, N < 10^1058 */
        !           339:   if (Bint <    540) return        6;
        !           340:   if (Bint <    963) return       12;
        !           341:   if (Bint <   1023) return       24;
        !           342:   if (Bint <   1330) return       48;
        !           343:   if (Bint <   1628) return       36;
        !           344:   if (Bint <   1967) return       60;
        !           345:   if (Bint <   2349) return      120;
        !           346:   if (Bint <   3083) return      180;
        !           347:   if (Bint <   3132) return      240;
        !           348:   if (Bint <   3270) return      504;
        !           349:   if (Bint <   3838) return      360;
        !           350:   if (Bint <   4115) return      420;
        !           351:   if (Bint <   4621) return      720;
        !           352:   if (Bint <   4987) return      840;
        !           353:   if (Bint <   5079) return     1440;
        !           354:   if (Bint <   6212) return     1260;
        !           355:   if (Bint <   6686) return     1680;
        !           356:   if (Bint <   8137) return     2520;
        !           357:   if (Bint <   8415) return     3360;
        !           358:   if (Bint <  10437) return     5040;
        !           359:   if (Bint <  11643) return    13860;
        !           360:   if (Bint <  12826) return    10080;
        !           361:   if (Bint <  11643) return    13860;
        !           362:   if (Bint <  12826) return    10080;
        !           363:   if (Bint <  13369) return    16380;
        !           364:   if (Bint <  13540) return    21840;
        !           365:   if (Bint <  15060) return    18480;
        !           366:   if (Bint <  15934) return    27720;
        !           367:   if (Bint <  17695) return    32760;
        !           368:   if (Bint <  18816) return    36960;
        !           369:   if (Bint <  21338) return    55440;
        !           370:   if (Bint <  23179) return    65520;
        !           371:   if (Bint <  23484) return    98280;
        !           372:   if (Bint <  27465) return   110880;
        !           373:   if (Bint <  30380) return   131040;
        !           374:   if (Bint <  31369) return   166320;
        !           375:   if (Bint <  33866) return   196560;
        !           376:   if (Bint <  34530) return   262080;
        !           377:   if (Bint <  36195) return   277200;
        !           378:   if (Bint <  37095) return   360360;
        !           379:   if (Bint <  38179) return   480480;
        !           380:   if (Bint <  41396) return   332640;
        !           381:   if (Bint <  43301) return   554400;
        !           382:   if (Bint <  47483) return   720720;
        !           383:   if (Bint <  47742) return   665280;
        !           384:   if (Bint <  50202) return   831600;
        !           385:   if (Bint <  52502) return  1113840;
        !           386:   if (Bint <  60245) return  1441440;
        !           387:   if (Bint <  63112) return  1663200;
        !           388:   if (Bint <  65395) return  2227680;
        !           389:   if (Bint <  69895) return  2162160;
        !           390:   if (Bint <  71567) return  2827440;
        !           391:   if (Bint <  75708) return  3326400;
        !           392:   if (Bint <  79377) return  3603600;
        !           393:   if (Bint <  82703) return  6126120;
        !           394:   if (Bint <  91180) return  4324320;
        !           395:   if (Bint <  93978) return  6683040;
        !           396:   if (Bint <  98840) return  7207200;
        !           397:   if (Bint <  99282) return 11138400;
        !           398:   if (Bint < 105811) return  8648640;
        !           399:
        !           400:   B = racine(N);
        !           401:   for (t = 8648640+840;; t+=840)
        !           402:   {
        !           403:     gpmem_t av = avma;
        !           404:     if (cmpii(e(t),B) > 0) break;
        !           405:     avma = av;
        !           406:   }
        !           407:   avma = av0; return t;
        !           408: }
        !           409:
        !           410: extern ulong u_gener(ulong p);
        !           411:
        !           412: /* tabdl[i] = discrete log of i+1 in (Z/q)^*, q odd prime */
        !           413: static GEN
        !           414: computetabdl(ulong q)
        !           415: {
        !           416:   GEN v = cgetg(q-1,t_VECSMALL), w = v-1; /* w[i] = dl(i) */
        !           417:   ulong g,qm3s2,qm1s2,a,i;
        !           418:
        !           419:   g = u_gener(q);
        !           420:   qm3s2 = (q-3)>>1;
        !           421:   qm1s2 = qm3s2+1;
        !           422:   w[q-1] = qm1s2; a = 1;
        !           423:   for (i=1; i<=qm3s2; i++)
        !           424:   {
        !           425:     a = mulssmod(g,a,q);
        !           426:     w[a]   = i;
        !           427:     w[q-a] = i+qm1s2;
        !           428:   }
        !           429:   return v;
        !           430: }
        !           431:
        !           432: static void
        !           433: compute_fg(ulong q, int half, GEN *tabf, GEN *tabg)
        !           434: {
        !           435:   const long qm3s2 = (q-3)>>1;
        !           436:   const long l = half? qm3s2: q-2;
        !           437:   ulong x;
        !           438:   *tabf = computetabdl(q);
        !           439:   *tabg = cgetg(l+1,t_VECSMALL);
        !           440:   for (x=1; x<=l; x++) (*tabg)[x] = (*tabf)[x] + (*tabf)[q-x-1];
        !           441: }
        !           442:
        !           443: /* p odd prime */
        !           444: static GEN
        !           445: get_jac(ulong q, ulong p, int k, GEN tabf, GEN tabg)
        !           446: {
        !           447:   GEN ze, vpk;
        !           448:   long i, qm3s2;
        !           449:   ulong x, pk;
        !           450:
        !           451:   pk = u_pow(p,k);
        !           452:   vpk = cgetg(pk+1,t_VECSMALL);
        !           453:   for (i=1; i<=pk; i++) vpk[i] = 0;
        !           454:   ze = tabcyc[pkfalse];
        !           455:
        !           456:   qm3s2 = (q-3)>>1;
        !           457:   for (x=1; x<=qm3s2; x++) vpk[ tabg[x]%pk + 1 ] += 2;
        !           458:   vpk[ (2*tabf[qm3s2+1])%pk + 1 ]++;
        !           459:   return u_red(vpk,ze);
        !           460: }
        !           461:
        !           462: /* p = 2 */
        !           463: static GEN
        !           464: get_jac2(GEN N, ulong q, int k, GEN *j2q, GEN *j3q)
        !           465: {
        !           466:   GEN jpq, vpk, tabf, tabg;
        !           467:   long i, qm3s2;
        !           468:   ulong x, pk;
        !           469:
        !           470:   if (k == 1) return NULL;
        !           471:
        !           472:   compute_fg(q,0, &tabf,&tabg);
        !           473:
        !           474:   pk = u_pow(2,k);
        !           475:   vpk = cgetg(pk+1,t_VECSMALL);
        !           476:   for (i=1; i<=pk; i++) vpk[i] = 0;
        !           477:
        !           478:   qm3s2 = (q-3)>>1;
        !           479:   for (x=1; x<=qm3s2; x++) vpk[ tabg[x]%pk + 1 ] += 2;
        !           480:   vpk[ (2*tabf[qm3s2+1])%pk + 1 ]++;
        !           481:   jpq = u_red_mod_cyclo2n(vpk, k);
        !           482:
        !           483:   if (k == 2) return jpq;
        !           484:
        !           485:   if (mod8(N) >= 5)
        !           486:   {
        !           487:     GEN v8 = cgetg(9,t_VECSMALL);
        !           488:     for (x=1; x<=8; x++) v8[x] = 0;
        !           489:     for (x=1; x<=q-2; x++) v8[ ((2*tabf[x]+tabg[x])&7) + 1 ]++;
        !           490:     *j2q = polinflate(gsqr(u_red_mod_cyclo2n(v8,3)), pk>>3);
        !           491:     *j2q = red_mod_cyclo2n(*j2q, k);
        !           492:   }
        !           493:
        !           494:   for (i=1; i<=pk; i++) vpk[i] = 0;
        !           495:   for (x=1; x<=q-2; x++) vpk[ (tabf[x]+tabg[x])%pk + 1 ]++;
        !           496:   *j3q = gmul(jpq, u_red_mod_cyclo2n(vpk,k));
        !           497:   *j3q = red_mod_cyclo2n(*j3q, k);
        !           498:   return jpq;
        !           499: }
        !           500:
        !           501: static void
        !           502: calcjac(GEN et)
        !           503: {
        !           504:   gpmem_t av;
        !           505:   ulong q, l;
        !           506:   int lfaq,p,k,i,j;
        !           507:   GEN J,tabf,tabg,faq,faqpr,faqex;
        !           508:
        !           509:   globfa = (GEN)decomp(shifti(et,-vali(et)))[1];
        !           510:   l = lg(globfa);
        !           511:   tabfaq= cgetg(l,t_VEC);
        !           512:   tabj  = cgetg(l,t_VEC);
        !           513:   for (i=1; i<l; i++)
        !           514:   {
        !           515:     q = itos((GEN)globfa[i]); /* odd prime */
        !           516:     faq = decomp(stoi(q-1)); tabfaq[i] = (long)faq;
        !           517:     faqpr = (GEN)faq[1];
        !           518:     faqex = (GEN)faq[2]; lfaq = lg(faqpr);
        !           519:
        !           520:     av = avma;
        !           521:     compute_fg(q, 1, &tabf, &tabg);
        !           522:
        !           523:     J = cgetg(lfaq,t_VEC);
        !           524:     J[1] = lgetg(1,t_STR); /* dummy */
        !           525:     for (j=2; j<lfaq; j++) /* skip p = faqpr[1] = 2 */
        !           526:     {
        !           527:       p = itos((GEN)faqpr[j]);
        !           528:       k = itos((GEN)faqex[j]);
        !           529:       J[j] = (long)get_jac(q,p,k,tabf,tabg);
        !           530:     }
        !           531:     tabj[i] = (long)gerepilecopy(av, J);
        !           532:   }
        !           533: }
        !           534:
        !           535: static void
        !           536: inittabs(int lv)
        !           537: {
        !           538:   int i;
        !           539:   tabaall = (GEN*)cgetg(lv,t_VEC);
        !           540:   tabtall = (GEN*)cgetg(lv,t_VEC);
        !           541:   tabcyc  = (GEN*)cgetg(lv,t_VEC);
        !           542:   for (i=1; i<lv; i++) tabcyc[i] = gzero;
        !           543:   tabE = cgetg(lv,t_VEC);
        !           544:   tabTH= cgetg(lv,t_VEC);
        !           545:   tabeta=cgetg(lv,t_VEC);
        !           546:   tabmatvite = (GEN*)cgetg(lv,t_VEC);
        !           547:   tabmatinvvite = (GEN*)cgetg(lv,t_VEC);
        !           548:   tabavite = cgetg(lv,t_VEC);
        !           549:   tabpkvite = cgetg(lv,t_VECSMALL);
        !           550:   for (i=1; i<lv; i++)
        !           551:   {
        !           552:     tabE[i] = tabTH[i] = tabeta[i] = tabavite[i] = zero;
        !           553:     tabmatvite[i] = tabmatinvvite[i] = gzero;
        !           554:   }
        !           555:   sgt  = cgetg(lv,t_VECSMALL);
        !           556:   ctsgt= cgetg(lv,t_VECSMALL);
        !           557:   for (i=1; i<lv; i++) tabpkvite[i] = sgt[i] = ctsgt[i] = 0;
        !           558: }
        !           559:
        !           560: static GEN
        !           561: finda(GEN N, int pk, int p)
        !           562: {
        !           563:   int ph,k;
        !           564:   ulong u;
        !           565:   GEN a,b,N1;
        !           566:
        !           567:   if (!isinstep5 && tabpkvite[p])
        !           568:     return gpowgs((GEN)tabavite[p],tabpkvite[p]/pk);
        !           569:   else
        !           570:   {
        !           571:     k = pvaluation(addis(N,-1),stoi(p),&N1);
        !           572:     ph = u_pow(p,k-1); tabpkvite[p] = p*ph;
        !           573:     u = 2;
        !           574:     if (p>2)
        !           575:     {
        !           576:       for(;;u++)
        !           577:       {
        !           578:        a = powgi(gmodulcp(stoi(u),N),N1);
        !           579:        b = gpowgs(a,ph);
        !           580:        if (!gcmp1(b)) break;
        !           581:       }
        !           582:     }
        !           583:     else
        !           584:     {
        !           585:       while(krosg(u,N)!=-1) u++;
        !           586:       a = powgi(gmodulcp(stoi(u),N),N1);
        !           587:       b = gpowgs(a,ph);
        !           588:     }
        !           589:     if (!isinstep5) tabavite[p] = (long)a;
        !           590: /* Checking b^p = 1 mod N is done economically in filltabs */
        !           591:     b = mppgcd(addis(lift(b),-1),N);
        !           592:     if (!gcmp1(b)) {errfill = b; return NULL;}
        !           593:     return gpowgs(a,(p*ph)/pk);
        !           594:   }
        !           595: }
        !           596:
        !           597: static void
        !           598: filltabs(GEN N, int p, int k, ulong ltab)
        !           599: {
        !           600:   const ulong mask = (1<<kglob)-1;
        !           601:   gpmem_t av;
        !           602:   int pk,pk2,i,j,LE=0;
        !           603:   ulong s,e;
        !           604:   GEN tabt,taba,m,E=gzero,p1,a=gzero,a2=gzero;
        !           605:
        !           606:   pk = u_pow(p,k);
        !           607:   ishack = isinstep5 && (pk >= lg((GEN)tabcyc) || !signe(tabcyc[pk]));
        !           608:   pk2 = pkfalse;
        !           609:   tabcyc[pk2] = cyclo(pk,0);
        !           610:
        !           611:   p1 = cgetg(pk+1,t_VEC);
        !           612:   for (i=1; i<=pk; i++)
        !           613:     p1[i] = (long)FpX_res(gpowgs(polx[0],i-1), tabcyc[pk2], N);
        !           614:   tabeta[pk2] = (long)p1;
        !           615:
        !           616:   if (p > 2)
        !           617:   {
        !           618:     LE = pk - pk/p + 1; E = cgetg(LE,t_VECSMALL);
        !           619:     for (i=1,j=0; i<pk; i++)
        !           620:       if (i%p) E[++j] = i;
        !           621:   }
        !           622:   else if (k >= 3)
        !           623:   {
        !           624:     LE = (pk>>2) + 1; E = cgetg(LE,t_VECSMALL);
        !           625:     for (i=1,j=0; i<pk; i++)
        !           626:       if ((i%8)==1 || (i%8)==3) E[++j] = i;
        !           627:   }
        !           628:   if (p>2 || k>=3)
        !           629:   {
        !           630:     tabE[pk2] = (long)E;
        !           631:     p1 = cgetg(LE,t_VEC);
        !           632:     for (i=1; i<LE; i++)
        !           633:     {
        !           634:       GEN p2 = cgetg(3,t_VECSMALL);
        !           635:       p2[1] = p2[2] = E[i];
        !           636:       p1[i] = (long)p2;
        !           637:     }
        !           638:     tabTH[pk2] = (long)p1;
        !           639:   }
        !           640:
        !           641:   if (pk > 2 && smodis(N,pk) == 1)
        !           642:   {
        !           643:     int ph,jj;
        !           644:     GEN vpa,p1,p2,p3;
        !           645:
        !           646:     if (DEBUGLEVEL&& !isinstep5) fprintferr("%ld ",pk);
        !           647:     a = finda(N,pk,p); if (!a) return;
        !           648:     ph = pk - pk/p;
        !           649:     vpa = cgetg(ph+1,t_COL); vpa[1] = (long)a;
        !           650:     if (k>1) a2 = gsqr(a);
        !           651:     jj = 1;
        !           652:     for (i=2; i<pk; i++) /* vpa[i] = a^i */
        !           653:       if (i%p) { jj++; vpa[jj] = lmul((i%p==1) ? a2 : a, (GEN)vpa[jj-1]); }
        !           654:     if (jj!=ph) err(bugparier,"filltabs1");
        !           655:     if (!gcmp1(gmul(a,(GEN)vpa[ph])))
        !           656:     {
        !           657:       if (signe(errfill)<=0) errfill = stoi(-1);
        !           658:       return;
        !           659:     }
        !           660:     p1 = cgetg(ph+1,t_MAT);
        !           661:     p2 = cgetg(ph+1,t_COL); p1[ph] = (long)p2;
        !           662:     for (i=1; i<=ph; i++) p2[i] = un;
        !           663:     p1[ph-1] = (long)vpa; p3 = vpa;
        !           664:     for (j=3; j<=ph; j++)
        !           665:     {
        !           666:       p2 = cgetg(ph+1,t_COL); p1[ph+1-j] = (long)p2;
        !           667:       for (i=1; i<=ph; i++) p2[i] = lmul((GEN)vpa[i],(GEN)p3[i]);
        !           668:       p3 = p2;
        !           669:     }
        !           670:     tabmatvite[pk2] = p1;
        !           671:     tabmatinvvite[pk2] = invmat(p1);
        !           672:   }
        !           673:
        !           674:   tabt = cgetg(ltab+1,t_VECSMALL);
        !           675:   taba = cgetg(ltab+1,t_VECSMALL);
        !           676:   av = avma;
        !           677:   m = divis(N,pk);
        !           678:   for (e=1; e<=ltab && signe(m); e++)
        !           679:   {
        !           680:     s = vali(m); m = shifti(m,-s);
        !           681:     tabt[e] = e==1? s: s+kglob;
        !           682:     taba[e] = signe(m)? ((modBIL(m) & mask)+1)>>1: 0;
        !           683:     m = shifti(m, -kglob);
        !           684:   }
        !           685:   avma = av;
        !           686:   if (e > ltab) err(bugparier,"filltabs");
        !           687:   setlg(taba, e); tabaall[pk2] = taba;
        !           688:   setlg(tabt, e); tabtall[pk2] = tabt;
        !           689: }
        !           690:
        !           691:
        !           692: static GEN
        !           693: calcglobs(GEN N, ulong t)
        !           694: {
        !           695:   GEN fat,fapr,faex;
        !           696:   int lfa,pk,p,ex,i,k;
        !           697:   ulong ltab, ltaball;
        !           698:
        !           699:   NBITSN = bit_accuracy(lgefint(N)) - 1;
        !           700:   while (bittest(N,NBITSN)==0) NBITSN--;
        !           701:   NBITSN++;
        !           702:   kglob=3; while (((kglob+1)*(kglob+2) << (kglob-1)) < NBITSN) kglob++;
        !           703:   ltab = (NBITSN/kglob) + 2;
        !           704:
        !           705:   fat = decomp(stoi(t));
        !           706:   fapr = (GEN)fat[1];
        !           707:   faex = (GEN)fat[2];
        !           708:   lfa = lg(fapr); ltaball = 1;
        !           709:   for (i=1; i<lfa; i++)
        !           710:   {
        !           711:     pk = u_pow(itos((GEN)fapr[i]), itos((GEN)faex[i]));
        !           712:     if (pk > ltaball) ltaball = pk;
        !           713:   }
        !           714:   inittabs(ltaball+1);
        !           715:   if (DEBUGLEVEL) fprintferr("Fast pk-values: ");
        !           716:   for (i=1; i<lfa; i++)
        !           717:   {
        !           718:     p = itos((GEN)fapr[i]);
        !           719:     ex= itos((GEN)faex[i]);
        !           720:     for (k=1; k<=ex; k++)
        !           721:     {
        !           722:       filltabs(N,p,k,ltab);
        !           723:       if (signe(errfill)) break;
        !           724:     }
        !           725:   }
        !           726:   if (DEBUGLEVEL) fprintferr("\n");
        !           727:   return fapr;
        !           728: }
        !           729:
        !           730: /* Calculer sig_a^{-1}(z) pour z dans Q(ze) et sig_a: ze -> ze^a */
        !           731: static GEN
        !           732: aut(int pk, GEN z,int a)
        !           733: {
        !           734:   GEN v = cgetg(pk+1,t_VEC);
        !           735:   int i;
        !           736:   for (i=1; i<=pk; i++)
        !           737:     v[i] = (long)polcoeff0(z, (a*(i-1))%pk, 0);
        !           738:   return gmodulcp(gtopolyrev(v,0), tabcyc[pkfalse]);
        !           739: }
        !           740:
        !           741: /* calculer z^v pour v dans Z[G] represente par des couples [sig_x^{-1},y] */
        !           742: static GEN
        !           743: autvec(int pk, GEN z, GEN v)
        !           744: {
        !           745:   int i,lv = lg(v);
        !           746:   GEN s = gun;
        !           747:   for (i=1; i<lv; i++)
        !           748:     if (((GEN)v[i])[2])
        !           749:       s = gmul(s, gpowgs(aut(pk,z,((GEN)v[i])[1]), ((GEN)v[i])[2]));
        !           750:   return s;
        !           751: }
        !           752:
        !           753: static GEN
        !           754: get_AL(GEN N, int pk)
        !           755: {
        !           756:   const int r = smodis(N, pk);
        !           757:   GEN AL, E = (GEN)tabE[pkfalse];
        !           758:   int i, LE = lg(E);
        !           759:
        !           760:   AL = cgetg(LE,t_VEC);
        !           761:   for (i=1; i<LE; i++)
        !           762:   {
        !           763:     GEN p1 = cgetg(3,t_VECSMALL); AL[i] = (long)p1;
        !           764:     p1[1] = E[i];
        !           765:     p1[2] = (r*E[i]) / pk;
        !           766:   }
        !           767:   return AL;
        !           768: }
        !           769:
        !           770: static int
        !           771: look_eta(int pk, GEN s)
        !           772: {
        !           773:   GEN etats = (GEN)tabeta[pkfalse];
        !           774:   long i;
        !           775:   for (i=1; i<=pk; i++)
        !           776:     if (gegal(s, (GEN)etats[i])) return i-1;
        !           777:   return pk;
        !           778: }
        !           779:
        !           780: static int
        !           781: step4a(GEN N, ulong q, int p, int k, GEN jpq)
        !           782: {
        !           783:   int pk,pk2,ind;
        !           784:   GEN AL,s1,s2,s3;
        !           785:   red_t R;
        !           786:
        !           787:   pk = u_pow(p,k); pk2=pkfalse;
        !           788:   if (dotime) (void)timer2();
        !           789:   if (!jpq)
        !           790:   {
        !           791:     GEN tabf, tabg;
        !           792:
        !           793:     compute_fg(q,1, &tabf,&tabg);
        !           794:     jpq = get_jac(q,p,k,tabf,tabg);
        !           795:     if (dotime) sgtjac+=timer2();
        !           796:   }
        !           797:   R.N = N;
        !           798:   R.C = tabcyc[pk2];
        !           799:   AL = get_AL(N, pk);
        !           800:
        !           801:   s1 = autvec(pk,jpq,(GEN)tabTH[pk2]);
        !           802:   if (dotime) sgtaut+=timer2();
        !           803:   s2 = powpolmod(&R,k,pk,s1);
        !           804:   if (dotime) {sgt[pk2]+=timer2();ctsgt[pk2]++;};
        !           805:   s3 = autvec(pk,jpq,AL);
        !           806:   if (dotime) sgtaut+=timer2();
        !           807:   s3 = _red(gmul(lift(s3),s2), &R);
        !           808:   if (dotime) sgt[pk2]+=timer2();
        !           809:
        !           810:   ind = look_eta(pk, s3);
        !           811:   if (ind == pk) return -1;
        !           812:   return (ind%p) != 0;
        !           813: }
        !           814:
        !           815: /* x == -1 mod N ? */
        !           816: static int
        !           817: is_m1(GEN x, GEN N)
        !           818: {
        !           819:   return egalii(addis(x,1), N);
        !           820: }
        !           821:
        !           822: /* p=2, k>=3 */
        !           823: static int
        !           824: step4b(GEN N, ulong q, int k)
        !           825: {
        !           826:   const int pk = u_pow(2,k);
        !           827:   int ind,pk2;
        !           828:   GEN AL,s1,s2,s3, j2q,j3q;
        !           829:   red_t R;
        !           830:
        !           831:   if (dotime) (void)timer2();
        !           832:   (void)get_jac2(N,q,k, &j2q,&j3q);
        !           833:   if (dotime) sgtjac+=timer2();
        !           834:
        !           835:   pk2 = pkfalse;
        !           836:   R.N = N;
        !           837:   R.C = tabcyc[pk2];
        !           838:   AL = get_AL(N, pk);
        !           839:
        !           840:   s1 = autvec(pk,j3q,(GEN)tabTH[pk2]);
        !           841:   if (dotime) sgtaut+=timer2();
        !           842:   s2 = powpolmod(&R, k,pk,s1);
        !           843:   if (dotime) {sgt[pk2]+=timer2();ctsgt[pk2]++;}
        !           844:   s3 = autvec(pk,j3q,AL);
        !           845:   if (dotime) sgtaut+=timer2();
        !           846:   s3 = _red(gmul(lift(s3),s2), &R);
        !           847:   if (mod8(N) >= 5) s3 = _red(gmul(j2q, s3), &R);
        !           848:   if (dotime) sgt[pk2]+=timer2();
        !           849:
        !           850:   ind = look_eta(pk, s3);
        !           851:   if (ind == pk) return -1;
        !           852:   if ((ind&1)==0) return 0;
        !           853:   else
        !           854:   {
        !           855:     s3 = powmodulo(stoi(q), shifti(N,-1), N);
        !           856:     if (dotime) {sgt[pk2]+=timer2();ctsgt[pk2]++;}
        !           857:     return is_m1(s3, N);
        !           858:   }
        !           859: }
        !           860:
        !           861: /* p=2, k=2 */
        !           862: static int
        !           863: step4c(GEN N, ulong q)
        !           864: {
        !           865:   const int pk = 4;
        !           866:   int ind,pk2;
        !           867:   GEN s0,s1,s3, jpq = get_jac2(N,q,2, NULL,NULL);
        !           868:   red_t R;
        !           869:
        !           870:   pk2 = pkfalse;
        !           871:   R.N = N;
        !           872:   R.C = tabcyc[pk2];
        !           873:
        !           874:   if (dotime) (void)timer2();
        !           875:   s0 = sqrmod4(jpq, &R);
        !           876:   s1 = gmulsg(q,s0);
        !           877:   s3 = powpolmod(&R, 2,pk,s1);
        !           878:   if (mod4(N) == 3) s3 = _red(gmul(s0,s3), &R);
        !           879:   if (dotime) {sgt[pk2]+=timer2();ctsgt[pk2]++;}
        !           880:
        !           881:   ind = look_eta(pk, s3);
        !           882:   if (ind == pk) return -1;
        !           883:   if ((ind&1)==0) return 0;
        !           884:   else
        !           885:   {
        !           886:     s3 = powmodulo(stoi(q), shifti(N,-1), N);
        !           887:     if (dotime) sgt[pk2]+=timer2();
        !           888:     return is_m1(s3,N);
        !           889:   }
        !           890: }
        !           891:
        !           892: /* p=2, k=1 */
        !           893: static int
        !           894: step4d(GEN N, ulong q)
        !           895: {
        !           896:   GEN s1;
        !           897:
        !           898:   if (dotime) (void)timer2();
        !           899:   s1 = powmodulo(negi(stoi(q)), shifti(N,-1), N);
        !           900:   if (dotime) {sgt[2]+=timer2();ctsgt[2]++;}
        !           901:   if (gcmp1(s1)) return 0;
        !           902:   if (is_m1(s1,N)) return (mod4(N) == 1);
        !           903:   return -1;
        !           904: }
        !           905:
        !           906: /* return 1 [OK so far],0 [APRCL fails] or < 0 [not a prime] */
        !           907: static int
        !           908: step5(GEN N, int p, GEN et)
        !           909: {
        !           910:   ulong ct = 0, q;
        !           911:   gpmem_t av;
        !           912:   int k, fl = -1;
        !           913:   byteptr d = diffptr+2;
        !           914:   const ulong ltab = (NBITSN/kglob)+2;
        !           915:
        !           916:   av = avma;
        !           917:   for (q = 3; *d; )
        !           918:   {
        !           919:     if (q%p != 1 || smodis(et,q) == 0) goto repeat;
        !           920:
        !           921:     if (smodis(N,q) == 0) return -1;
        !           922:     k = u_val(q-1, p);
        !           923:     filltabs(N,p,k,ltab);
        !           924:
        !           925:     if (p>=3)        fl = step4a(N,q,p,k, NULL);
        !           926:     else if (k >= 3) fl = step4b(N,q,k);
        !           927:     else if (k == 2) fl = step4c(N,q);
        !           928:     else             fl = step4d(N,q);
        !           929:     if (ishack) tabmatvite[1] = gzero;
        !           930:     if (fl == -1) return (int)(-q);
        !           931:     if (fl == 1) {ctglob = max(ctglob,ct); return 1;}
        !           932:     ct++;
        !           933:     avma = av;
        !           934:    repeat:
        !           935:     NEXT_PRIME_VIADIFF(q,d);
        !           936:   }
        !           937:   return 0;
        !           938: }
        !           939:
        !           940: static GEN
        !           941: step6(GEN N, ulong t, GEN et)
        !           942: {
        !           943:   GEN N1,r,p1;
        !           944:   ulong i;
        !           945:   gpmem_t av;
        !           946:
        !           947:   if (dotime) (void)timer2();
        !           948:   N1 = resii(N, et);
        !           949:   r = gun; av = avma;
        !           950:   for (i=1; i<t; i++)
        !           951:   {
        !           952:     r = resii(mulii(r,N1), et);
        !           953:     if (!signe(resii(N,r)) && !gcmp1(r) && !egalii(r,N))
        !           954:     {
        !           955:       p1 = cgetg(3,t_VEC);
        !           956:       p1[1] = (long)r;
        !           957:       p1[2] = zero; return p1;
        !           958:     }
        !           959:     if ((i & 0x1f) == 0) r = gerepileuptoint(av, r);
        !           960:   }
        !           961:   if (dotime) sgt6 = timer2();
        !           962:   return gun;
        !           963: }
        !           964:
        !           965: static GEN
        !           966: _res(long a, long b)
        !           967: {
        !           968:   GEN z;
        !           969:   if (b) { z=cgetg(3, t_VEC); z[1]=lstoi(a); z[2]=lstoi(b); }
        !           970:   else   { z=cgetg(2, t_VEC); z[1]=lstoi(a); }
        !           971:   return z;
        !           972: }
        !           973:
        !           974: void
        !           975: seetimes()
        !           976: {
        !           977:   int i;
        !           978:   ulong s,sc;
        !           979:
        !           980:   s = sc = 0; for (i=1; i<lg(sgt); i++) {s+=sgt[i]; sc+=ctsgt[i];}
        !           981:   printf("Timings in ms:\nJacobi sums = %lu, Galois Automorphisms = %lu\n",sgtjac,sgtaut);
        !           982:   printf("Global Fermat powerings = %lu\n",s);
        !           983:   printf("Number of Fermat powerings = %lu\n",sc);
        !           984:   printf("Individual Fermat powerings = "); output(gtovec(sgt));
        !           985:   printf("Number of individual Fermat powerings = "); output(gtovec(ctsgt));
        !           986:   printf("Final trial divisions = %lu\n",sgt6);
        !           987:   printf("Maximal number of nondeterministic steps = %lu\n",ctglob);
        !           988: }
        !           989:
        !           990: GEN
        !           991: aprcl(GEN N)
        !           992: {
        !           993:   GEN et,fat,flaglp,faq,faqpr,faqex,res;
        !           994:   long fl;
        !           995:   ulong lfat,p,q,lfaq,k,t,i,j,l;
        !           996:   gpmem_t av,av2,avinit = avma;
        !           997:
        !           998:   if (cmpis(N,12) <= 0)
        !           999:     switch(itos(N))
        !          1000:     {
        !          1001:       case 2: case 3: case 5: case 7: case 11: return gun;
        !          1002:       default: return _res(0,0);
        !          1003:     }
        !          1004:   ctglob = 0;
        !          1005:   if (dotime) (void)timer2();
        !          1006:   t = compt(N);
        !          1007:   if (DEBUGLEVEL) fprintferr("Choosing t = %ld\n",t);
        !          1008:   et = e(t);
        !          1009:   if (cmpii(sqri(et),N) < 0) err(bugparier,"aprcl: e(t) too small");
        !          1010:   if (!gcmp1(mppgcd(N,mulsi(t,et)))) return _res(1,0);
        !          1011:
        !          1012:   isinstep5 = 0;
        !          1013:   errfill = gzero;
        !          1014:   fat = calcglobs(N,t); lfat = lg(fat);
        !          1015:   if (signe(errfill))
        !          1016:   {
        !          1017:     GEN z;
        !          1018:
        !          1019:     avma = avinit;
        !          1020:     if (signe(errfill)<0) return _res(1,0);
        !          1021:     else {z=cgetg(3,t_VEC); z[1]=(long)errfill; z[2]=zero; return z;}
        !          1022:   }
        !          1023:   p = itos((GEN)fat[lfat-1]); /* largest p | t */
        !          1024:   flaglp = cgetg(p+1, t_VECSMALL);
        !          1025:   flaglp[2] = 0;
        !          1026:   for (i=2; i<lfat; i++)
        !          1027:   {
        !          1028:     p = itos((GEN)fat[i]); q = p*p;
        !          1029:     flaglp[p] = (powuumod(smodis(N,q),p-1,q) != 1);
        !          1030:   }
        !          1031:   calcjac(et);
        !          1032:   if (dotime)
        !          1033:   {
        !          1034:     sgtjac = timer2();
        !          1035:     fprintferr("Jacobi sums and tables computed\nq-values: ");
        !          1036:   }
        !          1037:   sgtaut = 0;
        !          1038:   av = avma; l = lg(globfa);
        !          1039:   for (i=1; i<l; i++)
        !          1040:   {
        !          1041:     avma = av;
        !          1042:     q = itos((GEN)globfa[i]);
        !          1043:     if (dotime) fprintferr("%ld ",q);
        !          1044:     faq = (GEN)tabfaq[i];
        !          1045:     faqpr = (GEN)faq[1];
        !          1046:     faqex = (GEN)faq[2]; lfaq = lg(faqpr);
        !          1047:     av2 = avma;
        !          1048:     for (j=1; j<lfaq; j++)
        !          1049:     {
        !          1050:       avma = av2;
        !          1051:       p = itos((GEN)faqpr[j]);
        !          1052:       k = itos((GEN)faqex[j]);
        !          1053:       if (p >= 3)      fl = step4a(N,q,p,k, gmael(tabj,i,j));
        !          1054:       else if (k >= 3) fl = step4b(N,q,k);
        !          1055:       else if (k == 2) fl = step4c(N,q);
        !          1056:       else             fl = step4d(N,q);
        !          1057:       if (fl == -1) return _res(q,p);
        !          1058:       if (fl == 1) flaglp[p] = 1;
        !          1059:     }
        !          1060:   }
        !          1061:   if (dotime) fprintferr("\nNormal test done; testing conditions lp\n");
        !          1062:   isinstep5 = 1;
        !          1063:   for (i=1; i<lfat; i++)
        !          1064:   {
        !          1065:     p = itos((GEN)fat[i]);
        !          1066:     if (flaglp[p] == 0)
        !          1067:     {
        !          1068:       errfill = gzero;
        !          1069:       fl = step5(N,p,et);
        !          1070:       if (signe(errfill))
        !          1071:       {
        !          1072:        GEN z;
        !          1073:
        !          1074:        avma = avinit;
        !          1075:        if (signe(errfill)<0) return _res(1,0);
        !          1076:        else {z=cgetg(3,t_VEC); z[1]=(long)errfill; z[2]=zero; return z;}
        !          1077:       }
        !          1078:       if (fl < 0) return _res(fl,p);
        !          1079:       if (fl==0) err(talker,"aprcl test fails! this is highly improbable");
        !          1080:     }
        !          1081:   }
        !          1082:   if (dotime) fprintferr("Conditions lp done, doing step6\n");
        !          1083:   res = step6(N,t,et);
        !          1084:   if (dotime && (typ(res) == t_INT)) seetimes();
        !          1085:   return res;
        !          1086: }
        !          1087:
        !          1088: long
        !          1089: isprimeAPRCL(GEN N)
        !          1090: {
        !          1091:   gpmem_t av = avma;
        !          1092:   GEN res = aprcl(N);
        !          1093:   avma = av; return (typ(res) == t_INT);
        !          1094: }

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