Beispiel #1
0
def find_mod2pow_splitting(i):
    P = F.primes_above(2)[0]
    if i == 1:
        R = ResidueRing(P, 1)
        M = MatrixSpace(R, 2)
        return [M(matrix_lift(a).list()) for a in find_mod2_splitting()]

    R = ResidueRing(P, i)
    M = MatrixSpace(R, 2)
    # arbitrary lift
    wbar = [M(matrix_lift(a).list()) for a in find_mod2pow_splitting(i - 1)]

    # Find lifts of wbar[1] and wbar[2] that have square -1
    k = P.residue_field()
    Mk = MatrixSpace(k, 2)

    t = 2**(i - 1)
    s = M(t)

    L = []
    for j in [1, 2]:
        C = Mk(matrix_lift(wbar[j]**2 + M(1)) / t)
        A = Mk(matrix_lift(wbar[j]))
        # Find all matrices B in Mk such that AB+BA=C.
        L.append([
            wbar[j] + s * M(matrix_lift(B)) for B in Mk if A * B + B * A == C
        ])

    g = M(F.gen())
    t = M(t)
    two = M(2)
    ginv = M(F.gen()**(-1))
    for w1 in L[0]:
        for w2 in L[1]:
            w0 = ginv * (two * g * wbar[3] - w1 - w2 - w1 * w2)
            w3 = g * w0 + w2 * w1
            if w0 * w0 != w0 - M(1):
                continue
            if w3 * w3 != M(-1):
                continue
            return w0, w1, w2, w3

    raise ValueError
def find_mod2pow_splitting(i):
    P = F.primes_above(2)[0]
    if i == 1:
        R = ResidueRing(P, 1)
        M = MatrixSpace(R, 2)
        return [M(matrix_lift(a).list()) for a in find_mod2_splitting()]

    R = ResidueRing(P, i)
    M = MatrixSpace(R, 2)
    # arbitrary lift
    wbar = [M(matrix_lift(a).list()) for a in find_mod2pow_splitting(i - 1)]

    # Find lifts of wbar[1] and wbar[2] that have square -1
    k = P.residue_field()
    Mk = MatrixSpace(k, 2)

    t = 2 ** (i - 1)
    s = M(t)

    L = []
    for j in [1, 2]:
        C = Mk(matrix_lift(wbar[j] ** 2 + M(1)) / t)
        A = Mk(matrix_lift(wbar[j]))
        # Find all matrices B in Mk such that AB+BA=C.
        L.append([wbar[j] + s * M(matrix_lift(B)) for B in Mk if A * B + B * A == C])

    g = M(F.gen())
    t = M(t)
    two = M(2)
    ginv = M(F.gen() ** (-1))
    for w1 in L[0]:
        for w2 in L[1]:
            w0 = ginv * (two * g * wbar[3] - w1 - w2 - w1 * w2)
            w3 = g * w0 + w2 * w1
            if w0 * w0 != w0 - M(1):
                continue
            if w3 * w3 != M(-1):
                continue
            return w0, w1, w2, w3

    raise ValueError
def test_reduced_rep(B=50):
    """
    Unit test: run a simple consistency check that reduced_rep is
    working sensibly.
    
    INPUT:

    - `B` -- positive integer

    OUTPUT:

    - None (assertion raised if something detected wrong)

    EXAMPLES::

        sage: sage.modular.hilbert.sqrt5_tables.test_reduced_rep()
    """
    a = F.gen()
    z = -45 * a + 28
    v = [reduced_rep(a ** i * z) for i in range(-B, B)]
    assert len(set(v)) == 1
def find_mod2pow_splitting(i):
    """
    Return elements w0, w1, w2, w3 that determine a mod-`2^i` splitting
    of the Hamilton quaternion algebra over Q(sqrt(5)).

    INPUT:

    - `i` -- positive integer

    OUTPUT:

    - four 2x2 matrices over a residue ring of Q(sqrt(5)) of characteristic a power of 2
    
    EXAMPLES::

        sage: import sage.modular.hilbert.sqrt5_fast_python
        sage: w = sage.modular.hilbert.sqrt5_fast_python.find_mod2pow_splitting(1); w
        (
        [    1     g]  [    0 1 + g]  [1 + g     g]  [1 1]
        [1 + g     0], [    g     0], [    g 1 + g], [0 1]
        )
        sage: w = sage.modular.hilbert.sqrt5_fast_python.find_mod2pow_splitting(2); w
        (
        [      3 2 + 3*g]  [      0 1 + 3*g]  [3 + 3*g     3*g]
        [  1 + g       2], [      g       0], [    3*g   1 + g],
        [3 + 2*g 3 + 2*g]
        [      2 1 + 2*g]
        )
        sage: w[1]^2
        [3 0]
        [0 3]
        sage: w[2]^2
        [3 0]
        [0 3]
        sage: w = sage.modular.hilbert.sqrt5_fast_python.find_mod2pow_splitting(4)
        sage: w[1]^2
        [15  0]
        [ 0 15]
        sage: w[2]^2
        [15  0]
        [ 0 15]
        sage: w[1], w[2]
        (
        [       0 1 + 15*g]  [15 + 15*g  12 + 7*g]
        [       g        0], [ 4 + 11*g     1 + g]
        )

    TESTS:

    The power must be positive::

        sage: sage.modular.hilbert.sqrt5_fast_python.find_mod2pow_splitting(0)
        Traceback (most recent call last):
        ...
        ValueError: i must be positive    
    """
    P = F.primes_above(2)[0]
    i = ZZ(i)
    if i <= 0:
        raise ValueError, "i must be positive"
    
    if i == 1:
        R = ResidueRing(P, 1)
        M = MatrixSpace(R,2)
        return tuple([M(matrix_lift(a).list()) for a in find_mod2_splitting()])

    R = ResidueRing(P, i)
    M = MatrixSpace(R,2)
    # arbitrary lift
    wbar = [M(matrix_lift(a).list()) for a in find_mod2pow_splitting(i-1)]

    # Find lifts of wbar[1] and wbar[2] that have square -1
    k = P.residue_field()
    Mk = MatrixSpace(k, 2)
    
    t = 2**(i-1)
    s = M(t)

    L = []
    for j in [1,2]:
        C = Mk(matrix_lift(wbar[j]**2 + M(1)) / t)
        A = Mk(matrix_lift(wbar[j]))
        # Find all matrices B in Mk such that AB+BA=C.
        L.append([wbar[j]+s*M(matrix_lift(B)) for B in Mk if A*B + B*A == C])

    g = M(F.gen())
    t = M(t)
    two = M(2)
    ginv = M(F.gen()**(-1))
    for w1 in L[0]:
        for w2 in L[1]:
            w0 = ginv*(two*g*wbar[3] -w1 -w2 - w1*w2)
            w3 = g*w0 + w2*w1
            if w0*w0 != w0 - M(1):
                continue
            if w3*w3 != M(-1):
                continue
            return w0, w1, w2, w3
        
    raise ValueError