Spaces of homomorphisms between modular abelian varieties

EXAMPLES:

First, we consider J0(37). This Jacobian has two simple factors, corresponding to distinct newforms. These two intersect nontrivially in J0(37).

sage: J = J0(37)
sage: D = J.decomposition() ; D
[
Simple abelian subvariety 37a(1,37) of dimension 1 of J0(37),
Simple abelian subvariety 37b(1,37) of dimension 1 of J0(37)
]
sage: D[0].intersection(D[1])
(Finite subgroup with invariants [2, 2] over QQ of
  Simple abelian subvariety 37a(1,37) of dimension 1 of J0(37),
 Simple abelian subvariety of dimension 0 of J0(37))
>>> from sage.all import *
>>> J = J0(Integer(37))
>>> D = J.decomposition() ; D
[
Simple abelian subvariety 37a(1,37) of dimension 1 of J0(37),
Simple abelian subvariety 37b(1,37) of dimension 1 of J0(37)
]
>>> D[Integer(0)].intersection(D[Integer(1)])
(Finite subgroup with invariants [2, 2] over QQ of
  Simple abelian subvariety 37a(1,37) of dimension 1 of J0(37),
 Simple abelian subvariety of dimension 0 of J0(37))

As an abstract product, since these newforms are distinct, the corresponding simple abelian varieties are not isogenous, and so there are no maps between them. The endomorphism ring of the corresponding product is thus isomorphic to the direct sum of the endomorphism rings for each factor. Since the factors correspond to abelian varieties of dimension 1, these endomorphism rings are each isomorphic to ZZ.

sage: Hom(D[0],D[1]).gens()
()
sage: A = D[0] * D[1] ; A
Abelian subvariety of dimension 2 of J0(37) x J0(37)
sage: A.endomorphism_ring().gens()
(Abelian variety endomorphism of Abelian subvariety of dimension 2 of J0(37) x J0(37),
 Abelian variety endomorphism of Abelian subvariety of dimension 2 of J0(37) x J0(37))
sage: [ x.matrix() for x in A.endomorphism_ring().gens() ]
[
[1 0 0 0]  [0 0 0 0]
[0 1 0 0]  [0 0 0 0]
[0 0 0 0]  [0 0 1 0]
[0 0 0 0], [0 0 0 1]
]
>>> from sage.all import *
>>> Hom(D[Integer(0)],D[Integer(1)]).gens()
()
>>> A = D[Integer(0)] * D[Integer(1)] ; A
Abelian subvariety of dimension 2 of J0(37) x J0(37)
>>> A.endomorphism_ring().gens()
(Abelian variety endomorphism of Abelian subvariety of dimension 2 of J0(37) x J0(37),
 Abelian variety endomorphism of Abelian subvariety of dimension 2 of J0(37) x J0(37))
>>> [ x.matrix() for x in A.endomorphism_ring().gens() ]
[
[1 0 0 0]  [0 0 0 0]
[0 1 0 0]  [0 0 0 0]
[0 0 0 0]  [0 0 1 0]
[0 0 0 0], [0 0 0 1]
]

However, these two newforms have a congruence between them modulo 2, which gives rise to interesting endomorphisms of J0(37).

sage: E = J.endomorphism_ring()
sage: E.gens()
(Abelian variety endomorphism of Abelian variety J0(37) of dimension 2,
 Abelian variety endomorphism of Abelian variety J0(37) of dimension 2)
sage: [ x.matrix() for x in E.gens() ]
[
[1 0 0 0]  [ 0  1  1 -1]
[0 1 0 0]  [ 1  0  1  0]
[0 0 1 0]  [ 0  0 -1  1]
[0 0 0 1], [ 0  0  0  1]
]
sage: (-1*E.gens()[0] + E.gens()[1]).matrix()
[-1  1  1 -1]
[ 1 -1  1  0]
[ 0  0 -2  1]
[ 0  0  0  0]
>>> from sage.all import *
>>> E = J.endomorphism_ring()
>>> E.gens()
(Abelian variety endomorphism of Abelian variety J0(37) of dimension 2,
 Abelian variety endomorphism of Abelian variety J0(37) of dimension 2)
>>> [ x.matrix() for x in E.gens() ]
[
[1 0 0 0]  [ 0  1  1 -1]
[0 1 0 0]  [ 1  0  1  0]
[0 0 1 0]  [ 0  0 -1  1]
[0 0 0 1], [ 0  0  0  1]
]
>>> (-Integer(1)*E.gens()[Integer(0)] + E.gens()[Integer(1)]).matrix()
[-1  1  1 -1]
[ 1 -1  1  0]
[ 0  0 -2  1]
[ 0  0  0  0]

Of course, these endomorphisms will be reflected in the Hecke algebra, which is in fact the full endomorphism ring of J0(37) in this case:

sage: J.hecke_operator(2).matrix()
[-1  1  1 -1]
[ 1 -1  1  0]
[ 0  0 -2  1]
[ 0  0  0  0]
sage: T = E.image_of_hecke_algebra()
sage: T.gens()
(Abelian variety endomorphism of Abelian variety J0(37) of dimension 2,
 Abelian variety endomorphism of Abelian variety J0(37) of dimension 2)
sage: [ x.matrix() for x in T.gens() ]
[
[1 0 0 0]  [ 0  1  1 -1]
[0 1 0 0]  [ 1  0  1  0]
[0 0 1 0]  [ 0  0 -1  1]
[0 0 0 1], [ 0  0  0  1]
]
sage: T.index_in(E)
1
>>> from sage.all import *
>>> J.hecke_operator(Integer(2)).matrix()
[-1  1  1 -1]
[ 1 -1  1  0]
[ 0  0 -2  1]
[ 0  0  0  0]
>>> T = E.image_of_hecke_algebra()
>>> T.gens()
(Abelian variety endomorphism of Abelian variety J0(37) of dimension 2,
 Abelian variety endomorphism of Abelian variety J0(37) of dimension 2)
>>> [ x.matrix() for x in T.gens() ]
[
[1 0 0 0]  [ 0  1  1 -1]
[0 1 0 0]  [ 1  0  1  0]
[0 0 1 0]  [ 0  0 -1  1]
[0 0 0 1], [ 0  0  0  1]
]
>>> T.index_in(E)
1

Next, we consider J0(33). In this case, we have both oldforms and newforms. There are two copies of J0(11), one for each degeneracy map from J0(11) to J0(33). There is also one newform at level 33. The images of the two degeneracy maps are, of course, isogenous.

sage: J = J0(33)
sage: D = J.decomposition()
sage: D
[
Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33),
Simple abelian subvariety 11a(3,33) of dimension 1 of J0(33),
Simple abelian subvariety 33a(1,33) of dimension 1 of J0(33)
]
sage: Hom(D[0],D[1]).gens()
(Abelian variety morphism:
  From: Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33)
  To:   Simple abelian subvariety 11a(3,33) of dimension 1 of J0(33),)
sage: Hom(D[0],D[1]).gens()[0].matrix()
[ 0  1]
[-1  0]
>>> from sage.all import *
>>> J = J0(Integer(33))
>>> D = J.decomposition()
>>> D
[
Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33),
Simple abelian subvariety 11a(3,33) of dimension 1 of J0(33),
Simple abelian subvariety 33a(1,33) of dimension 1 of J0(33)
]
>>> Hom(D[Integer(0)],D[Integer(1)]).gens()
(Abelian variety morphism:
  From: Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33)
  To:   Simple abelian subvariety 11a(3,33) of dimension 1 of J0(33),)
>>> Hom(D[Integer(0)],D[Integer(1)]).gens()[Integer(0)].matrix()
[ 0  1]
[-1  0]

Then this gives that the component corresponding to the sum of the oldforms will have a rank 4 endomorphism ring. We also have a rank one endomorphism ring for the newform 33a (since it is again 1-dimensional), which gives a rank 5 endomorphism ring for J0(33).

sage: DD = J.decomposition(simple=False) ; DD
[
Abelian subvariety of dimension 2 of J0(33),
Abelian subvariety of dimension 1 of J0(33)
]
sage: A, B = DD
sage: A == D[0] + D[1]
True
sage: A.endomorphism_ring().gens()
(Abelian variety endomorphism of Abelian subvariety of dimension 2 of J0(33),
 Abelian variety endomorphism of Abelian subvariety of dimension 2 of J0(33),
 Abelian variety endomorphism of Abelian subvariety of dimension 2 of J0(33),
 Abelian variety endomorphism of Abelian subvariety of dimension 2 of J0(33))
sage: B.endomorphism_ring().gens()
(Abelian variety endomorphism of Abelian subvariety of dimension 1 of J0(33),)
sage: E = J.endomorphism_ring() ; E.gens()  # long time (3s on sage.math, 2011)
(Abelian variety endomorphism of Abelian variety J0(33) of dimension 3,
 Abelian variety endomorphism of Abelian variety J0(33) of dimension 3,
 Abelian variety endomorphism of Abelian variety J0(33) of dimension 3,
 Abelian variety endomorphism of Abelian variety J0(33) of dimension 3,
 Abelian variety endomorphism of Abelian variety J0(33) of dimension 3)
>>> from sage.all import *
>>> DD = J.decomposition(simple=False) ; DD
[
Abelian subvariety of dimension 2 of J0(33),
Abelian subvariety of dimension 1 of J0(33)
]
>>> A, B = DD
>>> A == D[Integer(0)] + D[Integer(1)]
True
>>> A.endomorphism_ring().gens()
(Abelian variety endomorphism of Abelian subvariety of dimension 2 of J0(33),
 Abelian variety endomorphism of Abelian subvariety of dimension 2 of J0(33),
 Abelian variety endomorphism of Abelian subvariety of dimension 2 of J0(33),
 Abelian variety endomorphism of Abelian subvariety of dimension 2 of J0(33))
>>> B.endomorphism_ring().gens()
(Abelian variety endomorphism of Abelian subvariety of dimension 1 of J0(33),)
>>> E = J.endomorphism_ring() ; E.gens()  # long time (3s on sage.math, 2011)
(Abelian variety endomorphism of Abelian variety J0(33) of dimension 3,
 Abelian variety endomorphism of Abelian variety J0(33) of dimension 3,
 Abelian variety endomorphism of Abelian variety J0(33) of dimension 3,
 Abelian variety endomorphism of Abelian variety J0(33) of dimension 3,
 Abelian variety endomorphism of Abelian variety J0(33) of dimension 3)

In this case, the image of the Hecke algebra will only have rank 3, so that it is of infinite index in the full endomorphism ring. However, if we call this image T, we can still ask about the index of T in its saturation, which is 1 in this case.

sage: # long time
sage: T = E.image_of_hecke_algebra()
sage: T.gens()
(Abelian variety endomorphism of Abelian variety J0(33) of dimension 3,
 Abelian variety endomorphism of Abelian variety J0(33) of dimension 3,
 Abelian variety endomorphism of Abelian variety J0(33) of dimension 3)
sage: T.index_in(E)
+Infinity
sage: T.index_in_saturation()
1
>>> from sage.all import *
>>> # long time
>>> T = E.image_of_hecke_algebra()
>>> T.gens()
(Abelian variety endomorphism of Abelian variety J0(33) of dimension 3,
 Abelian variety endomorphism of Abelian variety J0(33) of dimension 3,
 Abelian variety endomorphism of Abelian variety J0(33) of dimension 3)
>>> T.index_in(E)
+Infinity
>>> T.index_in_saturation()
1

AUTHORS:

  • William Stein (2007-03)

  • Craig Citro, Robert Bradshaw (2008-03): Rewrote with modabvar overhaul

class sage.modular.abvar.homspace.EndomorphismSubring(A, gens=None, category=None)[source]

Bases: Homspace

A subring of the endomorphism ring.

INPUT:

  • A – an abelian variety

  • gens – (default: None) if given should be a tuple of the generators as matrices

EXAMPLES:

sage: J0(23).endomorphism_ring()
Endomorphism ring of Abelian variety J0(23) of dimension 2
sage: sage.modular.abvar.homspace.EndomorphismSubring(J0(25))
Endomorphism ring of Abelian variety J0(25) of dimension 0
sage: E = J0(11).endomorphism_ring()
sage: type(E)
<class 'sage.modular.abvar.homspace.EndomorphismSubring_with_category'>
sage: E.homset_category()
Category of modular abelian varieties over Rational Field
sage: E.category()
Category of endsets of modular abelian varieties over Rational Field
sage: E in Rings()
True
sage: TestSuite(E).run(skip=["_test_prod"])
>>> from sage.all import *
>>> J0(Integer(23)).endomorphism_ring()
Endomorphism ring of Abelian variety J0(23) of dimension 2
>>> sage.modular.abvar.homspace.EndomorphismSubring(J0(Integer(25)))
Endomorphism ring of Abelian variety J0(25) of dimension 0
>>> E = J0(Integer(11)).endomorphism_ring()
>>> type(E)
<class 'sage.modular.abvar.homspace.EndomorphismSubring_with_category'>
>>> E.homset_category()
Category of modular abelian varieties over Rational Field
>>> E.category()
Category of endsets of modular abelian varieties over Rational Field
>>> E in Rings()
True
>>> TestSuite(E).run(skip=["_test_prod"])
abelian_variety()[source]

Return the abelian variety that this endomorphism ring is attached to.

EXAMPLES:

sage: J0(11).endomorphism_ring().abelian_variety()
Abelian variety J0(11) of dimension 1
>>> from sage.all import *
>>> J0(Integer(11)).endomorphism_ring().abelian_variety()
Abelian variety J0(11) of dimension 1
discriminant()[source]

Return the discriminant of this ring, which is the discriminant of the trace pairing.

Note

One knows that for modular abelian varieties, the endomorphism ring should be isomorphic to an order in a number field. However, the discriminant returned by this function will be \(2^n\) ( \(n =\) self.dimension()) times the discriminant of that order, since the elements are represented as 2d x 2d matrices. Notice, for example, that the case of a one dimensional abelian variety, whose endomorphism ring must be ZZ, has discriminant 2, as in the example below.

EXAMPLES:

sage: J0(33).endomorphism_ring().discriminant()
-64800
sage: J0(46).endomorphism_ring().discriminant()  # long time (6s on sage.math, 2011)
24200000000
sage: J0(11).endomorphism_ring().discriminant()
2
>>> from sage.all import *
>>> J0(Integer(33)).endomorphism_ring().discriminant()
-64800
>>> J0(Integer(46)).endomorphism_ring().discriminant()  # long time (6s on sage.math, 2011)
24200000000
>>> J0(Integer(11)).endomorphism_ring().discriminant()
2
image_of_hecke_algebra(check_every=1)[source]

Compute the image of the Hecke algebra inside this endomorphism subring.

We simply calculate Hecke operators up to the Sturm bound, and look at the submodule spanned by them. While computing, we can check to see if the submodule spanned so far is saturated and of maximal dimension, in which case we may be done. The optional argument check_every determines how many Hecke operators we add in before checking to see if this condition is met.

INPUT:

  • check_every – integer (default: 1); if this integer is positive, this integer determines how many Hecke operators we add in before checking to see if the submodule spanned so far is maximal and saturated

OUTPUT: the image of the Hecke algebra as a subring of self

EXAMPLES:

sage: E = J0(33).endomorphism_ring()
sage: E.image_of_hecke_algebra()
Subring of endomorphism ring of Abelian variety J0(33) of dimension 3
sage: E.image_of_hecke_algebra().gens()
(Abelian variety endomorphism of Abelian variety J0(33) of dimension 3,
 Abelian variety endomorphism of Abelian variety J0(33) of dimension 3,
 Abelian variety endomorphism of Abelian variety J0(33) of dimension 3)
sage: [ x.matrix() for x in E.image_of_hecke_algebra().gens() ]
[
[1 0 0 0 0 0]  [ 0  2  0 -1  1 -1]  [ 0  0  1 -1  1 -1]
[0 1 0 0 0 0]  [-1 -2  2 -1  2 -1]  [ 0 -1  1  0  1 -1]
[0 0 1 0 0 0]  [ 0  0  1 -1  3 -1]  [ 0  0  1  0  2 -2]
[0 0 0 1 0 0]  [-2  2  0  1  1 -1]  [-2  0  1  1  1 -1]
[0 0 0 0 1 0]  [-1  1  0  2  0 -3]  [-1  0  1  1  0 -1]
[0 0 0 0 0 1], [-1  1 -1  1  1 -2], [-1  0  0  1  0 -1]
]
sage: J0(33).hecke_operator(2).matrix()
[-1  0  1 -1  1 -1]
[ 0 -2  1  0  1 -1]
[ 0  0  0  0  2 -2]
[-2  0  1  0  1 -1]
[-1  0  1  1 -1 -1]
[-1  0  0  1  0 -2]
>>> from sage.all import *
>>> E = J0(Integer(33)).endomorphism_ring()
>>> E.image_of_hecke_algebra()
Subring of endomorphism ring of Abelian variety J0(33) of dimension 3
>>> E.image_of_hecke_algebra().gens()
(Abelian variety endomorphism of Abelian variety J0(33) of dimension 3,
 Abelian variety endomorphism of Abelian variety J0(33) of dimension 3,
 Abelian variety endomorphism of Abelian variety J0(33) of dimension 3)
>>> [ x.matrix() for x in E.image_of_hecke_algebra().gens() ]
[
[1 0 0 0 0 0]  [ 0  2  0 -1  1 -1]  [ 0  0  1 -1  1 -1]
[0 1 0 0 0 0]  [-1 -2  2 -1  2 -1]  [ 0 -1  1  0  1 -1]
[0 0 1 0 0 0]  [ 0  0  1 -1  3 -1]  [ 0  0  1  0  2 -2]
[0 0 0 1 0 0]  [-2  2  0  1  1 -1]  [-2  0  1  1  1 -1]
[0 0 0 0 1 0]  [-1  1  0  2  0 -3]  [-1  0  1  1  0 -1]
[0 0 0 0 0 1], [-1  1 -1  1  1 -2], [-1  0  0  1  0 -1]
]
>>> J0(Integer(33)).hecke_operator(Integer(2)).matrix()
[-1  0  1 -1  1 -1]
[ 0 -2  1  0  1 -1]
[ 0  0  0  0  2 -2]
[-2  0  1  0  1 -1]
[-1  0  1  1 -1 -1]
[-1  0  0  1  0 -2]
index_in(other, check=True)[source]

Return the index of self in other.

INPUT:

  • other – another endomorphism subring of the same abelian variety

  • check – boolean (default: True); whether to do some type and other consistency checks

EXAMPLES:

sage: R = J0(33).endomorphism_ring()
sage: R.index_in(R)
1
sage: J = J0(37) ; E = J.endomorphism_ring() ; T = E.image_of_hecke_algebra()
sage: T.index_in(E)
1
sage: J = J0(22) ; E = J.endomorphism_ring() ; T = E.image_of_hecke_algebra()
sage: T.index_in(E)
+Infinity
>>> from sage.all import *
>>> R = J0(Integer(33)).endomorphism_ring()
>>> R.index_in(R)
1
>>> J = J0(Integer(37)) ; E = J.endomorphism_ring() ; T = E.image_of_hecke_algebra()
>>> T.index_in(E)
1
>>> J = J0(Integer(22)) ; E = J.endomorphism_ring() ; T = E.image_of_hecke_algebra()
>>> T.index_in(E)
+Infinity
index_in_saturation()[source]

Given a Hecke algebra T, compute its index in its saturation.

EXAMPLES:

sage: End(J0(23)).image_of_hecke_algebra().index_in_saturation()
1
sage: End(J0(44)).image_of_hecke_algebra().index_in_saturation()
2
>>> from sage.all import *
>>> End(J0(Integer(23))).image_of_hecke_algebra().index_in_saturation()
1
>>> End(J0(Integer(44))).image_of_hecke_algebra().index_in_saturation()
2
class sage.modular.abvar.homspace.Homspace(domain, codomain, cat)[source]

Bases: HomsetWithBase

A space of homomorphisms between two modular abelian varieties.

Element[source]

alias of Morphism

calculate_generators()[source]

If generators haven’t already been computed, calculate generators for this homspace. If they have been computed, do nothing.

EXAMPLES:

sage: E = End(J0(11))
sage: E.calculate_generators()
>>> from sage.all import *
>>> E = End(J0(Integer(11)))
>>> E.calculate_generators()
free_module()[source]

Return this endomorphism ring as a free submodule of a big \(\ZZ^{4nm}\), where \(n\) is the dimension of the domain abelian variety and \(m\) the dimension of the codomain.

OUTPUT: free module

EXAMPLES:

sage: E = Hom(J0(11), J0(22))
sage: E.free_module()
Free module of degree 8 and rank 2 over Integer Ring
Echelon basis matrix:
[ 1  0 -3  1  1  1 -1 -1]
[ 0  1 -3  1  1  1 -1  0]
>>> from sage.all import *
>>> E = Hom(J0(Integer(11)), J0(Integer(22)))
>>> E.free_module()
Free module of degree 8 and rank 2 over Integer Ring
Echelon basis matrix:
[ 1  0 -3  1  1  1 -1 -1]
[ 0  1 -3  1  1  1 -1  0]
gen(i=0)[source]

Return \(i\)-th generator of self.

INPUT:

  • i – integer

OUTPUT: a morphism

EXAMPLES:

sage: E = End(J0(22))
sage: E.gen(0).matrix()
[1 0 0 0]
[0 1 0 0]
[0 0 1 0]
[0 0 0 1]
>>> from sage.all import *
>>> E = End(J0(Integer(22)))
>>> E.gen(Integer(0)).matrix()
[1 0 0 0]
[0 1 0 0]
[0 0 1 0]
[0 0 0 1]
gens()[source]

Return tuple of generators for this endomorphism ring.

EXAMPLES:

sage: E = End(J0(22))
sage: E.gens()
(Abelian variety endomorphism of Abelian variety J0(22) of dimension 2,
 Abelian variety endomorphism of Abelian variety J0(22) of dimension 2,
 Abelian variety endomorphism of Abelian variety J0(22) of dimension 2,
 Abelian variety endomorphism of Abelian variety J0(22) of dimension 2)
>>> from sage.all import *
>>> E = End(J0(Integer(22)))
>>> E.gens()
(Abelian variety endomorphism of Abelian variety J0(22) of dimension 2,
 Abelian variety endomorphism of Abelian variety J0(22) of dimension 2,
 Abelian variety endomorphism of Abelian variety J0(22) of dimension 2,
 Abelian variety endomorphism of Abelian variety J0(22) of dimension 2)
identity()[source]

Return the identity endomorphism.

EXAMPLES:

sage: E = End(J0(11))
sage: E.identity()
Abelian variety endomorphism of Abelian variety J0(11) of dimension 1
sage: E.one()
Abelian variety endomorphism of Abelian variety J0(11) of dimension 1

sage: H = Hom(J0(11), J0(22))
sage: H.identity()
Traceback (most recent call last):
...
TypeError: the identity map is only defined for endomorphisms
>>> from sage.all import *
>>> E = End(J0(Integer(11)))
>>> E.identity()
Abelian variety endomorphism of Abelian variety J0(11) of dimension 1
>>> E.one()
Abelian variety endomorphism of Abelian variety J0(11) of dimension 1

>>> H = Hom(J0(Integer(11)), J0(Integer(22)))
>>> H.identity()
Traceback (most recent call last):
...
TypeError: the identity map is only defined for endomorphisms
matrix_space()[source]

Return the underlying matrix space that we view this endomorphism ring as being embedded into.

EXAMPLES:

sage: E = End(J0(22))
sage: E.matrix_space()
Full MatrixSpace of 4 by 4 dense matrices over Integer Ring
>>> from sage.all import *
>>> E = End(J0(Integer(22)))
>>> E.matrix_space()
Full MatrixSpace of 4 by 4 dense matrices over Integer Ring
ngens()[source]

Return number of generators of self.

OUTPUT: integer

EXAMPLES:

sage: E = End(J0(22))
sage: E.ngens()
4
>>> from sage.all import *
>>> E = End(J0(Integer(22)))
>>> E.ngens()
4