Beispiel #1
0
def next_prime_not_dividing(P, I):
    while True:
        p = P.smallest_integer()
        if p == 1:
            Q = F.ideal(2)
        elif p % 5 in [2,3]: # inert
            Q = F.primes_above(next_prime(p))[0]
        elif p == 5:
            Q = F.ideal(7)
        else: # p split
            A = F.primes_above(p)
            if A[0] == P:
                Q = A[1]
            else:
                Q = F.primes_above(next_prime(p))[0]
        if not Q.divides(I):
            return Q
        else:
            P = Q # try again
Beispiel #2
0
def next_prime_not_dividing(P, I):
    while True:
        p = P.smallest_integer()
        if p == 1:
            Q = F.ideal(2)
        elif p % 5 in [2,3]: # inert
            Q = F.primes_above(next_prime(p))[0]
        elif p == 5:
            Q = F.ideal(7)
        else: # p split
            A = F.primes_above(p)
            if A[0] == P:
                Q = A[1]
            else:
                Q = F.primes_above(next_prime(p))[0]
        if not Q.divides(I):
            return Q
        else:
            P = Q # try again
def find_mod2_splitting():
    """
    Return elements w0, w1, w2, w3 that determine a mod-2 splitting
    of the Hamilton quaternion algebra over Q(sqrt(5)).

    OUTPUT:

    - four 2x2 matrices over the residue field of Q(sqrt(5)) of order 4.
    
    EXAMPLES::

        sage: import sage.modular.hilbert.sqrt5_fast_python
        sage: w = sage.modular.hilbert.sqrt5_fast_python.find_mod2_splitting(); w
        (
        [       1     abar]  [       0 abar + 1]  [abar + 1     abar]  [1 1]
        [abar + 1        0], [    abar        0], [    abar abar + 1], [0 1]
        )
        sage: w[1]^2, w[2]^2
        (
        [1 0]  [1 0]
        [0 1], [0 1]
        )
        sage: span([vector(z.list()) for z in w]).dimension()
        4
    """
    P = F.primes_above(2)[0]
    k = P.residue_field()
    M = MatrixSpace(k,2)
    V = k**4
    g = k.gen() # image of golden ratio

    m1 = M(-1)
    sqrt_minus_1 = [(w, V(w.list())) for w in M if w*w == m1]
    one = M(1)
    v_one = V(one.list())
    for w1, v1 in sqrt_minus_1:
        for w2, v2  in sqrt_minus_1:
            w0 = (g-1)*(w1+w2 - w1*w2)
            w3 = g*w0 + w2*w1
            if w0*w0 != w0 - 1:
                continue
            if w3*w3 != -1:
                continue
            if V.span([w0.list(),v1,v2,w3.list()]).dimension() == 4:
                return w0, w1, w2, w3
Beispiel #4
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 find_mod2_splitting():
    P = F.primes_above(2)[0]
    k = P.residue_field()
    M = MatrixSpace(k, 2)
    V = k ** 4
    g = k.gen()  # image of golden ratio

    m1 = M(-1)
    sqrt_minus_1 = [(w, V(w.list())) for w in M if w * w == m1]
    one = M(1)
    v_one = V(one.list())
    for w1, v1 in sqrt_minus_1:
        for w2, v2 in sqrt_minus_1:
            w0 = (g - 1) * (w1 + w2 - w1 * w2)
            w3 = g * w0 + w2 * w1
            if w0 * w0 != w0 - 1:
                continue
            if w3 * w3 != -1:
                continue
            if V.span([w0.list(), v1, v2, w3.list()]).dimension() == 4:
                return w0, w1, w2, w3
Beispiel #7
0
def find_mod2_splitting():
    P = F.primes_above(2)[0]
    k = P.residue_field()
    M = MatrixSpace(k, 2)
    V = k**4
    g = k.gen()  # image of golden ratio

    m1 = M(-1)
    sqrt_minus_1 = [(w, V(w.list())) for w in M if w * w == m1]
    one = M(1)
    v_one = V(one.list())
    for w1, v1 in sqrt_minus_1:
        for w2, v2 in sqrt_minus_1:
            w0 = (g - 1) * (w1 + w2 - w1 * w2)
            w3 = g * w0 + w2 * w1
            if w0 * w0 != w0 - 1:
                continue
            if w3 * w3 != -1:
                continue
            if V.span([w0.list(), v1, v2, w3.list()]).dimension() == 4:
                return w0, w1, w2, w3
Beispiel #8
0
def next_prime_of_characteristic_coprime_to(P, I):
    p = next_prime(P.smallest_integer())
    N = ZZ(I.norm())
    while N%p == 0:
        p = next_prime(p)
    return F.primes_above(p)[0]
Beispiel #9
0
def next_prime_of_characteristic_coprime_to(P, I):
    p = next_prime(P.smallest_integer())
    N = ZZ(I.norm())
    while N%p == 0:
        p = next_prime(p)
    return F.primes_above(p)[0]
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