def necklaces(n, k, weights=None): """ Returns the number of necklace colorings. Given integers n >= 1 and k >= 2, this returns the number of ways to color a necklace of n beads with k colors. A necklace of length n colored by k colors is an equivalence class of n-character strings over an alphabet of size k, taking all rotations as equivalent. The optional argument weights can be a list or tuple of positive integers summing to n. If the colors used are k_0, k_1, ..., k_{n - 1}, then weights[i] is the number of times that color k_i is used. See Charalambides - Enumerative Combinatorics chapter 13 for more details. Input: n: Positive integer. k: Positive integer >= 2. weights: Optional list of weights. Returns: The number of colorings. Examples: >>> necklaces(3, 2) 4 >>> necklaces(10, 5) 976887 This is how we would count the colorings of a necklace with 6 beads using 3 colors, where each color is used exactly 2 times: >>> necklaces(6, 3, [2, 2, 2]) 16 """ if weights: j = gcd(weights) ss = 0 for d in xdivisors(j): ll = [e/d for e in weights] ss += euler_phi(d)*multinomial(n//d, ll) return ss//n else: ss = 0 for d in xdivisors(n): ss += euler_phi(d)*k**(n//d) return ss//n
def test_euler_phi_inverse(self): self.assertRaisesRegexp(ValueError, "euler_phi_inverse: Must have n > 0.", euler_phi_inverse, -1) self.assertEqual(euler_phi_inverse([(2, 2), (5, 2)]), [101, 125, 202, 250]) values = defaultdict(list) for k in xrange(1, 1001): phi = euler_phi(k) values[phi].append(k) for v in xrange(1, 201): inv = euler_phi_inverse(v) self.assertEqual(inv, values[v])
def test_euler_phi(self): self.assertRaisesRegexp(ValueError, "euler_phi: Must have n > 0.", euler_phi, -1) self.assertRaisesRegexp(ValueError, "euler_phi: Must have n > 0.", euler_phi, -1) values = [ 1, 1, 2, 2, 4, 2, 6, 4, 6, 4, 10, 4, 12, 6, 8, 8, 16, 6, 18, 8, 12, 10, 22, 8, 20, 12, 18, 12, 28, 8, 30, 16, 20, 16, 24, 12, 36, 18, 24, 16, 40, 12, 42, 20, 24, 22, 46, 16, 42, 20, 32, 24, 52, 18, 40, 24, 36, 28, 58, 16, 60, 30, 36, 32, 48, 20, 66, 32, 44, 24, 70, 24, 72, 36, 40, 36, 60, 24, 78, 32, 54, 40, 82, 24, 64, 42, 56, 40, 88, 24, 72, 44, 60, 46, 72, 32, 96, 42, 60, 40, 100, 32, 102, 48, 48, 52, 106, 36, 108, 40, 72, 48, 112, 36, 88, 56, 72, 58, 96, 32, 110, 60, 80, 60, 100, 36, 126, 64, 84, 48, 130, 40, 108, 66, 72, 64, 136, 44, 138, 48, 92, 70, 120, 48, 112, 72, 84, 72, 148, 40, 150, 72, 96, 60, 120, 48, 156, 78, 104, 64, 132, 54, 162, 80, 80, 82, 166, 48, 156, 64, 108, 84, 172, 56, 120, 80, 116, 88, 178, 48, 180, 72, 120, 88, 144, 60, 160, 92, 108, 72, 190, 64, 192, 96, 96, 84, 196, 60, 198, 80 ] computed = [euler_phi(e) for e in xrange(1, 201)] self.assertEqual(values, computed)
def primitive_root(n, n_factorization=None, phi=None, phi_divisors=None): """Returns a primitive root modulo n. Given a positive integer n of the form n = 2, 4, p**a, or 2*p**a for p an odd prime and a >= 1, this function returns the least primitive root of n. Input: * n: int (n > 1) * n_factorization: list (default=None) The prime factorization of n. * phi: int (default=None) The value of euler_phi(n). * phi_divisors: list (default=None) A list of the prime divisors of euler_phi(n). Returns: * g: int The least primitive root of n. Raises: * ValueError: if primitive roots don't exist modulo n. Examples: >>> primitive_root(7) 3 >>> primitive_root(11) 2 >>> primitive_root(14) 3 >>> primitive_root(12) Traceback (most recent call last): ... ValueError: primitive_root: No primitive root for n. Details: An integer a is called a primitive root mod n if a generates the multiplicative group of units modulo n. Equivalently, a is a primitive root modulo n if the order of a modulo m is euler_phi(n). As noted above, primitive roots only exist for moduli of the form n = 2, 4, p**a, 2*p**a, where p > 2 is prime, and a >= 1. See Theorem 6.11 of "Elementary Number Theory" by Jones and Jones for a proof of this fact. See also Chapter 10 of "Introduction to Analytic Number Theory" by Apostol. This method uses the fact that an integer a coprime to n is a primitive root if and only if a**(euler_phi(n)/p) != 1 (mod n) for each prime p dividing euler_phi(n). See Lemma 6.4 in Jones and Jones for a proof of this. Note also that there is another way to construct primitive roots for composite moduli. To find a primitive root modulu p**a for p an odd prime and a >= 2, first compute g, a primitive root modulo p using the above criteria. Next, compute g1 = g**(p - 1) (mod p**2). If g1 != 1, then g is a primitive root modulo p**a for every a >= 1. Otherwise, g + p is. Finally, note that when p is an odd prime, if g is a primitive root modulo p**a, then either g or g + p**a (whichever is odd) is a primitive root modulo 2*p**a. See Lemma 1.4.5 of "A Course in Computational Algebraic Number Theory" by Cohen for more details. """ if n_factorization is None: n_factorization = factor.factor(n) if n % 4 == 0 and n != 4: raise ValueError("primitive_root: No primitive root for n.") if len(n_factorization) > 2: raise ValueError("primitive_root: No primitive root for n.") if n % 2 == 1 and len(n_factorization) > 1: raise ValueError("primitive_root: No primitive root for n.") if phi is None: phi = functions.euler_phi(n_factorization) if phi_divisors is None: phi_divisors = factor.prime_divisors(phi) for g in xrange(1, n): if is_primitive_root(g, n, phi=phi, phi_divisors=phi_divisors): return g
def is_primitive_root(a, n, phi=None, phi_divisors=None): """Returns True if a is a primitive root mod n and False otherwise. Given an integer a and modulus n, this method determines whether or not a is a primitive root modulo n. Input: * a: int * n: int (n > 0) The modulus. * phi: int (default=None) Value of euler_phi(n). * phi_divisors: list (default=None) List of prime divisors of euler_phi(n). Returns: * b: bool b is True if a is a primitive root mod n and False otherwise. Note that b will be False when no primitive roots exist modulo n. Raises: * ValueError: if n <= 1. Examples: >>> is_primitive_root(2, 11) True >>> is_primitive_root(3, 11) False >>> is_primitive_root(3, -2) Traceback (most recent call last): ... ValueError: is_primitive_root: n must be >= 2. Details: An integer a is called a primitive root mod n if a generates the multiplicative group of units modulo n. Equivalently, a is a primitive root modulo n if the order of a modulo m is euler_phi(n). The algorithm is based on the observation that an integer a coprime to n is a primitive root modulo n if and only if a**(euler_phi(n)/d) != 1 (mod n) for each divisor d of euler_phi(n). See Lemma 6.4 of "Elementary Number Theory" by Jones and Jones for a proof. Primitive roots exist only for the moduli n = 1, 2, 4, p**a, and 2*p**a, where p is an odd prime and a >= 1. These cases are captured in the above Lemma, however some simple divisibility tests allow us to exit early for certain moduli. See Chapter 6 of "Elementary Number Theory" by Jones and Jones for more details. See also Chapter 10 of "Introduction to Analytic Number Theory" by Apostol. """ if n <= 1: raise ValueError("is_primitive_root: n must be >= 2.") if n > 4 and n % 4 == 0: return False if gcd(a, n) != 1: return False if phi is None: phi = functions.euler_phi(n) if phi_divisors is None: phi_divisors = factor.prime_divisors(phi) for d in phi_divisors: if pow(a, phi // d, n) == 1: return False return True
def is_primitive_root(a, n, phi=None, phi_divisors=None): """Returns True if a is a primitive root mod n and False otherwise. Given an integer a and modulus n, this method determines whether or not a is a primitive root modulo n. Input: * a: int * n: int (n > 0) The modulus. * phi: int (default=None) Value of euler_phi(n). * phi_divisors: list (default=None) List of prime divisors of euler_phi(n). Returns: * b: bool b is True if a is a primitive root mod n and False otherwise. Note that b will be False when no primitive roots exist modulo n. Raises: * ValueError: if n <= 1. Examples: >>> is_primitive_root(2, 11) True >>> is_primitive_root(3, 11) False >>> is_primitive_root(3, -2) Traceback (most recent call last): ... ValueError: is_primitive_root: n must be >= 2. Details: An integer a is called a primitive root mod n if a generates the multiplicative group of units modulo n. Equivalently, a is a primitive root modulo n if the order of a modulo m is euler_phi(n). The algorithm is based on the observation that an integer a coprime to n is a primitive root modulo n if and only if a**(euler_phi(n)/d) != 1 (mod n) for each divisor d of euler_phi(n). See Lemma 6.4 of "Elementary Number Theory" by Jones and Jones for a proof. Primitive roots exist only for the moduli n = 1, 2, 4, p**a, and 2*p**a, where p is an odd prime and a >= 1. These cases are captured in the above Lemma, however some simple divisibility tests allow us to exit early for certain moduli. See Chapter 6 of "Elementary Number Theory" by Jones and Jones for more details. See also Chapter 10 of "Introduction to Analytic Number Theory" by Apostol. """ if n <= 1: raise ValueError("is_primitive_root: n must be >= 2.") if n > 4 and n % 4 == 0: return False if gcd(a, n) != 1: return False if phi is None: phi = functions.euler_phi(n) if phi_divisors is None: phi_divisors = factor.prime_divisors(phi) for d in phi_divisors: if pow(a, phi//d, n) == 1: return False return True