예제 #1
0
def test_round_two():
    # Poly must be monic, irreducible, and over ZZ:
    raises(ValueError, lambda: round_two(Poly(3 * x ** 2 + 1)))
    raises(ValueError, lambda: round_two(Poly(x ** 2 - 1)))
    raises(ValueError, lambda: round_two(Poly(x ** 2 + QQ(1, 2))))

    # Test on many fields:
    cases = (
        # A couple of cyclotomic fields:
        (cyclotomic_poly(5), DomainMatrix.eye(4, QQ), 125),
        (cyclotomic_poly(7), DomainMatrix.eye(6, QQ), -16807),
        # A couple of quadratic fields (one 1 mod 4, one 3 mod 4):
        (x ** 2 - 5, DM([[1, (1, 2)], [0, (1, 2)]], QQ), 5),
        (x ** 2 - 7, DM([[1, 0], [0, 1]], QQ), 28),
        # Dedekind's example of a field with 2 as essential disc divisor:
        (x ** 3 + x ** 2 - 2 * x + 8, DM([[1, 0, 0], [0, 1, 0], [0, (1, 2), (1, 2)]], QQ).transpose(), -503),
        # A bunch of cubics with various forms for F -- all of these require
        # second or third enlargements. (Five of them require a third, while the rest require just a second.)
        # F = 2^2
        (x**3 + 3 * x**2 - 4 * x + 4, DM([((1, 2), (1, 4), (1, 4)), (0, (1, 2), (1, 2)), (0, 0, 1)], QQ).transpose(), -83),
        # F = 2^2 * 3
        (x**3 + 3 * x**2 + 3 * x - 3, DM([((1, 2), 0, (1, 2)), (0, 1, 0), (0, 0, 1)], QQ).transpose(), -108),
        # F = 2^3
        (x**3 + 5 * x**2 - x + 3, DM([((1, 4), 0, (3, 4)), (0, (1, 2), (1, 2)), (0, 0, 1)], QQ).transpose(), -31),
        # F = 2^2 * 5
        (x**3 + 5 * x**2 - 5 * x - 5, DM([((1, 2), 0, (1, 2)), (0, 1, 0), (0, 0, 1)], QQ).transpose(), 1300),
        # F = 3^2
        (x**3 + 3 * x**2 + 5, DM([((1, 3), (1, 3), (1, 3)), (0, 1, 0), (0, 0, 1)], QQ).transpose(), -135),
        # F = 3^3
        (x**3 + 6 * x**2 + 3 * x - 1, DM([((1, 3), (1, 3), (1, 3)), (0, 1, 0), (0, 0, 1)], QQ).transpose(), 81),
        # F = 2^2 * 3^2
        (x**3 + 6 * x**2 + 4, DM([((1, 3), (2, 3), (1, 3)), (0, 1, 0), (0, 0, (1, 2))], QQ).transpose(), -108),
        # F = 2^3 * 7
        (x**3 + 7 * x**2 + 7 * x - 7, DM([((1, 4), 0, (3, 4)), (0, (1, 2), (1, 2)), (0, 0, 1)], QQ).transpose(), 49),
        # F = 2^2 * 13
        (x**3 + 7 * x**2 - x + 5, DM([((1, 2), 0, (1, 2)), (0, 1, 0), (0, 0, 1)], QQ).transpose(), -2028),
        # F = 2^4
        (x**3 + 7 * x**2 - 5 * x + 5, DM([((1, 4), 0, (3, 4)), (0, (1, 2), (1, 2)), (0, 0, 1)], QQ).transpose(), -140),
        # F = 5^2
        (x**3 + 4 * x**2 - 3 * x + 7, DM([((1, 5), (4, 5), (4, 5)), (0, 1, 0), (0, 0, 1)], QQ).transpose(), -175),
        # F = 7^2
        (x**3 + 8 * x**2 + 5 * x - 1, DM([((1, 7), (6, 7), (2, 7)), (0, 1, 0), (0, 0, 1)], QQ).transpose(), 49),
        # F = 2 * 5 * 7
        (x**3 + 8 * x**2 - 2 * x + 6, DM([(1, 0, 0), (0, 1, 0), (0, 0, 1)], QQ).transpose(), -14700),
        # F = 2^2 * 3 * 5
        (x**3 + 6 * x**2 - 3 * x + 8, DM([(1, 0, 0), (0, (1, 4), (1, 4)), (0, 0, 1)], QQ).transpose(), -675),
        # F = 2 * 3^2 * 7
        (x**3 + 9 * x**2 + 6 * x - 8, DM([(1, 0, 0), (0, (1, 2), (1, 2)), (0, 0, 1)], QQ).transpose(), 3969),
        # F = 2^2 * 3^2 * 7
        (x**3 + 15 * x**2 - 9 * x + 13, DM([((1, 6), (1, 3), (1, 6)), (0, 1, 0), (0, 0, 1)], QQ).transpose(), -5292),
    )
    for f, B_exp, d_exp in cases:
        K = QQ.alg_field_from_poly(f)
        B = K.maximal_order().QQ_matrix
        d = K.discriminant()
        assert d == d_exp
        # The computed basis need not equal the expected one, but their quotient
        # must be unimodular:
        assert (B.inv()*B_exp).det()**2 == 1
예제 #2
0
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)'
예제 #3
0
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
예제 #4
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
예제 #5
0
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
예제 #6
0
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
예제 #7
0
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)'
예제 #8
0
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
예제 #9
0
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
예제 #10
0
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
예제 #11
0
 def _do_round_two(self):
     from sympy.polys.numberfields.basis import round_two
     ZK, dK = round_two(self.ext.minpoly, radicals=self._nilradicals_mod_p)
     self._maximal_order = ZK
     self._discriminant = dK