def test_is_power(self): self.assertRaisesRegexp(ValueError, "is_power: Must have k >= 1.", is_power, 10, 0) self.assertRaisesRegexp(ValueError, "is_power: Must have n >= 1.", is_power, 0, 3) for k in [2, 3, 5, 7, 11]: self.assertEqual(is_power(k), False) for k in xrange(10): a = random.randint(10, 100) b = random.randint(10, 100) n = a**b x, y = is_power(n) self.assertTrue(x**y == n) for k in xrange(10): a = random.randint(10, 100) b = random.randint(10, 100) n = a**b x, y = is_power(n, b) self.assertTrue(x**y == n) values = [ 4, 8, 9, 16, 25, 27, 32, 36, 49, 64, 81, 100, 121, 125, 128, 144, 169, 196, 216, 225, 243, 256, 289, 324, 343, 361, 400, 441, 484, 512, 529, 576, 625, 676, 729, 784, 841, 900, 961, 1000 ] powers = [e for e in xrange(1, 1001) if is_power(e)] self.assertEqual(values, powers) self.assertEqual(is_power([(2, 4), (3, 2)]), (12, 2)) self.assertEqual(is_power([(2, 4), (3, 3)]), False) self.assertEqual(is_power([(3, 4), (5, 4)]), (15, 4)) self.assertEqual(is_power([(3, 4), (5, 4)], 2), (225, 2))
def factor(n, skip_trial_division=False, use_cfrac=False): r"""Returns the factorization of the integer `n`. Parameters ---------- n : int Integer to be factored. skip_trial_division : bool, optional (default=False) If False, performs a preliminary trial division using the precomputed list of primes. If True, then this step is skipped. use_cfrac : bool, optional (default=False) If True, applies the cfrac method to search for factors instead of the Pollard rho method. If False, then the Pollard rho method is used to search for factors. Returns ------- factorization : list A list of pairs (p, e) consisting of the primes p and exponents e such that ``p**e`` divides `n`. Notes ----- This method uses a variety of techniques to obtain a factorization of `n`. First, we perform trial division using a precomputed list of primes to find all small prime factors. After this, we apply Pollard's rho method to find any remaining small prime divisors. References ---------- .. [1] H. Riesel, "Prime Numbers and Computer Methods for Factorization", 2nd edition, Birkhauser Verlag, Basel, Switzerland, 1994. Examples -------- >>> factor(100) [(2, 2), (5, 2)] >>> factor(537869) [(37, 1), (14537, 1)] >>> factor(2**91 - 1) [(127, 1), (911, 1), (8191, 1), (112901153L, 1), (23140471537L, 1)] >>> factor(10**22 + 1) [(89, 1), (101, 1), (1052788969L, 1), (1056689261L, 1)] """ fac = collections.defaultdict(int) _is_prime = primality.is_probable_prime if use_cfrac: _factor = algorithms.cfrac else: _factor = algorithms.pollard_rho_brent if n == 0: raise ValueError("Prime factorization of 0 not defined") # Detect perfect powers. ab = is_power(n) if ab: (n, multiplier) = ab else: (n, multiplier) = (n, 1) # Take care of the sign if n < 0: fac[-1] = 1 n *= -1 # Strip off all small factors of n for p in _PRIME_LIST: if n == 1: break elif p*p > n: fac[n] += 1 n = 1 break while n % p == 0: fac[p] += 1 n //= p # Next, strip off remaining factors. while n > 1: if _is_prime(n): fac[n] += 1 n = 1 else: d = _factor(n) while not _is_prime(d): d = _factor(d) while n % d == 0: fac[d] += 1 n = n // d factorization = sorted([(p, fac[p]*multiplier) for p in fac]) return factorization