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)
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)
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)
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)
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)
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)
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)
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)