def Pall_mass_density_at_odd_prime(self, p):
    """
    Returns the local representation density of a form (for
    representing itself) defined over `ZZ`, at some prime `p>2`.

    REFERENCES:
        Pall's article "The Weight of a Genus of Positive n-ary Quadratic Forms"
        appearing in Proc. Symp. Pure Math. VIII (1965), pp95--105.

    INPUT:
        `p` -- a prime number > 2.

    OUTPUT:
        a rational number.

    EXAMPLES::

        sage: Q = QuadraticForm(ZZ, 3, [1,0,0,1,0,1])
        sage: Q.Pall_mass_density_at_odd_prime(3)
        [(0, Quadratic form in 3 variables over Integer Ring with coefficients:
        [ 1 0 0 ]
        [ * 1 0 ]
        [ * * 1 ])] [(0, 3, 8)] [8/9] 8/9
        8/9
    """
    ## Check that p is a positive prime -- unnecessary since it's done implicitly in the next step. =)
    if p<=2:
        raise TypeError, "Oops!  We need p to be a prime > 2."

    ## Step 1: Obtain a p-adic (diagonal) local normal form, and
    ## compute the invariants for each Jordan block.
    jordan_list = self.jordan_blocks_by_scale_and_unimodular(p)
    modified_jordan_list = [(a, Q.dim(), Q.det())  for (a,Q) in jordan_list]     ## List of pairs (scale, det)
    #print jordan_list
    #print modified_jordan_list

    ## Step 2: Compute the list of local masses for each Jordan block
    jordan_mass_list = []
    for (s,n,d) in modified_jordan_list:
        generic_factor = prod([1 - p**(-2*j)  for j in range(1, floor((n-1)/2)+1)])
        #print "generic factor: ", generic_factor
        if (n % 2 == 0):
            m = n/2
            generic_factor *= (1 + legendre_symbol(((-1)**m) * d, p) * p**(-m))
        #print "jordan_mass: ", generic_factor
        jordan_mass_list = jordan_mass_list + [generic_factor]

    ## Step 3: Compute the local mass $\al_p$ at p.
        MJL = modified_jordan_list
    s = len(modified_jordan_list)
    M = [sum([MJL[j][1]  for j in range(i, s)])  for i in range(s-1)]    ## Note: It's s-1 since we don't need the last M.
    #print "M = ", M
    nu = sum([M[i] * MJL[i][0] * MJL[i][1]  for i in range(s-1)]) - ZZ(sum([J[0] * J[1] * (J[1]-1)  for J in MJL]))/ZZ(2)
    p_mass = prod(jordan_mass_list)
    p_mass *= 2**(s-1) * p**nu

    print jordan_list, MJL, jordan_mass_list, p_mass

    ## Return the result
    return p_mass
Example #2
0
def least_quadratic_nonresidue(p):
    """
    Returns the smallest positive integer quadratic non-residue in Z/pZ for primes p>2.

    EXAMPLES::

        sage: least_quadratic_nonresidue(5)
        2
        sage: [least_quadratic_nonresidue(p) for p in prime_range(3,100)]
        [2, 2, 3, 2, 2, 3, 2, 5, 2, 3, 2, 3, 2, 5, 2, 2, 2, 2, 7, 5, 3, 2, 3, 5]

    TESTS:

    Raises an error if input is a positive composite integer.

    ::

        sage: least_quadratic_nonresidue(20)
        Traceback (most recent call last):
        ...
        ValueError: Oops!  p must be a prime number > 2.


    Raises an error if input is 2. This is because every integer is a
    quadratic residue modulo 2.

    ::

        sage: least_quadratic_nonresidue(2)
        Traceback (most recent call last):
        ...
        ValueError: Oops!  There are no quadratic non-residues in Z/2Z.
    """
    from sage.functions.all import floor
    p1 = abs(p)

    ## Deal with the prime p = 2 and |p| <= 1.
    if p1 == 2:
        raise ValueError("Oops!  There are no quadratic non-residues in Z/2Z.")
    if p1 < 2:
        raise ValueError("Oops!  p must be a prime number > 2.")

    ## Find the smallest non-residue mod p
    ## For 7/8 of primes the answer is 2, 3 or 5:
    if p%8 in (3,5):
        return ZZ(2)
    if p%12 in (5,7):
        return ZZ(3)
    if p%5 in (2,3):
        return ZZ(5)
    ## default case (first needed for p=71):
    if not p.is_prime():
        raise ValueError("Oops!  p must be a prime number > 2.")
    from sage.misc.misc import xsrange
    for r in xsrange(7,p):
        if legendre_symbol(r, p) == -1:
            return ZZ(r)
def Pall_mass_density_at_odd_prime(self, p):
    """
    Returns the local representation density of a form (for
    representing itself) defined over `ZZ`, at some prime `p>2`.

    REFERENCES:
        Pall's article "The Weight of a Genus of Positive n-ary Quadratic Forms"
        appearing in Proc. Symp. Pure Math. VIII (1965), pp95--105.

    INPUT:
        `p` -- a prime number > 2.

    OUTPUT:
        a rational number.

    EXAMPLES::

        sage: Q = QuadraticForm(ZZ, 3, [1,0,0,1,0,1])
        sage: Q.Pall_mass_density_at_odd_prime(3)
        [(0, Quadratic form in 3 variables over Integer Ring with coefficients:
        [ 1 0 0 ]
        [ * 1 0 ]
        [ * * 1 ])] [(0, 3, 8)] [8/9] 8/9
        8/9
    """
    ## Check that p is a positive prime -- unnecessary since it's done implicitly in the next step. =)
    if p <= 2:
        raise TypeError("Oops!  We need p to be a prime > 2.")

    ## Step 1: Obtain a p-adic (diagonal) local normal form, and
    ## compute the invariants for each Jordan block.
    jordan_list = self.jordan_blocks_by_scale_and_unimodular(p)
    modified_jordan_list = [(a, Q.dim(), Q.det()) for (a, Q) in jordan_list
                            ]  ## List of pairs (scale, det)
    #print jordan_list
    #print modified_jordan_list

    ## Step 2: Compute the list of local masses for each Jordan block
    jordan_mass_list = []
    for (s, n, d) in modified_jordan_list:
        generic_factor = prod(
            [1 - p**(-2 * j) for j in range(1,
                                            floor((n - 1) / 2) + 1)])
        #print "generic factor: ", generic_factor
        if (n % 2 == 0):
            m = n / 2
            generic_factor *= (1 + legendre_symbol(((-1)**m) * d, p) * p**(-m))
        #print "jordan_mass: ", generic_factor
        jordan_mass_list = jordan_mass_list + [generic_factor]

        ## Step 3: Compute the local mass $\al_p$ at p.
        MJL = modified_jordan_list
    s = len(modified_jordan_list)
    M = [sum([MJL[j][1] for j in range(i, s)]) for i in range(s - 1)
         ]  ## Note: It's s-1 since we don't need the last M.
    #print "M = ", M
    nu = sum([M[i] * MJL[i][0] * MJL[i][1] for i in range(s - 1)
              ]) - ZZ(sum([J[0] * J[1] * (J[1] - 1) for J in MJL])) / ZZ(2)
    p_mass = prod(jordan_mass_list)
    p_mass *= 2**(s - 1) * p**nu

    print jordan_list, MJL, jordan_mass_list, p_mass

    ## Return the result
    return p_mass
def _next_good_prime(p, R, qq, patience, qqold):
    """
    Find the next prime `\\ell` which is good by ``qq`` but not by ``qqold``, 1 mod ``p``, and for which
    ``b^2+4*c`` is a square mod `\\ell`, for the sequence ``R`` if it is possible in runtime patience.

    INPUT:

    - ``p`` -- a prime

    - ``R`` -- an object in the class ``BinaryRecurrenceSequence``

    - ``qq`` -- a perfect power

    - ``patience`` -- a real number

    - ``qqold`` --  a perfect power less than or equal to ``qq``

    OUTPUT:

    - A prime `\\ell` such that `\\ell` is 1 mod ``p``, ``b^2+4*c`` is a square mod `\\ell` and the period of `\\ell` has ``goodness`` by ``qq`` but not ``qqold``, if patience has not be surpased.  Otherwise ``False``.


    EXAMPLES::

        sage: R = BinaryRecurrenceSequence(1,1)
        sage: sage.combinat.binary_recurrence_sequences._next_good_prime(7,R,1,100,1)        #ran out of patience to search for good primes
        False
        sage: sage.combinat.binary_recurrence_sequences._next_good_prime(7,R,2,100,1)
        29
        sage: sage.combinat.binary_recurrence_sequences._next_good_prime(7,R,2,100,2)        #ran out of patience, as qqold == qq, so no primes work
        False

    """

    #We are looking for pth powers in R.
    #Our primes must be good by qq, but not qqold.
    #We only allow patience number of iterations to find a good prime.

    #The variable _ell for R keeps track of the last "good" prime returned
    #that was not found from the dictionary _PGoodness

    #First, we check to see if we have already computed the goodness of a prime that fits
    #our requirement of being good by qq but not by qqold.  This is stored in the _PGoodness
    #dictionary.

    #Then if we have, we return the smallest such prime and delete it from the list.  If not, we
    #search through patience number of primes R._ell to find one good by qq but not qqold.  If it is
    #not good by either qqold or qq, then we add this prime to R._PGoodness under its goodness.

    #Possible_Primes keeps track of possible primes satisfying our goodness requirements we might return
    Possible_Primes = []

    #check to see if anything in R._PGoodness fits our goodness requirements
    for j in R._PGoodness:
        if (qqold < j <= qq) and len(R._PGoodness[j]):
            Possible_Primes.append(R._PGoodness[j][0])

    #If we found good primes, we take the smallest
    if Possible_Primes != []:
        q = min(Possible_Primes)
        n = _goodness(q, R, p)
        del R._PGoodness[n][
            0]  #if we are going to use it, then we delete it from R._PGoodness
        return q

    #If nothing is already stored in R._PGoodness, we start (from where we left off at R._ell) checking
    #for good primes.  We only tolerate patience number of tries before giving up.
    else:
        i = 0
        while i < patience:
            i += 1
            R._ell = next_prime(R._ell)

            #we require that R._ell is 1 mod p, so that p divides the order of the multiplicative
            #group mod R._ell, so that not all elements of GF(R._ell) are pth powers.
            if R._ell % p == 1:

                #requiring that b^2 + 4c is a square in GF(R._ell) ensures that the period mod R._ell
                #divides R._ell - 1
                if legendre_symbol(R.b**2 + 4 * R.c, R._ell) == 1:

                    N = _goodness(R._ell, R, p)

                    #proceed only if R._ell statisfies the goodness requirements
                    if qqold < N <= qq:
                        return R._ell

                    #if we do not use the prime, we store it in R._PGoodness
                    else:
                        if N in R._PGoodness:
                            R._PGoodness[N].append(R._ell)
                        else:
                            R._PGoodness[N] = [R._ell]

        return False
Example #5
0
def has_equivalent_Jordan_decomposition_at_prime(self, other, p):
    """
    Determines if the given quadratic form has a Jordan decomposition
    equivalent to that of self.

    INPUT:
        a QuadraticForm

    OUTPUT:
        boolean

    EXAMPLES::

        sage: Q1 = QuadraticForm(ZZ, 3, [1, 0, -1, 1, 0, 3])
        sage: Q2 = QuadraticForm(ZZ, 3, [1, 0, 0, 2, -2, 6])
        sage: Q3 = QuadraticForm(ZZ, 3, [1, 0, 0, 1, 0, 11])
        sage: [Q1.level(), Q2.level(), Q3.level()]
        [44, 44, 44]
        sage: Q1.has_equivalent_Jordan_decomposition_at_prime(Q2,2)
        False
        sage: Q1.has_equivalent_Jordan_decomposition_at_prime(Q2,11)
        False
        sage: Q1.has_equivalent_Jordan_decomposition_at_prime(Q3,2)
        False
        sage: Q1.has_equivalent_Jordan_decomposition_at_prime(Q3,11)
        True
        sage: Q2.has_equivalent_Jordan_decomposition_at_prime(Q3,2)
        True
        sage: Q2.has_equivalent_Jordan_decomposition_at_prime(Q3,11)
        False

    """
    ## Sanity Checks
    #if not isinstance(other, QuadraticForm):
    if not isinstance(other, type(self)):
        raise TypeError(
            "Oops!  The first argument must be of type QuadraticForm.")
    if not is_prime(p):
        raise TypeError("Oops!  The second argument must be a prime number.")

    ## Get the relevant local normal forms quickly
    self_jordan = self.jordan_blocks_by_scale_and_unimodular(p,
                                                             safe_flag=False)
    other_jordan = other.jordan_blocks_by_scale_and_unimodular(p,
                                                               safe_flag=False)

    ## DIAGNOSTIC
    #print "self_jordan = ", self_jordan
    #print "other_jordan = ", other_jordan

    ## Check for the same number of Jordan components
    if len(self_jordan) != len(other_jordan):
        return False

    ## Deal with odd primes:  Check that the Jordan component scales, dimensions, and discriminants are the same
    if p != 2:
        for i in range(len(self_jordan)):
            if (self_jordan[i][0] != other_jordan[i][0]) \
               or (self_jordan[i][1].dim() != other_jordan[i][1].dim()) \
               or (legendre_symbol(self_jordan[i][1].det() * other_jordan[i][1].det(), p) != 1):
                return False

        ## All tests passed for an odd prime.
        return True

    ## For p = 2:  Check that all Jordan Invariants are the same.
    elif p == 2:

        ## Useful definition
        t = len(self_jordan)  ## Define t = Number of Jordan components

        ## Check that all Jordan Invariants are the same (scale, dim, and norm)
        for i in range(t):
            if (self_jordan[i][0] != other_jordan[i][0]) \
               or (self_jordan[i][1].dim() != other_jordan[i][1].dim()) \
               or (valuation(GCD(self_jordan[i][1].coefficients()), p) != valuation(GCD(other_jordan[i][1].coefficients()), p)):
                return False

        ## DIAGNOSTIC
        #print "Passed the Jordan invariant test."

        ## Use O'Meara's isometry test 93:29 on p277.
        ## ------------------------------------------

        ## List of norms, scales, and dimensions for each i
        scale_list = [ZZ(2)**self_jordan[i][0] for i in range(t)]
        norm_list = [
            ZZ(2)**(self_jordan[i][0] +
                    valuation(GCD(self_jordan[i][1].coefficients()), 2))
            for i in range(t)
        ]
        dim_list = [(self_jordan[i][1].dim()) for i in range(t)]

        ## List of Hessian determinants and Hasse invariants for each Jordan (sub)chain
        ## (Note: This is not the same as O'Meara's Gram determinants, but ratios are the same!)  -- NOT SO GOOD...
        ## But it matters in condition (ii), so we multiply all by 2 (instead of dividing by 2 since only square-factors matter, and it's easier.)
        j = 0
        self_chain_det_list = [
            self_jordan[j][1].Gram_det() * (scale_list[j]**dim_list[j])
        ]
        other_chain_det_list = [
            other_jordan[j][1].Gram_det() * (scale_list[j]**dim_list[j])
        ]
        self_hasse_chain_list = [
            self_jordan[j][1].scale_by_factor(
                ZZ(2)**self_jordan[j][0]).hasse_invariant__OMeara(2)
        ]
        other_hasse_chain_list = [
            other_jordan[j][1].scale_by_factor(
                ZZ(2)**other_jordan[j][0]).hasse_invariant__OMeara(2)
        ]

        for j in range(1, t):
            self_chain_det_list.append(self_chain_det_list[j - 1] *
                                       self_jordan[j][1].Gram_det() *
                                       (scale_list[j]**dim_list[j]))
            other_chain_det_list.append(other_chain_det_list[j - 1] *
                                        other_jordan[j][1].Gram_det() *
                                        (scale_list[j]**dim_list[j]))
            self_hasse_chain_list.append(self_hasse_chain_list[j-1] \
                                         * hilbert_symbol(self_chain_det_list[j-1], self_jordan[j][1].Gram_det(), 2) \
                                         * self_jordan[j][1].hasse_invariant__OMeara(2))
            other_hasse_chain_list.append(other_hasse_chain_list[j-1] \
                                          * hilbert_symbol(other_chain_det_list[j-1], other_jordan[j][1].Gram_det(), 2) \
                                          * other_jordan[j][1].hasse_invariant__OMeara(2))

        ## SANITY CHECK -- check that the scale powers are strictly increasing
        for i in range(1, len(scale_list)):
            if scale_list[i - 1] >= scale_list[i]:
                raise RuntimeError(
                    "Oops!  There is something wrong with the Jordan Decomposition -- the given scales are not strictly increasing!"
                )

        ## DIAGNOSTIC
        #print "scale_list = ", scale_list
        #print "norm_list = ", norm_list
        #print "dim_list = ", dim_list
        #print
        #print "self_chain_det_list = ", self_chain_det_list
        #print "other_chain_det_list = ", other_chain_det_list
        #print "self_hasse_chain_list = ", self_hasse_chain_list
        #print "other_hasse_chain_det_list = ", other_hasse_chain_list

        ## Test O'Meara's two conditions
        for i in range(t - 1):

            ## Condition (i): Check that their (unit) ratio is a square (but it suffices to check at most mod 8).
            modulus = norm_list[i] * norm_list[i + 1] / (scale_list[i]**2)
            if modulus > 8:
                modulus = 8
            if (modulus > 1) and ((
                (self_chain_det_list[i] / other_chain_det_list[i]) % modulus)
                                  != 1):
                #print "Failed when i =", i, " in condition 1."
                return False

            ## Check O'Meara's condition (ii) when appropriate
            if norm_list[i + 1] % (4 * norm_list[i]) == 0:
                if self_hasse_chain_list[i] * hilbert_symbol(norm_list[i] * other_chain_det_list[i], -self_chain_det_list[i], 2) \
                       != other_hasse_chain_list[i] * hilbert_symbol(norm_list[i], -other_chain_det_list[i], 2):      ## Nipp conditions
                    #print "Failed when i =", i, " in condition 2."
                    return False

        ## All tests passed for the prime 2.
        return True

    else:
        raise TypeError("Oops!  This should not have happened.")
Example #6
0
def _exceptionals(E, L, patience=1000):
    r"""
    Determine which primes in L are exceptional for E, using Proposition 19
    of Section 2.8 of Serre's ``Proprietes Galoisiennes des Points d'Ordre
    Fini des Courbes Elliptiques'' [Serre72].

    INPUT:

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

    - ``L`` - list - a list of prime numbers.

    - ``patience`` - int (a bound on the number of traces of Frobenius to
                          use while trying to prove surjectivity).

    OUTPUT: list - The list of all primes l in L for which the mod l image
                   might fail to be surjective.

    EXAMPLES::

        sage: K = NumberField(x**2 - 29, 'a'); a = K.gen()
        sage: E = EllipticCurve([1, 0, ((5 + a)/2)**2, 0, 0])
        sage: sage.schemes.elliptic_curves.gal_reps_number_field._exceptionals(E, [29, 31])
        [29]
    """

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

    output = []

    L = list(set(L)) # Remove duplicates from L.

    for l in L:
        if l == 2: # c.f. Section 5.3(a) of [Serre72].
            if (E.j_invariant() - 1728).is_square():
                output.append(2)
            elif not E.division_polynomial(2).is_irreducible():
                output.append(2)

        elif l == 3: # c.f. Section 5.3(b) of [Serre72].
            if K(-3).is_square():
                output.append(3)
            elif not (K['x'].gen()**3 - E.j_invariant()).is_irreducible():
                output.append(3)
            elif not E.division_polynomial(3).is_irreducible():
                output.append(3)

        elif (K.discriminant() % l) == 0:
            if not K['x'](cyclotomic_polynomial(l)).is_irreducible():
                # I.E. if the action on lth roots of unity is not surjective
                # (We want this since as a Galois module, \wedge^2 E[l]
                # is isomorphic to the lth roots of unity.)
                output.append(l)

    for l in output:
        L.remove(l)
    if 2 in L:
        L.remove(2)
    if 3 in L:
        L.remove(3)

    # If the image is not surjective, then it is contained in one of the
    # maximal subgroups. So, we start by creating a dictionary between primes
    # l in L and possible maximal subgroups in which the mod l image could
    # be contained. This information is stored as a triple whose elements
    # are True/False according to whether the mod l image could be contained
    # in:
    #      0. A Borel or normalizer of split Cartan subgroup.
    #      1. A nonsplit Cartan subgroup or its normalizer.
    #      2. An exceptional subgroup of GL_2.

    D = {}
    for l in L:
        D[l] = [True, True, True]

    for P in K.primes_of_degree_one_iter():
        try:
            trace = E.change_ring(P.residue_field()).trace_of_frobenius()
        except ArithmeticError: # Bad reduction at P.
            continue

        patience -= 1

        determinant = P.norm()
        discriminant = trace**2 - 4 * determinant

        unexc = [] # Primes we discover are unexceptional go here.

        for l in D.iterkeys():
            tr = GF(l)(trace)
            det = GF(l)(determinant)
            disc = GF(l)(discriminant)

            if tr == 0:
                # I.E. if Frob_P could be contained in the normalizer of
                # a Cartan subgroup, but not in the Cartan subgroup.
                continue

            if disc == 0:
                # I.E. If the matrix might be non-diagonalizable over F_{p^2}.
                continue

            if legendre_symbol(disc, l) == 1:
                # If the matrix is diagonalizable over F_p, it can't be
                # contained in a non-split Cartan subgroup. Since we've
                # gotten rid of the case where it is contained in the
                # of a nonsplit Cartan subgroup but not the Cartan subgroup,
                D[l][1] = False
            else:
                # If the matrix is not diagonalizable over F_p, it can't
                # be contained Borel subgroup.
                D[l][0] = False

            if det != 0: # c.f. [Serre72], Section 2.8, Prop. 19
                u = trace**2 / det
                if u not in (1, 2, 4) and u**2 - 3 * u + 1 != 0:
                    D[l][2] = False


            if D[l] == [False, False, False]:
                unexc.append(l)

        for l in unexc:
            D.pop(l)
        unexc = []

        if (D == {}) or (patience == 0):
            break

    for l in D.iterkeys():
        output.append(l)

    output.sort()
    return output
def _next_good_prime(p, R, qq, patience, qqold):

    """
    Find the next prime `\\ell` which is good by ``qq`` but not by ``qqold``, 1 mod ``p``, and for which
    ``b^2+4*c`` is a square mod `\\ell`, for the sequence ``R`` if it is possible in runtime patience.

    INPUT:

    - ``p`` -- a prime

    - ``R`` -- an object in the class ``BinaryRecurrenceSequence``

    - ``qq`` -- a perfect power

    - ``patience`` -- a real number

    - ``qqold`` --  a perfect power less than or equal to ``qq``

    OUTPUT:

    - A prime `\\ell` such that `\\ell` is 1 mod ``p``, ``b^2+4*c`` is a square mod `\\ell` and the period of `\\ell` has ``goodness`` by ``qq`` but not ``qqold``, if patience has not be surpased.  Otherwise ``False``.


    EXAMPLES::

        sage: R = BinaryRecurrenceSequence(1,1)
        sage: sage.combinat.binary_recurrence_sequences._next_good_prime(7,R,1,100,1)        #ran out of patience to search for good primes
        False
        sage: sage.combinat.binary_recurrence_sequences._next_good_prime(7,R,2,100,1)
        29
        sage: sage.combinat.binary_recurrence_sequences._next_good_prime(7,R,2,100,2)        #ran out of patience, as qqold == qq, so no primes work
        False

    """

    #We are looking for pth powers in R.
    #Our primes must be good by qq, but not qqold.
    #We only allow patience number of iterations to find a good prime.

    #The variable _ell for R keeps track of the last "good" prime returned
    #that was not found from the dictionary _PGoodness

    #First, we check to see if we have already computed the goodness of a prime that fits
    #our requirement of being good by qq but not by qqold.  This is stored in the _PGoodness
    #dictionary.

    #Then if we have, we return the smallest such prime and delete it from the list.  If not, we
    #search through patience number of primes R._ell to find one good by qq but not qqold.  If it is
    #not good by either qqold or qq, then we add this prime to R._PGoodness under its goodness.

    #Possible_Primes keeps track of possible primes satisfying our goodness requirements we might return
    Possible_Primes = []


    #check to see if anything in R._PGoodness fits our goodness requirements
    for j in R._PGoodness:
        if (qqold < j <= qq) and len(R._PGoodness[j]):
            Possible_Primes.append(R._PGoodness[j][0])

    #If we found good primes, we take the smallest
    if Possible_Primes != []:
        q = min(Possible_Primes)
        n = _goodness(q, R, p)
        del R._PGoodness[n][0]    #if we are going to use it, then we delete it from R._PGoodness
        return q

    #If nothing is already stored in R._PGoodness, we start (from where we left off at R._ell) checking
    #for good primes.  We only tolerate patience number of tries before giving up.
    else:
        i = 0
        while i < patience:
            i += 1
            R._ell = next_prime(R._ell)

            #we require that R._ell is 1 mod p, so that p divides the order of the multiplicative
            #group mod R._ell, so that not all elements of GF(R._ell) are pth powers.
            if R._ell % p == 1:

                #requiring that b^2 + 4c is a square in GF(R._ell) ensures that the period mod R._ell
                #divides R._ell - 1
                if legendre_symbol(R.b**2+4*R.c, R._ell) == 1:

                    N = _goodness(R._ell, R, p)

                    #proceed only if R._ell statisfies the goodness requirements
                    if qqold < N <= qq:
                        return R._ell

                    #if we do not use the prime, we store it in R._PGoodness
                    else:
                        if N in R._PGoodness:
                            R._PGoodness[N].append(R._ell)
                        else :
                            R._PGoodness[N] = [R._ell]

        return False
def _maybe_borels(E, L, patience=100):
    r"""
    Determine which primes in L might have an image contained in a
    Borel subgroup, using straight-forward checking of traces of
    Frobenius.

    .. NOTE:

       This function will sometimes return primes for which the image
       is not contained in a Borel subgroup.  This issue cannot always
       be fixed by increasing patience as it may be a result of a
       failure of a local-global principle for isogenies.

    INPUT:

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

    - ``L`` - list - a list of prime numbers.

    - ``patience`` - int (a positive integer bounding the number of
                          traces of Frobenius to use while trying to
                          prove irreducibility).

    OUTPUT: list - The list of all primes `\ell` in L for which the
                   mod `\ell` image might be contained in a Borel
                   subgroup of `GL_2(\mathbf{F}_{\ell})`.

    EXAMPLES::

        sage: E = EllipticCurve('11a1') # has a 5-isogeny
        sage: sage.schemes.elliptic_curves.gal_reps_number_field._maybe_borels(E,primes(40))
        [5]

    Example to show that the output may contain primes where the
    representation is in fact reducible.  Over `\QQ` the following is
    essentially the unique such example by [Sutherland12]_::

        sage: E = EllipticCurve_from_j(2268945/128)
        sage: sage.schemes.elliptic_curves.gal_reps_number_field._maybe_borels(E, [7, 11])
        [7]

    This curve does posess a 7-isogeny modulo every prime of good reduction, but has no rational 7-isogeny::

        sage: E.isogenies_prime_degree(7)
        []

    A number field example:

        sage: K.<i> = QuadraticField(-1)
        sage: E = EllipticCurve([1+i, -i, i, -399-240*i,  2627+2869*i])
        sage: sage.schemes.elliptic_curves.gal_reps_number_field._maybe_borels(E, primes(20))
        [2, 3]

    Here the curve really does possess isognies of degrees 2 and 3::

        sage: [len(E.isogenies_prime_degree(l)) for l in [2,3]]
        [1, 1]
    """
    E = _over_numberfield(E)
    K = E.base_field()

    L = list(set(L))  # Remove duplicates from L and makes a copy for output
    L.sort()

    include_2 = False
    if 2 in L:  # c.f. Section 5.3(a) of [Serre72].
        L.remove(2)
        include_2 = not E.division_polynomial(2).is_irreducible()

    for P in K.primes_of_degree_one_iter():
        if not (L and patience):  # stop if no primes are left, or
            # patience is exhausted
            break

        patience -= 1

        # Check whether the Frobenius polynomial at P is irreducible
        # modulo each l, dropping l from the list if so.

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

        determinant = P.norm()
        discriminant = trace ** 2 - 4 * determinant

        for l in L:
            if legendre_symbol(discriminant, l) == -1:
                L.remove(l)

    if include_2:
        L = [2] + L
    return L
def has_equivalent_Jordan_decomposition_at_prime(self, other, p):
    """
    Determines if the given quadratic form has a Jordan decomposition
    equivalent to that of self.
    
    INPUT:
        a QuadraticForm

    OUTPUT:
        boolean
    
    EXAMPLES::

        sage: Q1 = QuadraticForm(ZZ, 3, [1, 0, -1, 1, 0, 3])
        sage: Q2 = QuadraticForm(ZZ, 3, [1, 0, 0, 2, -2, 6])
        sage: Q3 = QuadraticForm(ZZ, 3, [1, 0, 0, 1, 0, 11])
        sage: [Q1.level(), Q2.level(), Q3.level()]
        [44, 44, 44]
        sage: Q1.has_equivalent_Jordan_decomposition_at_prime(Q2,2)
        False
        sage: Q1.has_equivalent_Jordan_decomposition_at_prime(Q2,11)
        False
        sage: Q1.has_equivalent_Jordan_decomposition_at_prime(Q3,2)
        False
        sage: Q1.has_equivalent_Jordan_decomposition_at_prime(Q3,11)
        True 
        sage: Q2.has_equivalent_Jordan_decomposition_at_prime(Q3,2)
        True 
        sage: Q2.has_equivalent_Jordan_decomposition_at_prime(Q3,11)
        False
    
    """
    ## Sanity Checks
    #if not isinstance(other, QuadraticForm):
    if type(other) != type(self):
        raise TypeError, "Oops!  The first argument must be of type QuadraticForm."
    if not is_prime(p):
        raise TypeError, "Oops!  The second argument must be a prime number."

    ## Get the relevant local normal forms quickly
    self_jordan = self.jordan_blocks_by_scale_and_unimodular(p, safe_flag= False)
    other_jordan = other.jordan_blocks_by_scale_and_unimodular(p, safe_flag=False)    

    ## DIAGNOSTIC
    #print "self_jordan = ", self_jordan
    #print "other_jordan = ", other_jordan


    ## Check for the same number of Jordan components
    if len(self_jordan) != len(other_jordan):
        return False


    ## Deal with odd primes:  Check that the Jordan component scales, dimensions, and discriminants are the same
    if p != 2:
        for i in range(len(self_jordan)):
            if (self_jordan[i][0] != other_jordan[i][0]) \
               or (self_jordan[i][1].dim() != other_jordan[i][1].dim()) \
               or (legendre_symbol(self_jordan[i][1].det() * other_jordan[i][1].det(), p) != 1):
                return False

        ## All tests passed for an odd prime.
        return True


    ## For p = 2:  Check that all Jordan Invariants are the same.
    elif p == 2:

        ## Useful definition
        t = len(self_jordan)          ## Define t = Number of Jordan components


        ## Check that all Jordan Invariants are the same (scale, dim, and norm)
        for i in range(t):
            if (self_jordan[i][0] != other_jordan[i][0]) \
               or (self_jordan[i][1].dim() != other_jordan[i][1].dim()) \
               or (valuation(GCD(self_jordan[i][1].coefficients()), p) != valuation(GCD(other_jordan[i][1].coefficients()), p)):
                return False

        ## DIAGNOSTIC
        #print "Passed the Jordan invariant test."


        ## Use O'Meara's isometry test 93:29 on p277.
        ## ------------------------------------------

        ## List of norms, scales, and dimensions for each i
        scale_list = [ZZ(2)**self_jordan[i][0]  for i in range(t)]
        norm_list = [ZZ(2)**(self_jordan[i][0] + valuation(GCD(self_jordan[i][1].coefficients()), 2))  for i in range(t)]
        dim_list = [(self_jordan[i][1].dim())  for i in range(t)]

        ## List of Hessian determinants and Hasse invariants for each Jordan (sub)chain
        ## (Note: This is not the same as O'Meara's Gram determinants, but ratios are the same!)  -- NOT SO GOOD...
        ## But it matters in condition (ii), so we multiply all by 2 (instead of dividing by 2 since only square-factors matter, and it's easier.)
        j = 0
        self_chain_det_list = [ self_jordan[j][1].Gram_det() * (scale_list[j]**dim_list[j])]
        other_chain_det_list = [ other_jordan[j][1].Gram_det() * (scale_list[j]**dim_list[j])]
        self_hasse_chain_list = [ self_jordan[j][1].scale_by_factor(ZZ(2)**self_jordan[j][0]).hasse_invariant__OMeara(2) ]
        other_hasse_chain_list = [ other_jordan[j][1].scale_by_factor(ZZ(2)**other_jordan[j][0]).hasse_invariant__OMeara(2) ]
                   
        for j in range(1, t):
            self_chain_det_list.append(self_chain_det_list[j-1] * self_jordan[j][1].Gram_det() * (scale_list[j]**dim_list[j]))
            other_chain_det_list.append(other_chain_det_list[j-1] * other_jordan[j][1].Gram_det() * (scale_list[j]**dim_list[j]))
            self_hasse_chain_list.append(self_hasse_chain_list[j-1] \
                                         * hilbert_symbol(self_chain_det_list[j-1], self_jordan[j][1].Gram_det(), 2) \
                                         * self_jordan[j][1].hasse_invariant__OMeara(2))
            other_hasse_chain_list.append(other_hasse_chain_list[j-1] \
                                          * hilbert_symbol(other_chain_det_list[j-1], other_jordan[j][1].Gram_det(), 2) \
                                          * other_jordan[j][1].hasse_invariant__OMeara(2))


        ## SANITY CHECK -- check that the scale powers are strictly increasing        
        for i in range(1, len(scale_list)):
            if scale_list[i-1] >= scale_list[i]:
                   raise RuntimeError, "Oops!  There is something wrong with the Jordan Decomposition -- the given scales are not strictly increasing!"


        ## DIAGNOSTIC
        #print "scale_list = ", scale_list
        #print "norm_list = ", norm_list
        #print "dim_list = ", dim_list
        #print
        #print "self_chain_det_list = ", self_chain_det_list
        #print "other_chain_det_list = ", other_chain_det_list
        #print "self_hasse_chain_list = ", self_hasse_chain_list
        #print "other_hasse_chain_det_list = ", other_hasse_chain_list

        
        ## Test O'Meara's two conditions
        for i in range(t-1):

            ## Condition (i): Check that their (unit) ratio is a square (but it suffices to check at most mod 8).
            modulus = norm_list[i] * norm_list[i+1] / (scale_list[i] ** 2)
            if modulus > 8:
                   modulus = 8 
            if (modulus > 1) and (((self_chain_det_list[i] / other_chain_det_list[i]) % modulus) != 1):
                #print "Failed when i =", i, " in condition 1."
                return False
            
            ## Check O'Meara's condition (ii) when appropriate
            if norm_list[i+1] % (4 * norm_list[i]) == 0:
                if self_hasse_chain_list[i] * hilbert_symbol(norm_list[i] * other_chain_det_list[i], -self_chain_det_list[i], 2) \
                       != other_hasse_chain_list[i] * hilbert_symbol(norm_list[i], -other_chain_det_list[i], 2):      ## Nipp conditions
                    #print "Failed when i =", i, " in condition 2."
                    return False


        ## All tests passed for the prime 2.
        return True
            
    else:
        raise TypeError, "Oops!  This should not have happened."
def _exceptionals(E, L, patience=1000):
    r"""
    Determine which primes in L are exceptional for E, using Proposition 19
    of Section 2.8 of Serre's ``Proprietes Galoisiennes des Points d'Ordre
    Fini des Courbes Elliptiques'' [Serre72].

    INPUT:

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

    - ``L`` - list - a list of prime numbers.

    - ``patience`` - int (a bound on the number of traces of Frobenius to
                          use while trying to prove surjectivity).

    OUTPUT: list - The list of all primes l in L for which the mod l image
                   might fail to be surjective.

    EXAMPLES::

        sage: K = NumberField(x**2 - 29, 'a'); a = K.gen()
        sage: E = EllipticCurve([1, 0, ((5 + a)/2)**2, 0, 0])
        sage: sage.schemes.elliptic_curves.gal_reps_number_field._exceptionals(E, [29, 31])
        [29]
    """

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

    output = []

    L = list(set(L))  # Remove duplicates from L.

    for l in L:
        if l == 2:  # c.f. Section 5.3(a) of [Serre72].
            if (E.j_invariant() - 1728).is_square():
                output.append(2)
            elif not E.division_polynomial(2).is_irreducible():
                output.append(2)

        elif l == 3:  # c.f. Section 5.3(b) of [Serre72].
            if K(-3).is_square():
                output.append(3)
            elif not (K['x'].gen()**3 - E.j_invariant()).is_irreducible():
                output.append(3)
            elif not E.division_polynomial(3).is_irreducible():
                output.append(3)

        elif (K.discriminant() % l) == 0:
            if not K['x'](cyclotomic_polynomial(l)).is_irreducible():
                # I.E. if the action on lth roots of unity is not surjective
                # (We want this since as a Galois module, \wedge^2 E[l]
                # is isomorphic to the lth roots of unity.)
                output.append(l)

    for l in output:
        L.remove(l)
    if 2 in L:
        L.remove(2)
    if 3 in L:
        L.remove(3)

    # If the image is not surjective, then it is contained in one of the
    # maximal subgroups. So, we start by creating a dictionary between primes
    # l in L and possible maximal subgroups in which the mod l image could
    # be contained. This information is stored as a triple whose elements
    # are True/False according to whether the mod l image could be contained
    # in:
    #      0. A Borel or normalizer of split Cartan subgroup.
    #      1. A nonsplit Cartan subgroup or its normalizer.
    #      2. An exceptional subgroup of GL_2.

    D = {}
    for l in L:
        D[l] = [True, True, True]

    for P in K.primes_of_degree_one_iter():
        try:
            trace = E.change_ring(P.residue_field()).trace_of_frobenius()
        except ArithmeticError:  # Bad reduction at P.
            continue

        patience -= 1

        determinant = P.norm()
        discriminant = trace**2 - 4 * determinant

        unexc = []  # Primes we discover are unexceptional go here.

        for l in D.iterkeys():
            tr = GF(l)(trace)
            det = GF(l)(determinant)
            disc = GF(l)(discriminant)

            if tr == 0:
                # I.E. if Frob_P could be contained in the normalizer of
                # a Cartan subgroup, but not in the Cartan subgroup.
                continue

            if disc == 0:
                # I.E. If the matrix might be non-diagonalizable over F_{p^2}.
                continue

            if legendre_symbol(disc, l) == 1:
                # If the matrix is diagonalizable over F_p, it can't be
                # contained in a non-split Cartan subgroup. Since we've
                # gotten rid of the case where it is contained in the
                # of a nonsplit Cartan subgroup but not the Cartan subgroup,
                D[l][1] = False
            else:
                # If the matrix is not diagonalizable over F_p, it can't
                # be contained Borel subgroup.
                D[l][0] = False

            if det != 0:  # c.f. [Serre72], Section 2.8, Prop. 19
                u = trace**2 / det
                if u not in (1, 2, 4) and u**2 - 3 * u + 1 != 0:
                    D[l][2] = False

            if D[l] == [False, False, False]:
                unexc.append(l)

        for l in unexc:
            D.pop(l)
        unexc = []

        if (D == {}) or (patience == 0):
            break

    for l in D.iterkeys():
        output.append(l)

    output.sort()
    return output
def _maybe_borels(E, L, patience=100):
    r"""
    Determine which primes in L might have an image contained in a
    Borel subgroup, using straight-forward checking of traces of
    Frobenius.

    .. NOTE:

       This function will sometimes return primes for which the image
       is not contained in a Borel subgroup.  This issue cannot always
       be fixed by increasing patience as it may be a result of a
       failure of a local-global principle for isogenies.

    INPUT:

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

    - ``L`` - list - a list of prime numbers.

    - ``patience`` - int (a positive integer bounding the number of
                          traces of Frobenius to use while trying to
                          prove irreducibility).

    OUTPUT: list - The list of all primes `\ell` in L for which the
                   mod `\ell` image might be contained in a Borel
                   subgroup of `GL_2(\mathbf{F}_{\ell})`.

    EXAMPLES::

        sage: E = EllipticCurve('11a1') # has a 5-isogeny
        sage: sage.schemes.elliptic_curves.gal_reps_number_field._maybe_borels(E,primes(40))
        [5]

    Example to show that the output may contain primes where the
    representation is in fact reducible.  Over `\QQ` the following is
    essentially the unique such example by [Sutherland12]_::

        sage: E = EllipticCurve_from_j(2268945/128)
        sage: sage.schemes.elliptic_curves.gal_reps_number_field._maybe_borels(E, [7, 11])
        [7]

    This curve does posess a 7-isogeny modulo every prime of good reduction, but has no rational 7-isogeny::

        sage: E.isogenies_prime_degree(7)
        []

    A number field example:

        sage: K.<i> = QuadraticField(-1)
        sage: E = EllipticCurve([1+i, -i, i, -399-240*i,  2627+2869*i])
        sage: sage.schemes.elliptic_curves.gal_reps_number_field._maybe_borels(E, primes(20))
        [2, 3]

    Here the curve really does possess isognies of degrees 2 and 3::

        sage: [len(E.isogenies_prime_degree(l)) for l in [2,3]]
        [1, 1]
    """
    E = _over_numberfield(E)
    K = E.base_field()

    L = list(set(L))  # Remove duplicates from L and makes a copy for output
    L.sort()

    include_2 = False
    if 2 in L:  # c.f. Section 5.3(a) of [Serre72].
        L.remove(2)
        include_2 = not E.division_polynomial(2).is_irreducible()

    for P in K.primes_of_degree_one_iter():
        if not (L and patience):  # stop if no primes are left, or
            # patience is exhausted
            break

        patience -= 1

        # Check whether the Frobenius polynomial at P is irreducible
        # modulo each l, dropping l from the list if so.

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

        determinant = P.norm()
        discriminant = trace**2 - 4 * determinant

        for l in L:
            if legendre_symbol(discriminant, l) == -1:
                L.remove(l)

    if include_2:
        L = [2] + L
    return L