Beispiel #1
0
def _possible_normalizers(E, SA):
    r"""Find a list containing all primes `l` such that the Galois image at `l`
    is contained in the normalizer of a Cartan subgroup, such that the
    corresponding quadratic character is ramified only at the given primes.

    INPUT:

    - ``E`` - EllipticCurve - over a number field K.

    - ``SA`` - list - a list of primes of K.

    OUTPUT:

    - list - A list of primes, which contains all primes `l` such that the
             Galois image at `l` is contained in the normalizer of a Cartan
             subgroup, such that the corresponding quadratic character is
             ramified only at primes in SA.

    - If `E` has geometric CM that is not defined over its ground field, a
      ValueError is raised.

    EXAMPLES::

        sage: E = EllipticCurve([0,0,0,-56,4848])
        sage: 5 in sage.schemes.elliptic_curves.gal_reps_number_field._possible_normalizers(E, [ZZ.ideal(2)])
        True
    """

    E = _over_numberfield(E)
    K = E.base_field()
    SA = [K.ideal(I.gens()) for I in SA]

    x = K['x'].gen()
    selmer_group = K.selmer_group(SA, 2) # Generators of the selmer group.

    if selmer_group == []:
        return []

    V = VectorSpace(GF(2), len(selmer_group))
    # We think of this as the character group of the selmer group.

    traces_list = []
    W = V.zero_subspace()

    deg_one_primes = K.primes_of_degree_one_iter()

    while W.dimension() < V.dimension() - 1:
        P = deg_one_primes.next()

        k = P.residue_field()

        defines_valid_character = True
        # A prime P defines a quadratic residue character
        # on the Selmer group. This variable will be set
        # to zero if any elements of the selmer group are
        # zero mod P (i.e. the character is ramified).

        splitting_vector = [] # This will be the values of this
        # character on the generators of the Selmer group.

        for a in selmer_group:
            abar = k(a)
            if abar == 0:
                # Ramification.
                defines_valid_character = False
                break

            if abar.is_square():
                splitting_vector.append(GF(2)(0))
            else:
                splitting_vector.append(GF(2)(1))

        if not defines_valid_character:
            continue

        if splitting_vector in W:
            continue

        try:
            Etilde = E.change_ring(k)
        except ArithmeticError: # Bad reduction.
            continue

        tr = Etilde.trace_of_frobenius()

        if tr == 0:
            continue

        traces_list.append(tr)

        W = W + V.span([splitting_vector])

    bad_primes = set([])

    for i in traces_list:
        for p in i.prime_factors():
            bad_primes.add(p)

    # We find the unique vector v in V orthogonal to W:
    v = W.matrix().transpose().kernel().basis()[0]

    # We find the element a of the selmer group corresponding to v:
    a = 1
    for i in xrange(len(selmer_group)):
        if v[i] == 1:
            a *= selmer_group[i]

    # Since we've already included the above bad primes, we can assume
    # that the quadratic character corresponding to the exceptional primes
    # we're looking for is given by mapping into Gal(K[\sqrt{a}]/K).

    patience = 5 * K.degree()
    # Number of Frobenius elements to check before suspecting that E
    # has CM and computing the set of CM j-invariants of K to check.
    # TODO: Is this the best value for this parameter?

    while True:
        P = deg_one_primes.next()

        k = P.residue_field()

        if not k(a).is_square():
            try:
                tr = E.change_ring(k).trace_of_frobenius()
            except ArithmeticError: # Bad reduction.
                continue

            if tr == 0:
                patience -= 1

                if patience == 0:
                    # We suspect E has CM, so we check:
                    if E.j_invariant() in cm_j_invariants(K):
                        raise ValueError("The curve E should not have CM.")

            else:
                for p in tr.prime_factors():
                    bad_primes.add(p)

                bad_primes = sorted(bad_primes)
                return bad_primes
def _possible_normalizers(E, SA):
    r"""Find a list containing all primes `l` such that the Galois image at `l`
    is contained in the normalizer of a Cartan subgroup, such that the
    corresponding quadratic character is ramified only at the given primes.

    INPUT:

    - ``E`` - EllipticCurve - over a number field K.

    - ``SA`` - list - a list of primes of K.

    OUTPUT:

    - list - A list of primes, which contains all primes `l` such that the
             Galois image at `l` is contained in the normalizer of a Cartan
             subgroup, such that the corresponding quadratic character is
             ramified only at primes in SA.

    - If `E` has geometric CM that is not defined over its ground field, a
      ValueError is raised.

    EXAMPLES::

        sage: E = EllipticCurve([0,0,0,-56,4848])
        sage: 5 in sage.schemes.elliptic_curves.gal_reps_number_field._possible_normalizers(E, [ZZ.ideal(2)])
        True
    """

    E = _over_numberfield(E)
    K = E.base_field()
    SA = [K.ideal(I.gens()) for I in SA]

    x = K['x'].gen()
    selmer_group = K.selmer_group(SA, 2)  # Generators of the selmer group.

    if selmer_group == []:
        return []

    V = VectorSpace(GF(2), len(selmer_group))
    # We think of this as the character group of the selmer group.

    traces_list = []
    W = V.zero_subspace()

    deg_one_primes = K.primes_of_degree_one_iter()

    while W.dimension() < V.dimension() - 1:
        P = next(deg_one_primes)

        k = P.residue_field()

        defines_valid_character = True
        # A prime P defines a quadratic residue character
        # on the Selmer group. This variable will be set
        # to zero if any elements of the selmer group are
        # zero mod P (i.e. the character is ramified).

        splitting_vector = []  # This will be the values of this
        # character on the generators of the Selmer group.

        for a in selmer_group:
            abar = k(a)
            if abar == 0:
                # Ramification.
                defines_valid_character = False
                break

            if abar.is_square():
                splitting_vector.append(GF(2)(0))
            else:
                splitting_vector.append(GF(2)(1))

        if not defines_valid_character:
            continue

        if splitting_vector in W:
            continue

        try:
            Etilde = E.change_ring(k)
        except ArithmeticError:  # Bad reduction.
            continue

        tr = Etilde.trace_of_frobenius()

        if tr == 0:
            continue

        traces_list.append(tr)

        W = W + V.span([splitting_vector])

    bad_primes = set([])

    for i in traces_list:
        for p in i.prime_factors():
            bad_primes.add(p)

    # We find the unique vector v in V orthogonal to W:
    v = W.matrix().transpose().kernel().basis()[0]

    # We find the element a of the selmer group corresponding to v:
    a = 1
    for i in xrange(len(selmer_group)):
        if v[i] == 1:
            a *= selmer_group[i]

    # Since we've already included the above bad primes, we can assume
    # that the quadratic character corresponding to the exceptional primes
    # we're looking for is given by mapping into Gal(K[\sqrt{a}]/K).

    patience = 5 * K.degree()
    # Number of Frobenius elements to check before suspecting that E
    # has CM and computing the set of CM j-invariants of K to check.
    # TODO: Is this the best value for this parameter?

    while True:
        P = next(deg_one_primes)

        k = P.residue_field()

        if not k(a).is_square():
            try:
                tr = E.change_ring(k).trace_of_frobenius()
            except ArithmeticError:  # Bad reduction.
                continue

            if tr == 0:
                patience -= 1

                if patience == 0:
                    # We suspect E has CM, so we check:
                    if E.j_invariant() in cm_j_invariants(K):
                        raise ValueError("The curve E should not have CM.")

            else:
                for p in tr.prime_factors():
                    bad_primes.add(p)

                bad_primes = sorted(bad_primes)
                return bad_primes
Beispiel #3
0
def _semistable_reducible_primes(E):
    r"""Find a list containing all semistable primes l unramified in K/QQ
    for which the Galois image for E could be reducible.

    INPUT:

    - ``E`` - EllipticCurve - over a number field.

    OUTPUT: list - A list of primes, which contains all primes l unramified
                   in K/QQ, such that E is semistable at all primes lying
                   over l, and the Galois image at l is reducible. If E has
                   CM defined over its ground field, a ValueError is raised.

    EXAMPLES::

        sage: E = EllipticCurve([0, -1, 1, -10, -20]) # X_0(11)
        sage: 5 in sage.schemes.elliptic_curves.gal_reps_number_field._semistable_reducible_primes(E)
        True
    """

    E = _over_numberfield(E)
    K = E.base_field()
    deg_one_primes = K.primes_of_degree_one_iter()

    bad_primes = set([]) # This will store the output.

    # We find two primes (of distinct residue characteristics) which are
    # of degree 1, unramified in K/Q, and at which E has good reduction.
    # Both of these primes will give us a nontrivial divisibility constraint
    # on the exceptional primes l. For both of these primes P, we precompute
    # a generator and the trace of Frob_P^12.

    precomp = []
    last_char = 0 # The residue characteristic of the most recent prime.

    while len(precomp) < 2:
        P = deg_one_primes.next()

        if not P.is_principal():
            continue

        det = P.norm()
        if det == last_char:
            continue

        if P.ramification_index() != 1:
            continue

        try:
            tr = E.change_ring(P.residue_field()).trace_of_frobenius()
        except ArithmeticError: # Bad reduction at P.
            continue

        x = P.gens_reduced()[0]

        precomp.append((x, _tr12(tr, det)))
        last_char = det

    x, tx = precomp[0]
    y, ty = precomp[1]

    Kgal = K.galois_closure('b')
    maps = K.embeddings(Kgal)

    for i in xrange(2 ** (K.degree() - 1)):
        ## We iterate through all possible characters. ##

        # Here, if i = i_{l-1} i_{l-2} cdots i_1 i_0 in binary, then i
        # corresponds to the character prod sigma_j^{i_j}.

        phi1x = 1
        phi2x = 1
        phi1y = 1
        phi2y = 1

        # We compute the two algebraic characters at x and y:
        for j in xrange(K.degree()):
            if i % 2 == 1:
                phi1x *= maps[j](x)
                phi1y *= maps[j](y)
            else:
                phi2x *= maps[j](x)
                phi2y *= maps[j](y)
            i = int(i/2)

        # Any prime with reducible image must divide both of:
        gx = phi1x**12 + phi2x**12 - tx
        gy = phi1y**12 + phi2y**12 - ty

        if (gx != 0) or (gy != 0):
            for prime in Integer(Kgal.ideal([gx, gy]).norm()).prime_factors():
                bad_primes.add(prime)

            continue

        ## It is possible that our curve has CM. ##

        # Our character must be of the form Nm^K_F for an imaginary
        # quadratic subfield F of K (which is the CM field if E has CM).
        # We compute F:

        a = (Integer(phi1x + phi2x)**2 - 4 * x.norm()).squarefree_part()

        y = QQ['y'].gen()
        F = NumberField(y**2 - a, 'a')

        # Next, we turn K into relative number field over F.

        K = K.relativize(F.embeddings(K)[0], 'b')
        E = E.change_ring(K.structure()[1])

        ## We try to find a nontrivial divisibility condition. ##

        patience = 5 * K.absolute_degree()
        # Number of Frobenius elements to check before suspecting that E
        # has CM and computing the set of CM j-invariants of K to check.
        # TODO: Is this the best value for this parameter?

        while True:
            P = deg_one_primes.next()

            if not P.is_principal():
                continue

            try:
                tr = E.change_ring(P.residue_field()).trace_of_frobenius()
            except ArithmeticError: # Bad reduction at P.
                continue

            x = P.gens_reduced()[0].norm(F)
            div = (x**12).trace() - _tr12(tr, x.norm())

            patience -= 1

            if div != 0:
                # We found our divisibility constraint.

                for prime in Integer(div).prime_factors():
                    bad_primes.add(prime)

                # Turn K back into an absolute number field.

                E = E.change_ring(K.structure()[0])
                K = K.structure()[0].codomain()

                break

            if patience == 0:
                # We suspect that E has CM, so we check:
                f = K.structure()[0]
                if f(E.j_invariant()) in cm_j_invariants(f.codomain()):
                    raise ValueError("The curve E should not have CM.")

    L = sorted(bad_primes)
    return L
def _semistable_reducible_primes(E):
    r"""Find a list containing all semistable primes l unramified in K/QQ
    for which the Galois image for E could be reducible.

    INPUT:

    - ``E`` - EllipticCurve - over a number field.

    OUTPUT:

    A list of primes, which contains all primes `l` unramified in
    `K/\mathbb{QQ}`, such that `E` is semistable at all primes lying
    over `l`, and the Galois image at `l` is reducible. If `E` has CM
    defined over its ground field, a ``ValueError`` is raised.

    EXAMPLES::

        sage: E = EllipticCurve([0, -1, 1, -10, -20]) # X_0(11)
        sage: 5 in sage.schemes.elliptic_curves.gal_reps_number_field._semistable_reducible_primes(E)
        True
    """

    E = _over_numberfield(E)
    K = E.base_field()
    deg_one_primes = K.primes_of_degree_one_iter()

    bad_primes = set([])  # This will store the output.

    # We find two primes (of distinct residue characteristics) which are
    # of degree 1, unramified in K/Q, and at which E has good reduction.
    # Both of these primes will give us a nontrivial divisibility constraint
    # on the exceptional primes l. For both of these primes P, we precompute
    # a generator and the trace of Frob_P^12.

    precomp = []
    last_char = 0  # The residue characteristic of the most recent prime.

    while len(precomp) < 2:
        P = next(deg_one_primes)

        if not P.is_principal():
            continue

        det = P.norm()
        if det == last_char:
            continue

        if P.ramification_index() != 1:
            continue

        try:
            tr = E.change_ring(P.residue_field()).trace_of_frobenius()
        except ArithmeticError:  # Bad reduction at P.
            continue

        x = P.gens_reduced()[0]

        precomp.append((x, _tr12(tr, det)))
        last_char = det

    x, tx = precomp[0]
    y, ty = precomp[1]

    Kgal = K.galois_closure('b')
    maps = K.embeddings(Kgal)

    for i in xrange(2**(K.degree() - 1)):
        ## We iterate through all possible characters. ##

        # Here, if i = i_{l-1} i_{l-2} cdots i_1 i_0 in binary, then i
        # corresponds to the character prod sigma_j^{i_j}.

        phi1x = 1
        phi2x = 1
        phi1y = 1
        phi2y = 1

        # We compute the two algebraic characters at x and y:
        for j in xrange(K.degree()):
            if i % 2 == 1:
                phi1x *= maps[j](x)
                phi1y *= maps[j](y)
            else:
                phi2x *= maps[j](x)
                phi2y *= maps[j](y)
            i = int(i / 2)

        # Any prime with reducible image must divide both of:
        gx = phi1x**12 + phi2x**12 - tx
        gy = phi1y**12 + phi2y**12 - ty

        if (gx != 0) or (gy != 0):
            for prime in Integer(Kgal.ideal([gx, gy]).norm()).prime_factors():
                bad_primes.add(prime)

            continue

        ## It is possible that our curve has CM. ##

        # Our character must be of the form Nm^K_F for an imaginary
        # quadratic subfield F of K (which is the CM field if E has CM).
        # We compute F:

        a = (Integer(phi1x + phi2x)**2 - 4 * x.norm()).squarefree_part()

        y = QQ['y'].gen()
        F = NumberField(y**2 - a, 'a')

        # Next, we turn K into relative number field over F.

        K = K.relativize(F.embeddings(K)[0], 'b')
        E = E.change_ring(K.structure()[1])

        ## We try to find a nontrivial divisibility condition. ##

        patience = 5 * K.absolute_degree()
        # Number of Frobenius elements to check before suspecting that E
        # has CM and computing the set of CM j-invariants of K to check.
        # TODO: Is this the best value for this parameter?

        while True:
            P = next(deg_one_primes)

            if not P.is_principal():
                continue

            try:
                tr = E.change_ring(P.residue_field()).trace_of_frobenius()
            except ArithmeticError:  # Bad reduction at P.
                continue

            x = P.gens_reduced()[0].norm(F)
            div = (x**12).trace() - _tr12(tr, x.norm())

            patience -= 1

            if div != 0:
                # We found our divisibility constraint.

                for prime in Integer(div).prime_factors():
                    bad_primes.add(prime)

                # Turn K back into an absolute number field.

                E = E.change_ring(K.structure()[0])
                K = K.structure()[0].codomain()

                break

            if patience == 0:
                # We suspect that E has CM, so we check:
                f = K.structure()[0]
                if f(E.j_invariant()) in cm_j_invariants(f.codomain()):
                    raise ValueError("The curve E should not have CM.")

    L = sorted(bad_primes)
    return L