Esempio n. 1
0
def Sp(n, R, var='a'):
    """
    Return the symplectic group of degree n over R.

    .. note::
        This group is also available via ``groups.matrix.Sp()``.

    EXAMPLES::

        sage: Sp(4,5)
        Symplectic Group of rank 2 over Finite Field of size 5
        sage: Sp(3,GF(7))
        Traceback (most recent call last):
        ...
        ValueError: the degree n (=3) must be even

    TESTS::

        sage: groups.matrix.Sp(2, 3)
        Symplectic Group of rank 1 over Finite Field of size 3
    """
    if n % 2 != 0:
        raise ValueError, "the degree n (=%s) must be even" % n
    if isinstance(R, (int, long, Integer)):
        R = FiniteField(R, var)
    if is_FiniteField(R):
        return SymplecticGroup_finite_field(n, R)
    else:
        return SymplecticGroup_generic(n, R)
Esempio n. 2
0
    def __init__(self, prime=2, level=1, base_ring=rings.IntegerRing()):
        r"""
        Create a supersingular module.

        EXAMPLES::

            sage: SupersingularModule(3)
            Module of supersingular points on X_0(1)/F_3 over Integer Ring
        """

        if not prime.is_prime():
            raise ValueError("the argument prime must be a prime number")
        if prime.divides(level):
            raise ValueError(
                "the argument level must be coprime to the argument prime")
        if level != 1:
            raise NotImplementedError(
                "supersingular modules of level > 1 not yet implemented")
        self.__prime = prime
        from sage.rings.all import FiniteField
        self.__finite_field = FiniteField(prime**2, 'a')
        self.__level = level
        self.__hecke_matrices = {}
        hecke.HeckeModule_free_module.__init__(self,
                                               base_ring,
                                               prime * level,
                                               weight=2)
Esempio n. 3
0
def SL(n, R, var='a'):
    r"""
    Return the special linear group of degree `n` over the ring
    `R`.
    
    EXAMPLES::
    
        sage: SL(3,GF(2))
        Special Linear Group of degree 3 over Finite Field of size 2
        sage: G = SL(15,GF(7)); G
        Special Linear Group of degree 15 over Finite Field of size 7
        sage: G.category()
        Category of finite groups
        sage: G.order()
        1956712595698146962015219062429586341124018007182049478916067369638713066737882363393519966343657677430907011270206265834819092046250232049187967718149558134226774650845658791865745408000000
        sage: len(G.gens())
        2
        sage: G = SL(2,ZZ); G
        Special Linear Group of degree 2 over Integer Ring
        sage: G.gens()
        [
        [ 0  1]
        [-1  0],
        [1 1]
        [0 1]
        ]
    
    Next we compute generators for `\mathrm{SL}_3(\ZZ)`.
    
    ::
    
        sage: G = SL(3,ZZ); G
        Special Linear Group of degree 3 over Integer Ring
        sage: G.gens()
        [
        [0 1 0]
        [0 0 1]
        [1 0 0],
        [ 0  1  0]
        [-1  0  0]
        [ 0  0  1],
        [1 1 0]
        [0 1 0]
        [0 0 1]
        ]

        sage: TestSuite(G).run()
    """
    if isinstance(R, (int, long, Integer)):
        R = FiniteField(R, var)
    if is_FiniteField(R):
        return SpecialLinearGroup_finite_field(n, R)
    else:
        return SpecialLinearGroup_generic(n, R)
Esempio n. 4
0
def SO(n, R, e=0, var='a'):
    """
    Return the special orthogonal group of degree `n` over the
    ring `R`.

    INPUT:

    -  ``n`` - the degree

    -  ``R`` - ring

    -  ``e`` - a parameter for orthogonal groups only
       depending on the invariant form

    .. note::
        This group is also available via ``groups.matrix.SO()``.

    EXAMPLES::

        sage: G = SO(3,GF(5))
        sage: G.gens()
        [
        [2 0 0]
        [0 3 0]
        [0 0 1],
        [3 2 3]
        [0 2 0]
        [0 3 1],
        [1 4 4]
        [4 0 0]
        [2 0 4]
        ]
        sage: G = SO(3,GF(5))
        sage: G.as_matrix_group()
        Matrix group over Finite Field of size 5 with 3 generators:
        [[[2, 0, 0], [0, 3, 0], [0, 0, 1]], [[3, 2, 3], [0, 2, 0], [0, 3, 1]], [[1, 4, 4], [4, 0, 0], [2, 0, 4]]]

    TESTS::

        sage: groups.matrix.SO(2, 3, e=1)
        Special Orthogonal Group of degree 2, form parameter 1, over the Finite Field of size 3
    """
    if isinstance(R, (int, long, Integer)):
        R = FiniteField(R, var)
    if n%2!=0 and e != 0:
        raise ValueError, "must have e = 0 for n even"
    if n%2 == 0 and e**2 != 1:
            raise ValueError, "must have e=-1 or e=1 if n is even"
    if is_FiniteField(R):
        return SpecialOrthogonalGroup_finite_field(n, R, e)
    else:
        return SpecialOrthogonalGroup_generic(n, R, e)
Esempio n. 5
0
def GO( n , R , e=0 ):
    """
    Return the general orthogonal group.
    
    EXAMPLES:
    """
    if n%2!=0 and e!=0:
        raise ValueError, "if e = 0, then n must be even."
    if n%2 == 0 and e**2!=1:
        raise ValueError, "must have e=-1 or e=1, if d is even."
    if isinstance(R, (int, long, Integer)):
        R = FiniteField(R)
    if is_FiniteField(R):
        return GeneralOrthogonalGroup_finite_field(n, R, e)
    else:
        return GeneralOrthogonalGroup_generic(n, R, e)
Esempio n. 6
0
def Sp(n, R, var='a'):
    """
    Return the symplectic group of degree n over R.
    
    EXAMPLES::
    
        sage: Sp(4,5)
        Symplectic Group of rank 2 over Finite Field of size 5
        sage: Sp(3,GF(7))
        Traceback (most recent call last):
        ...
        ValueError: the degree n (=3) must be even
    """
    if n%2!=0:
        raise ValueError, "the degree n (=%s) must be even"%n
    if isinstance(R, (int, long, Integer)):
        R = FiniteField(R, var)
    if is_FiniteField(R):
        return SymplecticGroup_finite_field(n, R)
    else:
        return SymplecticGroup_generic(n, R)
Esempio n. 7
0
def GO( n , R , e=0 ):
    """
    Return the general orthogonal group.

    .. note::
        This group is also available via ``groups.matrix.GO()``.

    EXAMPLES:

    TESTS::

        sage: groups.matrix.GO(2, 3, e=-1)
        General Orthogonal Group of degree 2, form parameter -1, over the Finite Field of size 3
    """
    if n%2!=0 and e!=0:
        raise ValueError, "if e = 0, then n must be even."
    if n%2 == 0 and e**2!=1:
        raise ValueError, "must have e=-1 or e=1, if d is even."
    if isinstance(R, (int, long, Integer)):
        R = FiniteField(R)
    if is_FiniteField(R):
        return GeneralOrthogonalGroup_finite_field(n, R, e)
    else:
        return GeneralOrthogonalGroup_generic(n, R, e)
Esempio n. 8
0
def GL(n, R, var='a'):
    """
    Return the general linear group of degree `n` over the ring
    `R`.

    .. note::
        This group is also available via ``groups.matrix.GL()``.

    EXAMPLES::

        sage: G = GL(6,GF(5))
        sage: G.order()
        11064475422000000000000000
        sage: G.base_ring()
        Finite Field of size 5
        sage: G.category()
        Category of finite groups
        sage: TestSuite(G).run()

        sage: G = GL(6, QQ)
        sage: G.category()
        Category of groups
        sage: TestSuite(G).run()

    Here is the Cayley graph of (relatively small) finite General Linear Group::

        sage: g = GL(2,3)
        sage: d = g.cayley_graph(); d
        Digraph on 48 vertices
        sage: d.show(color_by_label=True, vertex_size=0.03, vertex_labels=False)
        sage: d.show3d(color_by_label=True)

    ::

        sage: F = GF(3); MS = MatrixSpace(F,2,2)
        sage: gens = [MS([[0,1],[1,0]]),MS([[1,1],[0,1]])]
        sage: G = MatrixGroup(gens)
        sage: G.order()
        48
        sage: G.cardinality()
        48
        sage: H = GL(2,F)
        sage: H.order()
        48
        sage: H == G           # Do we really want this equality?
        False
        sage: H.as_matrix_group() == G
        True
        sage: H.gens()
        [
        [2 0]
        [0 1],
        [2 1]
        [2 0]
        ]

    TESTS::

        sage: groups.matrix.GL(2, 3)
        General Linear Group of degree 2 over Finite Field of size 3
    """
    if isinstance(R, (int, long, Integer)):
        R = FiniteField(R, var)
    if is_FiniteField(R):
        return GeneralLinearGroup_finite_field(n, R)
    return GeneralLinearGroup_generic(n, R)
def is_geom_trivial_when_field(C, bad_primes, B=200):
    r"""
    Determine if the geometric endomorphism ring is trivial assuming the
    geometric endomorphism algebra is a field.

    This is Algorithm 4.15 in [Lom2019]_.

    INPUT:

    - ``C`` -- the hyperelliptic curve.

    - ``bad_primes`` -- the list of odd primes of bad reduction.

    - ``B`` -- (default: 200) the bound which appears in the statement of
      the algorithm from [Lom2019]_

    OUTPUT:

    Boolean indicating whether or not the geometric endomorphism
    algebra is the field of rational numbers.

    WARNING:

    There is a very small chance that this algorithm returns ``False`` when in
    fact it is ``True``. In this case, as explained in the discussion
    immediately preceding Algorithm 4.15 of [Lom2019]_, this can be established
    by increasing the optional `B` parameter. Mathematically, this algorithm
    gives the correct answer only in the limit as `B \to \infty`, although in
    practice `B = 200` was sufficient to correctly verify every single entry
    in the LMFDB. However, strictly speaking, a ``False`` returned by this
    function is not provably ``False``.

    EXAMPLES:

    This is LMFDB curve 461.a.461.2::

        sage: from sage.schemes.hyperelliptic_curves.jacobian_endomorphism_utils import is_geom_trivial_when_field
        sage: R.<x> = QQ[]
        sage: f = 4*x^5 - 4*x^4 - 156*x^3 + 40*x^2 + 1088*x - 1223
        sage: C = HyperellipticCurve(f)
        sage: is_geom_trivial_when_field(C,[461])
        True

    This is LMFDB curve 4489.a.4489.1::

        sage: f = x^6 + 4*x^5 + 2*x^4 + 2*x^3 + x^2 - 2*x + 1
        sage: C = HyperellipticCurve(f)
        sage: is_geom_trivial_when_field(C,[67])
        False
    """

    running_gcd = 0
    R = PolynomialRing(ZZ,2,"xv")
    x,v = R.gens()
    T = PolynomialRing(QQ,'v')
    g = v - x**4

    for p in prime_range(3,B):
        if p not in bad_primes:
            Cp = C.change_ring(FiniteField(p))
            fp = Cp.frobenius_polynomial()
            if satisfies_coefficient_condition(fp, p):
                # This defines the polynomial f_v**[4] from the paper
                fp4 = T(R(fp).resultant(g))
                if fp4.is_irreducible():
                    running_gcd = gcd(running_gcd, NumberField(fp,'a').discriminant())
                    if running_gcd <= 24:
                        return True
    return False
def get_is_geom_field(f, C, bad_primes, B=200):
    r"""
    Determine whether the geometric endomorphism algebra is a field.

    This is Algorithm 4.10 in [Lom2019]_. The computation done here
    may allow one to immediately conclude that the geometric endomorphism
    ring is trivial (i.e. the integer ring); this information is output
    in a second boolean to avoid unnecessary subsequent computation.

    An additional optimisation comes from Part (2) of Theorem 4.8 in
    [Lom2019]_, from which we can conclude that the endomorphism ring
    is geometrically trivial, and from Proposition 4.7 in loc. cit. from
    which we can rule out potential QM.

    INPUT:

    - ``f`` -- a polynomial defining the hyperelliptic curve.

    - ``C`` -- the hyperelliptic curve.

    - ``bad_primes`` -- the list of odd primes of bad reduction.

    - ``B`` -- (default: 200) the bound which appears in the statement of
      the algorithm from [Lom2019]_

    OUTPUT:

    Pair of booleans (bool1, bool2). `bool1` indicates if the
    geometric endomorphism algebra is a field; `bool2` indicates if the
    geometric endomorphism algebra is the field of rational numbers.

    WARNING:

    There is a very small chance that this algorithm return ``False`` when in
    fact it is ``True``. In this case, as explained in the discussion
    immediately preceding Algorithm 4.15 of [Lom2019]_, this can be established
    by increasing the optional `B` parameter. Mathematically, this algorithm
    gives the correct answer only in the limit as `B \to \infty`, although in
    practice `B = 200` was sufficient to correctly verify every single entry
    in the LMFDB. However, strictly speaking, a ``False`` returned by this
    function is not provably ``False``.

    EXAMPLES:

    This is LMFDB curve 940693.a.960693.1::

        sage: from sage.schemes.hyperelliptic_curves.jacobian_endomorphism_utils import get_is_geom_field
        sage: R.<x> = QQ[]
        sage: f = 4*x^6 - 12*x^5 + 20*x^3 - 8*x^2 - 4*x + 1
        sage: C = HyperellipticCurve(f)
        sage: get_is_geom_field(f,C,[13,269])
        (False, False)

    This is LMFDB curve 3125.a.3125.1::

        sage: f = 4*x^5 + 1
        sage: C = HyperellipticCurve(f)
        sage: get_is_geom_field(f,C,[5])
        (True, False)

    This is LMFDB curve 277.a.277.2::

        sage: f = 4*x^6 - 36*x^4 + 56*x^3 - 76*x^2 + 44*x - 23
        sage: C = HyperellipticCurve(f)
        sage: get_is_geom_field(f,C,[277])
        (True, True)
    """

    if C.has_odd_degree_model():
        C_odd = C.odd_degree_model()
        f_odd, h_odd = C_odd.hyperelliptic_polynomials()
        # if f was odd to begin with, then f_odd = f
        assert f_odd.degree() == 5

        if (4*f_odd + h_odd**2).degree() == 5:
            f_new = 4*f_odd + h_odd**2
            if f_new.is_irreducible():
                # i.e. the Jacobian is geometrically simple
                f_disc_odd_prime_exponents = [v for _,v in f_new.discriminant().prime_to_S_part([ZZ(2)]).factor()]
                if 1 in f_disc_odd_prime_exponents:
                    return (True, True)  # Theorem 4.8 (2)
                # At this point we are in the situation of Algorithm 4.10
                # Step 1, so either the geometric endomorphism algebra is a
                # field or it is a quaternion algebra. This latter case implies
                # that the Jacobian is the square of an elliptic curve modulo
                # a prime p where f is also irreducible (which exist by
                # Chebotarev density). This contradicts Prop 4.7, hence we can
                # conclude as follows.
                return (True, False)

    if f.is_irreducible():
        assert f.degree() == 6  # else we should already have exited by now
        G = f.galois_group()
        if G.order() in [360, 720]:
            return (True, True)  # Algorithm 4.10 Step 2

    R = PolynomialRing(ZZ,2,"xv")
    x,v = R.gens()
    T = PolynomialRing(QQ,'v')
    g = v - x**12

    for p in prime_range(3,B):
        if p not in bad_primes:
            fp = C.change_ring(FiniteField(p)).frobenius_polynomial()

            # This defines the polynomial f_v**[12] from the paper
            fp12 = T(R(fp).resultant(g))

            if fp12.is_irreducible():
                # i.e. the Jacobian is geometrically simple
                f_disc_odd_prime_exponents = [v for _,v in f.discriminant().prime_to_S_part([ZZ(2)]).factor()]
                if 1 in f_disc_odd_prime_exponents:
                    return (True, True)  # Theorem 4.8 (2)
                return (True, False) # Algorithm 4.10 Step 3 plus Prop 4.7 as above
    return (False, False)