def lehman(n): """ Returns a nontrivial divisor of n, or proves primality. Given an integer n > 1, this algorithm finds a nontrivial factor of n if n is not prime, or returns n if n is prime. Input: * n: int (n >= 3) Output: * d: int If d == n, then n is proven prime. Otherwise, d is a nontrivial divisor of n. Examples: >>> l = 1112470797641561909 >>> lehman(l) 1056689261L Details: The algorithm used is Lehman's Method. This algorithm runs in time O(n^(1/3)), where n is the number to be factored / proven prime. This is substantially better than O(n^(1/2)) trial division for reasonably small value of n, but this algorithm is not suited for large values of n. See section 8.4 of "A Course in Computational Algebraic Number Theory" by Cohen or section 5.1.2 of "Prime Numbers - A Computational Perspective" by Crandall and Pomerance for more details. """ # first, we trial divide up to floor(n^(1/3)) bound = integer_nth_root(3, n) d = trial_division(n, bound) if d < n: return d for k in xrange(1, bound + 1): if k % 2 == 0: r = 1 m = 2 else: r = k + n m = 4 # we want to iterate over a, where 4*k*n <= a^2 <= 4*k*n + bound^2 # and a = r (mod m) fkn = 4*k*n a = integer_sqrt(fkn) # now, increase a until a = r (mod m) rm = r % m while a % m != rm: a += 1 ub = fkn + bound**2 while fkn <= a*a <= ub: c = a*a - fkn b = integer_sqrt(c) if b*b == c: return gcd(a + b, n) a += m return n
def fermat(n): r"""Returns a nontrivial divisor of `n`, or proves primality. Given an integer `n` > 1, this algorithm attempts to find a factor of `n` using Fermat's method. Parameters ---------- n : int (n > 1) Returns ------- d : int If n == d, then n is proven prime. Otherwise, d is a nontrivial divisor of n. Notes ----- This algorithm runs in time O((n + 1) / 2 - sqrt(n)), where n is the number to be factored. In the worst case, n = 2*p, this algorithm is much worse than trial division. Note that the worse case for Fermat's method is the best case for trial division. References ---------- .. [1] R. Crandall, C. Pomerance, "Prime Numbers: A Computational Perspective", Springer-Verlag, New York, 2001. .. [2] D.E. Knuth, "The Art of Computer Programming, Volume 2: Seminumerical Algorithms", Addison-Wesley Longman Publishing Co., Inc, Boston, MA, 1997. Examples -------- >>> fermat(100) 2 >>> fermat(1112470797641561909) 1052788969 """ if n % 2 == 0: return 2 for a in xrange(integer_sqrt(n) + 1, (n + 9)//6 + 1): t = a*a - n b = integer_sqrt(t) if b*b == t: return a - b return n
def fermat(n): r"""Returns a nontrivial divisor of `n`, or proves primality. Given an integer `n` > 1, this algorithm attempts to find a factor of `n` using Fermat's method. Parameters ---------- n : int (n > 1) Returns ------- d : int If n == d, then n is proven prime. Otherwise, d is a nontrivial divisor of n. Notes ----- This algorithm runs in time O((n + 1) / 2 - sqrt(n)), where n is the number to be factored. In the worst case, n = 2*p, this algorithm is much worse than trial division. Note that the worse case for Fermat's method is the best case for trial division. References ---------- .. [1] R. Crandall, C. Pomerance, "Prime Numbers: A Computational Perspective", Springer-Verlag, New York, 2001. .. [2] D.E. Knuth, "The Art of Computer Programming, Volume 2: Seminumerical Algorithms", Addison-Wesley Longman Publishing Co., Inc, Boston, MA, 1997. Examples -------- >>> fermat(100) 2 >>> fermat(1112470797641561909) 1052788969 """ if n % 2 == 0: return 2 for a in xrange(integer_sqrt(n) + 1, (n + 9) // 6 + 1): t = a * a - n b = integer_sqrt(t) if b * b == t: return a - b return n
def _pell_general(D, N, one_solution=False): """ test with D = 1121311213, N = 11889485036288588 """ # Find fundamental solution to Pell for (t, u) in QuadraticIrrational(D).convergents(): if t*t - D*u*u == 1: break # Now find fundamental solution to general Pell fundamental_solutions = [] residues = sqrts_mod_n(N, D) L = N*(t - 1) print residues for r in residues: for x in itertools.count(r, D): w = (x*x - N)//D if w < 0: continue elif 2*D*w > L: break y = integer_sqrt(w) if y*y == w: if one_solution: yield (x, y) return fundamental_solutions.append((x, y)) (r, s) = (-x, y) if (x*r - D*y*s) % N != 0 or (x*s - y*r) % N != 0: fundamental_solutions.append((r, s)) minimal_positive_solutions = [] for (x, y) in fundamental_solutions: if x < 0: (r, s) = (-x, -y) p = r*t + s*u*D q = r*u + s*t minimal_positive_solutions.append((p, q)) else: minimal_positive_solutions.append((x, y)) minimal_positive_solutions.sort() if not minimal_positive_solutions: return print minimal_positive_solutions while True: for i in xrange(len(minimal_positive_solutions)): x, y = minimal_positive_solutions[i] yield (x, y) minimal_positive_solutions[i] = (x*t + y*u*D, x*u + y*t)
def cfrac_aq_pairs(n): """ Yields tripes (i, A_{i - 1}, Q_i) for i > 0, where A_{i - 1}^2 = (-1)^i Q_i (mod n) Input: * n: int Output: * X: generator Details This algorithm expands sqrt(n) into a simple continued fraction. The values (i, A_{i - 1}, Q_i) output by this algorithm correspond to """ g = integer_sqrt(n) A0, A1 = 0, 1 Q0, Q1 = n, 1 P0 = 0 r0 = g for i in itertools.count(): q = (g + P0)//Q1 r1 = g + P0 - q*Q1 A2 = (q*A1 + A0) % n P1 = g - r1 Q2 = Q0 + q*(r1 - r0) if i > 0: yield (i, A1, Q1) A0, A1 = A1, A2 Q0, Q1 = Q1, Q2 P0 = P1 r0 = r1
def _initialize_sqrt(self, d): """Initializes the continued fraction expansion of sqrt(d). """ r = integer_sqrt(d) if r*r == d: raise ValueError("QuadraticIrrational: d cannot be a perfect square.") Q = 1 P = 0 terms = [] while True: q = (P + r)//Q terms.append(q) # The continued fraction expansion of sqrt(d) is periodic of the # form [a0; a1, a2, ..., a2, a1, 2*a0], so we can terminate when we # encounter a partial quotient equal to 2*a0. See Theorem 5.10 of # "Fundamental Number with Applications" by Mollin for details. if q == 2*r: break P = q*Q - P Q = (d - P*P)//Q self.period_length = len(terms) - 1 self.pre_period = [r] self.fundamental_period = terms[1:]
def _initialize_quadratic(self, d, p, q): """Initializes the continued fraction expansion of (p + sqrt(d))/q, for (p, q) != (0, 1). """ r = integer_sqrt(d) if r*r == d: raise ValueError("QuadraticIrrational: d cannot be a perfect square.") # A quadratic irrational can be written in the form (P + sqrt(D))/Q, # for some integers P, Q != 0, and D not a perfect square, with # (D - P*P) = 0 (mod D). If we don't have this last divisibility # condition, then we modify P, Q, and D as appropriate. See Theorem 9.23 # of "The Theory of Numbers - A Text and Source Book of Problems" by # Adler and Coury for details. if (d - p*p) % q == 0: Q = q P = p D = d else: abs_q = abs(q) Q = abs_q*q P = abs_q*p D = q*q*d r = integer_sqrt(D) pq_pairs = {(p, q): 0} partial_quotients = [] for i in itertools.count(1): a = (P + r)//Q P = a*Q - P Q = (D - P*P)//Q partial_quotients.append(a) # Encountering a (P, Q) pair which we have already seen means that # we have started a new period, and so we can break out of the loop. if (P, Q) in pq_pairs: j = pq_pairs[(P, Q)] k = i break else: pq_pairs[(P, Q)] = i self.period_length = k - j self.pre_period = partial_quotients[0:j] self.fundamental_period = partial_quotients[j:]
def eratosthenes1(n): r"""Returns a list of all primes p <= n. Parameters ---------- n : int Returns ------- primes : list A list of the primes <= n. See Also -------- chartres, eratosthenes2, luo Notes ----- This algorithm is an implementation of the first extension of the sieve of Eratosthenes by removing the multiples of 2 from the set of candidates. This has the effect of halving the required space and time of the algorithm. See the paper [1] for details. See the commentary [2] for more details and extensions. All versions of the Sieve of Eratosthenes require O(n*log(log(n))) operations to find the primes up to n. Using a simple wheel like this cuts down on the required time, but the overall complexity is not changed. References ---------- .. [1] X. Luo, "A Practical Sieve Algorithm for Finding Prime Numbers", Communications of the ACM, Volume 32, Number 3, March 1989. .. [2] Quesada, Pritchard, James, "Additional Notes on a Practical Sieve Algorithm", Communications of the ACM, Volume 35, Issue 3, March 1992. Examples -------- >>> eratosthenes1(20) [2, 3, 5, 7, 11, 13, 17, 19] >>> len(eratosthenes(10**6)) 78498 """ if n <= 1: return [] m = n//2 + 1 block = bytearray([1])*m sqrt = integer_sqrt(m) for i in xrange(1, sqrt + 1): if block[i]: k = 2*i + 1 start = k*k//2 count = (m - start)//k + ((m - start) % k > 0) block[start::k] = bytearray([0])*count return [2] + [2*i + 1 for i in xrange(1, n//2 + n % 2) if block[i]]
def phi3(n, a, b, c): s2 = 0 for i in xrange(a, c): bi = phi(integer_sqrt(n//primes[i]), b) + b - 1 for j in xrange(i, bi): idx = phi(n//(primes[i]*primes[j]), b) + b - 1 s2 += idx - j return s2
def phi3(n, a, b, c): s2 = 0 for i in xrange(a, c): bi = phi(integer_sqrt(n // primes[i]), b) + b - 1 for j in xrange(i, bi): idx = phi(n // (primes[i] * primes[j]), b) + b - 1 s2 += idx - j return s2
def test_integer_sqrt(self): self.assertRaisesRegexp(ValueError, "integer_sqrt: Must have n >= 0.", integer_sqrt, -1) for i in xrange(100): a = random.randint(100, 1000) b = random.randint(100, 1000) n = a**b r = integer_sqrt(n) self.assertTrue(r**2 <= n < (r + 1)**2)
def moebius_xrange(a, b=None): """Return an iterator over values of moebius(k) for a <= k < b. Input: * a: int (a > 0) * b: int (b > a) (default=None) Returns: * P: generator The values output by this generator are tuples (n, moebius(n)) where n is an integer in [a, b), and moebius(n) is the value of the moebius function. Examples: >>> list(moebius_xrange(10, 20)) [(10, 1), (11, -1), (12, 0), (13, -1), (14, 1), (15, 1), (16, 0), (17, -1), (18, 0), (19, -1)] Details: All primes <= sqrt(b) are computed, and a segmented sieve is used to build the values using the multiplicative property of the moebius function. See the paper "Computing the Summation of the Moebius Function" by Deleglise and Rivat for more information. """ if a < 2: a = 1 if b is None: b, a = a, 1 if b <= a: return block_size = integer_sqrt(b) prime_list = primes(block_size) for start in xrange(a, b, block_size): block = [1]*block_size values = [1]*block_size for p in prime_list: offset = ((p*(start//p + 1) - a) % block_size) % p for i in xrange(offset, block_size, p): if (start + i) % (p*p) == 0: block[i] = 0 else: block[i] *= -1 values[i] *= p for i in xrange(block_size): if start + i >= b: return if block[i] and values[i] < start + i: block[i] *= -1 yield (start + i, block[i])
def moebius_xrange(a, b=None): """Return an generator over values of moebius(k) for a <= k < b. Input: * a: int (a > 0) * b: int (b > a) (default=None) Returns: * P: generator The values output by this generator are tuples (n, moebius(n)) where n is an integer in [a, b), and moebius(n) is the value of the moebius function. Examples: >>> list(moebius_xrange(10, 20)) [(10, 1), (11, -1), (12, 0), (13, -1), (14, 1), (15, 1), (16, 0), (17, -1), (18, 0), (19, -1)] Details: All primes <= sqrt(b) are computed, and a segmented sieve is used to build the values using the multiplicative property of the moebius function. See the paper "Computing the Summation of the Moebius Function" by Deleglise and Rivat for more information. """ if a < 2: a = 1 if b is None: b, a = a, 1 if b <= a: return block_size = integer_sqrt(b) prime_list = prime_sieves.primes(block_size) for start in xrange(a, b, block_size): block = [1] * block_size values = [1] * block_size for p in prime_list: offset = ((p * (start // p + 1) - a) % block_size) % p for i in xrange(offset, block_size, p): if (start + i) % (p * p) == 0: block[i] = 0 else: block[i] *= -1 values[i] *= p for i in xrange(block_size): if start + i >= b: return if block[i] and values[i] < start + i: block[i] *= -1 yield (start + i, block[i])
def fermat(n): """ Returns a nontrivial divisor of n, or proves primality. Given an integer n > 1, this algorithm attempts to find a factor of n using Fermat's method. Input: * n: int (n > 1) Output: * d: int If n == d, then n is proven prime. Otherwise, d is a nontrivial divisor of n. Examples: >>> m = 1112470797641561909 >>> fermat(m) 1052788969 Details: The algorithm used here is Fermat's method. This algorithm runs in time O((n + 1) / 2 - sqrt(n)), where n is the number to be factored. In the worst case, this algorithm is much worse than trial division. See section 5.1.1 of "Prime Numbers - A Computation Perspective" by Crandall and Pomerance for more details. """ if n % 2 == 0: return 2 a = integer_sqrt(n) + 1 while a <= (n + 9)//6: t = a**2 - n b = integer_sqrt(t) if b*b == t: return a - b a += 1 return n
def trial_division(n, bound=None): """ Returns the smallest prime divisor of n, or proves primality. Given an integer n > 1, this algorithm attempts to find a factor of n by using trial division. Input: * n: int (n > 1) * bound: int (default=None) The bound for trial division. Output: * d: int The smallest prime factor of n, or n itself if n is prime. Examples: >>> trial_division(100) 2 >>> trial_division(10000004400000259) 100000007 Details: This method uses trial division to find the smallest prime factor of n. The algorithm runs through the precomputed list of primes first, and then uses a simple wheel modulo 30 after that. This algorithm is very useful to find small prime factors of a number, but serves a poor primality test for numbers more than 12 digits. """ if bound is None: bound = integer_sqrt(n) + 1 # First trial divide by the primes in our stored list. for d in PRIME_LIST: if d > bound: return n if n % d == 0: return d # Next we use a wheel for the rest. All primes >= 7 fall into one of eight # residue classes modulo 30. This uses that fact to avoid trial dividing by # numbers divisible by 2, 3, or 5. offset = {1: 6, 7: 4, 11: 2, 13: 4, 17: 2, 19: 4, 23: 6, 29: 2} d += offset[d % 30] while d <= bound: if n % d == 0: return d d += offset[d % 30] return n
def legendre(n): r"""Returns the number of primes <= n. Parameters ---------- n : int (n > 0) Returns ------- count : int The number of primes <= n. Notes ----- This method uses the function `primes` to compute the primes, and simple does some bookkeeping to maintain a running count. Examples -------- >>> pi_table(10) ([2, 3, 5, 7], [0, 0, 1, 2, 2, 3, 3, 4, 4, 4, 4]) """ if n <= 1: return 0 elif n <= _PRIME_LIST[-1]: return bisect(_PRIME_LIST, n) root = integer_sqrt(n) primes = sieves.primes(root) a = len(primes) def phi(x, a, cache={}): if (x, a) in cache: return cache[x, a] if a == 1: return (x + 1) // 2 value = (x + 1) // 2 for i in xrange(2, a + 1): p = primes[i - 1] if p > x: break value -= phi(x // p, i - 1) cache[x, a] = value return value return phi(n, a) + a - 1
def legendre(n): r"""Returns the number of primes <= n. Parameters ---------- n : int (n > 0) Returns ------- count : int The number of primes <= n. Notes ----- This method uses the function `primes` to compute the primes, and simple does some bookkeeping to maintain a running count. Examples -------- >>> pi_table(10) ([2, 3, 5, 7], [0, 0, 1, 2, 2, 3, 3, 4, 4, 4, 4]) """ if n <= 1: return 0 elif n <= _PRIME_LIST[-1]: return bisect(_PRIME_LIST, n) root = integer_sqrt(n) primes = rosemary.number_theory.sieves.primes(root) a = len(primes) def phi(x, a, cache={}): if (x, a) in cache: return cache[x, a] if a == 1: return (x + 1)//2 value = (x + 1)//2 for i in xrange(2, a + 1): p = primes[i - 1] if p > x: break value -= phi(x//p, i - 1) cache[x, a] = value return value return phi(n, a) + a - 1
def prime_count(n): r = integer_sqrt(n) V = [n//i for i in range(1, r + 1)] V += range(V[-1] - 1, 0, -1) S = {i: (i + 1)//2 for i in V} for p in range(2, r + 1): if S[p] > S[p-1]: sp = S[p-1] p2 = p*p for v in V: if v < p2: break S[v] -= (S[v//p] - sp) return S
def prime_count(n): r = integer_sqrt(n) V = [n // i for i in range(1, r + 1)] V += range(V[-1] - 1, 0, -1) S = {i: (i + 1) // 2 for i in V} for p in range(2, r + 1): if S[p] > S[p - 1]: sp = S[p - 1] p2 = p * p for v in V: if v < p2: break S[v] -= (S[v // p] - sp) return S
def discrete_log(a, b, p): """ Finds a positiveinteger k such that a^k = b (mod p). Input: * a: int Base of the exponential. Typically, this will be a primitive root modulo p. * b: int The target. Must be * p: int Output: * k: int We have 0 <= k < p is an integer satisfying a^k = b (mod p). Details: The algorithm is based on the Baby-Step Giant-Step method due to Shanks. Using a dictionary data type, this algoritm runs in O(sqrt(n)) time and space. We are following the method as described in Algorithm 2.4.1 in Number Theory for Computing by Yan. Examples: >>> discrete_log(2, 6, 19) 14 >>> pow(2, 14, 19) 6 >>> discrete_log(59, 67, 113) 11 >>> pow(59, 11, 113) 67 """ m = integer_sqrt(p) + 1 am = pow(a, m, p) cache = {} val = am for k in xrange(1, m + 1): cache[val] = k val = (val*am) % p val = b for k in xrange(m + 1): if val in cache: return cache[val]*m - k val = (val*a) % p
def is_square(cls, n): """Returns False if n is not a perfect square, and returns the square root of n otherwise. """ # The number of squares modulo 64, 63, 65, and 11 is 12, 16, 21, and 6, # respectively. So if n is not a square, then the probability that this # will no be detected in the table lookups is 12/64*16/63*21/65*6/11 = # 6/715, which is less than 1 percent. if cls.q64[n % 64] == 0: return False if cls.q45045[n % 45045] == 0: return False else: q = integer_sqrt(n) if q * q == n: return q return False
def moebius_xrange(a, b=None): """ Return an iterator over values of moebius(k) for 1 <= k <= n. Input: * a: int (a > 0) * b: int (b > a) (default=None) Output: * P: generator The values output by this generator are tuples (n, moebius(n)) where n is an integer in [a, b), and moebius(n) is the value of the moebius function. Examples: >>> list(moebius_xrange(10, 20)) [(10, 1), (11, -1), (12, 0), (13, -1), (14, 1), (15, 1), (16, 0), (17, -1), (18, 0), (19, -1)] """ if b is None: b, a = a, 1 block_size = integer_sqrt(b) prime_list = primes(block_size) for start in xrange(a, b, block_size): block = [1]*block_size values = [1]*block_size for p in prime_list: offset = ((p*(start//p + 1) - a) % block_size) % p for i in xrange(offset, block_size, p): if (start + i) % (p*p) == 0: block[i] = 0 else: block[i] *= -1 values[i] *= p for i in xrange(block_size): if start + i >= b: return if block[i] and values[i] < start + i: block[i] *= -1 yield (start + i, block[i])
def prime_sum2(n): root = integer_sqrt(n) primes = sieves.primes(root) a = len(primes) sum_table = [0] * (root + 1) accumulation = primes[:] for i in xrange(1, len(accumulation)): accumulation[i] += accumulation[i - 1] for (p, total) in zip(primes, accumulation): sum_table[p] = total for i in xrange(2, root + 1): if not sum_table[i]: sum_table[i] = sum_table[i - 1] def phi(x, a, cache={}): if (x, a) in cache: return cache[x, a] if x == 0: return 0 if a == 0: return x * (x + 1) // 2 value = x * (x + 1) // 2 for i in xrange(1, a + 1): p = primes[i - 1] if p > x: break value -= p * phi(x // p, i - 1) cache[x, a] = value return value return phi(n, a) + sum(primes) - 1
def prime_sum2(n): root = integer_sqrt(n) primes = rosemary.number_theory.sieves.primes(root) a = len(primes) sum_table = [0]*(root + 1) accumulation = primes[:] for i in xrange(1, len(accumulation)): accumulation[i] += accumulation[i - 1] for (p, total) in zip(primes, accumulation): sum_table[p] = total for i in xrange(2, root + 1): if not sum_table[i]: sum_table[i] = sum_table[i - 1] def phi(x, a, cache={}): if (x, a) in cache: return cache[x, a] if x == 0: return 0 if a == 0: return x*(x + 1)//2 value = x*(x + 1)//2 for i in xrange(1, a + 1): p = primes[i - 1] if p > x: break value -= p*phi(x//p, i - 1) cache[x, a] = value return value return phi(n, a) + sum(primes) - 1
def lehman(n): r"""Returns a nontrivial divisor of `n`, or proves primality. Given an integer `n` > 1, this algorithm attempts to find a factor of `n` using Lehman's method. Parameters ---------- n : int (n > 1) Returns ------- d : int If d == n, then n is proven prime. Otherwise, d is a nontrivial divisor of n. Notes ----- This algorithm runs in time O(n^(1/3)). This is substantially better than O(n^(1/2)) trial division for reasonably small value of n, but this algorithm is not suited for large values of n. See section 8.4 of [1] or section 5.1.2 of [2] for more details. References ---------- .. [1] H. Cohen, "A Course in Computational Algebraic Number Theory", Springer-Verlag, New York, 2000. .. [2] R. Crandall, C. Pomerance, "Prime Numbers: A Computational Perspective", Springer-Verlag, New York, 2001. Examples -------- >>> lehman(100) 2 >>> lehman(1112470797641561909) 1056689261L """ # first, we trial divide up to floor(n^(1/3)) bound = integer_nth_root(3, n) d = trial_division(n, bound) if d < n: return d for k in xrange(1, bound + 1): if k % 2 == 0: r = 1 m = 2 else: r = k + n m = 4 # we want to iterate over a, where 4*k*n <= a^2 <= 4*k*n + bound^2 # and a = r (mod m) fkn = 4*k*n a = integer_sqrt(fkn) # now, increase a until a = r (mod m) rm = r % m while a % m != rm: a += 1 ub = fkn + bound**2 while fkn <= a*a <= ub: c = a*a - fkn b = integer_sqrt(c) if b*b == c: return gcd(a + b, n) a += m return n
def trial_division(n, bound=None): r"""Returns the smallest prime divisor of `n`, or proves primality. Given an integer `n` > 1, this algorithm attempts to find a factor of `n` by using trial division. Parameters ---------- n : int (n > 1) bound : int, optional (default=None) If a non-None value is passed, then only trial divisors <= `bound` are considered. Otherwise, all trial divisors up the the square root of `n` are considered. Returns ------- d : int The smallest prime factor of `n`, or `n` itself if `n` is prime. Note that if `bound` less than the square root of `n` is passed, then there are no guarantees of the primality of `n`. Notes ----- This method uses trial division to find the smallest prime factor of n, requiring O(sqrt(n)) arithmetic operations. The algorithm runs through the precomputed list of primes first, and then uses a simple modulo 30 wheel after that. This algorithm is very useful to find small prime factors of a number, but serves as a poor primality test for numbers more than 12 digits. References ---------- .. [1] H. Cohen, "A Course in Computational Algebraic Number Theory", Springer-Verlag, New York, 2000. .. [2] R. Crandall, C. Pomerance, "Prime Numbers: A Computational Perspective", Springer-Verlag, New York, 2001. .. [3] V. Shoup, "A Computational Introduction to Number Theory and Algebra", Cambridge University Press, New York, 2009. Examples -------- >>> trial_division(100) 2 >>> trial_division(10000004400000259) 100000007 >>> trial_division(10000004400000259, 100) 10000004400000259 """ if bound is None: bound = integer_sqrt(n) + 1 # First trial divide by the primes in our stored list. for d in _PRIME_LIST: if d > bound: return n if n % d == 0: return d # Next we use a wheel for the rest. All primes >= 7 fall into one of # eight residue classes modulo 30. This uses that fact to avoid trial # dividing by numbers divisible by 2, 3, or 5. offset = {1: 6, 7: 4, 11: 2, 13: 4, 17: 2, 19: 4, 23: 6, 29: 2} d += offset[d % 30] while d <= bound: if n % d == 0: return d d += offset[d % 30] return n
def _cfrac_aq_pairs(n): r"""Yields triples (i, A_{i - 1}, Q_i) for i > 0, where A_{i - 1}^2 = (-1)^i Q_i (mod n) Parameters ---------- n : int Yields ------ (i, A_{i - 1}, Q_i) : tuple Yields integer tuples consisting of the index `i`, the numerator of the (i - 1)th convergent A({i - 1} (mod n), and the quantity Q_{i} coming from the continued fraction expansion of sqrt(n). Notes ----- The continued fraction expansion of sqrt(n) is computed, using the formulas given in section 2 of [1]. See also appendix 8 of [2]. References ---------- .. [1] M.A. Morrison, J. Brillhart, "A Method of Factoring and the Factorization of F7", Mathematics of Computation, Vol. 29, Num. 129, Jan. 1975. .. [2] H. Riesel, "Prime Numbers and Computer Methods for Factorization", 2nd edition, Birkhauser Verlag, Basel, Switzerland, 1994. Examples -------- >>> X = _cfrac_aq_pairs(1000009) >>> X.next() (1, 1000, 9) >>> X.next() (2, 222001, 445) >>> X.next() (3, 889004, 873) >>> X.next() (4, 1000000, 81) """ g = integer_sqrt(n) A0, A1 = 0, 1 Q0, Q1 = n, 1 P0 = 0 r0 = g for i in itertools.count(): q = (g + P0)//Q1 r1 = g + P0 - q*Q1 A2 = (q*A1 + A0) % n P1 = g - r1 Q2 = Q0 + q*(r1 - r0) if i > 0: yield (i, A1, Q1) A0, A1 = A1, A2 Q0, Q1 = Q1, Q2 P0 = P1 r0 = r1
def lehmer(n): if n <= 1: return 0 elif n <= _PRIME_LIST[-1]: return bisect(_PRIME_LIST, n) root = integer_nth_root(4, n**3) primes = rosemary.number_theory.sieves.primes(root) a = bisect(primes, integer_nth_root(4, n)) b = bisect(primes, integer_sqrt(n)) c = bisect(primes, integer_nth_root(3, n)) def phi(x, a, cache={}): if (x, a) in cache: return cache[x, a] if a <= 7: if a == 1: value = x - x//2 elif a == 2: value = x - x//2 - x//3 + x//6 elif a == 3: value = x - x//2 - x//3 - x//5 + x//6 + x//10 + x//15 - x//30 elif a == 4: value = (x - x//2 - x//3 - x//5 - x//7 + x//6 + x//10 + x//14 + x//15 + x//21 + x//35 - x//30 - x//42 - x//70 - x//105 + x//210) elif a == 5: value = (x - x//2 - x//3 - x//5 - x//7 - x//11 + x//6 + x//10 + x//14 + x//22 + x//15 + x//21 + x//33 + x//35 + x//55 + x//77 - x//30 - x//42 - x//66 - x//70 - x//110 - x//154 - x//105 - x//165 - x//231 - x//385 + x//210 + x//330 + x//462 + x//770 + x//1155 - x//2310) elif a == 6: value = (x - x//2 - x//3 - x//5 - x//7 - x//11 - x//13 + x//6 + x//10 + x//14 + x//22 + x//26 + x//15 + x//21 + x//33 + x//39 + x//35 + x//55 + x//65 + x//77 + x//91 + x//143 - x//30 - x//42 - x//66 - x//78 - x//70 - x//110 - x//130 - x//154 - x//182 - x//286 - x//105 - x//165 - x//195 - x//231 - x//273 - x//429 - x//385 - x//455 - x//715 - x//1001 + x//210 + x//330 + x//390 + x//462 + x//546 + x//858 + x//770 + x//910 + x//1430 + x//2002 + x//1155 + x//1365 + x//2145 + x//3003 + x//5005 - x//2310 - x//2730 - x//4290 - x//6006 - x//10010 - x//15015 + x//30030) else: value = (x - x//2 - x//3 - x//5 - x//7 - x//11 - x//13 - x//17 + x//6 + x//10 + x//14 + x//22 + x//26 + x//34 + x//15 + x//21 + x//33 + x//39 + x//51 + x//35 + x//55 + x//65 + x//85 + x//77 + x//91 + x//119 + x//143 + x//187 + x//221 - x//30 - x//42 - x//66 - x//78 - x//102 - x//70 - x//110 - x//130 - x//170 - x//154 - x//182 - x//238 - x//286 - x//374 - x//442 - x//105 - x//165 - x//195 - x//255 - x//231 - x//273 - x//357 - x//429 - x//561 - x//663 - x//385 - x//455 - x//595 - x//715 - x//935 - x//1105 - x//1001 - x//1309 - x//1547 - x//2431 + x//210 + x//330 + x//390 + x//510 + x//462 + x//546 + x//714 + x//858 + x//1122 + x//1326 + x//770 + x//910 + x//1190 + x//1430 + x//1870 + x//2210 + x//2002 + x//2618 + x//3094 + x//4862 + x//1155 + x//1365 + x//1785 + x//2145 + x//2805 + x//3315 + x//3003 + x//3927 + x//4641 + x//7293 + x//5005 + x//6545 + x//7735 + x//12155 + x//17017 - x//2310 - x//2730 - x//3570 - x//4290 - x//5610 - x//6630 - x//6006 - x//7854 - x//9282 - x//14586 - x//10010 - x//13090 - x//15470 - x//24310 - x//34034 - x//15015 - x//19635 - x//23205 - x//36465 - x//51051 - x//85085 + x//30030 + x//39270 + x//46410 + x//72930 + x//102102 + x//170170 + x//255255 - x//510510) elif a >= bisect(primes, x**(0.5)) and x < primes[-1]: pi = bisect(primes, x) value = pi - a + 1 else: value = (x + 1)//2 for i in xrange(1, a): if primes[i] > x: break value -= phi(x//primes[i], i) cache[x, a] = value return value def phi2(n, a, b): s1 = 0 for i in xrange(a, b): s1 += phi(n//primes[i], b) + b - 1 return s1 def phi3(n, a, b, c): s2 = 0 for i in xrange(a, c): bi = phi(integer_sqrt(n//primes[i]), b) + b - 1 for j in xrange(i, bi): idx = phi(n//(primes[i]*primes[j]), b) + b - 1 s2 += idx - j return s2 value = (b + a - 2)*(b - a + 1)//2 + phi(n, a) - phi2(n, a, b) - phi3(n, a, b, c) return value
def eratosthenes2(n): r"""Returns a list of all primes p <= n. Parameters ---------- n : int Returns ------- primes : list A list of the primes <= n. See Also -------- chartres, eratosthenes1, luo Notes ----- This algorithm is an implementation of the second extension of the sieve of Eratosthenes by removing the multiples of 2 and 3 from the set of candidates. This has the effect of decreasing the required space and time to 1/3 of the naive Eratosthenes algorithm. See the paper [1] for details. See the commentary in [2] for more details and extensions. Note that [1] and [3] both claim that the second extension of the sieve of Eratosthenes is the most efficient in practice. References ---------- .. [1] X. Luo, "A Practical Sieve Algorithm for Finding Prime Numbers", Communications of the ACM, Volume 32, Number 3, March 1989. .. [2] Quesada, Pritchard, James, "Additional Notes on a Practical Sieve Algorithm", Communications of the ACM, Volume 35, Issue 3, March 1992. .. [3] J. Sorenson, "An Analysis of Two Prime Number Sieves", Technical Report 1028, University of Wisonsin, Computer Sciences Department, June 1991. Examples -------- >>> eratosthenes2(20) [2, 3, 5, 7, 11, 13, 17, 19] >>> len(eratosthenes2(10**6)) 78498 """ if n <= 1: return [] elif n <= 3: return range(2, n + 1) n += 1 offset = (n % 6 > 1) n = {0: n, 1: n - 1, 2: n + 4, 3: n + 3, 4: n + 2, 5: n + 1}[n % 6] m = n//3 block = bytearray([1])*m block[0] = 0 sqrt = integer_sqrt(n) for i in xrange(sqrt//3 + 1): if block[i]: k = (3*i + 1) | 1 kk = k*k a = kk//3 b = (kk + 4*k - 2*k*(i & 1))//3 block[a::2*k] = bytearray([0])*((m - a)//(2*k) + ((m - a) % (2*k) > 0)) block[b::2*k] = bytearray([0])*((m - b)//(2*k) + ((m - b) % (2*k) > 0)) return [2, 3] + [(3*i + 1) | 1 for i in xrange(1, n//3 - offset) if block[i]]
def discrete_log(a, b, p): """Finds a positive integer k such that a**k = b (mod p). Input: * a: int Base of the exponential. Typically, this will be a primitive root modulo p. * b: int The target. * p: int The modulus. This must be a prime. The primality of p is not verified. Returns: * k: int A positive integer such that a**k = b (mod p). If no solution exists, then None is returned. Raises: * ValueError: If no solution is found. Examples: >>> discrete_log(2, 6, 19) 14 >>> pow(2, 14, 19) 6 >>> discrete_log(59, 67, 113) 11 >>> pow(59, 11, 113) 67 >>> discrete_log(5, 3, 2017) 1030 >>> pow(5, 1030, 2017) 3 >>> discrete_log(2, 76, 100) 120 >>> discrete_log(2, 77, 100) Traceback (most recent call last): ... ValueError: discrete_log: No solution found. Details: The algorithm is based on the Baby-Step Giant-Step method due to Shanks. Using a dictionary data type, this algoritm runs in O(sqrt(n)) time and space. We follow the method as described in Algorithm 2.4.1 in Number Theory for Computing by Yan. See Chapter 5 of "Prime Numbers - A Computational Perspective" by Crandall and Pomerance for variants. See "A Computational Introduction to Number Theory and Algebra" by Shoup for more in depth analysis. """ m = integer_sqrt(p) + 1 am = pow(a, m, p) cache = {} val = am for k in xrange(1, m + 1): cache[val] = k val = (val*am) % p val = b x = 1 for k in xrange(m + 1): if val in cache: x = cache[val]*m - k break val = (val*a) % p if pow(a, x, p) == b % p: return x else: raise ValueError("discrete_log: No solution found.")
def luo(n): r"""Returns a list of all primes p <= n. Parameters ---------- n : int Returns ------- primes : list A list of the primes <= n. See Also -------- chartres, eratosthenes1, eratosthenes2 Notes ----- This algorithm is an implementation of the second extension of the sieve of Eratosthenes by removing the multiples of 2 and 3 from the set of candidates. This has the effect of decreasing the required space and time to 1/3 of the naive Eratosthenes algorithm. This implementation is based on the the exposition in the paper [1], as well as the optimizations made by Pritchard in [2]. Note that [1] and [3] both claim that the second extension of the sieve of Eratosthenes is the most efficient in practice. References ---------- .. [1] X. Luo, "A Practical Sieve Algorithm for Finding Prime Numbers", Communications of the ACM, Volume 32, Number 3, March 1989. .. [2] Quesada, Pritchard, James, "Additional Notes on a Practical Sieve Algorithm", Communications of the ACM, Volume 35, Issue 3, March 1992. .. [3] J. Sorenson, "An Analysis of Two Prime Number Sieves", Technical Report 1028, University of Wisonsin, Computer Sciences Department, June 1991. Examples -------- >>> luo(20) [2, 3, 5, 7, 11, 13, 17, 19] >>> len(luo(10**6)) 78498 """ if n <= 1: return [] elif n <= 6: return {2: [2], 3: [2, 3], 4: [2, 3], 5: [2, 3, 5], 6: [2, 3, 5]}[n] n += 1 offset = (n % 6 > 1) n = {0: n, 1: n - 1, 2: n + 4, 3: n + 3, 4: n + 2, 5: n + 1}[n % 6] m = n//3 sqrt = integer_sqrt(n) block = bytearray([1])*(n//3) a, k, t = 0, 1, 2 for i in xrange(1, sqrt + 1): k = 3 - k a += 4*k*i t += 4*k if block[i]: b = a + 2*i*(3 - k) + 1 block[a::t] = bytearray([0])*((m - a)//t + ((m - a) % t > 0)) block[b::t] = bytearray([0])*((m - b)//t + ((m - b) % t > 0)) return [2, 3] + [(3*i + 1) | 1 for i in xrange(1, m - offset) if block[i]]
def discrete_log(a, b, p): """Finds a positive integer k such that a**k = b (mod p). Input: * a: int Base of the exponential. Typically, this will be a primitive root modulo p. * b: int The target. * p: int The modulus. This must be a prime. The primality of p is not verified. Returns: * k: int A positive integer such that a**k = b (mod p). If no solution exists, then None is returned. Raises: * ValueError: If no solution is found. Examples: >>> discrete_log(2, 6, 19) 14 >>> pow(2, 14, 19) 6 >>> discrete_log(59, 67, 113) 11 >>> pow(59, 11, 113) 67 >>> discrete_log(5, 3, 2017) 1030 >>> pow(5, 1030, 2017) 3 >>> discrete_log(2, 76, 100) 120 >>> discrete_log(2, 77, 100) Traceback (most recent call last): ... ValueError: discrete_log: No solution found. Details: The algorithm is based on the Baby-Step Giant-Step method due to Shanks. Using a dictionary data type, this algoritm runs in O(sqrt(n)) time and space. We follow the method as described in Algorithm 2.4.1 in Number Theory for Computing by Yan. See Chapter 5 of "Prime Numbers - A Computational Perspective" by Crandall and Pomerance for variants. See "A Computational Introduction to Number Theory and Algebra" by Shoup for more in depth analysis. """ m = integer_sqrt(p) + 1 am = pow(a, m, p) cache = {} val = am for k in xrange(1, m + 1): cache[val] = k val = (val * am) % p val = b x = 1 for k in xrange(m + 1): if val in cache: x = cache[val] * m - k break val = (val * a) % p if pow(a, x, p) == b % p: return x else: raise ValueError("discrete_log: No solution found.")
def pritchard(n): r"""Returns a list of all primes <= n. Parameters ---------- n : int Returns ------- primes : list A list of the primes <= n. See Also -------- chartres, eratosthenes1, eratosthenes2, luo Notes ----- This method uses the linear sieve by Pritchard to find the primes up to n. Our implementation is based on exposition in the paper [1]. For additional details, see the original paper [2]. Despite asymptotically faster runtime than the Sieve of Eratosthenes, this algorithm is slower in practice. See the paper [3] for details. References ---------- .. [1] Dunten, Jones, Sorenson, "A Space-Efficient Fast Prime Number Sieve", Information Processing Letters Volume 59, Issue 2, 1996. .. [2] P. Pritchard, "Linear Prime-Number Sieves: A Family Tree", Science of Computer Programming, Volume 9, Issue 1, 1987. .. [3] J. Sorenson, "An Analysis of Two Prime Number Sieves", Technical Report 1028, University of Wisonsin, Computer Sciences Department, June 1991. Examples -------- >>> pritchard(20) [2, 3, 5, 7, 11, 13, 17, 19] >>> len(pritchard(10**6)) 78498 """ if n <= 1: return [] prime_list = primes(integer_sqrt(n)) block = [1]*(n + 1) block[0] = 0 block[1] = 0 for f in xrange(2, n//2 + 1): for p in prime_list: if p*f > n: break block[p*f] = 0 if f % p == 0: break return [i for i in xrange(2, n + 1) if block[i]]
def lehman(n): r"""Returns a nontrivial divisor of `n`, or proves primality. Given an integer `n` > 1, this algorithm attempts to find a factor of `n` using Lehman's method. Parameters ---------- n : int (n > 1) Returns ------- d : int If d == n, then n is proven prime. Otherwise, d is a nontrivial divisor of n. Notes ----- This algorithm runs in time O(n^(1/3)). This is substantially better than O(n^(1/2)) trial division for reasonably small value of n, but this algorithm is not suited for large values of n. See section 8.4 of [1] or section 5.1.2 of [2] for more details. References ---------- .. [1] H. Cohen, "A Course in Computational Algebraic Number Theory", Springer-Verlag, New York, 2000. .. [2] R. Crandall, C. Pomerance, "Prime Numbers: A Computational Perspective", Springer-Verlag, New York, 2001. Examples -------- >>> lehman(100) 2 >>> lehman(1112470797641561909) 1056689261L """ # first, we trial divide up to floor(n^(1/3)) bound = integer_nth_root(3, n) d = trial_division(n, bound) if d < n: return d for k in xrange(1, bound + 1): if k % 2 == 0: r = 1 m = 2 else: r = k + n m = 4 # we want to iterate over a, where 4*k*n <= a^2 <= 4*k*n + bound^2 # and a = r (mod m) fkn = 4 * k * n a = integer_sqrt(fkn) # now, increase a until a = r (mod m) rm = r % m while a % m != rm: a += 1 ub = fkn + bound**2 while fkn <= a * a <= ub: c = a * a - fkn b = integer_sqrt(c) if b * b == c: return gcd(a + b, n) a += m return n
def lehmer(n): if n <= 1: return 0 elif n <= _PRIME_LIST[-1]: return bisect(_PRIME_LIST, n) root = integer_nth_root(4, n**3) primes = sieves.primes(root) a = bisect(primes, integer_nth_root(4, n)) b = bisect(primes, integer_sqrt(n)) c = bisect(primes, integer_nth_root(3, n)) def phi(x, a, cache={}): if (x, a) in cache: return cache[x, a] if a <= 7: if a == 1: value = x - x // 2 elif a == 2: value = x - x // 2 - x // 3 + x // 6 elif a == 3: value = x - x // 2 - x // 3 - x // 5 + x // 6 + x // 10 + x // 15 - x // 30 elif a == 4: value = (x - x // 2 - x // 3 - x // 5 - x // 7 + x // 6 + x // 10 + x // 14 + x // 15 + x // 21 + x // 35 - x // 30 - x // 42 - x // 70 - x // 105 + x // 210) elif a == 5: value = (x - x // 2 - x // 3 - x // 5 - x // 7 - x // 11 + x // 6 + x // 10 + x // 14 + x // 22 + x // 15 + x // 21 + x // 33 + x // 35 + x // 55 + x // 77 - x // 30 - x // 42 - x // 66 - x // 70 - x // 110 - x // 154 - x // 105 - x // 165 - x // 231 - x // 385 + x // 210 + x // 330 + x // 462 + x // 770 + x // 1155 - x // 2310) elif a == 6: value = (x - x // 2 - x // 3 - x // 5 - x // 7 - x // 11 - x // 13 + x // 6 + x // 10 + x // 14 + x // 22 + x // 26 + x // 15 + x // 21 + x // 33 + x // 39 + x // 35 + x // 55 + x // 65 + x // 77 + x // 91 + x // 143 - x // 30 - x // 42 - x // 66 - x // 78 - x // 70 - x // 110 - x // 130 - x // 154 - x // 182 - x // 286 - x // 105 - x // 165 - x // 195 - x // 231 - x // 273 - x // 429 - x // 385 - x // 455 - x // 715 - x // 1001 + x // 210 + x // 330 + x // 390 + x // 462 + x // 546 + x // 858 + x // 770 + x // 910 + x // 1430 + x // 2002 + x // 1155 + x // 1365 + x // 2145 + x // 3003 + x // 5005 - x // 2310 - x // 2730 - x // 4290 - x // 6006 - x // 10010 - x // 15015 + x // 30030) else: value = ( x - x // 2 - x // 3 - x // 5 - x // 7 - x // 11 - x // 13 - x // 17 + x // 6 + x // 10 + x // 14 + x // 22 + x // 26 + x // 34 + x // 15 + x // 21 + x // 33 + x // 39 + x // 51 + x // 35 + x // 55 + x // 65 + x // 85 + x // 77 + x // 91 + x // 119 + x // 143 + x // 187 + x // 221 - x // 30 - x // 42 - x // 66 - x // 78 - x // 102 - x // 70 - x // 110 - x // 130 - x // 170 - x // 154 - x // 182 - x // 238 - x // 286 - x // 374 - x // 442 - x // 105 - x // 165 - x // 195 - x // 255 - x // 231 - x // 273 - x // 357 - x // 429 - x // 561 - x // 663 - x // 385 - x // 455 - x // 595 - x // 715 - x // 935 - x // 1105 - x // 1001 - x // 1309 - x // 1547 - x // 2431 + x // 210 + x // 330 + x // 390 + x // 510 + x // 462 + x // 546 + x // 714 + x // 858 + x // 1122 + x // 1326 + x // 770 + x // 910 + x // 1190 + x // 1430 + x // 1870 + x // 2210 + x // 2002 + x // 2618 + x // 3094 + x // 4862 + x // 1155 + x // 1365 + x // 1785 + x // 2145 + x // 2805 + x // 3315 + x // 3003 + x // 3927 + x // 4641 + x // 7293 + x // 5005 + x // 6545 + x // 7735 + x // 12155 + x // 17017 - x // 2310 - x // 2730 - x // 3570 - x // 4290 - x // 5610 - x // 6630 - x // 6006 - x // 7854 - x // 9282 - x // 14586 - x // 10010 - x // 13090 - x // 15470 - x // 24310 - x // 34034 - x // 15015 - x // 19635 - x // 23205 - x // 36465 - x // 51051 - x // 85085 + x // 30030 + x // 39270 + x // 46410 + x // 72930 + x // 102102 + x // 170170 + x // 255255 - x // 510510) elif a >= bisect(primes, x**(0.5)) and x < primes[-1]: pi = bisect(primes, x) value = pi - a + 1 else: value = (x + 1) // 2 for i in xrange(1, a): if primes[i] > x: break value -= phi(x // primes[i], i) cache[x, a] = value return value def phi2(n, a, b): s1 = 0 for i in xrange(a, b): s1 += phi(n // primes[i], b) + b - 1 return s1 def phi3(n, a, b, c): s2 = 0 for i in xrange(a, c): bi = phi(integer_sqrt(n // primes[i]), b) + b - 1 for j in xrange(i, bi): idx = phi(n // (primes[i] * primes[j]), b) + b - 1 s2 += idx - j return s2 value = (b + a - 2) * (b - a + 1) // 2 + phi(n, a) - phi2(n, a, b) - phi3( n, a, b, c) return value
def _cfrac_aq_pairs(n): r"""Yields triples (i, A_{i - 1}, Q_i) for i > 0, where A_{i - 1}^2 = (-1)^i Q_i (mod n) Parameters ---------- n : int Yields ------ (i, A_{i - 1}, Q_i) : tuple Yields integer tuples consisting of the index `i`, the numerator of the (i - 1)th convergent A({i - 1} (mod n), and the quantity Q_{i} coming from the continued fraction expansion of sqrt(n). Notes ----- The continued fraction expansion of sqrt(n) is computed, using the formulas given in section 2 of [1]. See also appendix 8 of [2]. References ---------- .. [1] M.A. Morrison, J. Brillhart, "A Method of Factoring and the Factorization of F7", Mathematics of Computation, Vol. 29, Num. 129, Jan. 1975. .. [2] H. Riesel, "Prime Numbers and Computer Methods for Factorization", 2nd edition, Birkhauser Verlag, Basel, Switzerland, 1994. Examples -------- >>> X = _cfrac_aq_pairs(1000009) >>> X.next() (1, 1000, 9) >>> X.next() (2, 222001, 445) >>> X.next() (3, 889004, 873) >>> X.next() (4, 1000000, 81) """ g = integer_sqrt(n) A0, A1 = 0, 1 Q0, Q1 = n, 1 P0 = 0 r0 = g for i in itertools.count(): q = (g + P0) // Q1 r1 = g + P0 - q * Q1 A2 = (q * A1 + A0) % n P1 = g - r1 Q2 = Q0 + q * (r1 - r0) if i > 0: yield (i, A1, Q1) A0, A1 = A1, A2 Q0, Q1 = Q1, Q2 P0 = P1 r0 = r1