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

Annotation of OpenXM_contrib/pari-2.2/src/modules/mpqs.c, Revision 1.2

1.2     ! noro        1: /* $Id: mpqs.c,v 1.17 2002/07/15 13:26:21 karim Exp $
1.1       noro        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: /* Written by Thomas Papanikolaou and Xavier Roblot
                     17:  *
                     18:  * Implementation of the Self-Initializing Multi-Polynomial Quadratic Sieve
                     19:  * based on code developed as part of the LiDIA project
                     20:  * (http://www.informatik.tu-darmstadt.de/TI/LiDIA/Welcome.html)
                     21:  */
                     22: #include "pari.h"
                     23:
                     24: #ifndef SEEK_SET
                     25: #  define SEEK_SET 0
                     26: #endif
                     27:
                     28: #ifdef __CYGWIN32__
                     29: /* otherwise fseek() goes crazy due to silent \n <--> LF translations */
                     30: #  define WRITE "wb"
                     31: #  define READ "rb"
                     32: #else
                     33: #  define WRITE "w"
                     34: #  define READ "r"
                     35: #endif
                     36:
                     37: #ifdef MPQS_DEBUG_VERYVERBOSE
                     38: #  ifndef MPQS_DEBUG_VERBOSE
                     39: #  define MPQS_DEBUG_VERBOSE
                     40: #  endif
                     41: #endif
                     42:
                     43: #ifdef MPQS_DEBUG_VERBOSE
                     44: #  ifndef MPQS_DEBUG
                     45: #  define MPQS_DEBUG
                     46: #  endif
                     47: #endif
                     48:
                     49: #define MPQS_STRING_LENGTH         (4 * 1024)
                     50: #define MPQS_CANDIDATE_ARRAY_SIZE  2000
                     51: #define MPQS_PRIMES_FOR_MULTIPLIER 5
                     52: /* `large primes' must be smaller than
                     53:  *   max(MPQS_LP_BOUND, largest_prime_in_FB) * MPQS_LP_FACTOR
                     54:  */
                     55: #define MPQS_LP_BOUND              125000 /* works for 32 and 64bit */
                     56: #define MPQS_LP_FACTOR             80
                     57:
                     58: typedef ulong *mpqs_gauss_row;
                     59: typedef long *mpqs_gauss_indices;
                     60: typedef mpqs_gauss_row *mpqs_gauss_matrix;
                     61:
                     62: /* BEGIN: global variables to disappear as soon as possible */
                     63: /* names for temp. files, set in mpqs_get_filename */
                     64: static char *FREL_str;
                     65: static char *FNEW_str;
                     66: static char *LPREL_str;
                     67: static char *LPNEW_str;
                     68: static char *TMP_str;
                     69: static char *COMB_str;
                     70:
                     71: /* our own pointer to PARI's or to our own prime diffs table.
                     72:  * NB the latter is never freed, unless we need to replace it with
                     73:  * an even larger one. */
                     74: static byteptr mpqs_diffptr = NULL;
                     75: static long mpqs_prime_count = 0;
                     76:
                     77: /* END: global variables to disappear as soon as possible */
                     78:
                     79: /******************************/
                     80:
                     81: /**
                     82:  ** determines a unique name for a file based on a short nickname
                     83:  **/
                     84:
                     85: /* name is allocated on the stack */
                     86: static char *
                     87: mpqs_get_filename(char *s)
                     88: {
                     89:   char *buf;
                     90:
                     91:   s = pari_unique_filename(s);
                     92:   buf = (char*) new_chunk((strlen(s) / sizeof(long)) + 2);
                     93:   return strcpy(buf, s);
                     94: }
                     95:
                     96: /**
                     97:  ** compares two `large prime' relations according to their
                     98:  ** first element (the large prime itself).
                     99:  **/
                    100:
                    101: static int
                    102: mpqs_relations_cmp(const void *a, const void *b)
                    103: {
                    104:   char **sa = (char **) a;
                    105:   char **sb = (char **) b;
                    106:   long qa = strtol(*sa, NULL, 10);
                    107:   long qb = strtol(*sb, NULL, 10);
                    108:   /* atol() isn't entirely portable for the Full Relations case where the
                    109:      strings of digits are too long to fit into a long --GN */
                    110:   if (qa < qb) return -1;
                    111:   else if (qa > qb) return 1;
                    112:   else return strcmp(*sa, *sb);
                    113: }
                    114:
                    115: /**
                    116:  ** Given a file "filename" containing full or `large prime' relations,
                    117:  ** this function rearranges the file so that relations are sorted by
                    118:  ** their first elements. Works also for sorting full relations.
                    119:  ** Works in memory, discards duplicate lines, and overwrites the
                    120:  ** original file.
                    121:  **/
                    122:
                    123: #define bummer(fn) err(talker, "error whilst writing to file %s", fn)
                    124: #define min_bufspace 120       /* use new buffer when < min_bufspace left */
                    125: #define buflist_size 1024      /* size of list-of-buffers blocks */
                    126:
                    127: static long
                    128: mpqs_sort_lp_file(char *filename)
                    129: {
                    130:   pariFILE *pTMP;
                    131:   FILE *TMP;
                    132:   char *old_s, **sort_table = (char**)avma, *buf, *cur_line;
                    133:   static char **buflist_head = NULL;
                    134:   char **buflist, **next_buflist;
1.2     ! noro      135:   long i, j, bufspace, length, count;
        !           136:   gpmem_t av=avma;
1.1       noro      137:
                    138:   if (!buflist_head)
                    139:   {
                    140:     buflist_head = (char **) gpmalloc(buflist_size * sizeof(char *));
                    141:     buflist = buflist_head;
                    142:     *buflist++ = NULL;         /* flag this as last and only buflist block */
                    143:   }
                    144:   else
                    145:     buflist = buflist_head + 1;
                    146:   /* this block will never be freed, and extra blocks may be allocated as
                    147:      needed and linked ahead of it.  NB it turns out that whilst extra
                    148:      buflist blocks might have been needed when we were still sorting
                    149:      entire FREL files  (more than 1023 buffers, corresponding to about
                    150:      20000 lines of c.200 characters),  they should never be touched now
                    151:      that we only sort LPNEW and FNEW files, which are rather shorter.
                    152:      But the code might as well stay around for paranoia, or for future
                    153:      upgrades to handling even larger numbers (and factor bases and thus
                    154:      relations files).  It only costs one comparison per buffer allocation.
                    155:      --GN */
                    156:
                    157:   pTMP = pari_fopen(filename, READ);
                    158:   TMP = pTMP->file;
                    159:   /* get first buffer and read first line, if any, into it */
                    160:   buf = (char *) gpmalloc(MPQS_STRING_LENGTH * sizeof(char));
                    161:   cur_line = buf;
                    162:   bufspace = MPQS_STRING_LENGTH;
                    163:
                    164:   if (fgets(cur_line, bufspace, TMP) == NULL)
                    165:   {                            /* file empty */
                    166:     avma = av;
                    167:     free(buf);
                    168:     pari_fclose(pTMP);
                    169:     return 0;
                    170:   }
                    171:   /* enter first buffer into buflist */
                    172:   *buflist++ = buf;            /* can't overflow the buflist block */
                    173:   length = strlen(cur_line) + 1; /* count the \0 byte as well */
                    174:   bufspace -= length;
                    175:
                    176:   /* at start of loop, one line from the file is sitting in cur_line inside
                    177:      buf, the next will go into cur_line + length, and there's room for
                    178:      bufspace further characters in buf.
                    179:      The loop reads another line if one exists, and if this overruns the
                    180:      current buffer, it allocates a fresh one --GN */
                    181:
                    182:   for (i=0, sort_table--; /* until end of file */; i++, sort_table--)
                    183:   {
                    184:     /* sort_table is allocated on the stack, 0x100 cells at a time. Hence the
                    185:      * stack must be left alone in the rest of the loop to keep the array
                    186:      * connected. In particular, buffers can't be new_chunk'ed --KB */
1.2     ! noro      187:     if ((i & 0xff) == 0) (void)new_chunk(0x100);
1.1       noro      188:     *sort_table = cur_line;
                    189:     cur_line += length;
                    190:
                    191:     /* if very little room is left, allocate a fresh buffer before
                    192:        attempting to read a line, and remember to free it if no
                    193:        further line is forthcoming.  This avoids some copying of
                    194:        partial lines --GN */
                    195:     if (bufspace < min_bufspace)
                    196:     {
                    197:       if (
                    198: #ifdef MPQS_DEBUG
                    199:          1 ||
                    200: #endif
                    201:          DEBUGLEVEL >= 7)
                    202:        fprintferr("MQPS: short of space -- another buffer for sorting\n");
                    203:       buf = (char *) gpmalloc(MPQS_STRING_LENGTH * sizeof(char));
                    204:       cur_line = buf;
                    205:       bufspace = MPQS_STRING_LENGTH;
                    206:       if (fgets(cur_line, bufspace, TMP) == NULL)
                    207:       {
                    208:        free(buf); break;
                    209:       }
                    210:       else
                    211:       {
                    212:        /* remember buffer for later deallocation */
                    213:        if (buflist - buflist_head >= buflist_size)
                    214:        {
                    215:          /* need another buflist block */
                    216:          next_buflist =
                    217:            (char **) gpmalloc(buflist_size * sizeof(char *));
                    218:          *next_buflist = (char *)buflist_head; /* link */
                    219:          buflist_head = next_buflist;
                    220:          buflist = buflist_head + 1;
                    221:        }
                    222:        *buflist++ = buf;
                    223:        length = strlen(cur_line) + 1;
                    224:        bufspace -= length;
                    225:        continue;
                    226:       }
                    227:     }
                    228:
                    229:     /* normal case:  try fitting another line into the current buffer,
                    230:        break if none exists */
                    231:     if (fgets(cur_line, bufspace, TMP) == NULL) break;
                    232:     length = strlen(cur_line) + 1;
                    233:     bufspace -= length;
                    234:
                    235:     /* check whether we got the entire line or only part of it */
                    236:     if (bufspace == 0 && cur_line[length-2] != '\n')
                    237:     {
                    238:       long lg1;
                    239:       if (
                    240: #ifdef MPQS_DEBUG
                    241:          1 ||
                    242: #endif
                    243:          DEBUGLEVEL >= 7)
                    244:        fprintferr("MQPS: line wrap -- another buffer for sorting\n");
                    245:       buf = (char *) gpmalloc(MPQS_STRING_LENGTH * sizeof(char));
                    246:       /* remember buffer for later deallocation */
                    247:       if (buflist - buflist_head >= buflist_size)
                    248:       {
                    249:        /* need another buflist block */
                    250:        next_buflist =
                    251:          (char **) gpmalloc(buflist_size * sizeof(char *));
                    252:        *next_buflist = (char *)buflist_head; /* link */
                    253:        buflist_head = next_buflist;
                    254:        buflist = buflist_head + 1;
                    255:       }
                    256:       *buflist++ = buf;
                    257:
                    258:       /* copy what we've got to the new buffer */
                    259:       (void)strcpy(buf, cur_line); /* cannot overflow */
                    260:       cur_line = buf + length - 1; /* point at the \0 byte */
                    261:       bufspace = MPQS_STRING_LENGTH - length + 1;
                    262:       /* read remainder of line */
                    263:       if (fgets(cur_line, bufspace, TMP) == NULL)
                    264:        err(talker,"MPQS: relations file truncated?!\n");
                    265:       lg1 = strlen(cur_line);
                    266:       length += lg1;           /* we already counted the \0 once */
                    267:       bufspace -= (lg1 + 1);   /* but here we must take it into account */
                    268:       cur_line = buf;          /* back up to the beginning of the line */
                    269:     }
                    270:   } /* for */
                    271:
                    272:   pari_fclose(pTMP);
                    273:
                    274: #if 0                          /* caught above, can no longer happen */
                    275:   if (i == 0)
                    276:   {
                    277:     avma = av; return 0;
                    278:   }
                    279: #endif
                    280:
                    281:   /* sort the whole lot in place by swapping pointers */
                    282:   qsort(sort_table, i, sizeof(char *), mpqs_relations_cmp);
                    283:
                    284:   /* copy results back to the original file, skipping exact duplicates */
                    285:   pTMP = pari_fopen(filename, WRITE); /* NOT safefopen */
                    286:   TMP = pTMP->file;
                    287:   old_s = sort_table[0];
                    288:   if (fputs(sort_table[0], TMP) < 0)
                    289:     bummer(filename);
                    290:   count = 1;
                    291:   for(j = 1; j < i; j++)
                    292:   {
                    293:     if (strcmp(old_s, sort_table[j]) != 0)
                    294:     {
                    295:       if (fputs(sort_table[j], TMP) < 0)
                    296:        bummer(filename);
                    297:       count++;
                    298:     }
                    299:     old_s = sort_table[j];
                    300:   }
                    301:   pari_fclose(pTMP);
                    302:   if (
                    303: #ifdef MPQS_DEBUG
                    304:       1 ||
                    305: #endif
                    306:       DEBUGLEVEL >= 6)
                    307:     fprintferr("MPQS: done sorting one file.\n");
                    308:
                    309:   /* deallocate buffers and any extraneous buflist blocks except the first */
                    310:   while (*--buflist)
                    311:   {
                    312:     if (buflist != buflist_head) /* not a linkage pointer */
                    313:       free((void *) *buflist); /* free a buffer */
                    314:     else                       /* linkage pointer */
                    315:     {
                    316:       next_buflist = (char **)(*buflist);
                    317:       free((void *)buflist_head); /* free a buflist block */
                    318:       buflist_head = next_buflist;
                    319:       buflist = buflist_head + buflist_size;
                    320:     }
                    321:   }
                    322: #if 0
                    323:   for (j = 0; j < i; j++)
                    324:   {
                    325:     buf = (char *)(sort_table[j]) - 1;
                    326:     if (*buf)                  /* check: deallocation flag or \0 ? */
                    327:       free(buf);
                    328:   }
                    329: #endif
                    330:   avma = av; return count;
                    331: }
                    332:
                    333: /**
                    334:  ** appends contents of file fp1 to file fp of name filename
                    335:  ** (auxiliary routine for merge sort) and returns number of
                    336:  ** lines copied.
                    337:  ** fp assumed open for appending and fp1 for reading;  fp will
                    338:  ** be closed afterwards.
                    339:  **/
                    340:
                    341: static long
                    342: mpqs_append_file(pariFILE *f, FILE *fp1)
                    343: {
                    344:   FILE *fp = f->file;
                    345:   char line[MPQS_STRING_LENGTH];
                    346:   long c = 0;
                    347:   while (fgets(line, MPQS_STRING_LENGTH, fp1) != NULL)
                    348:   {
                    349:     if (fputs(line, fp) < 0)
                    350:       err(talker, "error whilst appending to file %s", f->name);
                    351:     c++;
                    352:   }
                    353:   if (fflush(fp))
                    354:     err(warner, "error whilst flushing file %s", f->name);
                    355:   pari_fclose(f);
                    356:   return c;
                    357: }
                    358:
                    359: /**
                    360:  ** Does a merge-sort on the files LPREL and LPNEW;
                    361:  ** assumes that LPREL and LPNEW are already sorted.
                    362:  ** Creates/truncates the TMP file, writes result to it and closes it
                    363:  ** (via a call to mpqs_append_file()).
                    364:  ** Instead of LPREL, LPNEW we may also call this with FREL, FNEW.
                    365:  ** In the latter case mode should be 1 (and we return the count of
                    366:  ** all full relations), in the former 0 (and we return the count
                    367:  ** of frels we expect to be able to combine out of the present lprels).
                    368:  ** Moreover, if mode is 0, the combinable lprels are written out to a
                    369:  ** separate file (COMB) which we also create and close (the caller
                    370:  ** will find it exists iff our return value is nonzero), and we keep
                    371:  ** only one occurrence of each `large prime' in TMP (i.e. in the future
                    372:  ** LPREL file). --GN
                    373:  **/
                    374:
                    375: #define swap_lines { \
                    376:                       line_tmp = line_new_old; \
                    377:                       line_new_old = line_new; \
                    378:                       line_new = line_tmp; \
                    379:                   }
                    380:
                    381: static long
                    382: mpqs_mergesort_lp_file0(FILE *LPREL, FILE *LPNEW, long mode)
                    383: {
                    384:   /* TMP (renamed upon return) and COMB (deleted upon return) guaranteed not
                    385:    * to exist yet  --> safefopen for both temp files */
                    386:   pariFILE *pTMP = pari_safefopen(TMP_str, WRITE);
                    387:   FILE *TMP = pTMP->file;
                    388:   pariFILE *pCOMB = NULL;
                    389:   FILE *COMB = NULL; /* gcc -Wall */
                    390:   char line1[MPQS_STRING_LENGTH], line2[MPQS_STRING_LENGTH];
                    391:   char line[MPQS_STRING_LENGTH];
                    392:   char *line_new = line1, *line_new_old = line2, *line_tmp;
                    393:   long q_new, q_new_old = -1, q, i = 0, c = 0;
                    394:   long comb_in_progress;
                    395:
                    396:   /* if LPNEW is empty, copy LPREL to TMP.  Could be done by a rename
                    397:      if we didn't want to count the lines (again)... however, this
                    398:      case will not normally happen */
                    399:
                    400:   if (fgets(line_new, MPQS_STRING_LENGTH, LPNEW) == NULL)
                    401:   {
                    402:     i = mpqs_append_file(pTMP, LPREL);
                    403:     return (mode ? i : 0);
                    404:   }
                    405:   /* we now have a line_new from LPNEW */
                    406:
                    407:   /* if LPREL is empty, copy LPNEW to TMP... almost. */
                    408:
                    409:   if (fgets(line, MPQS_STRING_LENGTH, LPREL) == NULL)
                    410:   {
                    411:     if (fputs(line_new, TMP) < 0)
                    412:       bummer(TMP_str);
                    413:     if (mode)                  /* full relations mode */
                    414:     {
                    415:       i = mpqs_append_file(pTMP, LPNEW);
                    416:       return i + 1;            /* COMB cannot be open here */
                    417:     }
                    418:
                    419:     /* LP mode:  check for combinable relations */
                    420:     q_new_old = atol(line_new);
                    421:     /* we need to retain a copy of the old line just for a moment, because
                    422:        we may yet have to write it to COMB, too.  Do this simply by swapping
                    423:        the two buffers */
                    424:     swap_lines;
                    425:     comb_in_progress = 0;
                    426:     i = 0;
                    427:
                    428:     while (fgets(line_new, MPQS_STRING_LENGTH, LPNEW) != NULL)
                    429:     {
                    430:       q_new = atol(line_new);
                    431:       if (q_new_old == q_new)
                    432:       {
                    433:        /* found combinables, check whether we're already busy on this
                    434:           particular `large prime' */
                    435:        if (!comb_in_progress)
                    436:        {
                    437:          /* if not, write first line to COMB, creating and opening the
                    438:             file first if it isn't open yet */
                    439:          if (!pCOMB)
                    440:          {
                    441:            pCOMB = pari_safefopen(COMB_str, WRITE);
                    442:            COMB = pCOMB->file;
                    443:          }
                    444:          if (fputs(line_new_old, COMB) < 0)
                    445:            bummer(COMB_str);
                    446:          comb_in_progress = 1;
                    447:        }
                    448:        /* in any case, write the current line, and count it */
                    449:        if (fputs(line_new, COMB) < 0)
                    450:          bummer(COMB_str);
                    451:        i++;
                    452:       }
                    453:       else
                    454:       {                                /* not combinable */
                    455:        q_new_old = q_new;
                    456:        comb_in_progress = 0;
                    457:        /* and dump it to the TMP file */
                    458:        if (fputs(line_new, TMP) < 0)
                    459:          bummer(TMP_str);
                    460:        /* and stash it away for a moment */
                    461:        swap_lines;
                    462:        comb_in_progress = 0;
                    463:       }
                    464:     } /* while */
                    465:     if (pCOMB) pari_fclose(pCOMB);
                    466:     pari_fclose(pTMP);
                    467:     return i;
                    468:   }
                    469:
                    470:   /* normal case: both LPNEW and LPREL are not empty */
                    471:   q_new = atol(line_new);
                    472:   q = atol(line);
                    473:
                    474:   for(;;)                      /* main merging loop */
                    475:   {
                    476:     comb_in_progress = 0;
                    477:     i = 0;
                    478:
                    479:     /* first the harder case:  let LPNEW catch up with LPREL, and possibly
                    480:        overtake it, checking for combinables coming from LPNEW alone */
                    481:
                    482:     while (q > q_new)
                    483:     {
                    484:       if (mode || !comb_in_progress)
                    485:       {
                    486:        if (fputs(line_new, TMP) < 0)
                    487:          bummer(TMP_str);
                    488:       }
                    489:       if (mode)
                    490:        c++;                    /* in FREL mode, count lines written */
                    491:       else if (!comb_in_progress)
                    492:       {
                    493:        q_new_old = q_new;
                    494:        swap_lines;
                    495:       }
                    496:       if (fgets(line_new, MPQS_STRING_LENGTH, LPNEW) == NULL)
                    497:       {
                    498:        if (fputs(line, TMP) < 0)
                    499:          bummer(TMP_str);
                    500:        if (mode) c++; else c += i;
                    501:        i = mpqs_append_file(pTMP, LPREL);
                    502:        if (pCOMB) pari_fclose(pCOMB);
                    503:        return (mode ? c + i : c);
                    504:       }
                    505:       q_new = atol(line_new);
                    506:       if (mode) continue;
                    507:       /* LP mode only: */
                    508:       if (q_new_old != q_new)
                    509:       {                                /* not combinable */
                    510:        comb_in_progress = 0;
                    511:        /* next loop iteration will deal with it, or the loop may end */
                    512:       }
                    513:       else
                    514:       {
                    515:        /* found combinables, check whether we're already busy on this
                    516:           `large prime' */
                    517:        if (!comb_in_progress)
                    518:        {
                    519:          if (!pCOMB)
                    520:          {
                    521:            pCOMB = pari_safefopen(COMB_str, WRITE);
                    522:            COMB = pCOMB->file;
                    523:          }
                    524:          if (fputs(line_new_old, COMB) < 0)
                    525:            bummer(COMB_str);
                    526:          comb_in_progress = 1;
                    527:        }
                    528:        /* in any case, write the current line, and count it */
                    529:        if (fputs(line_new, COMB) < 0)
                    530:          bummer(COMB_str);
                    531:        i++;
                    532:       }
                    533:     } /* while q > q_new */
                    534:
                    535:     /* q <= q_new */
                    536:
                    537:     if (!mode) c += i;         /* accumulate count of combinables */
                    538:     i = 0;                     /* and clear it */
                    539:     comb_in_progress = 0;      /* redundant */
                    540:
                    541:     /* now let LPREL catch up with LPNEW, and possibly overtake it */
                    542:
                    543:     while (q < q_new)
                    544:     {
                    545:       if (fputs(line, TMP) < 0)
                    546:        bummer(TMP_str);
                    547:       if (mode) c++;
                    548:       if (fgets(line, MPQS_STRING_LENGTH, LPREL) == NULL)
                    549:       {
                    550:        if (fputs(line_new, TMP) < 0)
                    551:          bummer(TMP_str);
                    552:        i = mpqs_append_file(pTMP, LPNEW);
                    553:        if (pCOMB) pari_fclose(pCOMB);
                    554:        return (mode ? c + i + 1 : c);
                    555:       }
                    556:       else
                    557:        q = atol(line);
                    558:     }
                    559:
                    560:     /* q >= q_new */
                    561:
                    562:     /* Finally, it may happen that q == q_new, indicating combinables whose
                    563:        `large prime' is already represented in LPREL, and appears now once
                    564:        or more often in LPNEW.  Thus in this sub-loop we advance LPNEW.
                    565:        The `line' from LPREL is left alone, and will be written to TMP the
                    566:        next time around the main for loop;  we only write it to COMB here --
                    567:        unless all we find is an exact duplicate of the line we already have,
                    568:        that is.  (There can be at most one such, and if so it will simply be
                    569:        discarded, whether we are in LP or full relations mode.) */
                    570:
                    571:     while (q == q_new)
                    572:     {
                    573:       if (strcmp(line_new, line) == 0)
                    574:       {
                    575:        /* duplicate -- move right ahead to the next LPNEW line */
                    576:        ;                       /* do nothing here */
                    577:       }        /* end duplicate case */
                    578:       else if (mode)
                    579:       {
                    580:        /* full relations mode: write line_new out first, keep line */
                    581:        if (fputs(line_new, TMP) < 0)
                    582:          bummer(TMP_str);
                    583:        c++;
                    584:       }        /* end full relations case */
                    585:       else
                    586:       {
                    587:        /* LP mode, and combinable relation */
                    588:        if (!comb_in_progress)
                    589:        {
                    590:          if (!pCOMB)
                    591:          {
                    592:            pCOMB = pari_safefopen(COMB_str, WRITE);
                    593:            COMB = pCOMB->file;
                    594:          }
                    595:          if (fputs(line, COMB) < 0)
                    596:            bummer(COMB_str);
                    597:          comb_in_progress = 1;
                    598:        }
                    599:        if (fputs(line_new, COMB) < 0)
                    600:          bummer(COMB_str);
                    601:        i++;
                    602:       }        /* end combinable LP case */
                    603:       /* NB comb_in_progress is cleared by q_new becoming bigger than q,
                    604:         and thus the current while loop terminating, the next time through
                    605:         the main for loop */
                    606:
                    607:       /* common ending: get another line_new, if any */
                    608:       if (fgets(line_new, MPQS_STRING_LENGTH, LPNEW) == NULL)
                    609:       {
                    610:        if (fputs(line, TMP) < 0)
                    611:          bummer(TMP_str);
                    612:        if (mode) c++; else c += i;
                    613:        i = mpqs_append_file(pTMP, LPREL);
                    614:        if (pCOMB) pari_fclose(pCOMB);
                    615:        return (mode ? c + i : c);
                    616:       }
                    617:       else
                    618:        q_new = atol(line_new);
                    619:     } /* while */
                    620:
                    621:     if (!mode) c += i;         /* accumulate count of combinables */
                    622:   } /* for */
                    623: }
                    624:
                    625: static long
                    626: mpqs_mergesort_lp_file(char *REL_str, char *NEW_str, long mode)
                    627: {
                    628:   pariFILE *pREL = pari_fopen(REL_str, READ);
                    629:   pariFILE *pNEW = pari_fopen(NEW_str, READ);
                    630:   long tp = mpqs_mergesort_lp_file0(pREL->file, pNEW->file, mode);
                    631:
                    632:   pari_fclose(pREL);
                    633:   pari_fclose(pNEW);
                    634:   pari_unlink(REL_str);
                    635:   if (rename(TMP_str,REL_str))
                    636:     err(talker, "can\'t rename file %s to %s", TMP_str, REL_str);
                    637:   if (
                    638: #ifdef MPQS_DEBUG
                    639:           1 ||
                    640: #endif
                    641:           DEBUGLEVEL >= 6)
                    642:     fprintferr("MPQS: renamed file %s to %s\n", TMP_str, REL_str);
                    643:   return tp;
                    644: }
                    645:
                    646: /******************************/
                    647: /**
                    648:  ** return next prime larger than p, using *primes_ptr on the
                    649:  ** diffptr table first and pari's other wits after that
                    650:  **/
                    651:
                    652: static byteptr
                    653: mpqs_iterate_primes(long *p, byteptr primes_ptr)
                    654: {
                    655:   long prime = *p;
1.2     ! noro      656:   if (*primes_ptr) {
        !           657:     NEXT_PRIME_VIADIFF(prime,primes_ptr)
        !           658:   }
1.1       noro      659:   else
                    660:   {
1.2     ! noro      661:     gpmem_t av = avma;
1.1       noro      662:     prime = itos(nextprime(stoi(prime + 1)));
                    663:     avma = av;
                    664:   }
                    665:   *p = prime;
                    666:   return primes_ptr;
                    667: }
                    668:
                    669:
                    670: /**
                    671:  ** return the multiplier k for N to use in MPQS
                    672:  **/
                    673:
                    674: long
                    675: mpqs_find_k(GEN N, long tries)
                    676: {
                    677:   static long cand_table[] = { 1,3,5,7,11,13,15,17,19,21,23,
                    678:                                29,31,33,35,37,39,41,43,47,51,53,
                    679:                                55,57,59,61,65,67,69,71,73,79,83,
                    680:                                85,89,91,93,95,97,101,103,105,107,
                    681:                                109,113,127,131,137,139};
1.2     ! noro      682:   gpmem_t av = avma;
1.1       noro      683:   long best_k = 1, k, p, N_mod_4 = smodis(N, 4), x;
                    684:   GEN kN;
                    685:   double best_value = 1, value, dp;
                    686:   long i, j;
                    687:   byteptr primes_ptr;
                    688:
                    689:   for (i = 0; i < MPQS_PRIMES_FOR_MULTIPLIER; i++)
                    690:   {
                    691:     k = cand_table[i];
                    692:     x = (k * N_mod_4) % 4;
                    693:     if (x == 1)
                    694:     {
                    695:       value = -0.7 * log2 ((double) k);
                    696:       kN = mulis(N, k);
                    697:       if (smodis(kN, 8) == 1)
                    698:        value += 1.38629;
                    699:
                    700:       j = 0; p = 0;
                    701:       primes_ptr = diffptr;
                    702:       while (j <= tries)
                    703:       {
                    704:        primes_ptr = mpqs_iterate_primes(&p, primes_ptr);
                    705:        if (kross(smodis(kN, p), p) == 1)
                    706:         {
                    707:          j++;
                    708:          dp = log2((double) p) / p;
                    709:          value += (k % p == 0) ? dp : 2 * dp;
                    710:        }
                    711:       }
                    712:
                    713:       if (value > best_value)
                    714:       {
                    715:        best_value = value;
                    716:        best_k = k;
                    717:       }
                    718:     }
                    719:   }
                    720:   avma = av; return best_k;
                    721: }
                    722:
                    723: /******************************/
                    724: /**
                    725:  ** guesstimate up to what size we're going to need precomputed
                    726:  ** small primes
                    727:  **/
                    728:
                    729: static long
                    730: mpqs_find_maxprime(long size)
                    731: {
                    732:   double x;
                    733:
                    734:   if (size < 16000)
                    735:     return 176000;
                    736:
                    737:   x  = log((double)size);
                    738:   x += log(x);
                    739:   x -= 0.9427;
                    740:   x *= size;
                    741:
                    742:   return (long)x;
                    743: }
                    744:
                    745: /**
                    746:  ** return the number of primes initialized in PARI
                    747:  **/
                    748:
                    749: static long
1.2     ! noro      750: mpqs_count_primes(void)
1.1       noro      751: {
                    752:   byteptr p = mpqs_diffptr;
1.2     ! noro      753:   long gaps = 0;
1.1       noro      754:
1.2     ! noro      755:   for ( ; *p; p++)
        !           756:       if (*p == DIFFPTR_SKIP)
        !           757:          gaps++;
        !           758:   return (p - mpqs_diffptr - gaps);
1.1       noro      759: }
                    760:
                    761: /**
                    762:  ** create a factor base of size primes p_i with the
                    763:  ** property that legendre(k*N, p_i) == 0, 1
                    764:  ** FB[0] contains the size of the factor base;  FB[FB[0]+1] is the
                    765:  ** last prime p_i.
                    766:  ** FB[1] contains -1 which allows to handle negative values of Q(x).
                    767:  ** If a prime factor of N is found during the construction, it
                    768:  ** is returned in f, otherwise f = 0  (such a factor will necessarily
                    769:  ** fit into a C long).
                    770:  **/
                    771:
                    772: static long*
                    773: mpqs_create_FB(long size, GEN kN, long k, long *f)
                    774: {
                    775:   long i, kr, p = 0;
                    776:   long *FB;
                    777:   byteptr primes_ptr;
                    778:
                    779:   FB = (long *) calloc(size + 3, sizeof(long));
                    780:   if (!FB) err(memer);
                    781:   FB[0] = size;
                    782:   FB[1] = -1;
                    783:   /* pick up PARI's current differences-of-small-primes array */
                    784:   /* unless we already have our own.  We must then reset it to NULL */
                    785:   /* so we will not use a stale one the next time we are called */
                    786:   if (!mpqs_diffptr) mpqs_diffptr = diffptr;
                    787:
                    788:   if ((mpqs_prime_count ? mpqs_prime_count : mpqs_count_primes())
                    789:       < 3 * size)
                    790:   {
                    791:     long newsize = 3 * mpqs_find_maxprime(size);
                    792:     if (mpqs_diffptr != diffptr) free((void *) mpqs_diffptr);
                    793:     if (DEBUGLEVEL >= 2)
                    794:     {
                    795:       fprintferr("MPQS: precomputing auxiliary primes up to %ld\n",
                    796:                 newsize);
                    797:     }
                    798:     mpqs_diffptr = initprimes(newsize);
                    799:     /* count 'em once and remember the result */
                    800:     mpqs_prime_count = mpqs_count_primes();
                    801:   }
                    802:
                    803:   if (
                    804: #ifdef MPQS_DEBUG
                    805:       1 ||
                    806: #endif
                    807:       DEBUGLEVEL >= 7)
                    808:     fprintferr("MPQS: FB [-1");
                    809:   primes_ptr = mpqs_diffptr;
                    810:   for (i = 2; i < size + 2; )
                    811:   {
                    812:     primes_ptr = mpqs_iterate_primes(&p, primes_ptr);
                    813:
                    814:     /* testing p!=k was only correct because MPQS_PRIMES_FOR_MULTIPLIER
                    815:        is so small that the composite values k > 1 will never be chosen.
                    816:        Fixing this just in case someone increases that parameter one day...
                    817:        --GN */
                    818:     if (p > k || k%p)
                    819:     {
                    820:       kr = kross(smodis(kN, p), p);
                    821:       if (kr != -1)
                    822:       {
                    823:        if (kr == 0)
                    824:        {
                    825:          if (
                    826: #ifdef MPQS_DEBUG
                    827:              1 ||
                    828: #endif
                    829:              DEBUGLEVEL >= 7)
                    830:            fprintferr(",%ld...] Wait a second --\n", p);
                    831:          *f = p;
                    832:          return FB;
                    833:        }
                    834:        if (
                    835: #ifdef MPQS_DEBUG
                    836:            1 ||
                    837: #endif
                    838:            DEBUGLEVEL >= 7)
                    839:          fprintferr(",%ld", p);
                    840:        FB[i] = p, i++;
                    841:       }
                    842:     }
                    843:   }
                    844:
                    845:   if (
                    846: #ifdef MPQS_DEBUG
                    847:       1 ||
                    848: #endif
                    849:       DEBUGLEVEL >= 7)
                    850:   {
                    851:     fprintferr("]\n");
                    852:     flusherr();
                    853:   }
                    854:
                    855:   FB[i] = 0;
                    856:   if (DEBUGLEVEL >= 6)
                    857:     fprintferr("MPQS: last available index in FB is %ld\n", i - 1);
                    858:
                    859:   *f = 0;
                    860:   return FB;
                    861: }
                    862:
                    863: /******************************/
                    864:
                    865: /**
                    866:  ** see below for the format of the parameter table.
                    867:  ** These values are somewhat experimental and can be improved by
                    868:  ** further extensive testing.
                    869:  ** Tentative entries for 9...14 digits by GN, entry for 15 changed
                    870:  ** Tentative entries for 81...100 digits by GN, entry for 74 changed
                    871:  ** total_no_of_primes_for_A (penultimate entries in each row) increased
                    872:  ** throughout, partly so as to offset the effect of changed bin_index
                    873:  ** increment strategy --GN
                    874:  ** Added entries to govern sort intervals, commented out unused numbers
                    875:  ** of digits --GN
                    876:  **/
                    877:
                    878: static double
                    879: mpqs_parameters[99][8] =
                    880: {
                    881:   {  /*9*/ 0.8,     900,    20,  3, 13,  2, 70,  8},
                    882:   { /*10*/ 0.8,     900,    21,  3, 12,  2, 70,  8},
                    883:   { /*11*/ 0.8,     920,    22,  3, 12,  2, 70,  6},
                    884:   { /*12*/ 0.8,     960,    24,  3, 12,  2, 70,  6},
                    885:   { /*13*/ 0.8,    1020,    26,  3, 12,  2, 70,  6},
                    886:   { /*14*/ 0.8,    1100,    29,  3, 12,  2, 70,  6},
                    887:   { /*15*/ 0.8,    1200,    32,  3, 12,  2, 60,  8},
                    888:   { /*16*/ 0.8,    1400,    35,  3, 12,  2, 60,  8},
                    889:   { /*17*/ 0.8,    3000,    40,  3, 12,  2, 60,  8},
                    890:   { /*18*/ 0.8,    3000,    60,  3, 12,  2, 50, 10},
                    891:   { /*19*/ 0.8,    3600,    80,  3, 13,  2, 50, 10},
                    892:   { /*20*/ 0.8,    4000,   100,  3, 13,  2, 40, 10},
                    893:   { /*21*/ 0.8,    4300,   100,  3, 13,  2, 40, 10},
                    894:   { /*22*/ 0.8,    4500,   120,  3, 13,  3, 40, 10},
                    895:   { /*23*/ 0.8,    4800,   140,  3, 14,  3, 30, 10},
                    896:   { /*24*/ 0.8,    5000,   160,  3, 14,  4, 30, 10},
                    897:   { /*25*/ 0.8,    5000,   180,  3, 14,  4, 30, 10},
                    898:   { /*26*/ 0.9,    6000,   200,  5, 10,  4, 30, 10},
                    899:   { /*27*/ 1.17,   6000,   220,  5, 10,  5, 30, 10},
                    900:   { /*28*/ 1.17,   6500,   240,  5, 10,  5, 30, 10},
                    901:   { /*29*/ 1.17,   6500,   260,  5, 10,  5, 30, 10},
                    902:   { /*30*/ 1.36,   7000,   325,  5, 10,  5, 20, 10},
                    903:   { /*31*/ 1.36,   7000,   355,  5, 10,  5, 20, 10},
                    904:   { /*32*/ 1.36,   7500,   375,  5, 10,  5, 20, 10},
                    905:   { /*33*/ 1.43,   7500,   400,  6, 11,  6, 20, 10},
                    906:   { /*34*/ 1.43,   7500,   425,  6, 11,  6, 20, 10},
                    907:   { /*35*/ 1.43,   7500,   550,  6, 11,  6, 20, 10},
                    908:   { /*36*/ 1.43,   8000,   650,  6, 11,  6, 20, 10},
                    909:   { /*37*/ 1.69,   9000,   750,  6, 11,  7, 20, 10},
                    910:   { /*38*/ 1.69,  10000,   850,  6, 11,  7, 20, 10},
                    911:   { /*39*/ 1.69,  11000,   950,  6, 11,  7, 20, 10},
                    912:   { /*40*/ 1.69,  14000,  1000,  6, 11,  7, 20, 10},
                    913:   { /*41*/ 1.69,  14000,  1150,  6, 11,  8, 10, 10},
                    914:   { /*42*/ 1.69,  15000,  1300,  6, 11,  8, 10, 10},
                    915:   { /*43*/ 1.69,  15000,  1600,  6, 11,  8, 10, 10},
                    916:   { /*44*/ 1.69,  15000,  1900,  7, 12,  9, 10, 10},
                    917:   { /*45*/ 1.69,  15000,  2200,  7, 12,  9, 10, 10},
                    918:   { /*46*/ 1.69,  20000,  2500,  7, 12,  9, 10, 10},
                    919:   { /*47*/ 1.69,  25000,  2500,  7, 12, 10, 10, 10},
                    920:   { /*48*/ 1.69,  27500,  2700,  7, 12, 10, 10, 10},
                    921:   { /*49*/ 1.69,  30000,  2800,  7, 12, 10, 10, 10},
                    922:   { /*50*/ 1.75,  35000,  2900,  7, 12, 10, 10, 10},
                    923:   { /*51*/ 1.75,  40000,  3000,  7, 12, 10, 10, 10},
                    924:   { /*52*/ 1.85,  50000,  3200,  7, 12, 11, 10, 10},
                    925:   { /*53*/ 1.85,  50000,  3500,  7, 12, 11, 10, 10},
                    926:   { /*54*/ 1.95,  80000,  3800,  7, 13, 11, 10, 10},
                    927:   { /*55*/ 1.95,  90000,  4100,  7, 13, 11, 10, 10},
                    928:   { /*56*/ 1.95, 100000,  4400,  7, 13, 11, 10, 10},
                    929:   { /*57*/ 1.95,  80000,  4700,  8, 14, 12, 10, 10},
                    930:   { /*58*/ 1.95,  80000,  5000,  8, 14, 12, 10, 10},
                    931:   { /*59*/ 2.15, 130000,  5500,  8, 14, 12, 10,  8},
                    932:   { /*60*/ 2.15, 140000,  5800,  8, 14, 12, 10,  8},
                    933:   { /*61*/ 2.15, 150000,  6100,  8, 14, 13, 10,  8},
                    934:   { /*62*/ 2.15, 160000,  6400,  8, 14, 13, 10,  8},
                    935:   { /*63*/ 2.35, 170000,  6700,  8, 14, 13, 10,  8},
                    936:   { /*64*/ 2.35, 180000,  7000,  8, 14, 13, 10,  8},
                    937:   { /*65*/ 2.35, 190000,  7300,  8, 14, 13, 10,  8},
                    938:   { /*66*/ 2.35, 200000,  7600,  8, 14, 13, 10,  8},
                    939:   { /*67*/ 2.4,  150000,  7900,  8, 14, 13, 10,  8},
                    940:   { /*68*/ 2.4,  150000,  8200,  8, 15, 13, 10,  8},
                    941:   { /*69*/ 2.4,  130000,  8600,  8, 15, 13,  8,  6},
                    942:   { /*70*/ 2.45, 130000,  8800,  8, 15, 13,  8,  6},
                    943:   { /*71*/ 2.45, 130000,  8800,  9, 16, 13,  8,  6},
                    944:   { /*72*/ 2.4,  260000,  9400,  9, 16, 13,  5,  5},
                    945:   { /*73*/ 2.4,  270000,  9700,  9, 16, 13,  5,  5},
                    946:   { /*74*/ 2.4,  280000,  9800,  9, 16, 13,  5,  5},
                    947:   { /*75*/ 2.6,  140000,  9000,  9, 17, 13,  5,  5},
                    948:   { /*76*/ 2.6,  160000,  9400,  9, 17, 13,  5,  5},
                    949:   { /*77*/ 2.6,  180000,  9600,  9, 17, 13,  5,  5},
                    950:   { /*78*/ 2.6,  200000,  9800,  9, 17, 13,  5,  5},
                    951:   { /*79*/ 2.65, 220000, 10000,  9, 18, 13,  5,  5},
                    952:   { /*80*/ 2.65, 250000, 10500,  9, 18, 13,  5,  5},
                    953:   /* entries below due to Thomas Denny */
                    954:   { /*81*/ 3.1, 1500000, 16000,  9, 18, 15,  4,  4},
                    955:   { /*82*/ 3.1, 1500000, 17000,  9, 18, 15,  4,  4},
                    956:   { /*83*/ 3.1, 1500000, 18500,  9, 19, 16,  4,  4},
                    957:   { /*84*/ 3.2, 1500000, 20000,  9, 19, 16,  4,  4},
                    958:   { /*85*/ 3.2, 1500000, 21500,  9, 19, 16,  4,  4},
                    959:   { /*86*/ 3.2, 1500000, 23000,  9, 19, 16,  4,  4},
                    960:   { /*87*/ 3.2, 1500000, 25000,  9, 20, 17,  4,  4},
                    961:   { /*88*/ 3.3, 1500000, 27000,  9, 20, 17,  4,  4},
                    962:   { /*89*/ 3.3, 1500000, 28000,  9, 20, 17,  4,  4},
                    963:   { /*90*/ 3.5, 2000000, 30500,  9, 20, 17,  2,  2},
                    964:   { /*91*/ 3.6, 2000000, 32000,  9, 21, 18,  2,  2},
                    965:   { /*92*/ 3.6, 2000000, 35000,  9, 21, 18,  2,  2},
                    966:   { /*93*/ 3.7, 2000000, 37000,  9, 21, 18,  2,  2},
                    967:   { /*94*/ 3.7, 2000000, 39500,  9, 22, 18,  2,  2},
                    968:   { /*95*/ 3.7, 2500000, 41500,  9, 22, 18,  2,  2},
                    969:   { /*96*/ 3.8, 2500000, 45000, 10, 23, 18,  2,  2},
                    970:   { /*97*/ 3.8, 2500000, 47500, 10, 23, 18,  2,  2},
                    971:   { /*98*/ 3.7, 3000000, 51000, 10, 24, 18,  2,  2},
                    972:   { /*99*/ 3.8, 3000000, 53000, 10, 24, 18,  2,  2},
                    973:   {/*100*/ 3.8, 3500000, 51000, 10, 25, 18,  2,  2},
                    974:   {/*101*/ 3.8, 3500000, 54000, 10, 25, 18,  2,  2},
                    975:   {/*102*/ 3.8, 3500000, 57000, 10, 26, 18,  2,  2},
                    976:   {/*103*/ 3.9, 4000000, 61000, 10, 26, 18,  2,  2},
                    977:   {/*104*/ 3.9, 4000000, 66000, 10, 27, 18,  2,  2},
                    978:   {/*105*/ 3.9, 4000000, 70000, 10, 27, 18,  2,  2},
                    979:   {/*106*/ 3.9, 4000000, 75000, 10, 28, 18,  2,  2},
                    980:   {/*107*/ 3.9, 4000000, 80000, 10, 30, 18,  2,  2},
                    981: };
                    982:
                    983: /**
                    984:  ** Return the appropriate parameters for the initialization of MPQS
                    985:  **
                    986:  ** the parameter table for mpqs has the following format:
                    987:  **
                    988:  ** [d    -- decimal digits -- commented out]
                    989:  ** e    -- approximation accuracy
                    990:  ** M    -- size sieving interval
                    991:  ** s    -- size FB,
                    992:  ** fA   -- # prime factors in A
                    993:  ** pA   -- total # primes for determination of A,
                    994:  ** [maxB -- how many Bs to use before choosing a new A -- determined by fA]
                    995:  ** si   -- initial sieving index
                    996:  ** isoi -- initial sorting interval
                    997:  ** fsoi -- followup sorting interval increment
                    998:  **/
                    999:
                   1000: static void
                   1001: mpqs_read_parameters(ulong d, double *e, ulong *M, ulong *s, ulong *os,
                   1002:                     ulong *fA, ulong *pA, long *maxB, ulong *si,
                   1003:                     ulong *isoi, ulong *fsoi)
                   1004: {
                   1005:   long i = d;
                   1006:   if (i < 9) i = 9;
                   1007:   if (i > 107) i = 107;
                   1008:   i -= 9;
                   1009:
                   1010:   *e = mpqs_parameters[i][0];
                   1011:   *M = (ulong)mpqs_parameters[i][1];
                   1012:   *s = (ulong)mpqs_parameters[i][2];
                   1013:   if (*s >= 200) *os = *s + 70;
                   1014:   else *os = (ulong)(*s * 1.35);
                   1015:   *fA = (ulong)mpqs_parameters[i][3];
                   1016:   *pA = (ulong)mpqs_parameters[i][4];
                   1017: #if 0
                   1018:   *maxB = (long) pow(2.0, mpqs_parameters[i][3] - 1.0);
                   1019: #else
                   1020:   *maxB = 1l << (*fA - 1);
                   1021: #endif
                   1022:   *si = (ulong)mpqs_parameters[i][5];
                   1023:   *isoi = 10 * (ulong)mpqs_parameters[i][6]; /* percentages scaled by 10 */
                   1024:   *fsoi = 10 * (ulong)mpqs_parameters[i][7];
                   1025: }
                   1026:
                   1027: /******************************/
                   1028:
                   1029: /**
                   1030:  ** increment *x (!=0) to a larger value which has the same number of 1s
                   1031:  ** in its binary representation.  Cases which wrap around can be detected
                   1032:  ** by the caller afterwards as long as we keep total_no_of_primes_for_A
                   1033:  ** strictly less than BITS_IN_LONG.
                   1034:  **
                   1035:  ** Switch for the fast cases moved into here --GN
                   1036:  **
                   1037:  ** Changed switch to increment *x in all cases to the next larger number
                   1038:  ** which (a) has the same count of 1 bits and (b) does not arise from the
                   1039:  ** old value by moving a single 1 bit one position to the left  (which was
                   1040:  ** undesirable for the sieve). --GN based on discussion with TP
                   1041:  **/
                   1042: static void
                   1043: mpqs_increment(ulong *x)
                   1044: {
                   1045:   ulong r1_mask, r01_mask, slider=1;
                   1046:
                   1047:   /* ultra-fast 32-way computed jump handles 22 out of 32 cases */
                   1048:   switch (*x & 0x1f)
                   1049:   {
                   1050:   case 29:
                   1051:     (*x)++; break;             /* this does shift a single bit, but we'll
                   1052:                                   postprocess this case */
                   1053:   case 26:
                   1054:     (*x) += 2; break;          /* again */
                   1055:   case 1: case 3: case 6: case 9: case 11:
                   1056:   case 17: case 19: case 22: case 25: case 27:
                   1057:     (*x) += 3; return;
                   1058:   case 20:
                   1059:     (*x) += 4; break;          /* again */
                   1060:   case 5: case 12: case 14: case 21:
                   1061:     (*x) += 5; return;
                   1062:   case 2: case 7: case 13: case 18: case 23:
                   1063:     (*x) += 6; return;
                   1064:   case 10:
                   1065:     (*x) += 7; return;
                   1066:   case 8:
                   1067:     (*x) += 8; break;          /* and again */
                   1068:   case 4: case 15:
                   1069:     (*x) += 12; return;
                   1070:   default:                     /* 0, 16, 24, 28, 30, 31 */
                   1071:     /* isolate rightmost 1 */
                   1072:     r1_mask = ((*x ^ (*x - 1)) + 1) >> 1;
                   1073:     /* isolate rightmost 1 which has a 0 to its left */
                   1074:     r01_mask = ((*x ^ (*x + r1_mask)) + r1_mask) >> 2;
                   1075:     /* simple cases.  Both of these shift a single bit one position to the
                   1076:        left, and will need postprocessing */
                   1077:     if (r1_mask == r01_mask) { *x += r1_mask; break; }
                   1078:     if (r1_mask == 1) { *x += r01_mask; break; }
                   1079:     /* general case -- idea:
                   1080:        add r01_mask, kill off as many 1 bits as possible to its right
                   1081:        while at the same time filling in 1 bits from the LSB. */
                   1082:     if (r1_mask == 2) { *x += (r01_mask>>1) + 1; return; }
                   1083:     while (r01_mask > r1_mask && slider < r1_mask)
                   1084:     {
                   1085:       r01_mask >>= 1; slider <<= 1;
                   1086:     }
                   1087:     *x += r01_mask + slider - 1;
                   1088:     return;
                   1089:   }
                   1090:   /* post-process all cases which couldn't be finalized above.  If we get
                   1091:      here, slider still has its original value. */
                   1092:   r1_mask = ((*x ^ (*x - 1)) + 1) >> 1;
                   1093:   r01_mask = ((*x ^ (*x + r1_mask)) + r1_mask) >> 2;
                   1094:   if (r1_mask == r01_mask) { *x += r1_mask; return; }
                   1095:   if (r1_mask == 1) { *x += r01_mask; return; }
                   1096:   if (r1_mask == 2) { *x += (r01_mask>>1) + 1; return; }
                   1097:   while (r01_mask > r1_mask && slider < r1_mask)
                   1098:   {
                   1099:     r01_mask >>= 1; slider <<= 1;
                   1100:   }
                   1101:   *x += r01_mask + slider - 1;
                   1102:   return;
                   1103: }
                   1104:
                   1105: static long
                   1106: mpqs_invsmod(long b, long p)
                   1107: {
                   1108:   long v1 = 0, v2 = 1, v3, r, oldp = p;
                   1109:
                   1110:   while (b > 1)
                   1111:   {
                   1112:     v3 = v1 - (p / b) * v2; v1 = v2; v2 = v3;
                   1113:     r = p % b; p = b; b = r;
                   1114:   }
                   1115:
                   1116:   if (v2 < 0) v2 += oldp;
                   1117:   return v2;
                   1118: }
                   1119:
                   1120: /**
                   1121:  ** compute coefficients of the sieving polynomial for self initializing
                   1122:  ** variant. Coefficients A and B are returned and several tables are
                   1123:  ** updated.  See Thomas Sosnowski's diploma thesis.
                   1124:  **/
                   1125:
                   1126: static void
                   1127: mpqs_self_init(GEN A, GEN B, GEN N, GEN kN, long *FB, long *sqrt_mod_p_kN,
                   1128:                long *start_1, long *start_2, ulong no_of_primes_in_A,
                   1129:                ulong total_no_of_primes_for_A, ulong M, long **inv_A_H_i,
                   1130:                long *Q_prime, long *Q_prime_glob, GEN* H_i, long index_i,
                   1131:                long start_index_FB_for_A, long *inv_A2, GEN inv_A4,
                   1132:                ulong *bin_index, GEN *f)
                   1133: {
1.2     ! noro     1134:   gpmem_t av;
1.1       noro     1135:   GEN p1, p2;
                   1136:   ulong size_of_FB, nu_2;
                   1137:   long i, j, p, M_mod_p, tmp, tmp1, tmp2;
                   1138:
                   1139:   *f = NULL;
                   1140:   if (index_i == 0)
                   1141:   {
                   1142:     /* compute first polynomial with new A */
                   1143:     if (!*bin_index)
                   1144:     {
                   1145:       *bin_index = (1ul << no_of_primes_in_A) - 1;
                   1146:     }
                   1147:     else
                   1148:       mpqs_increment(bin_index);
                   1149:     if (*bin_index >= (1ul << total_no_of_primes_for_A)) /* wraparound */
                   1150:     {
                   1151:       if (DEBUGLEVEL >= 2)
                   1152:        fprintferr("MPQS: bin_index wraparound\n");
                   1153:       /* complain:  caller should increase some parameters... */
                   1154:       return;
                   1155:       /* caller should repeat the above test; if we simply increase the
                   1156:         total_no_of_primes_for_A, then bin_index now contains something
                   1157:         suitable for carrying on -- we'll probably end up not using
                   1158:         that particular index and skipping ahead to the next one, but
                   1159:         this isn't a problem.  OTOH total_no_of_primes_for_A should now
                   1160:         be so large that this should never happen except for ridiculous
                   1161:         input, like asking mpqs to factor 27, in which case it will act
                   1162:         as a safeguard against an infinite loop --GN */
                   1163:     }
                   1164:
                   1165:     /* determine primes used for A in this iteration */
                   1166:     for (i = 0, j = 0; (ulong)j < total_no_of_primes_for_A; j++)
                   1167:     {
                   1168:       if (*bin_index & (1 << j))
                   1169:       {
                   1170:        Q_prime[i] = Q_prime_glob[j];
                   1171:        i++;
                   1172:       }
                   1173:     }
                   1174:
                   1175:     /*
                   1176:      * compute coefficient A using
                   1177:      * A = prod (Q_prime[i], 0 < i < no_of_primes_in_A)
                   1178:      */
                   1179:
                   1180:     av = avma;
                   1181:     p1 = stoi(Q_prime[0]);
                   1182:     for (i = 1; (ulong)i < no_of_primes_in_A; i++)
                   1183:       p1 = mulis(p1, Q_prime[i]);
                   1184:     affii(p1, A);
                   1185:     avma = av;
                   1186:
                   1187:     /*
                   1188:      * let bound := no_of_primes_in_A. Compute H_i, 0 <= i < bound.
                   1189:      */
                   1190:
                   1191:     for (i = 0; (ulong)i < no_of_primes_in_A; i++)
                   1192:     {
                   1193:       av = avma;
                   1194:       p = Q_prime[i];
                   1195:       p1 = divis(A, p);
                   1196:       tmp = smodis(p1, p);
                   1197:       p1 = mulis(p1, mpqs_invsmod(tmp, p));
                   1198:       tmp = itos(mpsqrtmod(modis(kN, p), stoi(p)));
                   1199:       p1 = mulis(p1, tmp);
                   1200:       affii(modii(p1, A), H_i[i]);
                   1201:       avma = av;
                   1202:     }
                   1203:
                   1204:     /*
                   1205:      * Each B is of the form sum(v_i * H_i, 0 <= i < bound)
                   1206:      * where each v_j is +1 or -1. This has to be done only once
                   1207:      * (for index_i==0) for the coefficient A; if index_i > 0 then
                   1208:      * there is a linear recursion for B
                   1209:      */
                   1210:
                   1211:     /* compute actual B coefficient, by taking all v_i == 1 */
                   1212:     av = avma;
                   1213:     p1 = H_i[0];
                   1214:     for (i = 1; (ulong)i < no_of_primes_in_A; i++)
                   1215:       p1 = addii(p1, H_i[i]);
                   1216:     affii(p1, B);
                   1217:     avma = av;
                   1218:
                   1219:     /* ensure B = 1 mod 4 */
                   1220:     if (mod2(B) == 0)
                   1221:     {
                   1222:       /* B += (A % 4) * A; */
                   1223:       av = avma;
                   1224:       p1 = addii(B, mulsi(mod4(A), A));
                   1225:       affii(p1, B);
                   1226:       avma = av;
                   1227:     }
                   1228:
                   1229:     /* compute inv_A2[i] = 1/(2*A) mod p_i */
                   1230:     av = avma;
                   1231:     p1 = shifti(A, 1);
                   1232:     size_of_FB = FB[0] + 1;
                   1233:     for (i = 2; (ulong)i <= size_of_FB; i++)
                   1234:       inv_A2[i] = mpqs_invsmod(smodis(p1, FB[i]), FB[i]);
                   1235:     avma = av;
                   1236:
                   1237:     /* compute inv_A_H_i[i][j] = 1/A * H_i[i] mod p_j */
                   1238:     for (i = 0; (ulong)i < no_of_primes_in_A; i++)
                   1239:     {
                   1240:       for (j = 2; (ulong)j <= size_of_FB; j++)
                   1241:       {
                   1242:        av = avma;
                   1243:        p1 = mulis(H_i[i], inv_A2[j] << 1);
                   1244:        inv_A_H_i[i][j] = smodis(p1, FB[j]);
                   1245:        avma = av;
                   1246:       }
                   1247:     }
                   1248:
                   1249:     /* compute the roots z1, z2, of the polynomial Q(x) mod p_j and
                   1250:      * initialize start_1[i] with the first value p_i | Q(z1 + i p_j)
                   1251:      * initialize start_2[i] with the first value p_i | Q(z2 + i p_j)
                   1252:      */
                   1253:     for (j = 2; (ulong)j <= size_of_FB; j++)
                   1254:     {
                   1255:       p = FB[j];
                   1256:       M_mod_p = M % p;
                   1257:
                   1258:       tmp = p - smodis(B, p); /* tmp = -B mod p */
                   1259:
                   1260:       tmp1 = (tmp - sqrt_mod_p_kN[j]) % p;
                   1261:       if (tmp1 < 0) tmp1 += p;
                   1262:       tmp1 = mulssmod(tmp1, inv_A2[j], p);
                   1263:       tmp1 = (tmp1 + M_mod_p) % p;
                   1264:
                   1265:       tmp2 = (tmp + sqrt_mod_p_kN[j]) % p;
                   1266:       if (tmp2 < 0) tmp2 += p;
                   1267:       tmp2 = mulssmod(tmp2, inv_A2[j], p);
                   1268:       tmp2  = (tmp2 + M_mod_p) % p;
                   1269:
                   1270:       start_1[j] = (tmp1 < 0) ? tmp1 + p : tmp1;
                   1271:       start_2[j] = (tmp2 < 0) ? tmp2 + p : tmp2;
                   1272:     }
                   1273:
                   1274:     /* determine 1/(4A) mod kN */
                   1275:     av = avma;
                   1276:     if (!invmod(shifti(A,2), kN, &p1)) /* --GN */
                   1277:     {
                   1278:       /* inv_A4 is a factor > 1 of kN.  This cannot actually happen.
                   1279:          Catch it anyway, it doesn't cost more than two comparisons
                   1280:         against 0 / NULL */
                   1281:       p1 = mppgcd(p1, N);
                   1282:       *f = gerepileupto(av, p1);
                   1283:       return;                  /* we certainly can't use the current poly */
                   1284:     }
                   1285:     affii(p1, inv_A4);
                   1286:     avma = av;
                   1287:   }
                   1288:   else
                   1289:   {
                   1290:     /* no "real" computation -- use recursive formula
                   1291:      * first: update of B, compute B[index_i], index_i > 0
                   1292:      */
                   1293:
                   1294:     /* compute nu_2 = nu_2(index_i) */
                   1295:     nu_2 = 0;
                   1296:     j = index_i;
                   1297:     while ((j & 1) == 0)
                   1298:     {
                   1299:       nu_2++;
                   1300:       j >>= 1;
                   1301:     }
                   1302:
                   1303:     av = avma;
                   1304:     p1 = shifti(H_i[nu_2], 1);
                   1305:
                   1306:     if ((((j+1)/2) & 1) == 1)
                   1307:     {
                   1308:       i = -1;
                   1309:       p1 = subii(B, p1);
                   1310:     }
                   1311:     else
                   1312:     {
                   1313:       i = 1;
                   1314:       p1 = addii(B, p1);
                   1315:     }
                   1316:     affii(p1, B);
                   1317:     avma = av;
                   1318:
                   1319:     /* determine new starting positions for sieving */
                   1320:     size_of_FB = FB[0] + 1;
                   1321:
                   1322:     if (i == -1)
                   1323:     {
                   1324:       for (j = 2; (ulong)j <= size_of_FB; j++)
                   1325:       {
                   1326:        p = FB[j];
                   1327:        start_1[j] += inv_A_H_i[nu_2][j];
                   1328:        if (start_1[j] >= p)
                   1329:          start_1[j] -= p;
                   1330:        start_2[j] += inv_A_H_i[nu_2][j];
                   1331:        if (start_2[j] >= p)
                   1332:          start_2[j] -= p;
                   1333:       }
                   1334:     }
                   1335:     else
                   1336:     {
                   1337:       for (j = 2; (ulong)j <= size_of_FB; j++)
                   1338:       {
                   1339:        p = FB[j];
                   1340:        start_1[j] -= inv_A_H_i[nu_2][j];
                   1341:        if (start_1[j] < 0)
                   1342:          start_1[j] += p;
                   1343:        start_2[j] -= inv_A_H_i[nu_2][j];
                   1344:        if (start_2[j] < 0)
                   1345:          start_2[j] += p;
                   1346:       }
                   1347:     }
                   1348:   }
                   1349:
                   1350:   /* p=2 is a special case */
                   1351:   if (FB[2] == 2)
                   1352:   {
                   1353:     start_1[2] = 0; start_2[2] = 1;
                   1354:   }
                   1355:
                   1356:
                   1357:   /* now compute zeros of polynomials that have only one zero mod p
                   1358:      because p divides the coefficient A */
                   1359:
                   1360:   /* compute coefficient -C */
                   1361:   av = avma;
                   1362:   p1 = subii(kN, sqri(B));
                   1363:   p2 = divii(p1, shifti(A, 2));
                   1364:
                   1365:   for (j = 1; (ulong)j <= total_no_of_primes_for_A; j++)
                   1366:     if (*bin_index & (1 << (j-1)))
                   1367:     {
                   1368:       p = FB[start_index_FB_for_A + j];
                   1369:       tmp = mpqs_invsmod(smodis(B, p), p);
                   1370:       tmp2 = smodis (p2, p);
                   1371:       tmp = mulssmod(tmp2, tmp, p);
                   1372:       start_1[start_index_FB_for_A + j] =
                   1373:        start_2[start_index_FB_for_A + j] = (tmp + M) % p;
                   1374:     }
                   1375:   avma = av;
                   1376:
                   1377: #ifdef MPQS_DEBUG
                   1378:   {
                   1379:     /*
                   1380:      * check correctness of the roots z1, z2 mod p_i by evaluting
                   1381:      * A * z1^2 + B * z1 + C mod p_i and checking against 0 mod p_i
                   1382:      * C is written as (B*B-kN)/(4*A)
                   1383:      */
                   1384:     size_of_FB = FB[0] + 1;
                   1385:     for (j = 3; j <= size_of_FB; j++)
                   1386:     {
                   1387:       av = avma;
                   1388:       p = FB[j];
                   1389:       M_mod_p = M % p;
                   1390:
                   1391:       p1 = mulis(A, start_1[j] - M_mod_p);
                   1392:       p1 = addii(p1, B);
                   1393:       p1 = mulis(p1, start_1[j] - M_mod_p);
                   1394:       p2 = divii(subii(sqri(B), kN), shifti(A, 2));
                   1395:       p1 = addii(p1, p2);
                   1396:       if (smodis(p1, p) != 0)
                   1397:       {
                   1398:        fprintferr("MPQS: (1) j = %ld p = %ld\n", j, p);
                   1399:        fprintferr("MPQS: (1) index_i = %ld\n", index_i);
                   1400:        fprintferr("MPQS: A = %Z\n", A);
                   1401:        fprintferr("MPQS: B = %Z\n", B);
                   1402:        fprintferr("MPQS: C = %Z\n", p1);
                   1403:        fprintferr("MPQS: z1 = %ld\n", start_1[j] - M_mod_p);
                   1404:        err(talker, "MPQS: self_init: found wrong polynomial in (1)");
                   1405:       }
                   1406:
                   1407:       p1 = mulis(A, start_2[j]-M_mod_p);
                   1408:       p1 = addii(p1, B);
                   1409:       p1 = mulis(p1, start_2[j]-M_mod_p);
                   1410:       p2 = divii(subii(sqri(B), kN), shifti(A, 2));
                   1411:       p1 = addii(p1, p2);
                   1412:       if (smodis(p1, p) != 0)
                   1413:       {
                   1414:        fprintferr("MPQS: (2) j = %ld p = %ld\n", j, p);
                   1415:        fprintferr("MPQS: (2) index_i = %ld\n", index_i);
                   1416:        fprintferr("MPQS: A = %Z\n", A);
                   1417:        fprintferr("MPQS: B = %Z\n", B);
                   1418:        fprintferr("MPQS: C = %Z\n", p1);
                   1419:        fprintferr("MPQS: z2 = %ld\n", start_2[j] - M_mod_p);
                   1420:        err(talker, "MPQS: self_init: found wrong polynomial in (2)");
                   1421:       }
                   1422:       avma = av;
                   1423:     }
                   1424:     if (DEBUGLEVEL >= 4)
                   1425:       fprintferr("MPQS: checking of roots of Q(x) was successful\n");
                   1426:   }
                   1427: #endif
                   1428:
                   1429: }
                   1430:
                   1431: /******************************/
                   1432:
                   1433: /**
                   1434:  **  Main sieving routine:
                   1435:  **
                   1436:  **  FB     is a pointer to an array which holds the factor base
                   1437:  **  log_FB is a pointer to an array which holds the approximations for
                   1438:  **         the logarithms of the factor base elements
                   1439:  **  start_1, start_2
                   1440:  **         are arrays for starting points for different FB elements
                   1441:  **  sieve_array
                   1442:  **         points to a sieve array
                   1443:  **  sieve_array_end
                   1444:  **         points to the end of the sieve array
                   1445:  **  M      is the size of the sieving interval
                   1446:  **  starting_sieving_index
                   1447:  **         marks the first FB element which is used for sieving
                   1448:  **
                   1449:  **/
                   1450:
                   1451: #ifdef INLINE
                   1452:  INLINE
                   1453: #endif
                   1454: void
                   1455: mpqs_sieve_p(unsigned char *begin, unsigned char *end,
                   1456:              long p_times_4, long p, unsigned char log_p)
                   1457: {
                   1458:   register unsigned char *e = end - p_times_4;
                   1459:   while (e - begin >= 0)       /* signed comparison --GN2000Jun02 */
                   1460:   {
                   1461:     (*begin) += log_p, begin += p;
                   1462:     (*begin) += log_p, begin += p;
                   1463:     (*begin) += log_p, begin += p;
                   1464:     (*begin) += log_p, begin += p;
                   1465:   }
                   1466:   while (end - begin >= 0)     /* again --GN2000Jun02 */
                   1467:     (*begin) += log_p, begin += p;
                   1468: }
                   1469:
                   1470: static void
                   1471: mpqs_sieve(long *FB, unsigned char *log_FB, long *start_1, long *start_2,
                   1472:           unsigned char *sieve_array, unsigned char *sieve_array_end,
                   1473:           ulong M, ulong starting_sieving_index)
                   1474: {
                   1475:   register long p_times_4, p, *ptr_FB, start1, start2, l;
                   1476:   register unsigned char log_p;
                   1477:
                   1478:   memset (sieve_array, 0, (M << 1) * sizeof (unsigned char));
                   1479:
                   1480:   l = starting_sieving_index;
                   1481:   ptr_FB = &FB[l];
                   1482:
                   1483:   while ((p = *ptr_FB++) != 0)
                   1484:   {
                   1485:     p_times_4 = p * 4;
                   1486:     log_p = log_FB[l];
                   1487:     start1 = start_1[l];
                   1488:     start2 = start_2[l];
                   1489:
                   1490:     /* sieve with FB[l] from start_1[l] */
                   1491:     /* if start1 != start2 sieve with FB[l] from start_2[l] */
                   1492:     if (start1 == start2)
                   1493:       mpqs_sieve_p(sieve_array + start1, sieve_array_end,
                   1494:                   p_times_4, p, log_p);
                   1495:     else
                   1496:     {
                   1497:       mpqs_sieve_p(sieve_array + start1, sieve_array_end,
                   1498:                   p_times_4, p, log_p);
                   1499:       mpqs_sieve_p(sieve_array + start2, sieve_array_end,
                   1500:                   p_times_4, p, log_p);
                   1501:     }
                   1502:
                   1503:     l++;
                   1504:   }
                   1505: }
                   1506:
                   1507: /******************************/
                   1508:
                   1509: static long
                   1510: mpqs_eval_sieve(unsigned char *sieve_array, ulong M, long *candidates)
                   1511: {
                   1512:   ulong M_2 = M << 1;
                   1513:   int i = 0, count, q, r;
                   1514:   unsigned char *ptr = sieve_array;
                   1515:
                   1516:   r = M_2 % 4;
                   1517:   q = M_2  - r;
                   1518:   count = 0;
                   1519:   for (i = 0; i < q; i += 4, ptr += 4)
                   1520:   {
                   1521:     if (*(ptr+0) > 128) { candidates[count] = i+0; count++; }
                   1522:     if (*(ptr+1) > 128) { candidates[count] = i+1; count++; }
                   1523:     if (*(ptr+2) > 128) { candidates[count] = i+2; count++; }
                   1524:     if (*(ptr+3) > 128) { candidates[count] = i+3; count++; }
                   1525:   }
                   1526:   switch (r)
                   1527:   {
                   1528:     case 3:
                   1529:       if (*(ptr+0) > 128) { candidates[count] = i+0; count++; }
                   1530:       if (*(ptr+1) > 128) { candidates[count] = i+1; count++; }
                   1531:       if (*(ptr+2) > 128) { candidates[count] = i+2; count++; }
                   1532:       break;
                   1533:     case 2:
                   1534:       if (*(ptr+0) > 128) { candidates[count] = i+0; count++; }
                   1535:       if (*(ptr+1) > 128) { candidates[count] = i+1; count++; }
                   1536:       break;
                   1537:     case 1:
                   1538:       if (*(ptr+0) > 128) { candidates[count] = i+0; count++; }
                   1539:       break;
                   1540:     default:
                   1541:       break;
                   1542:   }
                   1543:   candidates[count] = 0;
                   1544:   return count;
                   1545: }
                   1546:
                   1547: /**
                   1548:  **  Main relation routine:
                   1549:  **
                   1550:  **  FB     is a pointer to an array which holds the factor base
                   1551:  **  log_FB is a pointer to an array which holds the approximations for
                   1552:  **         the logarithms of the factor base elements
                   1553:  **  start_1, start_2
                   1554:  **         are arrays for starting points for different FB elements
                   1555:  **  M      is the size of the sieving interval
                   1556:  **
                   1557:  **/
                   1558:
                   1559: #ifdef INLINE
                   1560: INLINE void
                   1561: mpqs_add_factor(char *s, ulong ei, ulong pi)
                   1562: {
                   1563:   sprintf(s + strlen(s), " %lu %lu", ei, pi);
                   1564: }
                   1565: #else
                   1566: #define mpqs_add_factor(s,ei,pi) \
                   1567:        sprintf(s + strlen(s), " %lu %lu", (ulong)ei, (ulong)pi)
                   1568: #endif
                   1569:
                   1570: /**
                   1571:  ** divide and return the remainder.  Leaves both the quotient and
                   1572:  ** the remainder on the stack as GENs;  the caller should clean up.
                   1573:  **/
                   1574:
                   1575: #ifdef INLINE
                   1576:  INLINE
                   1577: #else
                   1578:  static
                   1579: #endif
                   1580: ulong
                   1581: mpqs_div_rem(GEN x, long y, GEN *q)
                   1582: {
                   1583:   GEN r;
                   1584:   *q = dvmdis(x, y, &r);
                   1585:   if (signe(r)) return (ulong)(r[2]);
                   1586:   return 0;
                   1587: }
                   1588:
                   1589: static long
                   1590: mpqs_eval_candidates(GEN A, GEN inv_A4, GEN B, GEN kN, long k,
                   1591:                     double sqrt_kN,
                   1592:                     long *FB, long *start_1, long *start_2,
                   1593:                     ulong M, long bin_index, long *candidates,
                   1594:                     long number_of_candidates, long lp_bound,
                   1595:                     long start_index_FB_for_A,
                   1596:                     FILE *FREL, FILE *LPREL)
                   1597:      /* NB FREL, LPREL are actually FNEW, LPNEW when we get called */
                   1598: {
                   1599:   GEN Qx, A_2x_plus_B, Y, Qx_div_p;
                   1600:   double a, b, inv_2_a;
1.2     ! noro     1601:   long powers_of_2, p, tmp_p, remd_p, bi;
        !          1602:   gpmem_t av;
1.1       noro     1603:   long z1, z2, x, number_of_relations, x_minus_M;
                   1604:   char *relations;
                   1605:   ulong i, pi, ei, size_of_FB;
                   1606:   int useless_cand;
                   1607: #ifdef MPQS_DEBUG_VERBOSE
                   1608:   static char complaint[256], complaint0[256];
                   1609: #endif
                   1610:
                   1611:   /* FIXME: this is probably right !!! */
                   1612:
                   1613:   /*
                   1614:    * compute the roots of Q(X); this will be used to find the sign of
                   1615:    * Q(x) after reducing mod kN
                   1616:    */
                   1617:
                   1618:   a = gtodouble(A);
                   1619:   inv_2_a = 1 / (2.0 * a);
                   1620:   b = gtodouble(B);
                   1621:   z1 = (long) ((-b - sqrt_kN) * inv_2_a);
                   1622:   z2 = (long) ((-b + sqrt_kN) * inv_2_a);
                   1623:
                   1624:   number_of_relations = 0;
                   1625:   /* FIXME: this is definitely too loooooong ... */
                   1626:   /* then take the size of the FB into account.
                   1627:      We have in the worst case:  a leading " 1 1", a trailing " 0\n" with
                   1628:      the final NUL character, and in between up to size_of_FB pairs each
                   1629:      consisting of an exponent, a subscript into FB, and two spaces.
                   1630:      Moreover, subscripts into FB fit into 5 digits, and exponents fit
                   1631:      into 3 digits with room to spare -- anything needing 3 or more digits
                   1632:      for the subscript must come with an exponent of at most 2 digits.
                   1633:      Moreover the product of the first 58 primes is larger than 10^110,
                   1634:      so there cannot be more than 60 pairs in all, even if size_of_FB > 10^4.
                   1635:      --GN */
                   1636:   size_of_FB = FB[0];          /* one less than usually: don't count FB[1] */
                   1637:   if (size_of_FB > 60) size_of_FB = 60;
                   1638:   relations =
                   1639:     (char *) gpmalloc((8 + size_of_FB * 9) * sizeof(char));
                   1640: #ifdef MPQS_DEBUG_VERBOSE
                   1641:   complaint[0] = '\0';
                   1642: #endif
                   1643: #ifdef MPQS_DEBUG
                   1644:   size_of_FB = FB[0] + 1;      /* last useful subscript into FB */
                   1645: #endif
                   1646:
                   1647:   i = 0;
                   1648:   while (i < (ulong)number_of_candidates)
                   1649:   {
                   1650: #ifdef MPQS_DEBUG_VERYVERBOSE  /* this one really fills the screen... */
                   1651:     fprintferr("%c", (char)('0' + i%10));
                   1652: #endif
                   1653:     x = candidates[i++];
                   1654:     relations[0] = '\0';
                   1655:     av = avma;
                   1656:
                   1657:     /* A_2x_plus_B = (A*(2x)+B), Qx = (A*(2x)+B)^2/(4*A) = Q(x) */
                   1658:     x_minus_M = x - M;
                   1659:     A_2x_plus_B = modii(addii(mulis(A, x_minus_M << 1), B), kN);
                   1660:     Y = subii(kN, A_2x_plus_B);
                   1661:     if (absi_cmp(A_2x_plus_B, Y) < 0) Y = A_2x_plus_B;
                   1662:     /* absolute value of smallest absolute residue of A_2x_plus_B mod kN */
                   1663:
                   1664:     Qx = modii(sqri(Y), kN);
                   1665:
                   1666:     /* Most of the time, gcd(Qx, kN) will be either 1 or k.  However,
                   1667:        it may happen that Qx is a multiple of N, especially when N
                   1668:        is small, and this will lead to havoc below -- so we have to be
                   1669:        a little bit careful.  Of course we cannot possibly afford to
                   1670:        compute the gcd each time through this loop unless we are
                   1671:        debugging... --GN */
                   1672: #ifdef MPQS_DEBUG
                   1673:     {
1.2     ! noro     1674:       long ks;
        !          1675:       gpmem_t av1 = avma;
1.1       noro     1676:       GEN g = mppgcd(Qx, kN);
                   1677: /*      if ((ks = kronecker(divii(Qx, g), divii(kN, g))) != 1) */
                   1678:       if (is_pm1(g))
                   1679:       {
                   1680:        if ((ks = kronecker(Qx, kN)) != 1)
                   1681:        {
                   1682:          fprintferr("\nMPQS: 4*A*Q(x) = %Z\n", Qx);
                   1683:          fprintferr("\tKronecker symbol %ld\n", ks);
                   1684:          err(talker, "MPQS: 4*A*Q(x) is not a square (mod kN)");
                   1685:        }
                   1686:       }
                   1687: #ifdef MPQS_DEBUG_VERBOSE
                   1688:       else if (cmpis(g,k) /* != 0 */ )
                   1689:       {
                   1690:        char *gs = GENtostr(g);
                   1691:        sprintf(complaint, "\nMPQS: gcd(4*A*Q(x), kN) = %s\n", gs);
                   1692:        free(gs);
                   1693:        if (strcmp(complaint, complaint0) != 0)
                   1694:        {
                   1695:          fprintferr(complaint);
                   1696:          strcpy(complaint0, complaint);
                   1697:        }
                   1698:       }
                   1699: #endif
                   1700:       avma = av1;
                   1701:     }
                   1702: #endif
                   1703:
                   1704:     Qx = modii(mulii(Qx, inv_A4), kN);
                   1705:
                   1706:     /* check the sign of Qx */
                   1707:     if (z1 < x_minus_M && x_minus_M < z2)
                   1708:     {
                   1709:        Qx = subii(kN, Qx);
                   1710:        /* i = 1, ei = 1, pi */
                   1711:        mpqs_add_factor(relations, 1, 1);
                   1712:     }
                   1713:     if (!signe(Qx))
                   1714:     {
                   1715: #ifdef MPQS_DEBUG_VERBOSE
                   1716:       fprintferr("<+>");
                   1717: #endif
                   1718:       avma = av;
                   1719:       continue;
                   1720:     }
                   1721:
                   1722:     /* divide by powers of 2;  note that we're really dealing with
                   1723:        4*A*Q(x), so we remember an extra factor 2^2 */
                   1724:     powers_of_2 = vali(Qx);
                   1725:     Qx = shifti(Qx, -powers_of_2);
                   1726:     mpqs_add_factor(relations, powers_of_2 + 2, 2);
                   1727:     if (!signe(Qx))            /* this shouldn't happen */
                   1728:     {
                   1729: #ifdef MPQS_DEBUG_VERBOSE
                   1730:       fprintferr("<*>");
                   1731: #endif
                   1732:       avma = av;
                   1733:       continue;
                   1734:     }
                   1735:
                   1736:     /* we handled the case p = 2 already */
                   1737:     pi = 3;
                   1738:     bi = bin_index;
                   1739:     useless_cand = 0;
                   1740: #ifdef MPQS_DEBUG_VERBOSE
                   1741:     fprintferr("a");
                   1742: #endif
                   1743:
                   1744:     /* FB[3] .. FB[start_index_FB_for_A] do not divide A .
                   1745:      * p = FB[start_index_FB_for_A+j+1] divides A (to the first power)
                   1746:      * iff the 2^j bit in bin_index is set */
                   1747:     while ((p = FB[pi]) != 0 && !useless_cand)
                   1748:     {
                   1749:       tmp_p = x % p;
                   1750:
                   1751:       ei = 0;
                   1752:       if (bi && pi > (ulong)start_index_FB_for_A)
                   1753:       {
                   1754:        ei = bi & 1;    /* either 0 or 1 */
                   1755:        bi >>= 1;
                   1756:       }
                   1757:
                   1758:       if (tmp_p == start_1[pi] || tmp_p == start_2[pi])
                   1759:       {
                   1760:         /* p divides Q(x) and possibly A */
                   1761:         remd_p = mpqs_div_rem(Qx, p, &Qx_div_p);
                   1762:        if (remd_p)
                   1763:        {
                   1764:          useless_cand = 1;
                   1765:          break;
                   1766:        }
                   1767:         do
                   1768:         {
                   1769:          ei++;
                   1770:          Qx = Qx_div_p;
                   1771:          remd_p = mpqs_div_rem(Qx, p, &Qx_div_p);
                   1772:         } while (remd_p == 0);
                   1773:       }
                   1774:       if (ei)                  /* p might divide A but not Q(x) */
                   1775:         mpqs_add_factor(relations, ei, pi);
                   1776:
                   1777:       pi++;
                   1778:     }
                   1779:
                   1780:     if (useless_cand)
                   1781:     {
                   1782: #ifdef MPQS_DEBUG_VERBOSE
                   1783:       fprintferr("\b<");
                   1784: #endif
                   1785:       avma = av;
                   1786:       continue;
                   1787:     }
                   1788: #ifdef MPQS_DEBUG_VERBOSE
                   1789:     fprintferr("\bb");
                   1790: #endif
                   1791:
                   1792:     if (is_pm1(Qx))
                   1793:     {
                   1794:       char *Qxstring = GENtostr(Y);
                   1795:       strcat(relations, " 0");
                   1796:       fprintf(FREL, "%s :%s\n", Qxstring, relations);
                   1797:       number_of_relations++;
                   1798:
                   1799: #ifdef MPQS_DEBUG
                   1800:       {
                   1801:        GEN Qx_2, prod_pi_ei, pi_ei;
                   1802:        long lr = strlen(relations);
                   1803:        char *s, *t = gpmalloc(lr+1);
1.2     ! noro     1804:        long pi, ei;
        !          1805:         gpmem_t av1 = avma;
1.1       noro     1806:
                   1807: #ifdef MPQS_DEBUG_VERBOSE
                   1808:        fprintferr("\b(");
                   1809: #endif
                   1810:        Qx_2 = modii(sqri(Y), kN);
                   1811:        prod_pi_ei = gun;
                   1812:        strcpy(t, relations);
                   1813:        s = strtok(relations, " \n");
                   1814:        while (s != NULL)
                   1815:         {
                   1816:          ei = atol(s);
                   1817:          if (ei == 0) break;
                   1818:          s = strtok(NULL, " \n");
                   1819:          pi = atol(s);
                   1820:          pi_ei = powmodulo(stoi(FB[pi]), stoi(ei), kN);
                   1821:          prod_pi_ei = modii(mulii(prod_pi_ei, pi_ei), kN);
                   1822:          s = strtok(NULL, " \n");
                   1823:        }
                   1824:
                   1825:        if (!egalii(Qx_2, prod_pi_ei))
                   1826:        {
                   1827: #ifdef MPQS_DEBUG_VERBOSE
                   1828:          fprintferr("!)\n");
                   1829: #endif
                   1830:          fprintferr("MPQS: %s :%s\n", Qxstring, t);
                   1831:          fprintferr("\tQx_2 = %Z\n", Qx_2);
                   1832:          fprintferr("\t rhs = %Z\n", prod_pi_ei);
                   1833:          err(talker, "MPQS: wrong full relation found!!");
                   1834:        }
                   1835: #ifdef MPQS_DEBUG_VERBOSE
                   1836:        else
                   1837:          fprintferr(":)");
                   1838: #endif
                   1839:        avma = av1;
                   1840:        free(t);
                   1841:       }
                   1842: #endif
                   1843:
                   1844:       free(Qxstring);
                   1845:     }
                   1846:     else if (cmpis(Qx, lp_bound) > 0)
                   1847:     {
                   1848:       /* TO BE DONE: check for double large prime */
                   1849:       /* moved this else clause here where I think it belongs -- GN */
                   1850: #ifdef MPQS_DEBUG_VERBOSE
                   1851:       fprintferr("\b.");
                   1852: #endif
                   1853:     }
                   1854:     else if (k==1 || cgcd(k, itos(Qx)) == 1)
                   1855:     {
                   1856:       /* if (mpqs_isprime(itos(Qx))) */
                   1857:       char *Qxstring = GENtostr(Y);
                   1858:       char *L1string = GENtostr(Qx);
                   1859:       strcat(relations, " 0");
                   1860:       fprintf(LPREL, "%s @ %s :%s\n", L1string, Qxstring, relations);
                   1861:
                   1862: #ifdef MPQS_DEBUG
                   1863:       {
                   1864:        GEN Qx_2, prod_pi_ei, pi_ei;
                   1865:        long lr = strlen(relations);
                   1866:        char *s, *t = gpmalloc(lr+1);
1.2     ! noro     1867:        long pi, ei;
        !          1868:         gpmem_t av1 = avma;
1.1       noro     1869:
                   1870: #ifdef MPQS_DEBUG_VERBOSE
                   1871:        fprintferr("\b(");
                   1872: #endif
                   1873:        Qx_2 = modii(sqri(Y), kN);
                   1874:        prod_pi_ei = gun;
                   1875:        strcpy(t, relations);
                   1876:        s = strtok(relations, " \n");
                   1877:        while (s != NULL)
                   1878:         {
                   1879:          ei = atol(s);
                   1880:          if (ei == 0) break;
                   1881:          s = strtok(NULL, " \n");
                   1882:          pi = atol(s);
                   1883:          pi_ei = powmodulo(stoi(FB[pi]), stoi(ei), kN);
                   1884:          prod_pi_ei = modii(mulii(prod_pi_ei, pi_ei), kN);
                   1885:          s = strtok(NULL, " \n");
                   1886:        }
                   1887:        prod_pi_ei = modii(mulii(prod_pi_ei, Qx), kN);
                   1888:
                   1889:        if (!egalii(Qx_2, prod_pi_ei))
                   1890:        {
                   1891: #ifdef MPQS_DEBUG_VERBOSE
                   1892:          fprintferr("!)\n");
                   1893: #endif
                   1894:          fprintferr("MPQS: %s @ %s :%s\n",
                   1895:                     L1string, Qxstring, t);
                   1896:          fprintferr("\tQx_2 = %Z\n", Qx_2);
                   1897:          fprintferr("\t rhs = %Z\n", prod_pi_ei);
                   1898:          err(talker, "MPQS: wrong large prime relation found!!");
                   1899:        }
                   1900: #ifdef MPQS_DEBUG_VERBOSE
                   1901:        else
                   1902:          fprintferr(";)");
                   1903: #endif
                   1904:        avma = av1;
                   1905:        free(t);
                   1906:       }
                   1907: #endif
                   1908:
                   1909:       free(Qxstring);
                   1910:       free(L1string);
                   1911:     }
                   1912: #ifdef MPQS_DEBUG_VERBOSE
                   1913:     else
                   1914:       fprintferr("\b<k>");
                   1915: #endif
                   1916:
                   1917:     avma = av;
                   1918:   } /* while */
                   1919:
                   1920: #ifdef MPQS_DEBUG_VERBOSE
                   1921:   fprintferr("\n");
                   1922: #endif
                   1923:
                   1924:   free(relations);
                   1925:   return number_of_relations;
                   1926: }
                   1927:
                   1928: /******************************/
                   1929:
                   1930: /**
                   1931:  ** combines the large prime relations in COMB to full
                   1932:  ** relations in FNEW.  FNEW is assumed to be open for
                   1933:  ** writing / appending.
                   1934:  **/
                   1935:
                   1936: typedef struct
                   1937: {
                   1938:   long q;
                   1939:   char Y  [MPQS_STRING_LENGTH];
                   1940:   char ep [MPQS_STRING_LENGTH];
                   1941: } mpqs_lp_entry;
                   1942:
                   1943: static void
                   1944: mpqs_combine_exponents(long *ei, long ei_size, char *r1, char *r2)
                   1945: {
                   1946:   char ej [MPQS_STRING_LENGTH], ek [MPQS_STRING_LENGTH];
                   1947:   char *s;
                   1948:   long e, p;
                   1949:
                   1950:   memset(ei, 0, ei_size * sizeof(long));
                   1951:   strcpy(ej, r1);
                   1952:   strcpy(ek, r2);
                   1953:
                   1954:   s = strtok(ej, " \n");
                   1955:   while (s != NULL)
                   1956:   {
                   1957:     e = atol(s);
                   1958:     if (e == 0)
                   1959:       break;
                   1960:     s = strtok(NULL, " \n");
                   1961:     p = atol(s);
                   1962:     ei[p] += e;
                   1963:     s = strtok(NULL, " \n");
                   1964:   }
                   1965:
                   1966:   s = strtok(ek, " \n");
                   1967:   while (s != NULL)
                   1968:   {
                   1969:     e = atol(s);
                   1970:     if (e == 0)
                   1971:       break;
                   1972:     s = strtok(NULL, " \n");
                   1973:     p = atol(s);
                   1974:     ei[p] += e;
                   1975:     s = strtok(NULL, " \n");
                   1976:   }
                   1977:
                   1978: }
                   1979:
                   1980: static long
                   1981: mpqs_combine_large_primes(FILE *COMB, FILE *FNEW, long size_of_FB,
                   1982:                          GEN N, GEN kN, GEN *f
                   1983: #ifdef MPQS_DEBUG
                   1984:   , long *FB
                   1985: #endif
                   1986: )
                   1987: {
                   1988:   char buf [MPQS_STRING_LENGTH], *s1, *s2;
                   1989:   char new_relation [MPQS_STRING_LENGTH];
                   1990:   mpqs_lp_entry e[2];          /* we'll use the two alternatingly */
                   1991:   long *ei, ei_size = size_of_FB + 2;
                   1992:   long old_q;
                   1993:   GEN inv_q, Y1, Y2, new_Y, new_Y1;
                   1994:   long i, l, c = 0;
1.2     ! noro     1995:   gpmem_t av = avma, av2;
1.1       noro     1996:
                   1997:   *f = NULL;
                   1998:   if (fgets(buf, MPQS_STRING_LENGTH, COMB) == NULL)
                   1999:     return 0;                  /* nothing there -- should not happen */
                   2000:
                   2001:   /* put first lp relation in row 0 of e */
                   2002:   s1 = buf; s2 = strchr(s1, ' '); *s2 = '\0';
                   2003:   e[0].q = atol(s1);
                   2004:   s1 = s2 + 3; s2 = strchr(s1, ' '); *s2 = '\0';
                   2005:   strcpy(e[0].Y, s1);
                   2006:   s1 = s2 + 3;  s2 = strchr(s1, '\n'); *s2 = '\0';
                   2007:   strcpy(e[0].ep, s1);
                   2008:
                   2009:   i = 1;                       /* second relation will go into row 1 */
                   2010:   old_q = e[0].q;
                   2011:
                   2012:   while (!invmod(stoi(old_q), kN, &inv_q)) /* can happen --GN */
                   2013:   {
                   2014:     inv_q = mppgcd(inv_q, N);
                   2015:     if (is_pm1(inv_q) || egalii(inv_q, N)) /* pity */
                   2016:     {
                   2017: #ifdef MPQS_DEBUG
                   2018:       fprintferr("MPQS: skipping relation with non-invertible q\n");
                   2019: #endif
                   2020:       avma = av;
                   2021:       if (fgets(buf, MPQS_STRING_LENGTH, COMB) == NULL)
                   2022:        return 0;
                   2023:       s1 = buf; s2 = strchr(s1, ' '); *s2 = '\0';
                   2024:       e[0].q = atol(s1);
                   2025:       s1 = s2 + 3; s2 = strchr(s1, ' '); *s2 = '\0';
                   2026:       strcpy(e[0].Y, s1);
                   2027:       s1 = s2 + 3;  s2 = strchr(s1, '\n'); *s2 = '\0';
                   2028:       strcpy(e[0].ep, s1);
                   2029:       old_q = e[0].q;
                   2030:       continue;
                   2031:     }
                   2032:     *f = gerepileupto(av, inv_q);
                   2033:     return c;
                   2034:   }
                   2035:   Y1 = lisexpr(e[0].Y);
                   2036:   av2 = avma;                  /* preserve inv_q and Y1 */
                   2037:
                   2038:   ei = (long *) gpmalloc(ei_size * sizeof(long));
                   2039:
                   2040:   while (fgets(buf, MPQS_STRING_LENGTH, COMB) != NULL)
                   2041:   {
                   2042:     s1 = buf; s2 = strchr(s1, ' '); *s2 = '\0';
                   2043:     e[i].q = atol(s1);
                   2044:     s1 = s2 + 3; s2 = strchr(s1, ' '); *s2 = '\0';
                   2045:     strcpy(e[i].Y, s1);
                   2046:     s1 = s2 + 3;  s2 = strchr(s1, '\n'); *s2 = '\0';
                   2047:     strcpy(e[i].ep, s1);
                   2048:
                   2049:     if (e[i].q != old_q)
                   2050:     {
                   2051:       /* switch to combining a new bunch, swapping the rows */
                   2052:       old_q = e[i].q;
                   2053:       avma = av;               /* discard old inv_q and Y1 */
                   2054:       if (!invmod(stoi(old_q), kN, &inv_q)) /* can happen --GN */
                   2055:       {
                   2056:        inv_q = mppgcd(inv_q, N);
                   2057:        if (is_pm1(inv_q) || egalii(inv_q, N)) /* pity */
                   2058:        {
                   2059: #ifdef MPQS_DEBUG
                   2060:          fprintferr("MPQS: skipping relation with non-invertible q\n");
                   2061: #endif
                   2062:          avma = av;
                   2063:          old_q = -1;           /* sentinel */
                   2064:          av2 = avma;
                   2065:          continue;             /* discard this combination */
                   2066:        }
                   2067:        *f = gerepileupto(av, inv_q);
                   2068:        free (ei);
                   2069:        return c;
                   2070:       }
                   2071:       Y1 = lisexpr(e[i].Y);
                   2072:       i = 1 - i;               /* subsequent relations go to other row */
                   2073:       av2 = avma;              /* preserve inv_q and Y1 */
                   2074:       continue;
                   2075:     }
                   2076:     /* count and combine the two we've got, and continue in the same row */
                   2077:     c++;
                   2078:
                   2079:     mpqs_combine_exponents(ei, ei_size, e[1-i].ep, e[i].ep);
                   2080:     if (DEBUGLEVEL >= 6)
                   2081:     {
                   2082:       fprintferr("MPQS: combining\n");
                   2083:       fprintferr("    {%ld @ %s : %s}\n", old_q, e[1-i].Y, e[1-i].ep);
                   2084:       fprintferr("  * {%ld @ %s : %s}\n", e[i].q, e[i].Y, e[i].ep);
                   2085:     }
                   2086:     Y2 = lisexpr(e[i].Y);
                   2087:     new_Y = modii(mulii(mulii(Y1, Y2), inv_q), kN);
                   2088:     new_Y1 = subii(kN, new_Y);
                   2089:     if (absi_cmp(new_Y1, new_Y) < 0) new_Y = new_Y1;
                   2090:     s1 = GENtostr(new_Y);
                   2091:     strcpy(new_relation, s1);
                   2092:     free(s1);
                   2093:     strcat(new_relation, " :");
                   2094:     if (ei[1] % 2)
                   2095:       strcat(new_relation, " 1 1");
                   2096:     for (l = 2; l < ei_size; l++)
                   2097:     {
                   2098:       if (ei[l])
                   2099:       {
                   2100:        sprintf(buf, " %ld %ld", ei[l], l);
                   2101:        strcat(new_relation, buf);
                   2102:       }
                   2103:     }
                   2104:     strcat(new_relation, " 0");
                   2105:     if (DEBUGLEVEL >= 6) fprintferr(" == {%s}\n", new_relation);
                   2106:     strcat(new_relation, "\n");
                   2107:
                   2108: #ifdef MPQS_DEBUG
                   2109:     {
                   2110:       char ejk [MPQS_STRING_LENGTH];
                   2111:       GEN Qx_2, prod_pi_ei, pi_ei;
                   2112:       char *s;
1.2     ! noro     2113:       long pi, exi;
        !          2114:       gpmem_t av1 = avma;
1.1       noro     2115:       Qx_2 = modii(sqri(new_Y), kN);
                   2116:
                   2117:       strcpy(ejk, new_relation);
                   2118:       s = strchr(ejk, ':') + 2;
                   2119:       s = strtok(s, " \n");
                   2120:
                   2121:       prod_pi_ei = gun;
                   2122:       while (s != NULL)
                   2123:       {
                   2124:        exi = atol(s);
                   2125:        if (exi == 0) break;
                   2126:        s = strtok(NULL, " \n");
                   2127:        pi = atol(s);
                   2128:        pi_ei = powmodulo(stoi(FB[pi]), stoi(exi), kN);
                   2129:        prod_pi_ei = modii(mulii(prod_pi_ei, pi_ei), kN);
                   2130:        s = strtok(NULL, " \n");
                   2131:       }
                   2132:       avma = av1;
                   2133:
                   2134:       if (!egalii(Qx_2, prod_pi_ei))
                   2135:       {
                   2136:        free(ei);
                   2137:        err(talker,
                   2138:            "MPQS: combined large prime relation is false");
                   2139:       }
                   2140:     }
                   2141: #endif
                   2142:
                   2143:     if (fputs(new_relation, FNEW) < 0)
                   2144:     {
                   2145:       free(ei);
                   2146:       bummer(FNEW_str);
                   2147:     }
                   2148:     avma = av2;
                   2149:   } /* while */
                   2150:
                   2151:   free(ei);
                   2152:
                   2153:   if (DEBUGLEVEL >= 4)
                   2154:     fprintferr("MPQS: combined %ld full relation%s\n",
                   2155:               c, (c!=1 ? "s" : ""));
                   2156:   return c;
                   2157: }
                   2158:
                   2159: /******************************/
                   2160:
                   2161: #ifdef LONG_IS_64BIT
                   2162:
                   2163: #define MPQS_GAUSS_BITS 64
                   2164: static unsigned long mpqs_mask_bit[]  =
                   2165: {
                   2166:   0x8000000000000000UL, 0x4000000000000000UL,
                   2167:   0x2000000000000000UL, 0x1000000000000000UL,
                   2168:   0x0800000000000000UL, 0x0400000000000000UL,
                   2169:   0x0200000000000000UL, 0x0100000000000000UL,
                   2170:   0x0080000000000000UL, 0x0040000000000000UL,
                   2171:   0x0020000000000000UL, 0x0010000000000000UL,
                   2172:   0x0008000000000000UL, 0x0004000000000000UL,
                   2173:   0x0002000000000000UL, 0x0001000000000000UL,
                   2174:   0x0000800000000000UL, 0x0000400000000000UL,
                   2175:   0x0000200000000000UL, 0x0000100000000000UL,
                   2176:   0x0000080000000000UL, 0x0000040000000000UL,
                   2177:   0x0000020000000000UL, 0x0000010000000000UL,
                   2178:   0x0000008000000000UL, 0x0000004000000000UL,
                   2179:   0x0000002000000000UL, 0x0000001000000000UL,
                   2180:   0x0000000800000000UL, 0x0000000400000000UL,
                   2181:   0x0000000200000000UL, 0x0000000100000000UL,
                   2182:   0x0000000080000000UL, 0x0000000040000000UL,
                   2183:   0x0000000020000000UL, 0x0000000010000000UL,
                   2184:   0x0000000008000000UL, 0x0000000004000000UL,
                   2185:   0x0000000002000000UL, 0x0000000001000000UL,
                   2186:   0x0000000000800000UL, 0x0000000000400000UL,
                   2187:   0x0000000000200000UL, 0x0000000000100000UL,
                   2188:   0x0000000000080000UL, 0x0000000000040000UL,
                   2189:   0x0000000000020000UL, 0x0000000000010000UL,
                   2190:   0x0000000000008000UL, 0x0000000000004000UL,
                   2191:   0x0000000000002000UL, 0x0000000000001000UL,
                   2192:   0x0000000000000800UL, 0x0000000000000400UL,
                   2193:   0x0000000000000200UL, 0x0000000000000100UL,
                   2194:   0x0000000000000080UL, 0x0000000000000040UL,
                   2195:   0x0000000000000020UL, 0x0000000000000010UL,
                   2196:   0x0000000000000008UL, 0x0000000000000004UL,
                   2197:   0x0000000000000002UL, 0x0000000000000001UL
                   2198: };
                   2199:
                   2200: #else
                   2201:
                   2202: #define MPQS_GAUSS_BITS 32
                   2203: static unsigned long mpqs_mask_bit[]  =
                   2204: {
                   2205:   0x80000000UL, 0x40000000UL, 0x20000000UL, 0x10000000UL,
                   2206:   0x08000000UL, 0x04000000UL, 0x02000000UL, 0x01000000UL,
                   2207:   0x00800000UL, 0x00400000UL, 0x00200000UL, 0x00100000UL,
                   2208:   0x00080000UL, 0x00040000UL, 0x00020000UL, 0x00010000UL,
                   2209:   0x00008000UL, 0x00004000UL, 0x00002000UL, 0x00001000UL,
                   2210:   0x00000800UL, 0x00000400UL, 0x00000200UL, 0x00000100UL,
                   2211:   0x00000080UL, 0x00000040UL, 0x00000020UL, 0x00000010UL,
                   2212:   0x00000008UL, 0x00000004UL, 0x00000002UL, 0x00000001UL
                   2213: };
                   2214:
                   2215: #endif
                   2216:
                   2217: static mpqs_gauss_matrix
                   2218: mpqs_gauss_create_matrix(long rows, long cols)
                   2219: {
                   2220:   mpqs_gauss_matrix m;
                   2221:   long i, j, words = cols / MPQS_GAUSS_BITS;
                   2222:   if (cols % MPQS_GAUSS_BITS)
                   2223:     words++;
                   2224:   m = (mpqs_gauss_row *) gpmalloc(rows * sizeof(mpqs_gauss_row));
                   2225:   for (i = 0; i < rows; i++)
                   2226:   {
                   2227:     m[i] = (ulong *) gpmalloc(words * sizeof(ulong));
                   2228:     for (j = 0; j < words; j++)
                   2229:       m[i][j] = 0UL;
                   2230:   }
                   2231:   return m;
                   2232: }
                   2233:
                   2234: static void
                   2235: mpqs_gauss_destroy_matrix(mpqs_gauss_matrix m, long rows, long cols)
                   2236: {
                   2237:   long i;
                   2238:   (void) cols;
                   2239:   for (i = 0; i < rows; i++)
                   2240:     free(m[i]);
                   2241:   free(m);
                   2242: }
                   2243:
                   2244: static ulong
                   2245: mpqs_gauss_get_bit(mpqs_gauss_matrix m, long i, long j)
                   2246: {
                   2247:   return m[i][j / MPQS_GAUSS_BITS] & mpqs_mask_bit[j % MPQS_GAUSS_BITS];
                   2248: }
                   2249:
                   2250: static void
                   2251: mpqs_gauss_set_bit(mpqs_gauss_matrix m, long i, long j)
                   2252: {
                   2253:   m[i][j / MPQS_GAUSS_BITS] |= mpqs_mask_bit[j % MPQS_GAUSS_BITS];
                   2254: }
                   2255:
                   2256: static void
                   2257: mpqs_gauss_clear_bit(mpqs_gauss_matrix m, long i, long j)
                   2258: {
                   2259:   m[i][j / MPQS_GAUSS_BITS] &= ~mpqs_mask_bit[j % MPQS_GAUSS_BITS];
                   2260: }
                   2261:
                   2262: /* output an mpqs_gauss_matrix in PARI format */
                   2263: /* TODO -- this should do a little intelligent wrapping... GN */
                   2264: static void
                   2265: mpqs_gauss_print_matrix(mpqs_gauss_matrix m, long rows, long cols)
                   2266: {
                   2267:   long i, j;
                   2268:   fprintferr("\n[");
                   2269:   for (i = 0; i < rows; i++)
                   2270:   {
                   2271:     for (j = 0; j < cols - 1; j++)
                   2272:     {
                   2273:       if (mpqs_gauss_get_bit(m, i, j))
                   2274:         fprintferr("1, ");
                   2275:       else
                   2276:         fprintferr("0, ");
                   2277:     }
                   2278:
                   2279:     if (mpqs_gauss_get_bit(m, i, j))
                   2280:       fprintferr("1");
                   2281:     else
                   2282:       fprintferr("0");
                   2283:     if (i != rows - 1)
                   2284:       fprintferr("; ");
                   2285:   }
                   2286:   fprintferr("]\n");
                   2287: }
                   2288:
                   2289: /* x ^= y : row addition over F_2 */
                   2290: static void
                   2291: mpqs_gauss_add_rows(mpqs_gauss_row y, mpqs_gauss_row x, long k, long n)
                   2292: {
                   2293:   long i, q, r;
                   2294:   n = n - k;
                   2295:   r = n % 8; q = n - r + k; i = 0 + k;
                   2296:   for (; i < q; i += 8)
                   2297:   {
                   2298:     x[0+i] ^= y[0+i]; x[1+i] ^= y[1+i];
                   2299:     x[2+i] ^= y[2+i]; x[3+i] ^= y[3+i];
                   2300:     x[4+i] ^= y[4+i]; x[5+i] ^= y[5+i];
                   2301:     x[6+i] ^= y[6+i]; x[7+i] ^= y[7+i];
                   2302:   }
                   2303:   switch (r)
                   2304:   {
                   2305:     case 7: x[i] ^= y[i], i++;
                   2306:     case 6: x[i] ^= y[i], i++;
                   2307:     case 5: x[i] ^= y[i], i++;
                   2308:     case 4: x[i] ^= y[i], i++;
                   2309:     case 3: x[i] ^= y[i], i++;
                   2310:     case 2: x[i] ^= y[i], i++;
                   2311:     case 1: x[i] ^= y[i], i++;
                   2312:     default: ;
                   2313:   }
                   2314: }
                   2315:
                   2316: /* create and read an mpqs_gauss_matrix from a relation file FREL (opened
                   2317:    by caller).  Also record the position of each relation in the file for
                   2318:    later use
                   2319:    rows = size_of_FB+1, cols = rel */
                   2320: static mpqs_gauss_matrix
                   2321: mpqs_gauss_read_matrix(FILE *FREL, long rows, long cols, long *fpos)
                   2322: {
                   2323:   mpqs_gauss_matrix m;
                   2324:   long i = 0, e, p;
                   2325:   char buf[MPQS_STRING_LENGTH], *s;
                   2326:
                   2327:   m = mpqs_gauss_create_matrix(rows, cols);
                   2328:   if ((fpos[0] = ftell(FREL)) < 0)
                   2329:     err(talker, "ftell error on full relations file");
                   2330:   while (fgets(buf, MPQS_STRING_LENGTH, FREL) != NULL)
                   2331:   {
                   2332:     s = strchr(buf, ':') + 2;
                   2333:     s = strtok(s, " \n");
                   2334:     while (s != NULL)
                   2335:     {
                   2336:       e = atol(s);
                   2337:       if (e == 0)
                   2338:        break;
                   2339:       s = strtok(NULL, " \n");
                   2340:       p = atol(s);
                   2341:       if (e & 1)
                   2342:        mpqs_gauss_set_bit(m, p - 1, i);
                   2343:       s = strtok(NULL, " \n");
                   2344:     }
                   2345:     i++;
                   2346:     if (i < cols && (fpos[i] = ftell(FREL)) < 0)
                   2347:       err(talker, "ftell error on full relations file");
                   2348:   }
                   2349:   if (i != cols)
                   2350:   {
                   2351:     fprintferr("MPQS: full relations file %s than expected",
                   2352:               i > cols ? "longer" : "shorter");
                   2353:     err(talker, "MPQS panicking");
                   2354:   }
                   2355:   return m;
                   2356: }
                   2357:
                   2358: /* compute the kernel of an mpqs_gauss_matrix over F_2
                   2359:    uses the algorithm described by Knuth, Vol. 2 as modified by Henri Cohen
                   2360:    and optimized by Christian Batut, Thomas Papanikolaou and Xavier Roblot.
                   2361:    m = rows, n = cols */
                   2362: static mpqs_gauss_matrix
                   2363: mpqs_kernel(mpqs_gauss_matrix x, long m, long n, long *rank)
                   2364: {
                   2365:   long k, i, j, t, r;
                   2366:   mpqs_gauss_matrix ker_x;
                   2367:   mpqs_gauss_indices c, d;
                   2368:   long words = n / MPQS_GAUSS_BITS;
                   2369:   if (n % MPQS_GAUSS_BITS)
                   2370:     words++;
                   2371:
                   2372:   c = (long *) gpmalloc(m * sizeof(long));
                   2373:   for (k = 0; k < m; k++) c[k] = -1;
                   2374:
                   2375:   d = (long *) gpmalloc(n * sizeof(long));
                   2376:   r = 0;
                   2377:
                   2378:   for (k = 0; k < n; k++)
                   2379:   {
                   2380:     j = 0;
                   2381:     while (j < m && (c[j] >= 0 || mpqs_gauss_get_bit(x, j, k) == 0))
                   2382:       j++;
                   2383:
                   2384:     if (j == m)
                   2385:     {
                   2386:       d[k] = -1; /* no pivot found in column k */
                   2387:       r++;       /* column k is a vector of the kernel */
                   2388:     }
                   2389:     else
                   2390:     {
                   2391:       d[k] = j; /* the pivot in column k is at row j */
                   2392:       c[j] = k; /* a pivot at position j was found in column k */
                   2393:       for (t = 0; t < m; t++)
                   2394:       {
                   2395:        if (t != j)
                   2396:        {
                   2397:          if (mpqs_gauss_get_bit(x, t, k))
                   2398:            mpqs_gauss_add_rows(x[j], x[t], k / MPQS_GAUSS_BITS, words);
                   2399:         }
                   2400:       }
                   2401:     }
                   2402:   }
                   2403:
                   2404:   ker_x = mpqs_gauss_create_matrix(n, r);
                   2405:
                   2406:   for (j = k = 0; j < r; j++, k++)
                   2407:   {
                   2408:     while (d[k] != -1) k++;
                   2409:     for (i = 0; i < k; i++)
                   2410:     {
                   2411:       if (d[i] != -1)
                   2412:       {
                   2413:        if (mpqs_gauss_get_bit(x, d[i], k))
                   2414:          mpqs_gauss_set_bit(ker_x, i, j);
                   2415:        else
                   2416:          mpqs_gauss_clear_bit(ker_x, i, j);
                   2417:       }
                   2418:       else
                   2419:        mpqs_gauss_clear_bit(ker_x, i, j);
                   2420:     }
                   2421:     mpqs_gauss_set_bit(ker_x, k, j);
                   2422:   }
                   2423:
                   2424:   free(c);
                   2425:   free(d);
                   2426:
                   2427:   *rank = r;
                   2428:   return ker_x;
                   2429: }
                   2430:
                   2431: /******************************/
                   2432:
                   2433: static GEN
                   2434: mpqs_add_relation(GEN Y_prod, GEN N_or_kN, long *ei, char *r1)
                   2435: {
                   2436:   GEN Y, res;
                   2437:   char relation [MPQS_STRING_LENGTH];
                   2438:   char *s;
1.2     ! noro     2439:   long e, p;
        !          2440:   gpmem_t av = avma;
1.1       noro     2441:
                   2442:   strcpy(relation, r1);
                   2443:   s = strchr(relation, ':') - 1;
                   2444:   *s = '\0';
                   2445:   Y = lisexpr(relation);
                   2446:   res = modii(mulii(Y_prod, Y), N_or_kN);
                   2447:
                   2448:   s = s + 3;
                   2449:   s = strtok(s, " \n");
                   2450:   while (s != NULL)
                   2451:   {
                   2452:     e = atol(s);
                   2453:     if (e == 0)
                   2454:       break;
                   2455:     s = strtok(NULL, " \n");
                   2456:     p = atol(s);
                   2457:     ei[p] += e;
                   2458:     s = strtok(NULL, " \n");
                   2459:   }
                   2460:   return gerepileupto(av,res);
                   2461: }
                   2462:
                   2463: static char*
                   2464: mpqs_get_relation(long pos, FILE *FREL)
                   2465: {
                   2466:   static char buf [MPQS_STRING_LENGTH];
                   2467:   if (fseek(FREL, pos, SEEK_SET))
                   2468:     err(talker, "can\'t seek full relations file");
                   2469:   if (fgets(buf, MPQS_STRING_LENGTH, FREL) == NULL)
                   2470:     err(talker, "full relations file truncated?!");
                   2471:   return buf;
                   2472: }
                   2473:
                   2474: /* the following two reside in src/basemath/ifactor1.c */
1.2     ! noro     2475: extern long is_odd_power(GEN x, GEN *pt, long *mask);
        !          2476: extern int miller(GEN n, long k);
1.1       noro     2477:
                   2478: #define isprobableprime(n) (miller((n),17))
                   2479:
                   2480: static GEN
                   2481: mpqs_solve_linear_system(GEN kN, GEN N, long rel, long *FB, long size_of_FB)
                   2482: {
                   2483:   pariFILE *pFREL;
                   2484:   FILE *FREL;
                   2485:   GEN X, Y_prod, N_or_kN, D1, base, res, new_res;
1.2     ! noro     2486:   gpmem_t av=avma, av2, av3, lim, lim3, tetpil;
1.1       noro     2487:   long *fpos, *ei;
                   2488:   long i, j, H_cols, H_rows;
                   2489:   long res_last, res_next, res_size, res_max;
                   2490:   mpqs_gauss_matrix m, ker_m;
                   2491:   long done, flag, mask, rank;
                   2492:
                   2493: #ifdef MPQS_DEBUG
                   2494:   N_or_kN = kN;
                   2495: #else
                   2496:   N_or_kN = (DEBUGLEVEL >= 4 ? kN : N);
                   2497: #endif /* --GN */
                   2498:   pFREL = pari_fopen(FREL_str, READ);
                   2499:   FREL = pFREL->file;
                   2500:   fpos = (long *) gpmalloc(rel * sizeof(long));
                   2501:
                   2502:   m = mpqs_gauss_read_matrix(FREL, size_of_FB+1, rel, fpos);
                   2503:   if (DEBUGLEVEL >= 7)
                   2504:   {
                   2505:     fprintferr("\\\\ MATRIX READ BY MPQS\nFREL=");
                   2506:     mpqs_gauss_print_matrix(m, size_of_FB+1, rel);
                   2507:     fprintferr("\n");
                   2508:   }
                   2509:
                   2510:   ker_m = mpqs_kernel(m, size_of_FB+1, rel, &rank);
                   2511:   if (DEBUGLEVEL >= 4)
                   2512:   {
                   2513:     if (DEBUGLEVEL >= 7)
                   2514:     {
                   2515:       fprintferr("\\\\ KERNEL COMPUTED BY MPQS\nKERNEL=");
                   2516:       mpqs_gauss_print_matrix(ker_m, rel, rank);
                   2517:       fprintferr("\n");
                   2518:     }
                   2519:     /* put this here where the poor user has a chance of seeing it: */
                   2520:     fprintferr("MPQS: Gauss done: kernel has rank %ld, taking gcds...\n",
                   2521:               rank);
                   2522:   }
                   2523:
                   2524:   H_rows = rel;
                   2525:   H_cols = rank;
                   2526:
                   2527:   /* If the computed kernel turns out to be trivial, fail gracefully;
                   2528:      main loop may try to find some more relations --GN */
                   2529:   if (H_cols == 0)
                   2530:   {
                   2531:     if (DEBUGLEVEL >= 3)
                   2532:       err(warner, "MPQS: no solutions found from linear system solver");
                   2533:     /* ei has not yet been allocated */
                   2534:     mpqs_gauss_destroy_matrix(m, size_of_FB+1, rel);
                   2535:     mpqs_gauss_destroy_matrix(ker_m, rel, rank);
                   2536:     free(fpos);
                   2537:     pari_fclose(pFREL);
                   2538:     avma = av;
                   2539:     return NULL; /* no factors found */
                   2540:   }
                   2541:
                   2542:   /* If the rank is r, we can expect up to 2^r pairwise coprime factors,
                   2543:      but it may well happen that a kernel basis vector contributes nothing
                   2544:      new to the decomposition.  We will allocate room for up to eight factors
                   2545:      initially  (certainly adequate when one or two basis vectors work),
                   2546:      adjusting this down at the end to what we actually found, or up if
                   2547:      we are very lucky and find more factors.  In the upper half of our
                   2548:      vector, we store information about which factors we know to be composite
                   2549:      (zero) or believe to be composite ((long)NULL which is just 0) or suspect
                   2550:      to be prime (un), or an exponent (deux or some t_INT) if it is a proper
                   2551:      power */
                   2552:   av2 = avma; lim = stack_lim(av2,1);
                   2553:   if (rank > BITS_IN_LONG - 2)
                   2554:     res_max = VERYBIGINT;      /* this, unfortunately, is the common case */
                   2555:   else
                   2556:     res_max = 1L<<rank;                /* max number of factors we can hope for */
                   2557:   res_size = 8;                        /* no. of factors we can store in this res */
                   2558:   res = cgetg(2*res_size+1, t_VEC);
                   2559:   for (i=2*res_size; i; i--) res[i] = 0;
                   2560:   res_next = res_last = 1;
                   2561:
                   2562:   ei = (long *) gpmalloc((size_of_FB + 2) * sizeof(long));
                   2563:
                   2564:   for (i = 0; i < H_cols; i++) /* loop over basis of kernel */
                   2565:   {
                   2566:     X = Y_prod = gun;
                   2567:     memset(ei, 0, (size_of_FB + 2) * sizeof(long));
                   2568:
                   2569:     av3 = avma; lim3 = stack_lim(av3,1);
                   2570:     for (j = 0; j < H_rows; j++)
                   2571:     {
                   2572:       if (mpqs_gauss_get_bit(ker_m, j, i))
                   2573:        Y_prod = mpqs_add_relation(Y_prod, N_or_kN, ei,
                   2574:                                   mpqs_get_relation(fpos[j], FREL));
                   2575:       if (low_stack(lim3, stack_lim(av3,1)))
                   2576:       {
                   2577:        if(DEBUGMEM>1) err(warnmem,"[1]: mpqs_solve_linear_system");
                   2578:        Y_prod = gerepileupto(av3, Y_prod);
                   2579:       }
                   2580:     }
                   2581:     Y_prod = gerepileupto(av3, Y_prod);        /* unconditionally */
                   2582:
                   2583:     av3 = avma; lim3 = stack_lim(av3,1);
                   2584:     for (j = 2; j <= (size_of_FB + 1); j++)
                   2585:     {
                   2586:       if (ei[j] & 1)
                   2587:       {                                /* this cannot happen --GN */
                   2588:        mpqs_gauss_destroy_matrix(m, size_of_FB+1, rel);
                   2589:        mpqs_gauss_destroy_matrix(ker_m, rel, rank);
                   2590:        free(ei); free(fpos);
                   2591:        fprintferr("MPQS: the combination of the relations is a nonsquare\n");
                   2592:        err(bugparier, "factoring (MPQS)");
                   2593:       }
                   2594:       if (ei[j])
                   2595:       {
                   2596:        X = modii(mulii(X, powmodulo(stoi(FB[j]), stoi(ei[j]>>1), N_or_kN)),
                   2597:                  N_or_kN);
                   2598:        if (low_stack(lim3, stack_lim(av3,1)))
                   2599:        {
                   2600:          if(DEBUGMEM>1) err(warnmem,"[2]: mpqs_solve_linear_system");
                   2601:          X = gerepileupto(av3, X);
                   2602:        }
                   2603:       }
                   2604:     }
                   2605:     X = gerepileupto(av3, X);  /* unconditionally */
                   2606:     if (
                   2607: #ifdef MPQS_DEBUG
                   2608:        1 ||
                   2609: #endif
                   2610:        DEBUGLEVEL >= 1)
                   2611:     {                          /* this shouldn't happen either --GN */
                   2612:       if (signe(modii(subii(sqri(X), sqri(Y_prod)), N_or_kN)))
                   2613:       {
                   2614:        fprintferr("MPQS: X^2 - Y^2 != 0 mod %s\n",
                   2615:                   (N_or_kN == kN ? "kN" : "N"));
                   2616:        fprintferr("\tindex i = %ld\n", i);
                   2617:        err(warner, "MPQS: wrong relation found after Gauss");
                   2618:       }
                   2619:     }
                   2620:     /* if res_next < 3, we still haven't decomposed the original N, and
                   2621:        will want both a gcd and its cofactor, overwriting N.  Note that
                   2622:        gcd(X+Y_prod,N)==1 forces gcd(X-Y_prod,N)==N, so we can skip X-Y_prod
                   2623:        in such cases */
                   2624:     done = 0;                  /* (re-)counts probably-prime factors
                   2625:                                   (or powers whose bases we don't want to
                   2626:                                   handle any further) */
                   2627:     if (res_next < 3)
                   2628:     {
                   2629:       D1 = mppgcd(addii(X,Y_prod),N);
                   2630:       if (!is_pm1(D1))
                   2631:       {
                   2632:        if ((flag = egalii(D1, N))) /* assignment */
                   2633:                                /* this one's useless, try the other one */
                   2634:          D1 = mppgcd(subii(X,Y_prod),N);
                   2635:        if (!flag || (!is_pm1(D1) && !egalii(D1,N)))
                   2636:        {                       /* got something that works */
                   2637:           if (DEBUGLEVEL >= 5)
                   2638:             fprintferr("MPQS: splitting N after %ld kernel vector%s\n",
                   2639:                        i+1, (i? "s" : ""));
                   2640:          (void)mpdivis(N, D1, N); /* divide N in place */
                   2641:          res[1] = (long)N;     /* we'll gcopy this anyway before exiting */
                   2642:          res[2] = (long)D1;
                   2643:          res_last = res_next = 3;
                   2644:          if (res_max == 2) break; /* two out of two possible factors seen */
                   2645:          mask = 7;
                   2646:          /* (actually, 5th/7th powers aren't really worth the trouble.  OTOH
                   2647:             once we have the hooks for dealing with cubes, higher powers can
                   2648:             be handled essentially for free) */
                   2649:          if (isprobableprime(N)) { done++; res[res_size+1] = un; }
                   2650:          else if (carrecomplet(N, &base))
                   2651:          {                     /* squares could cost us a lot of time */
                   2652:            affii(base, N); done++; res[res_size+1] = deux;
                   2653:            if (DEBUGLEVEL >= 5)
                   2654:              fprintferr("MPQS: decomposed a square\n");
                   2655:          }
                   2656:          else if ((flag = is_odd_power(N, &base, &mask))) /* assignment */
                   2657:          {
                   2658:            affii(base, N); done++; res[res_size+1] = (long)(stoi(flag));
                   2659:            if (DEBUGLEVEL >= 5)
                   2660:              fprintferr("MPQS: decomposed a %s\n",
                   2661:                         (flag == 3 ? "cube" :
                   2662:                          (flag == 5 ? "5th power" : "7th power")));
                   2663:          }
                   2664:          else res[res_size+1] = zero; /* known composite */
                   2665:          mask = 7;
                   2666:          if (isprobableprime(D1)) { done++; res[res_size+2] = un; }
                   2667:          else if (carrecomplet(D1, &base))
                   2668:          {
                   2669:            res[2] = (long)base;
                   2670:            done++; res[res_size+2] = deux;
                   2671:            if (DEBUGLEVEL >= 5)
                   2672:              fprintferr("MPQS: decomposed a square\n");
                   2673:          }
                   2674:          else if ((flag = is_odd_power(D1, &base, &mask))) /* assignment */
                   2675:          {
                   2676:            res[2] = (long)base;
                   2677:            done++; res[res_size+2] = (long)(stoi(flag));
                   2678:            if (DEBUGLEVEL >= 5)
                   2679:              fprintferr("MPQS: decomposed a %s\n",
                   2680:                         (flag == 3 ? "cube" :
                   2681:                          (flag == 5 ? "5th power" : "7th power")));
                   2682:          }
                   2683:          else res[res_size+2] = zero; /* known composite */
                   2684:          if (done == 2) break; /* both factors look prime or were powers */
                   2685:          if (DEBUGLEVEL >= 5)
                   2686:            fprintferr("MPQS: got two factors, looking for more...\n");
                   2687:          /* and loop (after collecting garbage if necessary) */
                   2688:        } /* else loop to next kernel basis vector */
                   2689:       } /* D1!=1, nothing to be done when ==1 */
                   2690:     }
                   2691:     else                       /* we already have factors */
                   2692:     {
                   2693:       GEN X_plus_Y = addii(X, Y_prod);
                   2694:       GEN X_minus_Y = NULL;    /* will only be computed when needed */
                   2695:       for (j=1; j < res_next; j++)
                   2696:       {                                /* loop over known-composite factors */
                   2697:        if (res[res_size+j] && res[res_size+j] != zero)
                   2698:        {
                   2699:          done++; continue;     /* skip probable primes etc */
                   2700:        }
                   2701:        /* (actually, also skip square roots of squares etc.  They are
                   2702:           necessarily a lot smaller than the original N, and should
                   2703:           be easy to deal with later) */
                   2704:        av3 = avma;
                   2705:        D1 = mppgcd(X_plus_Y, (GEN)(res[j]));
                   2706:        if (is_pm1(D1)) continue; /* this one doesn't help us */
                   2707:        if ((flag = egalii(D1, (GEN)(res[j]))))
                   2708:        {                       /* bad one, try the other */
                   2709:           avma = av3;
                   2710:          if (!X_minus_Y) X_minus_Y = subii(X, Y_prod);
                   2711:           av3 = avma;
                   2712:          D1 = mppgcd(X_minus_Y, (GEN)(res[j]));
                   2713:        }
                   2714:        if (!flag || (!is_pm1(D1) && !egalii(D1, (GEN)(res[j]))))
                   2715:        {                       /* got one which splits this factor */
                   2716:           if (DEBUGLEVEL >= 5)
                   2717:             fprintferr("MPQS: resplitting a factor after %ld kernel vectors\n",
                   2718:                        i+1);      /* always plural */
                   2719:          /* first make sure there's room for another factor */
                   2720:          if (res_next > res_size)
                   2721:          {                     /* need to reallocate (_very_ rare case) */
                   2722:            long i1, new_size = 2*res_size;
                   2723:            GEN new_res;
                   2724:            if (new_size > res_max) new_size = res_max;
                   2725:            new_res = cgetg(2*new_size+1, t_VEC);
                   2726:            for (i1=2*new_size; i1>=res_next; i1--) new_res[i1] = 0;
                   2727:            for (i1=1; i1<res_next; i1++)
                   2728:            {
                   2729:              new_res[i1] = res[i1]; /* factors */
                   2730:              new_res[new_size+i1] = res[res_size+i1]; /* primality tags */
                   2731:            }
                   2732:            res = new_res; res_size = new_size; /* res_next unchanged */
                   2733:          }
                   2734:          /* now there is room; divide into existing factor and store the
                   2735:             new gcd.  Remove the known-composite flag from the old entry */
                   2736:          (void)mpdivis((GEN)(res[j]), D1, (GEN)(res[j]));
                   2737:          res[res_next] = (long)D1; res[res_size+j] = 0;
                   2738:          if (++res_next > res_max) break; /* all possible factors seen */
                   2739:          mask = 7;             /* check for 3rd and 5th powers */
                   2740:          if (isprobableprime((GEN)(res[j])))
                   2741:          {
                   2742:            done++; res[res_size+j] = un;
                   2743:          }
                   2744:          else if (carrecomplet((GEN)(res[j]), &base))
                   2745:          {
                   2746:            /* we no longer bother preserving the cloned N or what is left
                   2747:               of it when we hit it here */
                   2748:            res[j] = (long)base;
                   2749:            done++; res[res_size+j] = deux;
                   2750:            if (DEBUGLEVEL >= 5)
                   2751:              fprintferr("MPQS: decomposed a square\n");
                   2752:          }
                   2753:          else if ((flag = is_odd_power((GEN)(res[j]), &base, &mask))) /* = */
                   2754:          {
                   2755:            res[j] = (long)base;
                   2756:            done++; res[res_size+j] = (long)stoi(flag);
                   2757:            if (DEBUGLEVEL >= 5)
                   2758:              fprintferr("MPQS: decomposed a %s\n",
                   2759:                         (flag == 3 ? "cube" :
                   2760:                          (flag == 5 ? "5th power" : "7th power")));
                   2761:          }
                   2762:          else res[res_size+j] = zero; /* known composite */
                   2763:          mask = 7;
                   2764:          if (isprobableprime(D1))
                   2765:          {
                   2766:            done++; res[res_size+res_last] = un;
                   2767:          }
                   2768:          else if (carrecomplet(D1, &base))
                   2769:          {
                   2770:            res[res_last] = (long)base;
                   2771:            done++; res[res_size+res_last] = deux;
                   2772:            if (DEBUGLEVEL >= 5)
                   2773:              fprintferr("MPQS: decomposed a square\n");
                   2774:          }
                   2775:          else if ((flag = is_odd_power(D1, &base, &mask))) /* assignment */
                   2776:          {
                   2777:            res[res_last] = (long)base;
                   2778:            done++; res[res_size+res_last] = (long)stoi(flag);
                   2779:            if (DEBUGLEVEL >= 5)
                   2780:              fprintferr("MPQS: decomposed a %s\n",
                   2781:                         (flag == 3 ? "cube" :
                   2782:                          (flag == 5 ? "5th power" : "7th power")));
                   2783:          }
                   2784:          else res[res_size+res_last] = zero; /* known composite */
                   2785:        } /* else it didn't help on this factor, try the next one... */
                   2786:        else avma = av3;        /* ...after destroying the gcds */
                   2787:       }        /* loop over known composite factors */
                   2788:       if (res_next > res_last)
                   2789:       {
                   2790:        if (DEBUGLEVEL >= 5 && done < res_last)
                   2791:          fprintferr("MPQS: got %ld factors%s\n",
                   2792:                     res_last,
                   2793:                     (done < res_last ? ", looking for more..." : ""));
                   2794:        res_last = res_next;
                   2795:       }
                   2796:       /* we should break out of the outer loop when we have seen res_max
                   2797:         factors, and also when all current factors are probable primes */
                   2798:       if (res_next > res_max || done == res_next - 1) break;
                   2799:       /* else continue loop over kernel basis */
                   2800:     } /* end case of further splitting of existing factors */
                   2801:     /* garbage collection */
                   2802:     if (low_stack(lim, stack_lim(av2,1)))
                   2803:     {
                   2804:       long i1;
                   2805:       if(DEBUGMEM>1) err(warnmem,"[3]: mpqs_solve_linear_system");
                   2806:       tetpil=avma;
                   2807:       /* gcopy would have a problem with our NULL pointers... */
                   2808:       new_res = cgetg(lg(res), t_VEC);
                   2809:       for (i1=2*res_size; i1>=res_next; i1--) new_res[i1] = 0;
                   2810:       for (i1=1; i1<res_next; i1++)
                   2811:       {
                   2812:        new_res[i1] =
                   2813:          (isonstack((GEN)(res[i1])) ? licopy((GEN)(res[i1])) : res[i1]);
                   2814:        new_res[res_size+i1] = res[res_size+i1];
                   2815:       }
                   2816:       res = gerepile(av2, tetpil, new_res);
                   2817:       /* discard X and Y_prod */
                   2818:     }
                   2819:   } /* for (loop over kernel basis) */
                   2820:
                   2821:   if (res_next < 3)            /* still no factors seen */
                   2822:   {
                   2823:     pari_fclose(pFREL);
                   2824:     mpqs_gauss_destroy_matrix(m, size_of_FB+1, rel);
                   2825:     mpqs_gauss_destroy_matrix(ker_m, rel, rank);
                   2826:     free(ei); free(fpos);
                   2827:     avma = av;
                   2828:     return NULL; /* no factors found */
                   2829:   }
                   2830:   /* normal case:  convert internal format to ifac format as described in
                   2831:      src/basemath/ifactor1.c  (triples of components: value, exponent, class
                   2832:      [unknown, known composite, known prime]),  clean up and return result */
                   2833:   pari_fclose(pFREL);
                   2834:   mpqs_gauss_destroy_matrix(m, size_of_FB+1, rel);
                   2835:   mpqs_gauss_destroy_matrix(ker_m, rel, rank);
                   2836:   free(ei); free(fpos);
                   2837:   res_last = res_next - 1;     /* number of distinct factors found */
                   2838:   new_res = cgetg(3*res_last + 1, t_VEC);
                   2839:   if (DEBUGLEVEL >= 6)
                   2840:     fprintferr("MPQS: wrapping up vector of %ld factors\n", res_last);
                   2841:   for (i=1,j=1; i <= res_last; i++)
                   2842:   {
                   2843:     new_res[j++] =             /* value of factor */
                   2844:       isonstack((GEN)(res[i])) ? licopy((GEN)(res[i])) : res[i];
                   2845:     flag = res[res_size+i];
                   2846:     new_res[j++] =             /* exponent */
                   2847:       flag ?                   /* flag was zero or un or ... */
                   2848:        (flag == zero ? un :
                   2849:         (isonstack((GEN)flag) ? licopy((GEN)flag) : flag)
                   2850:         ) :
                   2851:           un;                  /* flag was (long)NULL */
                   2852:     new_res[j++] =             /* class */
                   2853:       flag == zero ? zero :    /* known composite */
                   2854:        (long)NULL;             /* base of power or suspected prime --
                   2855:                                   mark as `unknown' */
                   2856:     if (DEBUGLEVEL >= 6)
                   2857:       fprintferr("\tpackaging %ld: %Z ^%ld (%s)\n", i, res[i],
                   2858:                 itos((GEN)(new_res[j-2])),
                   2859:                 (flag == zero ? "comp." : "unknown"));
                   2860:   }
                   2861:   return gerepileupto(av, new_res);
                   2862: }
                   2863:
                   2864: /******************************/
                   2865:
                   2866: /* All percentages below are actually fixed-point quantities scaled by 10
                   2867:    (value of 1 means 0.1%, 1000 means 100%). --GN */
                   2868:
                   2869: #define max_percentage 1500    /* give up when nothing found after ~1.5
                   2870:                                   times the required number of relations has
                   2871:                                   been computed  (n might be a prime power
                   2872:                                   or the parameters might be exceptionally
                   2873:                                   unfortunate for it) --GN */
                   2874:
                   2875: /**
                   2876:  ** Factors N using the self-initializing multipolynomial quadratic sieve
                   2877:  ** (SIMPQS).  Returns one of the two factors, or (usually) a vector of
                   2878:  ** factors and exponents and information about which ones are definitely
                   2879:  ** still composite, or NULL when something goes wrong or when we can't
                   2880:  ** seem to make any headway.
                   2881:  **/
                   2882:
                   2883: /* TODO: this function to be renamed mpqs_main() with several extra para-
                   2884:    meters, with mpqs() as a wrapper for the standard case, so we can do
                   2885:    partial runs distributed across several machines etc.  (not necessarily
                   2886:    from gp, but certainly from a small dedicated C program). --GN */
                   2887:
                   2888: GEN
                   2889: mpqs(GEN N)
                   2890: {
                   2891:   GEN fact;                    /* will in the end hold our factor(s) */
                   2892:   ulong decimal_digits;                /* number of decimals of N */
                   2893:   long tc;                     /* number of candidates found in one
                   2894:                                   iteration */
                   2895:   long t;                      /* number of full relations found in one
                   2896:                                   iteration */
                   2897:   long tp;                     /* number of full relations found in one
                   2898:                                   iteration after combining large prime
                   2899:                                   relations */
                   2900:   long k;                      /* the multiplier */
                   2901:   GEN kN;                      /* k * N */
                   2902:   double sqrt_kN;              /* double approximation of sqrt(k*N) */
                   2903:   long *FB;                    /* the factor base */
                   2904:   ulong size_of_FB;            /* the size of the factor base */
                   2905:   ulong FB_overshoot;          /* the number of relations aimed for */
                   2906:   double log_multiplier;       /* maps logarithms of FB elements to
                   2907:                                   unsigned chars */
                   2908:   double tolerance;            /* used in sieving with logarithms */
                   2909:   unsigned char *log_FB;       /* logarithms of FB elements mapped to
                   2910:                                   unsigned chars */
                   2911:   unsigned char *sieve_array;  /* the sieve array */
                   2912:   unsigned char *sieve_array_end; /* the end of the sieve array */
                   2913:   ulong M;                     /* the sieve interval size [-M, M] */
                   2914:   ulong starting_sieving_index;        /* the first element in the FB used for
                   2915:                                   sieving */
                   2916:   long last_prime_in_FB;       /* the biggest prime in FB */
                   2917:   long *sqrt_mod_p_kN;         /* array containing sqrt(K*N) mod p_i,
                   2918:                                   where p_i are FB elements */
                   2919:   GEN A, B, inv_A4;            /* coefficients of polynomials in (SI) */
                   2920:   long *Q_prime_glob, *Q_prime;        /* used for self initialization (SI) */
                   2921:   GEN *H_i;                    /* will be used to compute the consecutive
                   2922:                                   B during (SI) */
                   2923:   long start_index_FB_for_A;   /* the first index in the FB used for
                   2924:                                   computing A during (SI), minus 1 */
                   2925:   ulong no_of_primes_in_A;     /* number of primes dividing A
                   2926:                                   during (SI) */
                   2927:   ulong total_no_of_primes_for_A; /* number of primes used for finding A
                   2928:                                     during (SI) */
                   2929:   long max_no_of_B;            /* how many B's to use before choosing
                   2930:                                   a new A during (SI) */
                   2931:   long index_i;                        /* denotes the current pair of coeffs
                   2932:                                   (A, B_i). If i == 0, a new A is
                   2933:                                   generated */
                   2934:   ulong bin_index;             /* used for choosing the prime factors for
                   2935:                                   for the A coeffs in mpqs_self_init() */
                   2936:   long i, p;                   /* counters */
                   2937:
                   2938:   /* Let (z0, z1) be the roots of Q(x) = A x^2 + Bx +C mod p_i;
                   2939:      then we know that
                   2940:      Q(z1 + i k) == 0 mod p_i and Q(z2 + i k) == 0 mod p_i */
                   2941:
                   2942:   long *start_1;               /* stores the position where p_i
                   2943:                                   divides Q(x) for the first time,
                   2944:                                   using z1 */
                   2945:   long *start_2;               /* same, but using z2 */
                   2946:   long *inv_A2;                        /* inv_A2[i] = 1/(2*A) mod p_i */
                   2947:   long **inv_A_H_i;            /* inv_A_H_i[i][j] = 1/A H_i[i] mod p_j */
                   2948:   long *candidates;            /* positions in the sieve_array which
                   2949:                                   probably factor over the FB */
                   2950:   long lp_bound;               /* size limit for large primes */
                   2951:   ulong sort_interval;         /* these determine when to sort and merge */
                   2952:   ulong followup_sort_interval;        /* the temporary files (scaled percentages) */
                   2953:   long total_full_relations = 0;
                   2954:   long total_partial_relations = 0;
                   2955:   pariFILE *pFREL;
                   2956:   pariFILE *pFNEW;
                   2957:   pariFILE *pLPREL;
                   2958:   pariFILE *pLPNEW;
                   2959:   pariFILE *pCOMB;
                   2960:   FILE *FNEW;
                   2961:   FILE *LPNEW;
                   2962:   long percentage = 0;         /* scaled by 10, see comment above */
                   2963:   long total_candidates_number = 0;
                   2964:   long useless_candidates = 0; /* another scaled percentage */
                   2965:   long vain_iterations = 0;
                   2966:   long good_iterations = 0;
                   2967:   long iterations = 0;
1.2     ! noro     2968:   gpmem_t av = avma;
1.1       noro     2969:
                   2970:   /* state flags for cleanup if we get interrupted --GN */
                   2971:   static char all_clean = 1;   /* set to 0 while mpqs() is busy */
                   2972:
                   2973:   if (DEBUGLEVEL >= 4)
                   2974:   {
                   2975:     if (!all_clean) { /* TODO: clean up... */ }
                   2976:     (void) timer2();           /* clear timer */
                   2977:     fprintferr("MPQS: number to factor N = %Z\n", N);
                   2978:   }
                   2979:
                   2980:   all_clean = 0;               /* activate clean-up trap */
                   2981:   {
                   2982:     char *s = GENtostr(N);
                   2983:     decimal_digits = strlen(s);
                   2984:     free(s);
                   2985:   }
                   2986:
                   2987:   if (decimal_digits >= 108)   /* changed to match Denny's parameters */
                   2988:   {
                   2989:     err(warner, "MPQS: number too big to be factored with MPQS, giving up");
                   2990:     avma = av;
                   2991:     all_clean = 1;
                   2992:     return NULL;
                   2993:   }
                   2994:
                   2995:   if (DEBUGLEVEL >= 4)
                   2996:     fprintferr("MPQS: factoring number of %ld decimal digits\n",
                   2997:               decimal_digits);
                   2998:
                   2999:   if (decimal_digits >= 70)
                   3000:     err(warner,
                   3001:        "MPQS: the factorization of this number will take %s hours",
                   3002:        decimal_digits >= 84 ? "many" : "several");
                   3003:
                   3004:   k = mpqs_find_k(N, 5);
                   3005:   if (DEBUGLEVEL >= 5)
                   3006:     fprintferr("MPQS: found multiplier %ld for N\n", k);
                   3007:
                   3008:   kN = mulis(N, k);
                   3009:   {
                   3010:     char *s = GENtostr(kN);
                   3011:     decimal_digits = strlen(s);
                   3012:     free(s);
                   3013:   }
                   3014:
                   3015:   if (DEBUGLEVEL >= 5)
                   3016:   {
                   3017:     fprintferr("MPQS: kN = %Z\n", kN);
                   3018:     fprintferr("MPQS: kN has %ld decimal digits\n",
                   3019:               decimal_digits);
                   3020:   }
                   3021:
                   3022:   mpqs_read_parameters(decimal_digits, &tolerance, &M, &size_of_FB,
                   3023:                       &FB_overshoot,
                   3024:                        &no_of_primes_in_A, &total_no_of_primes_for_A,
                   3025:                        &max_no_of_B, &starting_sieving_index,
                   3026:                       &sort_interval, &followup_sort_interval);
                   3027:   {
                   3028:     double bytesize = (size_of_FB + 1)/(8.*1048576.);
                   3029:     bytesize *= FB_overshoot;
                   3030:     if (bytesize > 32.)
                   3031:     {
                   3032:       err(warner,
                   3033:          "MPQS: Gauss elimination will require more than 32MBy of memory");
                   3034:       if (DEBUGLEVEL >= 1)
                   3035:        fprintferr("\t(estimated memory needed: %4.1fMBy)\n", bytesize);
                   3036:     }
                   3037:   }
                   3038:
                   3039:   if (DEBUGLEVEL >= 4)
                   3040:   {
                   3041:     fprintferr("MPQS: sieving interval = [%ld, %ld]\n",
                   3042:               -(long)M, M);
                   3043:     fprintferr("MPQS: size of factor base = %ld\n",
                   3044:               size_of_FB);
                   3045:     fprintferr("MPQS: striving for %ld relations\n",
                   3046:               FB_overshoot);
                   3047:     fprintferr("MPQS: first sorting at %ld%%, then every %3.1f%% / %3.1f%%\n",
                   3048:               sort_interval/10, followup_sort_interval/10.,
                   3049:               followup_sort_interval/20.);
                   3050:     fprintferr("MPQS: initial sieving index = %ld\n",
                   3051:               starting_sieving_index);
                   3052:   }
                   3053:   sieve_array =
                   3054:     (unsigned char *) gpmalloc((M << 1) * sizeof(unsigned char));
                   3055:   sieve_array_end = sieve_array + (M << 1) - 1;
                   3056:
                   3057:   if (DEBUGLEVEL >= 5)
                   3058:     fprintferr("MPQS: creating factor base FB of size = %ld\n",
                   3059:               size_of_FB);
                   3060:
                   3061:   FB = mpqs_create_FB(size_of_FB, kN, k, &p);
                   3062:
                   3063:   /* the following this way round to avoid overflow: --GN */
                   3064:   lp_bound = FB[FB[0]+1];
                   3065:   if (DEBUGLEVEL >= 4)
                   3066:     fprintferr("MPQS: largest prime in FB = %ld\n",
                   3067:               lp_bound);
                   3068:   if (lp_bound > MPQS_LP_BOUND)
                   3069:     lp_bound = MPQS_LP_BOUND;
                   3070:   lp_bound *= MPQS_LP_FACTOR;
                   3071:   if (DEBUGLEVEL >= 4)
                   3072:     fprintferr("MPQS: bound for `large primes\' = %ld\n",
                   3073:               lp_bound);
                   3074:
                   3075:   if (p != 0)
                   3076:   {
                   3077:     free(FB);
                   3078:     free(sieve_array);
                   3079:     if (DEBUGLEVEL >= 4)
                   3080:       fprintferr("\nMPQS: found factor = %ld whilst creating factor base\n",
                   3081:                 p);
                   3082:     if (mpqs_diffptr == diffptr) mpqs_diffptr = NULL;
                   3083:     avma = av;
                   3084:     /* TODO: free the FB etc!!! */
                   3085:     all_clean = 1;
                   3086:     return stoi(p);
                   3087:   }
                   3088:
                   3089:   if (DEBUGLEVEL >= 5)
                   3090:   {
                   3091:     fprintferr("MPQS: computing logarithm approximations for p_i in FB\n");
                   3092:     fprintferr("MPQS: computing sqrt(k*N) mod p_i\n");
                   3093:   }
                   3094:   last_prime_in_FB = FB[FB[0] + 1];
                   3095:   log_multiplier = (2 * (unsigned char) (0.5 * log2 (gtodouble(kN)) +
                   3096:                            log2 ((double) M) - tolerance *
                   3097:                            log2 ((double) last_prime_in_FB)));
                   3098:   log_multiplier = 127.0 / log_multiplier;
                   3099:
                   3100:   log_FB =
                   3101:     (unsigned char *) gpmalloc((size_of_FB + 2) * sizeof(unsigned char));
                   3102:   sqrt_mod_p_kN =
                   3103:     (long *) gpmalloc((size_of_FB + 2) * sizeof(long));
                   3104:
                   3105:   for (i = 2; (ulong)i < size_of_FB + 2; i++)
                   3106:   {
1.2     ! noro     3107:     gpmem_t av1 = avma;
1.1       noro     3108:     p = FB[i];
                   3109:
                   3110:     /* compute the approximations of the logarithms of p_i */
                   3111:     log_FB[i] =
                   3112:       (unsigned char) (log_multiplier * log2 ((double) p) * 2);
                   3113:
                   3114:     /* compute the x_i such that x_i^2 = (kN % p_i) mod p_i */
                   3115:     sqrt_mod_p_kN[i] = itos(mpsqrtmod(modis(kN, p), stoi(p)));
                   3116:     avma = av1;
                   3117:   }
                   3118:
                   3119:   if (DEBUGLEVEL >= 5)
                   3120:     fprintferr("MPQS: allocating arrays for self-initialization\n");
                   3121:
                   3122:   /* the size of coefficient A should be approximately */
                   3123:   /* sqrt(kN)/M, so the size of the primes p dividing */
                   3124:   /* A should be approximately (sqrt(kN/M))^(1/no_of_primes_in_A) */
                   3125:
                   3126:   /* compute expected size of coefficients, which also defines the tolerance
                   3127:      for the logarithmic sieve */
                   3128:   sqrt_kN = sqrt(gtodouble(kN));
                   3129:   tolerance = sqrt_kN / M;
                   3130:   tolerance =  pow(2.0, log2(tolerance) / no_of_primes_in_A);
                   3131:   if (tolerance > FB[size_of_FB - 1]) /* ??? */
                   3132:     err(talker, "MPQS: number of prime factors in A is too small");
                   3133:
                   3134:   /* choose primes in FB to use for building the A coefficient */
                   3135:   start_index_FB_for_A = 2;
                   3136:   while (FB[start_index_FB_for_A] < tolerance)
                   3137:     start_index_FB_for_A++;
                   3138:
                   3139:   if (start_index_FB_for_A > 7)
                   3140:     start_index_FB_for_A -= (no_of_primes_in_A >> 1);
                   3141:
                   3142:   /* ensure that the primes to be used for A do occur in the FB */
                   3143:   if (start_index_FB_for_A + total_no_of_primes_for_A >= size_of_FB)
                   3144:     start_index_FB_for_A = size_of_FB - total_no_of_primes_for_A - 1;
                   3145:
                   3146:   /* ensure that the multiplier k is smaller than the prime divisors of A */
                   3147:   if (k >= FB[start_index_FB_for_A])
                   3148:   {
                   3149:     do
                   3150:       start_index_FB_for_A++;
                   3151:     while (k >= FB[start_index_FB_for_A]);
                   3152:     if (start_index_FB_for_A + total_no_of_primes_for_A >= size_of_FB)
                   3153:       err(talker,
                   3154:          "MPQS: number of primes for A is too large, or FB too small");
                   3155:     /* this shouldn't happen */
                   3156:   }
                   3157:
                   3158:   /* now a selection of total_no_of_primes_for_A consecutive primes
                   3159:    * p = FB[start_index_FB_for_A+1], ... is chosen from the factor base */
                   3160:
                   3161:   /* (no need to copy them around as long as they are consecutive entries
                   3162:      in FB --GN) */
                   3163:   Q_prime =
                   3164:     (long *) gpmalloc(no_of_primes_in_A * sizeof(long));
                   3165: #if 1
                   3166:   Q_prime_glob = &(FB[start_index_FB_for_A + 1]);
                   3167: #else
                   3168:   Q_prime_glob =
                   3169:     (long *) gpmalloc(total_no_of_primes_for_A * sizeof(long));
                   3170:   for (i = 0; i < total_no_of_primes_for_A; i++)
                   3171:     Q_prime_glob[i] = FB[start_index_FB_for_A + i + 1];
                   3172: #endif
                   3173:
                   3174:   /* used for choosing the correct A coeffs in mpqs_self_init() */
                   3175:   bin_index = 0;
                   3176:
                   3177:   /* will be used to compute the consecutive B during
                   3178:      self-initialization */
                   3179:   H_i = (GEN *) gpmalloc(no_of_primes_in_A * sizeof(GEN));
                   3180:   for (i = 0; (ulong)i < no_of_primes_in_A; i++)
                   3181:     H_i[i] = cgeti(2 * total_no_of_primes_for_A);
                   3182:
                   3183:   inv_A_H_i =
                   3184:     (long **) gpmalloc(total_no_of_primes_for_A * sizeof(long *));
                   3185:   for (i = 0; (ulong)i < total_no_of_primes_for_A; i++)
                   3186:     inv_A_H_i[i] = (long *) gpmalloc((size_of_FB + 2) * sizeof(long));
                   3187:
                   3188:   start_1 = (long *) gpmalloc((size_of_FB + 2) * sizeof(long));
                   3189:   start_2 = (long *) gpmalloc((size_of_FB + 2) * sizeof(long));
                   3190:
                   3191:   /* the next will hold 1/(2*A) mod p_i, p_i in FB */
                   3192:   inv_A2 = (long *) gpmalloc((size_of_FB + 2) * sizeof(long));
                   3193:
                   3194:   candidates = (long *) gpmalloc(MPQS_CANDIDATE_ARRAY_SIZE * sizeof(long));
                   3195:
                   3196:   if (DEBUGLEVEL >= 5)
                   3197:   {
                   3198:     fprintferr("MPQS: index range of primes for A: [%ld, %ld]\n",
                   3199:               start_index_FB_for_A + 1,
                   3200:               start_index_FB_for_A + total_no_of_primes_for_A);
                   3201:     fprintferr("MPQS: coefficients A will be built from %ld primes each\n",
                   3202:               no_of_primes_in_A);
                   3203:   }
                   3204:
                   3205: /* CLEAN UP define */
                   3206:
                   3207: #define CLEANUP() \
                   3208:   free(FB); \
                   3209:   free(sieve_array); \
                   3210:   free(log_FB); \
                   3211:   free(sqrt_mod_p_kN); \
                   3212:   free(Q_prime); \
                   3213: /*  free(Q_prime_glob); */ \
                   3214:   free(H_i); \
                   3215:   for (i = 0; (ulong)i < total_no_of_primes_for_A; i++) \
                   3216:     free(inv_A_H_i[i]); \
                   3217:   free(inv_A_H_i); \
                   3218:   free(start_1); \
                   3219:   free(start_2); \
                   3220:   free(inv_A2); \
                   3221:   free(candidates);
                   3222:
                   3223:   /*
                   3224:    * main loop which
                   3225:    * - computes polynomials and their zeros (self initialization)
                   3226:    * - does the sieving
                   3227:    * - tests candidates of the sieve array
                   3228:    */
                   3229:
                   3230:   /* denotes the current pair of coeffs (A, B_i). If i == 0 a new A is
                   3231:     generated */
                   3232:   index_i = -1;
                   3233:
                   3234:   /* the coefficients of the polynomial currently used for sieving */
                   3235:   /* A will be at most as long as the product of
                   3236:      no_of_primes_in_A word-sized primes (was total_..., GN) */
                   3237:   /* B needs at most total_no_of_primes_for_A + 1 words [CHECK] --GN */
                   3238:   /* Take the double is just for safety ... */
                   3239:   A = cgeti(2 * no_of_primes_in_A);
                   3240:   B = cgeti(2 * total_no_of_primes_for_A + 1);
                   3241:
                   3242:   /* 1/4A mod kN */
                   3243:   inv_A4 = cgeti(lg(kN));
                   3244:
                   3245:   if (DEBUGLEVEL >= 5)
                   3246:     fprintferr("MPQS: starting main loop\n");
                   3247:   /* compute names for the temp files we'll need */
                   3248:   FREL_str  = mpqs_get_filename("FREL");
                   3249:   FNEW_str  = mpqs_get_filename("FNEW");
                   3250:   LPREL_str = mpqs_get_filename("LPREL");
                   3251:   LPNEW_str = mpqs_get_filename("LPNEW");
                   3252:   COMB_str  = mpqs_get_filename("COMB");
                   3253:   TMP_str = mpqs_get_filename("LPTMP");
                   3254:
                   3255:   /* just to create the temp files */
                   3256:   pFREL  = pari_safefopen(FREL_str,  WRITE); pari_fclose(pFREL);
                   3257:   pLPREL = pari_safefopen(LPREL_str, WRITE); pari_fclose(pLPREL);
                   3258:
                   3259:   pFNEW = pari_safefopen(FNEW_str,  WRITE);  FNEW = pFNEW->file;
                   3260:   pLPNEW= pari_safefopen(LPNEW_str, WRITE); LPNEW = pLPNEW->file;
                   3261:   for(;;)
                   3262:   {
                   3263:     /* at start of loop, FNEW and LPNEW are open for writing */
                   3264:     iterations++;
                   3265:     /* when all of the B's have already been used, choose new A ;
                   3266:        this is indicated by setting index_i to 0 */
                   3267:     if (index_i == (max_no_of_B - 1))
                   3268:       index_i = 0;
                   3269:     else
                   3270:       index_i++;
                   3271:
                   3272:     /* self initialization: compute polynomial and its zeros */
                   3273:
                   3274:     mpqs_self_init(A, B, N, kN, FB, sqrt_mod_p_kN, start_1, start_2,
                   3275:                   no_of_primes_in_A, total_no_of_primes_for_A,
                   3276:                   M, inv_A_H_i, Q_prime, Q_prime_glob, H_i,
                   3277:                   index_i, start_index_FB_for_A, inv_A2, inv_A4,
                   3278:                   &bin_index, &fact);
                   3279:     if (bin_index >= (1ul << total_no_of_primes_for_A)) /* wraparound */
                   3280:     {
                   3281:       /* TODO: increase some parameters.  For the moment, simply give up */
                   3282:       CLEANUP();
                   3283:       pari_fclose(pFNEW);
                   3284:       pari_fclose(pLPNEW);
                   3285:       /* FREL, LPREL are closed at this point */
                   3286:       pari_unlink(FREL_str);
                   3287:       pari_unlink(FNEW_str);
                   3288:       pari_unlink(LPREL_str);
                   3289:       pari_unlink(LPNEW_str);
                   3290:       if (mpqs_diffptr == diffptr) mpqs_diffptr = NULL;
                   3291:       all_clean = 1;
                   3292:       avma=av; return NULL;
                   3293:     }
                   3294:     if (fact)                  /* A4 not coprime to kN, fact divides N */
                   3295:     {                          /* (cannot actually happen) */
                   3296:       if (is_pm1(fact) || egalii(fact,N))
                   3297:        continue;               /* cannot use the current polynomial */
                   3298:       CLEANUP();
                   3299:       pari_fclose(pFNEW);
                   3300:       pari_fclose(pLPNEW);
                   3301:       pari_unlink(FREL_str);
                   3302:       pari_unlink(FNEW_str);
                   3303:       pari_unlink(LPREL_str);
                   3304:       pari_unlink(LPNEW_str);
                   3305:       if (mpqs_diffptr == diffptr) mpqs_diffptr = NULL;
                   3306:       all_clean = 1;
                   3307:       if (DEBUGLEVEL >= 4)
                   3308:       {
                   3309:        fprintferr("MPQS: whilst trying to invert A4 mod kN,\n");
                   3310:        fprintferr("\tfound factor = %Z\n", fact);
                   3311:        flusherr();
                   3312:       }
                   3313:       return gerepileupto(av, fact);
                   3314:     }
                   3315:
                   3316:     if (DEBUGLEVEL >= 6)
                   3317:     {
                   3318:       if (!index_i)
                   3319:        fprintferr("MPQS: chose prime pattern 0x%lX for A\n",
                   3320:                   bin_index);
                   3321:       if (signe(B) < 0)
                   3322:       {
                   3323:        setsigne(B,1);
                   3324:        fprintferr("MPQS: chose Q_%ld(x) = %Z x^2 - %Z x + C\n",
                   3325:                   index_i, A, B);
                   3326:        setsigne(B,-1);
                   3327:       }
                   3328:       else
                   3329:       {
                   3330:        fprintferr("MPQS: chose Q_%ld(x) = %Z x^2 + %Z x + C\n",
                   3331:                   index_i, A, B);
                   3332:       }
                   3333:     }
                   3334:
                   3335:     mpqs_sieve(FB, log_FB, start_1, start_2, sieve_array,
                   3336:               sieve_array_end, M, starting_sieving_index);
                   3337:
                   3338:     tc = mpqs_eval_sieve(sieve_array, M, candidates);
                   3339:     total_candidates_number += tc;
                   3340:     if (DEBUGLEVEL >= 6)
                   3341:       fprintferr("MPQS: found %lu candidate%s\n",
                   3342:                 tc, (tc==1? "" : "s"));
                   3343:
                   3344:     if (tc)
                   3345:     {
                   3346:       good_iterations++;
                   3347:       t = mpqs_eval_candidates(A, inv_A4, B, kN, k, sqrt_kN, FB,
                   3348:                               start_1, start_2,
                   3349:                               M, bin_index, candidates, tc, lp_bound,
                   3350:                               start_index_FB_for_A, FNEW, LPNEW);
                   3351:     }
                   3352:     else
                   3353:       t = 0;
                   3354:
                   3355:     total_full_relations += t;
                   3356:     percentage =
                   3357:       (long)((1000.0 * total_full_relations) / FB_overshoot);
                   3358:     useless_candidates =
                   3359:       (long)((1000.0 * (total_candidates_number - total_full_relations))
                   3360:             / (total_candidates_number ? total_candidates_number : 1));
                   3361:
                   3362:     if ((ulong)percentage < sort_interval)
                   3363:       continue;                        /* most main loops end here... */
                   3364:
                   3365:     /* Extra processing when we have completed a sort interval: */
                   3366:     if (DEBUGLEVEL >= 3)
                   3367:     {
                   3368:       if (DEBUGLEVEL >= 4)
                   3369:        fprintferr("\nMPQS: passing the %3.1f%% checkpoint, time = %ld ms\n",
                   3370:                   sort_interval/10., timer2());
                   3371:       else
                   3372:        fprintferr("\nMPQS: passing the %3.1f%% checkpoint\n",
                   3373:                   sort_interval/10.);
                   3374:       flusherr();
                   3375:     }
                   3376:     /* sort LPNEW and merge it into LPREL, diverting combinables into COMB */
                   3377:     pari_fclose(pLPNEW);
1.2     ! noro     3378:     (void)mpqs_sort_lp_file(LPNEW_str);
1.1       noro     3379:     tp = mpqs_mergesort_lp_file(LPREL_str, LPNEW_str, 0);
                   3380:     pLPNEW = pari_fopen(LPNEW_str, WRITE); /* NOT safefopen */
                   3381:     LPNEW = pLPNEW->file;
                   3382:
                   3383:     /* combine whatever there is to be combined */
                   3384:     if (tp > 0)
                   3385:     {
                   3386:       /* build full relations out of large prime relations */
                   3387:       pCOMB = pari_fopen(COMB_str, READ);
                   3388:       tp = mpqs_combine_large_primes(pCOMB->file, FNEW, size_of_FB, N, kN, &fact
                   3389: #ifdef MPQS_DEBUG
                   3390:                                     , FB
                   3391: #endif
                   3392:       );
                   3393:       pari_fclose(pCOMB);
                   3394:       pari_unlink(COMB_str);
                   3395:       /* now FREL, LPREL are closed and FNEW, LPNEW are still open */
                   3396:       if (fact)                        /* factor found during combining */
                   3397:       {
                   3398:        /* clean up */
                   3399:        CLEANUP();
                   3400:        pari_fclose(pLPNEW);
                   3401:        pari_fclose(pFNEW);
                   3402:        pari_unlink(FREL_str);
                   3403:        pari_unlink(FNEW_str);
                   3404:        pari_unlink(LPREL_str);
                   3405:        pari_unlink(LPNEW_str);
                   3406:        if (DEBUGLEVEL >= 4)
                   3407:        {
                   3408:          fprintferr("\nMPQS: split N whilst combining, time = %ld ms\n",
                   3409:                     timer2());
                   3410:          fprintferr("MPQS: found factor = %Z\n", fact);
                   3411:        }
                   3412:        if (mpqs_diffptr == diffptr) mpqs_diffptr = NULL;
                   3413:        all_clean = 1;
                   3414:        return gerepileupto(av, fact);
                   3415:       }
                   3416:     }
                   3417:
                   3418:     /* sort FNEW and merge it into FREL */
                   3419:     pari_fclose(pFNEW);
1.2     ! noro     3420:     (void)mpqs_sort_lp_file(FNEW_str);
1.1       noro     3421:     total_full_relations = mpqs_mergesort_lp_file(FREL_str, FNEW_str, 1);
                   3422:     /* this being the definitive count (combinables combined, and
                   3423:        duplicates removed) */
                   3424:     /* FNEW stays closed until we know whether we need to reopen it for
                   3425:        another iteration */
                   3426:
                   3427:     total_partial_relations += tp;
                   3428:
                   3429:     /* note that due to the removal of duplicates, percentage may actually
                   3430:        decrease at this point.  This may look funny in the diagnostics but
                   3431:        is nothing to worry about, since we _are_ making progress neverthe-
                   3432:        less. --GN */
                   3433:     percentage =
                   3434:       (long)((1000.0 * total_full_relations) / FB_overshoot);
                   3435:     vain_iterations =
                   3436:       (long)((1000.0 * (iterations - good_iterations))
                   3437:             / iterations);
                   3438:
                   3439:     /* TODO: the following could be improved (extrapolate from past
                   3440:        experience how many combined full relations we can expect in
                   3441:        addition to those we're finding directly) --GN */
                   3442:     if (percentage >= 840)
                   3443:     {
                   3444:       if (percentage >= 980)
                   3445:        sort_interval = percentage + 10;
                   3446:       else
                   3447:        sort_interval = percentage + (followup_sort_interval >> 1);
                   3448:       if (sort_interval >= 1000 && percentage < 1000)
                   3449:        sort_interval = 1000;
                   3450:     }
                   3451:     else
                   3452:     {
                   3453:       sort_interval = percentage + followup_sort_interval;
                   3454:     }
                   3455:
                   3456:     if (DEBUGLEVEL >= 4)
                   3457:     {
                   3458:       fprintferr("MPQS: done sorting%s, time = %ld ms\n",
                   3459:                 tp > 0 ? " and combining" : "",
                   3460:                 timer2());
                   3461:       fprintferr("MPQS: found %3.1f%% of the required relations\n",
                   3462:                 percentage/10.);
                   3463:       if (DEBUGLEVEL >= 5)
                   3464:       {
                   3465:        /* total_full_relations are always plural */
                   3466:        fprintferr("MPQS: found %ld full relations\n",
                   3467:                   total_full_relations);
                   3468:        fprintferr("MPQS:   (%ld of these from partial relations)\n",
                   3469:                   total_partial_relations);
                   3470:        fprintferr("MPQS: %4.1f%% useless candidates\n",
                   3471:                   useless_candidates/10.);
                   3472:        fprintferr("MPQS: %4.1f%% of the iterations yielded no candidates\n",
                   3473:                   vain_iterations/10.);
                   3474:        fprintferr("MPQS: next checkpoint at %3.1f%%\n",
                   3475:                   sort_interval/10.);
                   3476:       }
                   3477:     }
                   3478:
                   3479:     if (percentage < 1000)
                   3480:     {
                   3481:       pFNEW = pari_fopen(FNEW_str, WRITE); /* NOT safefopen */
                   3482:       FNEW = pFNEW->file;
                   3483:       /* at this point, LPNEW and FNEW are again open for writing */
                   3484:       continue;                        /* main loop */
                   3485:     }
                   3486:
                   3487:     /* percentage >= 1000, which implies total_full_relations > size_of_FB:
                   3488:        try finishing it off */
                   3489:
                   3490:     /* solve the system over F_2 */
                   3491:     if (DEBUGLEVEL >= 4)
                   3492:       fprintferr("\nMPQS: starting Gauss over F_2 on %ld distinct relations\n",
                   3493:                 total_full_relations);
                   3494:     fact = mpqs_solve_linear_system(kN, N,
                   3495:                                    total_full_relations,
                   3496:                                    FB, size_of_FB);
                   3497:
                   3498:     /* if solution found, clean up and return */
                   3499:     if (fact)
                   3500:     {
                   3501:       /* clean up */
                   3502:       CLEANUP();
                   3503:       pari_fclose(pLPNEW);
                   3504:       pari_unlink(FREL_str);
                   3505:       pari_unlink(FNEW_str);
                   3506:       pari_unlink(LPREL_str);
                   3507:       pari_unlink(LPNEW_str);
                   3508:       if (DEBUGLEVEL >= 4)
                   3509:       {
                   3510:        fprintferr("\nMPQS: time in Gauss and gcds = %ld ms\n",
                   3511:                   timer2());
                   3512:        if (typ(fact) == t_INT)
                   3513:          fprintferr("MPQS: found factor = %Z\n", fact);
                   3514:        else
                   3515:        {
                   3516:          long j, nf=(lg(fact)-1)/3;
                   3517:          if (nf==2)
                   3518:            fprintferr("MPQS: found factors = %Z\n\tand %Z\n",
                   3519:                        fact[4], fact[1]);
                   3520:          else
                   3521:          {
                   3522:            fprintferr("MPQS: found %ld factors =\n", nf);
                   3523:            for (j=nf; j; j--)
                   3524:              fprintferr("\t%Z%s\n", fact[3*j-2], (j>1? "," : ""));
                   3525:          }
                   3526:        }
                   3527:       }
                   3528:       if (mpqs_diffptr == diffptr) mpqs_diffptr = NULL;
                   3529:       all_clean = 1;
                   3530:       /* nuisance: fact may not be safe for a gcopy(), and thus
                   3531:         gerepilecopy(av, fact) will usually segfault on
                   3532:         one of the NULL markers.  However, it is already a nice
                   3533:         connected object, and it resides already the top of the
                   3534:         stack, so... :^) --GN */
                   3535:       return gerepileupto(av, fact);
                   3536:     }
                   3537:     else
                   3538:     {
                   3539:       if (DEBUGLEVEL >= 4)
                   3540:       {
                   3541:        fprintferr("\nMPQS: time in Gauss and gcds = %ld ms\n",
                   3542:                   timer2());
                   3543:        fprintferr("MPQS: no factors found.\n");
                   3544:        if (percentage <= max_percentage)
                   3545:          fprintferr("\nMPQS: restarting sieving ...\n");
                   3546:        else
                   3547:          fprintferr("\nMPQS: giving up.\n");
                   3548:       }
                   3549:       if (percentage > max_percentage)
                   3550:       {
                   3551:        /* clean up */
                   3552:        CLEANUP();
                   3553:        pari_fclose(pLPNEW);
                   3554:        pari_unlink(FREL_str);
                   3555:        pari_unlink(FNEW_str);
                   3556:        pari_unlink(LPREL_str);
                   3557:        pari_unlink(LPNEW_str);
                   3558:        if (mpqs_diffptr == diffptr) mpqs_diffptr = NULL;
                   3559:        all_clean = 1;
                   3560:        avma=av; return NULL;
                   3561:       }
                   3562:       pFNEW = pari_fopen(FNEW_str, WRITE); /* NOT safefopen */
                   3563:       FNEW = pFNEW->file;
                   3564:     }
                   3565:   } /* main loop */
                   3566: }

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