示例#1
0
文件: zmath.cpp 项目: Zoooook/Zmath
 void buildSieveTo(unsigned long long n){
     if(n<=4289995710U)
         doSieve(n);
     else{
         doSieve(4289995710U);
         doBigSieve(n);
     }
 }
示例#2
0
文件: zmath.cpp 项目: Zoooook/Zmath
 unsigned int primesUpToSmall(unsigned int n, std::vector<unsigned int>& primes){
     if(n>=60184){
         primes.reserve((unsigned int)(n/(log(n)-1.1)));
         doSieve(n);
     }else if(n>=17){
         primes.reserve((unsigned int)(1.25506*n/log(n)));
         doSieve(n);
     }else
         primes.reserve(6);
     unsigned int t=0;
     if(n>=2){
         primes[0]=2;
         t=1;
     }
     if(n>=3){
         primes[1]=3;
         t=2;
     }
     if(n>=5){
         primes[2]=5;
         t=3;
     }
     if(n>=7){
         primes[3]=7;
         t=4;
     }
     if(n>=11){
         primes[4]=11;
         t=5;
     }
     if(n>=13){
         primes[5]=13;
         t=6;
     }
     if(n>=17){
         unsigned int b=1;
         unsigned int p=17;
         while(p<=n){
             primes[t]=p;
             ++t;
             ++b;
             while(!sieve[b])
                 ++b;
             p=b/5760*30030+conversions[b%5760];
         }
     }
     return t;
 }
示例#3
0
文件: zmath.cpp 项目: Zoooook/Zmath
 bool isPrimeSmall(unsigned int n){
     if(n==2 || n==3 || n==5 || n==7 || n==11 || n==13)
         return true;
     if(!(n&1U) || !(n%3) || !(n%5) || !(n%7) || !(n%11) || !(n%13))
         return false;
     doSieve(n);
     return sieve[n/30030*5760+indexes[n%30030]];
 }
示例#4
0
文件: zmath.cpp 项目: Zoooook/Zmath
 void firstPrimesSmall(unsigned int n, std::vector<unsigned int>& primes){
     primes.reserve(n);
     if(n<=194682290)
         doSieve((unsigned int)(n*log(n*log(n))));
     else
         doSieve(4289995710U);
     unsigned int t=0;
     if(n>=1){
         primes[0]=2;
         t=1;
     }
     if(n>=2){
         primes[1]=3;
         t=2;
     }
     if(n>=3){
         primes[2]=5;
         t=3;
     }
     if(n>=4){
         primes[3]=7;
         t=4;
     }
     if(n>=5){
         primes[4]=11;
         t=5;
     }
     if(n>=6){
         primes[5]=13;
         t=6;
     }
     if(n>=7){
         unsigned int b=1;
         unsigned int p=17;
         while(t<n){
             primes[t]=p;
             ++t;
             if(t<n){
                 ++b;
                 while(!sieve[b])
                     ++b;
                 p=b/5760*30030+conversions[b%5760];
             }
         }
     }
 }
示例#5
0
int main(){
    // unsigned long max = 10000000UL;
    unsigned long max = 10000000UL;
    // unsigned long max = 500UL;

    // doSieve(max*log(max)*log(log(max)) , &modPrint);
    doSieve((max * log(max) + max * (log(log(max)) - 0.9385)), &modPrint);
    printf("max = %lu\n", (max * log(max) + max * (log(log(max)) - 0.9385)));
    // check(13);

    return 0;
}
示例#6
0
文件: zmath.cpp 项目: Zoooook/Zmath
 unsigned int numPrimesUpToSmall(unsigned int n){
     doSieve(n);
     if(n>=17){
         unsigned int t=6;
         unsigned int b=1;
         unsigned int maxb=n/1001*192; // this can put maxb up to 2 greater than where it should be
         if(n%30030){
             if(maxb/5760*30030+conversions[maxb%5760]>n) // maxb is at most 1 greater than where it should be
                 --maxb;
             while(maxb/5760*30030+conversions[maxb%5760]<n) // force maxb up to equal (prime) or 1 greater (composite) than where it should be
                 ++maxb;
             if(maxb/5760*30030+conversions[maxb%5760]>n) // put maxb where it should be
                 --maxb;
         }else if(maxb)
             --maxb;
         if(n<=4289995710U){
             while(b<=maxb){
                 ++t;
                 ++b;
                 while(!sieve[b])
                     ++b;
             }
         }else{
             t=203056267;
             b=3;
             maxb-=822856320;
             while(b<=maxb){
                 ++t;
                 ++b;
                 while(!bigsieve[b])
                     ++b;
             }
         }
         return t;
     }else if(n>=13)
         return 6;
     else if(n>=11)
         return 5;
     else if(n>=7)
         return 4;
     else if(n>=5)
         return 3;
     else if(n>=3)
         return 2;
     else if(n>=2)
         return 1;
     else
         return 0;
 }
示例#7
0
文件: latsieve.c 项目: FairSky/ggnfs
int latSieve(s32 *candidates, int maxCands, nfs_fb_t *FB,
             s32 qIndex, double sieveArea, s32 cacheSize)    
/***************************************************************************/
/* We will not actually test for smoothness - instead, we will just return */
/* the list of candidates and allow the caller to test them. They will be  */
/* returned as: (a_i, b_i) = (candidates[2*i], candidates[2*i+1]).         */
/* Return value: negative on error. Otherwise, the number of candidates.   */
/***************************************************************************/
/* This function should be modified, to accept an area instead of a range  */
/* on the c, d values. It should compute the range of values from the area */
/* after we've obtained (short) generators for the lattice.                */
/***************************************************************************/
{ s32 q, s;           /* Special q prime. */
  char logQ;
  s32 a1, b1, a2, b2; /* Short vectors spanning the lattice L_q. */
  s32 v1[2], v2[2];   /* temp garbage. */
  short *Array, entry, ratInit, normApprox;
  s32 C, E;   /* Defining the total rectangle in the (c,e)-plane to be sieved. */
  s32 Clength; 
  s32 E0, E1; /* A particular sub-rectangle being sieved. */
  int  numPieces, pieceESize; /* Number of sub-rectangles and the size. */
  s32 *primeVec; /* Primes prepared for sieving (Master index) */
  char *logs, *rlogs, *alogs, *rElogs, *aElogs; /* Logs of those primes. */
  s32 *rU, *aU, numRU, numAU; /* Ordinary primes to be vector-sieved with. */
  s32 *rExc, *aExc, numRExc, numAExc; /* `Exceptional primes'. */
  s32 numVecs, rfbSize, afbSize;
  s32 p, r, t1, t2, c, e; /* temp stuff. */
  s32 rD, aD; /* Crossover from sieve-by-rows to sieve-by-vectors. */
  s32 i, j, a, b, g, index;
  int  numCands=0, rfb_log_ff, afb_log_ff;

  rfb_log_ff = (int)(FB->rfb_lambda * fplog(FB->rfb[FB->rfb_size-1], FB->log_rlb));
  afb_log_ff = (int)(FB->afb_lambda * fplog(FB->afb[FB->afb_size-1], FB->log_alb));

#ifdef Q_FROM_RFB
  if (qIndex >= FB->rfb_size) {
    fprintf(stderr, "latSieve() Error - invalid qIndex!\n");
     return -1;
  }
  q = FB->rfb[2*qIndex]; s = FB->rfb[2*qIndex+1]; logQ = FB->rfb_log[qIndex];
  rfbSize = qIndex; afbSize = FB->afb_size;
#else
  if (qIndex >= FB->afb_size) {
    fprintf(stderr, "latSieve() Error - invalid qIndex!\n");
     return -1;
  }
  q = FB->afb[2*qIndex]; s = FB->afb[2*qIndex+1]; logQ = FB->afb_log[qIndex];
  rfbSize = FB->rfb_size; afbSize = qIndex;
#endif

  v1[0]=q; v1[1]=0;
  v2[0]=s; v2[1]=1;
  reduceBasis(v1, v2);
  a1=v1[0]; b1=v1[1]; a2=v2[0]; b2=v2[1];
  if (b1 < 0) { a1=-a1; b1=-b1;}
  if (b2 < 0) { a2=-a2; b2=-b2;}
//printf("For (q,s)=(%ld,%ld), L_q has basis: (%ld, %ld), (%ld, %ld)\n",q,s,a1,b1,a2,b2);

  /************************************************************************/
  /* We should compute the shape of the rectangle in the (c,e) plane.     */
  /* That is, assume a fixed amount of memory A, and find the rect.       */
  /* defined by -C<=c<=C, 0 < e <= E so that the average resulting 'b'    */
  /* value, |c*b1 + e*b2|, is minimal (or close to it).                   */
  /* Equivalently, minimize:                                              */
  /*  sum_R |c*b1 + e*b2|, where the sum is over all -C<=c<=C, 0 < e <= E */
  /* subject to the constraint that (2C+1)E = A.                          */
  /************************************************************************/
  /* We will approximate the solution to the above constrained optimization */
  /* problem later. But I think this should be pretty close (or even correct). */
  C = (s32)1*(sqrt(sieveArea*b2/(double)(2.0+2.0*b1)));

//  if (C<1000) C = 1000; /* Arbitrary, but seems reasonable. */
  E = (s32)(sieveArea/C);
  Clength = 2*C+1;
  numPieces = (int)((sizeof(short)*sieveArea/cacheSize));
  if (numPieces*cacheSize < sieveArea)
    numPieces++;
  pieceESize = (E/numPieces);
//if (numPieces > 1) 
// printf("q=(%ld, %ld), C=[%ld, %ld], E=%ld, numPieces=%d\n",q,s,-C,C,E,numPieces);
  

  Array = (short *)malloc(pieceESize*(Clength)*sizeof(short));


  /*********************************/
  /*    Prepare the primes.        */
  /*********************************/
  primeVec = (s32 *)malloc((rfbSize+afbSize + MAX_R_EXC + MAX_A_EXC)*4*sizeof(s32));
  logs = (char *)malloc((rfbSize+afbSize + MAX_R_EXC + MAX_A_EXC)*sizeof(char));
  rExc = &primeVec[4*(rfbSize+afbSize)];
  aExc = &primeVec[4*(rfbSize+afbSize + MAX_R_EXC)];
  
  rElogs = &logs[rfbSize+afbSize];
  aElogs = &logs[rfbSize+afbSize + MAX_R_EXC];
  numVecs = numRExc = numAExc = 0;
  rD = aD = 0; /* Arbitrary for now, but should be fixed later, when we can treat
                  the small primes differently. */

  for (i=rD; i<rfbSize; i++) {
    p = FB->rfb[2*i]; r = FB->rfb[2*i+1];

    t2 = (a2 - mulmod32(r, b2, p) + p)%p;
    t1 = (mulmod32(r, b1, p) - a1%p + p)%p;
    if (t1&&t2) {
      primeVec[4*numVecs]=p; primeVec[4*numVecs+1]=0;
      primeVec[4*numVecs+2] = mulmod32(t2, inverseModP(t1, p), p); primeVec[4*numVecs+3]=1;
      reduceBasis(&primeVec[4*numVecs], &primeVec[4*numVecs+2]);
      if (primeVec[4*numVecs+1]<0) { primeVec[4*numVecs]=-primeVec[4*numVecs]; primeVec[4*numVecs+1]=-primeVec[4*numVecs+1];}
      if (primeVec[4*numVecs+3]<0) { primeVec[4*numVecs+2]=-primeVec[4*numVecs+2]; primeVec[4*numVecs+3]=-primeVec[4*numVecs+3];}
      logs[numVecs++] = FB->rfb_log[i];
    } else if (t1==0) {
      rExc[4*numRExc] = 1; rExc[4*numRExc+1] = 0;
      rExc[4*numRExc+2] = 0; rExc[4*numRExc+3] = p;
      rElogs[numRExc++] = FB->rfb_log[i];
    } else {
      rExc[4*numRExc] = p; rExc[4*numRExc+1] = 0;
      rExc[4*numRExc+2] = 0; rExc[4*numRExc+3] = 1;
      rElogs[numRExc++] = FB->rfb_log[i];
    }
  }
  rU = primeVec; numRU = numVecs;
  rlogs = logs;

  for (i=aD; i<afbSize; i++) {
    p = FB->afb[2*i]; r = FB->afb[2*i+1];

    t2 = (a2 - mulmod32(r, b2, p) + p)%p;
    t1 = (mulmod32(r, b1, p) - a1%p + p)%p;
    if (t1&&t2) {
      primeVec[4*numVecs]=p; primeVec[4*numVecs+1]=0;
      primeVec[4*numVecs+2] = mulmod32(t2, inverseModP(t1, p), p); primeVec[4*numVecs+3]=1;
      reduceBasis(&primeVec[4*numVecs], &primeVec[4*numVecs+2]);
      if (primeVec[4*numVecs+1]<0) { primeVec[4*numVecs]=-primeVec[4*numVecs]; primeVec[4*numVecs+1]=-primeVec[4*numVecs+1];}
      if (primeVec[4*numVecs+3]<0) { primeVec[4*numVecs+2]=-primeVec[4*numVecs+2]; primeVec[4*numVecs+3]=-primeVec[4*numVecs+3];}

      logs[numVecs++] = FB->afb_log[i];
    } else if (t1==0) {
      aExc[4*numAExc] = 1; aExc[4*numAExc+1] = 0;
      aExc[4*numAExc+2] = 0; aExc[4*numAExc+3] = p;
      aElogs[numAExc++] = FB->afb_log[i];
    } else {
      aExc[4*numAExc] = p; aExc[4*numAExc+1] = 0;
      aExc[4*numAExc+2] = 0; aExc[4*numAExc+3] = 1;
      aElogs[numAExc++] = FB->afb_log[i];
    }
  }
  aU = &primeVec[4*numRU]; numAU = numVecs - numRU;
  alogs = &logs[numRU];

  /* Ok - let's sieve. */

  E0 = 1; E1 = pieceESize;
  for (i=0; i<numPieces; i++) {

    /* Initialize the sieve array for the rational sieve. */
    ratInit = (short)(rfb_log_ff - fplog_mpz(FB->m, FB->log_rlb));
    for (j=Clength*(E1-E0+1)-1; j>=0; j--)
      Array[j]=ratInit;

    /* We need to sieve by rows with the first rD primes here! */

    doSieve(Array, C, E0, E1, rU, numRU, rlogs);
    doSieveE(Array, -C, C, E0, E1, rExc, numRExc, rElogs);



    /* Initialize for the algebraic sieve. */
 /*******************************************************************/
 /* This needs to be implemented:                                   */
 /* We should use Lenstra's trick here: Instead of computing the    */
 /* norm for all candidates which survived the rational sieve,      */
 /* simply use the same really rough approximation for all of them. */
 /* Then, when we are pulling candidates out of the array, we can   */
 /* compute the real norm and look at it a bit more closely.        */
 /*******************************************************************/
    normApprox = fplog_evalF(a1+a2, b1+b2, FB) - 7; /* -3 for luck :) */
    entry = rfb_log_ff + logQ - normApprox;
    index=0;
    for (e=E0; e<=E1; e++) {
      for (c=-C; c<=C; c++) {
        if (Array[Clength*(e-E0)+c+C] >= 0) {
          b = c*b1 + e*b2; if (b<0)b=-b;
          if (Array[Clength*(e-E0)+c+C] >= fplog(b, FB->log_rlb))          
            Array[Clength*(e-E0)+c+C] = entry;
          else
            Array[Clength*(e-E0)+c+C] = VERYSMALL_SHORT;
        } else
          Array[Clength*(e-E0)+c+C] = VERYSMALL_SHORT;
      }
    }

    /* We need to sieve by rows with the first aD primes here! */
 
    doSieve(Array, C, E0, E1, aU, numAU, alogs);
    doSieveE(Array, -C, C, E0, E1, aExc, numAExc, aElogs);


    /* Find candidates. */
//    entry = fplog_evalF(a1+a2, b1+b2, FB);
    for (j=Clength*(E1-E0+1)-1; j>=0; j--) {
      if ((Array[j] >= 0)&&(numCands < maxCands)) {
        e = E0 + j/Clength;
        c = -C + (j%Clength);
        a = c*a1 + e*a2;
        b = c*b1 + e*b2;
        if (b<0) { a=-a; b=-b;}
        if ((Array[j] + normApprox - fplog_evalF(a,b, FB))>=0) {
          g = gcd(a,b); 
          if ((g==1)||(g==-1)) {
            candidates[2*numCands] = a;
            candidates[2*numCands+1] = b;
            numCands++;
          }
        }
      }
    }
    /* Prepare to do the next sub-rectangle. */
    E0 += pieceESize; E1 += pieceESize;
  }

  free(Array); 
  free(primeVec); 
  free(logs);
  return numCands;
}
示例#8
0
文件: zmath.cpp 项目: Zoooook/Zmath
 unsigned char factorSmall(unsigned int n, unsigned int* factors, unsigned char* exponents){
     unsigned char exp=0;
     unsigned char numfacs=0;
     while(!(n&1U)){
         ++exp;
         n>>=1;
     }
     if(exp){
         factors[0]=2;
         exponents[0]=exp;
         numfacs=1;
         exp=0;
     }
     while(!(n%3)){
         ++exp;
         n/=3;
     }
     if(exp){
         factors[numfacs]=3;
         exponents[numfacs]=exp;
         ++numfacs;
         exp=0;
     }
     while(!(n%5)){
         ++exp;
         n/=5;
     }
     if(exp){
         factors[numfacs]=5;
         exponents[numfacs]=exp;
         ++numfacs;
         exp=0;
     }
     while(!(n%7)){
         ++exp;
         n/=7;
     }
     if(exp){
         factors[numfacs]=7;
         exponents[numfacs]=exp;
         ++numfacs;
         exp=0;
     }
     while(!(n%11)){
         ++exp;
         n/=11;
     }
     if(exp){
         factors[numfacs]=11;
         exponents[numfacs]=exp;
         ++numfacs;
         exp=0;
     }
     while(!(n%13)){
         ++exp;
         n/=13;
     }
     if(exp){
         factors[numfacs]=13;
         exponents[numfacs]=exp;
         ++numfacs;
         exp=0;
     }
     unsigned int b = 1;
     unsigned int p = 17;
     if(maxsieve*maxsieve<n){
         while(b<maxbool && p*p<=n){
             while(!(n%p)){
                 ++exp;
                 n/=p;
             }
             if(exp){
                 factors[numfacs]=p;
                 exponents[numfacs]=exp;
                 ++numfacs;
                 exp=0;
             }
             ++b;
             while(!sieve[b])
                 ++b;
             p = b/5760*30030+conversions[b%5760];
         }
         if(p*p<=n)
             doSieve(sqrt(n));
     }
     if(p*p<=n){
         while(!sieve[b])
             ++b;
         p = b/5760*30030+conversions[b%5760];
     }
     while(p*p<=n){
         while(!(n%p)){
             ++exp;
             n/=p;
         }
         if(exp){
             factors[numfacs]=p;
             exponents[numfacs]=exp;
             ++numfacs;
             exp=0;
         }
         ++b;
         while(!sieve[b])
             ++b;
         p = b/5760*30030+conversions[b%5760];
     }
     if(n>1){
         factors[numfacs]=n;
         exponents[numfacs]=1;
         ++numfacs;
     }
     return numfacs;
 }