Exemplo n.º 1
0
def factors(n, veb, ra, ov, pr):
   '''Generates factors of n.
Strips small primes, then feeds to ecm function.

Input:
   n   -- An integer to factor
   veb -- If True, be verbose
   ra  -- If True, select sigma values randomly
   ov  -- How asymptotically fast the calculation is
   pr  -- What portion of the total processing power this run gets

Output: Factors of n, via a generator.

Notes:
1. A good value of ov for typical numbers is somewhere around 10. If this parameter is too high, overhead and memory usage grow.
2. If ra is set to False and veb is set to True, then results are reproducible. If ra is set to True, then one number may be done in parallel on disconnected machines (at only a small loss of efficiency, which is less if pr is set correctly).'''

   if type(n) not in T:
      raise ValueError('Number given must be integer or long.')

   if not 0 < pr <= 1:
      yield 'Error: pr must be between 0 and 1'
      return

   while not n & 1:
      n >>= 1
      yield 2

   n = mpz(n)
   k = inv_const(n)
   prime = 2
   trial_division_bound = max(10 * k**2, 100)

   while prime < trial_division_bound:
      prime = next_prime(prime)

      while not n % prime:
         n = n // prime
         yield prime

   if n in g.factorCache:
       if veb and n != 1:
           print( 'cache hit:', n )

       for i in getExpandedFactorList( g.factorCache[ n ] ):
           yield i

       return

   if isprime(n):
      yield n
      return

   if n == 1:
      return

   for factor in ecm(n, ra, ov, veb, trial_division_bound, pr):
      yield factor
Exemplo n.º 2
0
def sure_factors(n, u, curve_params, veb, ra, ov, tdb, pr):
   '''Factor n as far as possible with given smoothness bound and curve parameters, including possibly (but very rarely) calling ecm again.

Yields factors of n.'''
   f = mainloop(n, u, curve_params)

   if f == 1:
      return

   if f in g.factorCache:
       if veb and f != 1:
           print( 'cache hit:', f )

       for i in getExpandedFactorList( g.factorCache[ f ] ):
           yield i

       return

   if veb:
      print( 'Found factor:', f )
      #print('Mainloop call was:', n, u, curve_params)

   if isprime(f):
      congrats( f, veb )
      yield f
      n = n // f

      if n in g.factorCache:
          if veb and f != 1:
              print( 'cache hit:', n )

          for i in getExpandedFactorList( g.factorCache[ n ] ):
              yield i

          return

      if isprime(n):
         yield n

      #if veb:
      #   print('(factor processed)')
      return

   for factor in sub_sure_factors(f, u, curve_params):
      if factor in g.factorCache:
          if veb and factor != 1:
              print( 'cache hit:', factor )

          for i in getExpandedFactorList( g.factorCache[ factor ] ):
              yield i

          return

      if isprime(factor):
         congrats(f, veb)
         yield factor
      else:
         if veb:
            print('entering new ecm loop to deal with stubborn factor:', factor)

         for factor_of_factor in ecm(factor, True, ov, veb, tdb, pr):
            yield factor_of_factor

      n = n // factor

      if n in g.factorCache:
          if veb and n != 1:
              print( 'cache hit:', n )

          for i in getExpandedFactorList( g.factorCache[ n ] ):
              yield i

          return

   if isprime(n):
      yield n

   return
Exemplo n.º 3
0
def getECMFactorList( n ):
    return getExpandedFactorList( getECMFactors( n ) )
Exemplo n.º 4
0
def ecm(n, ra, ov, veb, tdb, pr): # DOCUMENTATION
   '''Input:
   n   -- An integer to factor
   veb -- If True, be verbose
   ra  -- If True, select sigma values randomly
   ov  -- How asymptotically fast the calculation is
   pr  -- What portion of the total processing power this run gets

Output: Factors of n, via a generator.

Notes:
1. A good value of ov for typical numbers is somewhere around 10. If this parameter is too high, overhead and memory usage grow.
2. If ra is set to False and veb is set to True, then results are reproducible. If ra is set to True, then one number may be done in parallel on disconnected machines (at only a small loss of efficiency, which is less if pr is set correctly).'''

   if veb:
      looking_for = 0
   k = inv_const(n)

   if ra:
      sigma = 6 + random.randrange(BILLION)
   else:
      sigma = 6

   for factor in sure_factors(n, k, list(range(sigma, sigma + k)), veb, ra, ov, tdb, pr):
      yield factor
      n = n // factor

      if n in g.factorCache:
          if veb and n != 1:
              print( 'cache hit:', n )

          for i in getExpandedFactorList( g.factorCache[ n ] ):
              yield i

          return

   if ra:
      sigma += k + random.randrange(BILLION)
   else:
      sigma += k

   x_max = 0.5 * math.log(n) / math.log(k)
   t = rho_ts(int(x_max))
   prime_probs = []
   nc = 1 + int(_12_LOG_2_OVER_49 * ov * ov * k)
   eff_nc = nc / pr

   for i in range(1 + (int(math.log(n)) >> 1)):
      if i < math.log(tdb):
         prime_probs.append(0)
      else:
         prime_probs.append(1.0/i)

   for i in range(len(prime_probs)):
      p_success = rho_ev((i - 2.65) / math.log(k), t)
      p_fail = max(0, (1 - p_success * math.log(math.log(k)))) ** (k / pr)
      prime_probs[i] = p_fail * prime_probs[i] / (p_fail * prime_probs[i] + 1 - prime_probs[i])

   while n != 1:
      low = int(k)
      high = n
      while high > low + 1:
         u = (high + low) >> 1
         sum = 0
         log_u = math.log(u)
         for i in range(len(prime_probs)):
            log_p = i - 2.65
            log_u = math.log(u)
            quot = log_p / log_u
            sum += prime_probs[i] * (rho_ev(quot - 1, t) - rho_ev(quot, t) * log_u)
         if sum < 0:
            high = u
         else:
            low = u

      if ra:
         sigma += nc + random.randrange(BILLION)
      else:
         sigma += nc

      for factor in sure_factors(n, u, list(range(sigma, sigma + nc)), veb, ra, ov, tdb, pr):
         yield factor
         n = n // factor

         if n in g.factorCache:
             if veb and n != 1:
                 print( 'cache hit:', n )

             for i in getExpandedFactorList( g.factorCache[ n ] ):
                 yield i

             return

      for i in range(len(prime_probs)):
         p_success = rho_ev((i - 2.65) / math.log(u), t)
         p_fail = max(0, (1 - p_success * math.log(math.log(u)))) ** eff_nc
         prime_probs[i] = p_fail * prime_probs[i] / (p_fail * prime_probs[i] + 1 - prime_probs[i])
      prime_probs = prime_probs[:1 + (int(math.log(n)) >> 1)]

      if veb and n != 1:
         m = max(prime_probs)
         for i in range(len(prime_probs)):
            if prime_probs[i] == m:
               break

         new_looking_for = (int(i / _5_LOG_10) + 1)
         new_looking_for += new_looking_for << 2

         if new_looking_for != looking_for:
            looking_for = new_looking_for
            print('Searching for primes around', looking_for, 'digits')

   return
Exemplo n.º 5
0
def getFactorList( n ):
    # We shouldn't have to check for lists here, but something isn't right...
    if isinstance( n, list ):
        return [ getFactorList( i ) for i in n ]

    return getExpandedFactorList( getFactors( n ) )