Exemplo n.º 1
0
// {{{ sieve()
void sieve(Polynomial &polynomial, Target &target, FactorBase &fb,   
   int pairs_needed, std::vector<int> &av, std::vector<int> &bv)
{
   std::vector<double> normv; 
   int b = 0;
   int pairs_found = 0;
   normv.resize(2*target.C+1);
   av.resize(pairs_needed);
   bv.resize(pairs_needed);
   int u = polynomial.d*target.t;
   int i;
   int p;
   NTL::ZZ numZ;
   NTL::ZZ valZ;


   while(pairs_found < pairs_needed)
   {
      // Note: i-C = a
      int a;

      b++;
			
      for(i=0; i<=2*target.C; i++)
      {
			valZ = (i-target.C) + b*polynomial.m;

         if(NTL::GCD(i-target.C, b)!=1 || valZ==0)
            normv[i] = SKIP;

         else
				normv[i] = 0.5 - log(abs(valZ));
      }


      // Test for RFB-smoothness
      for(i=0; i < target.t; i++)
      {
         p = fb.RFB[i];
         a = (int)(p * (-floor(target.C / p)) - (b * fb.RFBm[i])) + target.C;
         
			while(a < 0)
            a += p;
         
         while(a <= 2*target.C)
         {
            if(normv[a] != SKIP)
               normv[a] += fb.RFBlog[i];

            a += p;
         }

         // Now check p^2, p^3, ....
         int pPow = p * p;

         while(pPow < 2 * target.C)
         {
            a = (int)(pPow * (-floor(target.C/pPow))-
					(b*(polynomial.m % pPow))) + target.C;

            while(a < 0)
               a += pPow;
            
            while(a <= 2*target.C)
            {
               if(normv[a] != SKIP)
                  normv[a] += fb.RFBlog[i];
               
               a += pPow;
            }
            pPow *= p;
         }
      }

      // Initialize normv with -ln( (-b)^d*f(-a/b) )
      for(i=0; i<=2*target.C; i++)
      {
         if(normv[i] > 0)
         {
            // init Norm
            numZ = abs(algebraic_norm(polynomial, i-target.C, b));
            if(numZ == 0)
               normv[i] = SKIP;
            else
               normv[i] = fb.AFBlog[u-1] - log(numZ);
         }
         else
            normv[i] = SKIP;
      }

      // Test for AFB-smoothness
      for(i=0; i<u; i++)
      {
         p = fb.AFB[i];

         a = (int)(p * (-floor(target.C / p)) - (b * fb.AFBr[i])) + target.C;
         while(a < 0)
            a += p;

         while(a <= 2*target.C)
         {
            if(normv[a] != SKIP)
               normv[a] += fb.AFBlog[i];

            a += p;
         }
      }

      // Search for good (a,b)'s
      for(int i=0; i<=2*target.C; i++)
      {
         if(normv[i] > 0)
         {
            if(pairs_found < pairs_needed)
            {
               av[pairs_found] = i-target.C;
               bv[pairs_found++] = b;
            }
         }
      }

		// info
      std::cout << "\tit: " << b << " relation: " << pairs_found
			<< " needed: " << pairs_needed << " completed: (" 
			<< (pairs_found*100)/pairs_needed << "%)\r";
   }


}
Exemplo n.º 2
0
// {{{ linear_algebra()
void linear_algebra(
   GNFS::Polynomial &polynomial, 
   GNFS::Target &target, 
	FactorBase &fb, 
   Matrix &matrix, 
   const std::vector<int> &av, 
   const std::vector<int> &bv)
{

   NTL::ZZ aZ;
   NTL::ZZ bZ;
   NTL::ZZ pZ;
   NTL::ZZ valZ;
   NTL::ZZ numZ;
   int i;
   int j;
   int k;
   int u = polynomial.d*target.t;


   // Initialize sM
   for(j = 0; j <= matrix.sM.NumCols()-1; j++)
   {
      // Initialize row
      for(k = 0; k < matrix.sM.NumCols()-1; k++)
         matrix.sM[k][j] = 0;
      
      // Set the first column
      aZ = av[j];
      bZ = bv[j];
      valZ = aZ + bZ * polynomial.m;
      if(valZ < 0)
      {
         valZ *= -1;
         matrix.sM[0][j] = 1;
      }

      // Set a RFB row 
      i = 0;
      while(i < target.t && valZ != 1)
      {
         pZ = fb.RFB[i];
         if(valZ % pZ == 0)
         {
            if(matrix.sM[1+i][j]==0) matrix.sM[1+i][j]=1;
            else matrix.sM[1+i][j]=0;
            valZ = valZ / pZ;
         } 
         else i++;
      }

      // Set a AFB row 
      valZ = algebraic_norm(polynomial, av[j], bv[j]);
      if(valZ < 0)
         valZ *= -1;
      
      i = 0;
      while(i<u && valZ!=1)
      {
         pZ = fb.AFB[i];
         if(valZ % pZ == 0)
         {
            numZ = fb.AFBr[i];
            //while((aZ + bZ * numZ) % pZ != 0 && i<target.t) // TODO
            while((aZ + bZ * numZ) % pZ != 0) // TODO
            {
               pZ = fb.AFB[++i];
               numZ = fb.AFBr[i];
            }

            if(matrix.sM[1+target.t+i][j]==0) matrix.sM[1+target.t+i][j]=1;
            else matrix.sM[1+target.t+i][j]=0;

            valZ = valZ / pZ;
         }
         else i++;
         
      }

      // Set a QCB row
      for(i=0; i<target.digits; i++)
      {
         numZ = fb.QCB[i];
         valZ = fb.QCBs[i];
         valZ = aZ + bZ * valZ;
         if(Legendre(valZ, numZ) != 1)
         {
            matrix.sM[1+target.t+u+i][j]=1;
         
         }
      }
   }
   
   std::cout << "\tSize: " << matrix.sM.NumRows() << "x" << matrix.sM.NumCols() << std::endl;

   gaussian_elimination(matrix.sM);
   matrix.sfreeCols = get_freecols(matrix.sM);

}