def test_decomp_1(): # All prime decompositions in cyclotomic fields are in the "easy case," # since the index is unity. # Here we check the ramified prime. T = Poly(cyclotomic_poly(7)) raises(ValueError, lambda: prime_decomp(7)) P = prime_decomp(7, T) assert len(P) == 1 P0 = P[0] assert P0.e == 6 assert P0.f == 1 # Test powers: assert P0**0 == P0.ZK assert P0**1 == P0 assert P0**6 == 7 * P0.ZK
def primes_above(self, p): """Compute the prime ideals lying above a given rational prime *p*.""" from sympy.polys.numberfields.primes import prime_decomp ZK = self.maximal_order() dK = self.discriminant() rad = self._nilradicals_mod_p.get(p) return prime_decomp(p, ZK=ZK, dK=dK, radical=rad)
def test_repr(): T = Poly(x**2 + 7) ZK, dK = round_two(T) P = prime_decomp(2, T, dK=dK, ZK=ZK) assert repr(P[0]) == '[ (2, (3*x + 1)/2) e=1, f=1 ]' assert P[0].repr(field_gen=theta) == '[ (2, (3*theta + 1)/2) e=1, f=1 ]' assert P[0].repr(field_gen=theta, just_gens=True) == '(2, (3*theta + 1)/2)'
def test_PrimeIdeal_eq(): # `==` should fail on objects of different types, so even a completely # inert PrimeIdeal should test unequal to the rational prime it divides. T = Poly(cyclotomic_poly(7)) P0 = prime_decomp(5, T)[0] assert P0.f == 6 assert P0.as_submodule() == 5 * P0.ZK assert P0 != 5
def test_valuation_at_prime_ideal(): p = 7 T = Poly(cyclotomic_poly(p)) ZK, dK = round_two(T) P = prime_decomp(p, T, dK=dK, ZK=ZK) assert len(P) == 1 P0 = P[0] v = P0.valuation(p * ZK) assert v == P0.e # Test easy 0 case: assert P0.valuation(5 * ZK) == 0
def test_decomp_6(): # Another case where 2 divides the index. This is Dedekind's example of # an essential discriminant divisor. (See Cohen, Excercise 6.10.) T = Poly(x**3 + x**2 - 2 * x + 8) rad = {} ZK, dK = round_two(T, radicals=rad) p = 2 P = prime_decomp(p, T, dK=dK, ZK=ZK, radical=rad.get(p)) assert len(P) == 3 assert all(Pi.e == Pi.f == 1 for Pi in P) assert prod(Pi**Pi.e for Pi in P) == p * ZK
def test_decomp_4(): T = Poly(x**2 - 21) rad = {} ZK, dK = round_two(T, radicals=rad) # 21 is 1 mod 4, so field disc is 3*7, and theory says the # rational primes 3, 7 should be the square of a prime ideal. for p in [3, 7]: P = prime_decomp(p, T, dK=dK, ZK=ZK, radical=rad.get(p)) assert len(P) == 1 assert P[0].e == 2 assert P[0]**2 == p * ZK
def test_decomp_3(): T = Poly(x**2 - 35) rad = {} ZK, dK = round_two(T, radicals=rad) # 35 is 3 mod 4, so field disc is 4*5*7, and theory says each of the # rational primes 2, 5, 7 should be the square of a prime ideal. for p in [2, 5, 7]: P = prime_decomp(p, T, dK=dK, ZK=ZK, radical=rad.get(p)) assert len(P) == 1 assert P[0].e == 2 assert P[0]**2 == p * ZK
def test_pretty_printing(): d = -7 T = Poly(x**2 - d) rad = {} ZK, dK = round_two(T, radicals=rad) p = 2 P = prime_decomp(p, T, dK=dK, ZK=ZK, radical=rad.get(p)) assert repr(P[0]) == '[ (2, (3*x + 1)/2) e=1, f=1 ]' assert P[0]._pretty(field_gen=theta) == '[ (2, (3*theta + 1)/2) e=1, f=1 ]' assert P[0]._pretty(field_gen=theta, just_gens=True) == '(2, (3*theta + 1)/2)'
def test_decomp_2(): # More easy cyclotomic cases, but here we check unramified primes. ell = 7 T = Poly(cyclotomic_poly(ell)) for p in [29, 13, 11, 5]: f_exp = n_order(p, ell) g_exp = (ell - 1) // f_exp P = prime_decomp(p, T) assert len(P) == g_exp for Pi in P: assert Pi.e == 1 assert Pi.f == f_exp
def test_decomp_8(): # This time we consider various cubics, and try factoring all primes # dividing the index. cases = ( x**3 + 3 * x**2 - 4 * x + 4, x**3 + 3 * x**2 + 3 * x - 3, x**3 + 5 * x**2 - x + 3, x**3 + 5 * x**2 - 5 * x - 5, x**3 + 3 * x**2 + 5, x**3 + 6 * x**2 + 3 * x - 1, x**3 + 6 * x**2 + 4, x**3 + 7 * x**2 + 7 * x - 7, x**3 + 7 * x**2 - x + 5, x**3 + 7 * x**2 - 5 * x + 5, x**3 + 4 * x**2 - 3 * x + 7, x**3 + 8 * x**2 + 5 * x - 1, x**3 + 8 * x**2 - 2 * x + 6, x**3 + 6 * x**2 - 3 * x + 8, x**3 + 9 * x**2 + 6 * x - 8, x**3 + 15 * x**2 - 9 * x + 13, ) def display(T, p, radical, P, I, J): """Useful for inspection, when running test manually.""" print('=' * 20) print(T, p, radical) for Pi in P: print(f' ({Pi!r})') print("I: ", I) print("J: ", J) print(f'Equal: {I == J}') inspect = False for g in cases: T = Poly(g) rad = {} ZK, dK = round_two(T, radicals=rad) dT = T.discriminant() f_squared = dT // dK F = factorint(f_squared) for p in F: radical = rad.get(p) P = prime_decomp(p, T, dK=dK, ZK=ZK, radical=radical) I = prod(Pi**Pi.e for Pi in P) J = p * ZK if inspect: display(T, p, radical, P, I, J) assert I == J
def test_two_elt_rep(): ell = 7 T = Poly(cyclotomic_poly(ell)) ZK, dK = round_two(T) for p in [29, 13, 11, 5]: P = prime_decomp(p, T) for Pi in P: # We have Pi in two-element representation, and, because we are # looking at a cyclotomic field, this was computed by the "easy" # method that just factors T mod p. We will now convert this to # a set of Z-generators, then convert that back into a two-element # rep. The latter need not be identical to the two-elt rep we # already have, but it must have the same HNF. H = p * ZK + Pi.alpha * ZK gens = H.basis_element_pullbacks() # Note: we could supply f = Pi.f, but prefer to test behavior without it. b = _two_elt_rep(gens, ZK, p) if b != Pi.alpha: H2 = p * ZK + b * ZK assert H2 == H
def test_decomp_5(): # Here is our first test of the "hard case" of prime decomposition. # We work in a quadratic extension Q(sqrt(d)) where d is 1 mod 4, and # we consider the factorization of the rational prime 2, which divides # the index. # Theory says the form of p's factorization depends on the residue of # d mod 8, so we consider both cases, d = 1 mod 8 and d = 5 mod 8. for d in [-7, -3]: T = Poly(x**2 - d) rad = {} ZK, dK = round_two(T, radicals=rad) p = 2 P = prime_decomp(p, T, dK=dK, ZK=ZK, radical=rad.get(p)) if d % 8 == 1: assert len(P) == 2 assert all(P[i].e == 1 and P[i].f == 1 for i in range(2)) assert prod(Pi**Pi.e for Pi in P) == p * ZK else: assert d % 8 == 5 assert len(P) == 1 assert P[0].e == 1 assert P[0].f == 2 assert P[0].as_submodule() == p * ZK
def test_PrimeIdeal_add(): T = Poly(cyclotomic_poly(7)) P0 = prime_decomp(7, T)[0] # Adding ideals computes their GCD, so adding the ramified prime dividing # 7 to 7 itself should reproduce this prime (as a submodule). assert P0 + 7 * P0.ZK == P0.as_submodule()