Ambient Hecke modules#
- class sage.modular.hecke.ambient_module.AmbientHeckeModule(base_ring, rank, level, weight, category=None)#
Bases:
HeckeModule_free_moduleAn ambient Hecke module, i.e. a Hecke module that is isomorphic as a module over its base ring \(R\) to the standard free module \(R^k\) for some \(k\). This is the base class for ambient spaces of modular forms and modular symbols, and for Brandt modules.
- ambient_hecke_module()#
Return the ambient space that contains this ambient space.
This is, of course, just this space again.
EXAMPLES:
sage: M = ModularForms(11, 4); M.ambient_hecke_module() is M True
- complement()#
Return the largest Hecke-stable complement of this space.
EXAMPLES:
sage: M = ModularSymbols(11,2,1); M Modular Symbols space of dimension 2 for Gamma_0(11) of weight 2 with sign 1 over Rational Field sage: M.complement() Modular Symbols subspace of dimension 0 of Modular Symbols space of dimension 2 for Gamma_0(11) of weight 2 with sign 1 over Rational Field sage: C = M.cuspidal_subspace(); C Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 2 for Gamma_0(11) of weight 2 with sign 1 over Rational Field sage: C.complement() Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 2 for Gamma_0(11) of weight 2 with sign 1 over Rational Field
- decomposition_matrix()#
Return the matrix whose columns form a basis for the canonical sorted decomposition of
selfcoming from the Hecke operators.If the simple factors are \(D_0, \ldots, D_n\), then the first few columns are an echelonized basis for \(D_0\), the next an echelonized basis for \(D_1\), the next for \(D_2\), etc.
EXAMPLES:
sage: S = ModularSymbols(37, 2) sage: S.decomposition_matrix() [ 1 0 0 0 -1/3] [ 0 1 -1 0 1/2] [ 0 0 0 1 -1/2] [ 0 1 1 1 0] [ 0 0 0 0 1]
- decomposition_matrix_inverse()#
Return the inverse of the decomposition matrix.
This is the inverse of the matrix returned by
decomposition_matrix().EXAMPLES:
sage: S = ModularSymbols(37, 2) sage: t = S.decomposition_matrix_inverse(); t [ 1 0 0 0 1/3] [ 0 1/2 -1/2 1/2 -1/2] [ 0 -1/2 -1/2 1/2 0] [ 0 0 1 0 1/2] [ 0 0 0 0 1] sage: t * S.decomposition_matrix() == 1 True
- degeneracy_map(codomain, t=1)#
The \(t\)-th degeneracy map from
selfto the modulecodomain.The level of the codomain must be a divisor or multiple of level, and \(t\) must be a divisor of the quotient.
INPUT:
codomain- a Hecke module, which should be of the same type as self, or a positive integer (in which case Sage will usehecke_module_of_level()to find the “natural” module of the corresponding level).t- int, the parameter of the degeneracy map, i.e., the map is related to \(f(q)\) - \(f(q^t)\).
OUTPUT: A morphism from
selftocodomain.EXAMPLES:
sage: M = ModularSymbols(11,sign=1) sage: d1 = M.degeneracy_map(33); d1 Hecke module morphism degeneracy map corresponding to f(q) |--> f(q) defined by the matrix [ 1 0 0 0 -2 -1] [ 0 -1 1 0 0 0] Domain: Modular Symbols space of dimension 2 for Gamma_0(11) of weight ... Codomain: Modular Symbols space of dimension 6 for Gamma_0(33) of weight ... sage: M.degeneracy_map(33,3).matrix() [ 3 2 0 2 -2 1] [ 0 0 -1 1 0 0] sage: M = ModularSymbols(33,sign=1) sage: d2 = M.degeneracy_map(11); d2.matrix() [ 1 0] [ 0 -2] [ 0 2] [ 0 1] [-1 0] [-1 0] sage: (d2*d1).matrix() [4 0] [0 4]
sage: M = ModularSymbols(3,12,sign=1) sage: M.degeneracy_map(1) Hecke module morphism degeneracy map corresponding to f(q) |--> f(q) defined by the matrix [1 0] [0 0] [0 1] [0 1] [0 1] Domain: Modular Symbols space of dimension 5 for Gamma_0(3) of weight ... Codomain: Modular Symbols space of dimension 2 for Gamma_0(1) of weight ...
sage: S = M.cuspidal_submodule() sage: S.degeneracy_map(1) Hecke module morphism defined by the matrix [1 0] [0 0] [0 0] Domain: Modular Symbols subspace of dimension 3 of Modular Symbols space ... Codomain: Modular Symbols space of dimension 2 for Gamma_0(1) of weight ...
sage: D = ModularSymbols(10,4).cuspidal_submodule().decomposition() sage: D [ Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 10 for Gamma_0(10) of weight 4 with sign 0 over Rational Field, Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 10 for Gamma_0(10) of weight 4 with sign 0 over Rational Field ] sage: D[1].degeneracy_map(5) Hecke module morphism defined by the matrix [ 0 0 -1 1] [ 0 1/2 3/2 -2] [ 0 -1 1 0] [ 0 -3/4 -1/4 1] Domain: Modular Symbols subspace of dimension 4 of Modular Symbols space ... Codomain: Modular Symbols space of dimension 4 for Gamma_0(5) of weight ...
We check for a subtle caching bug that came up in work on github issue #10453:
sage: loads(dumps(J0(33).decomposition()[0].modular_symbols())) Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 9 for Gamma_0(33) of weight 2 with sign 0 over Rational Field
We check that certain absurd inputs are correctly caught:
sage: chi = kronecker_character(7) sage: ModularSymbols(Gamma0(7), 4).degeneracy_map(ModularSymbols(chi, 4)) Traceback (most recent call last): ... ValueError: the characters of the domain and codomain must match
- dual_free_module()#
The free module dual to self, as a submodule of the dual module of the ambient space. As this space is ambient anyway, this just returns self.free_module().
EXAMPLES:
sage: M = ModularForms(2,8); M.dual_free_module() Vector space of dimension 3 over Rational Field sage: M.dual_free_module() is M.free_module() True
- fcp(n, var='x')#
Return the factorization of the characteristic polynomial of the Hecke operator \(T_n\) of index \(n\) acting on this space.
INPUT:
self- Hecke module invariant under the Hecke operator of index n.int n- a positive integer.var- variable of polynomial (default \(x\))
OUTPUT:
list- list of the pairs (g,e), where g is an irreducible factor of the characteristic polynomial of T_n, and e is its multiplicity.
EXAMPLES:
sage: m = ModularSymbols(23, 2, sign=1) sage: m.fcp(2) (x - 3) * (x^2 + x - 1) sage: m.hecke_operator(2).charpoly('x').factor() (x - 3) * (x^2 + x - 1)
- free_module()#
Return the free module underlying this ambient Hecke module (the forgetful functor from Hecke modules to modules over the base ring)
EXAMPLES:
sage: ModularForms(59, 2).free_module() Vector space of dimension 6 over Rational Field
- hecke_bound()#
Return an integer B such that the Hecke operators \(T_n\), for \(n\leq B\), generate the full Hecke algebra as a module over the base ring. Note that we include the \(n\) with \(n\) not coprime to the level.
At present this returns an unproven guess for non-cuspidal spaces which appears to be valid for \(M_k(\Gamma_0(N))\), where k and N are the weight and level of self. (It is clearly valid for cuspidal spaces of any fixed character, as a consequence of the Sturm bound theorem.) It returns a hopelessly wrong answer for spaces of full level \(\Gamma_1\).
TODO: Get rid of this dreadful bit of code.
EXAMPLES:
sage: ModularSymbols(17, 4).hecke_bound() 15 sage: ModularSymbols(Gamma1(17), 4).hecke_bound() # wrong! 15
- hecke_images(i, v)#
Return images of the \(i\)-th standard basis vector under the Hecke operators \(T_p\) for all integers in \(v\).
INPUT:
i- nonnegative integerv- a list of positive integer
OUTPUT:
matrix- whose rows are the Hecke images
EXAMPLES:
sage: M = ModularSymbols(DirichletGroup(13).0, 3) sage: M.T(2)(M.0).element() (zeta12 + 4, 0, -1, 1) sage: M.hecke_images(0, [1,2]) [ 1 0 0 0] [zeta12 + 4 0 -1 1]
- hecke_module_of_level(level)#
Return the Hecke module corresponding to self at the given level, which should be either a divisor or a multiple of the level of self.
This raises NotImplementedError, and should be overridden in derived classes.
EXAMPLES:
sage: sage.modular.hecke.ambient_module.AmbientHeckeModule.hecke_module_of_level(ModularForms(2, 8),6) Traceback (most recent call last): ... NotImplementedError
- intersection(other)#
Return the intersection of self and other, which must both lie in a common ambient space of modular symbols.
EXAMPLES:
sage: M = ModularSymbols(43, sign=1) sage: A = M[0] + M[1] sage: B = M[1] + M[2] sage: A.rank(), B.rank() (2, 3) sage: C = A.intersection(B); C.rank() # TODO 1
- is_ambient()#
Return
Trueif and only ifselfis an ambient Hecke module.Warning
self can only be ambient by being of type AmbientHeckeModule.
For example, decomposing a simple ambient space yields a single factor, and that factor is not considered an ambient space.
EXAMPLES:
sage: m = ModularSymbols(10) sage: m.is_ambient() True
sage: a = m[0] # the unique simple factor sage: a == m True sage: a.is_ambient() False
- is_full_hecke_module(compute=True)#
Return
Trueif this space is invariant under the action of all Hecke operators, even those that divide the level. This is always true for ambient Hecke modules, so returnTrue.EXAMPLES:
sage: ModularSymbols(11, 4).is_full_hecke_module() True
- is_new(p=None)#
Return
Trueif this module is entirely new.EXAMPLES:
sage: ModularSymbols(11, 4).is_new() False sage: ModularSymbols(1, 12).is_new() True
- is_old(p=None)#
Return
Trueif this module is entirely old.EXAMPLES:
sage: ModularSymbols(22).is_old() True sage: ModularSymbols(3, 12).is_old() False
- is_submodule(V)#
Return
Trueif and only ifselfis a submodule ofV.Since this is an ambient space, this returns
Trueif and only ifVis equal toself.EXAMPLES:
sage: ModularSymbols(1, 4).is_submodule(ModularSymbols(11,4)) False sage: ModularSymbols(11, 4).is_submodule(ModularSymbols(11,4)) True
- linear_combination_of_basis(v)#
Given a list or vector of length equal to the dimension of self, construct the appropriate linear combination of the basis vectors of self.
EXAMPLES:
sage: ModularForms(3, 12).linear_combination_of_basis([1,0,0,0,1]) 2*q + 2049*q^2 + 177147*q^3 + 4196177*q^4 + 48830556*q^5 + O(q^6)
- new_submodule(p=None)#
Return the new or p-new submodule of self.
INPUT:
p- (default: None); if not None, return only the p-new submodule.
OUTPUT: the new or p-new submodule of self, i.e. the intersection of the kernel of the degeneracy lowering maps to level \(N/p\) (for the given prime \(p\), or for all prime divisors of \(N\) if \(p\) is not given).
If self is cuspidal this is a Hecke-invariant complement of the corresponding old submodule, but this may break down on Eisenstein subspaces (see the amusing example in William Stein’s book of a form which is new and old at the same time).
EXAMPLES:
sage: m = ModularSymbols(33); m.rank() 9 sage: m.new_submodule().rank() 3 sage: m.new_submodule(3).rank() 4 sage: m.new_submodule(11).rank() 8
- nonembedded_free_module()#
Return the free module corresponding to self as an abstract free module (rather than as a submodule of an ambient free module).
As this module is ambient anyway, this just returns
self.free_module().EXAMPLES:
sage: M = ModularSymbols(11, 2) sage: M.nonembedded_free_module() is M.free_module() True
- old_submodule(p=None)#
Return the old or p-old submodule of self, i.e. the sum of the images of the degeneracy maps from level \(N/p\) (for the given prime \(p\), or for all primes \(p\) dividing \(N\) if \(p\) is not given).
INPUT:
p- (default: None); if not None, return only the p-old submodule.
OUTPUT: the old or p-old submodule of self
EXAMPLES:
sage: m = ModularSymbols(33); m.rank() 9 sage: m.old_submodule().rank() 7 sage: m.old_submodule(3).rank() 6 sage: m.new_submodule(11).rank() 8
sage: e = DirichletGroup(16)([-1, 1]) sage: M = ModularSymbols(e, 3, sign=1); M Modular Symbols space of dimension 4 and level 16, weight 3, character [-1, 1], sign 1, over Rational Field sage: M.old_submodule() Modular Symbols subspace of dimension 3 of Modular Symbols space of dimension 4 and level 16, weight 3, character [-1, 1], sign 1, over Rational Field
Illustrate that github issue #10664 is fixed:
sage: ModularSymbols(DirichletGroup(42)[7], 6, sign=1).old_subspace(3) Modular Symbols subspace of dimension 0 of Modular Symbols space of dimension 40 and level 42, weight 6, character [-1, -1], sign 1, over Rational Field
- rank()#
Return the rank of this ambient Hecke module.
OUTPUT:
Integer
EXAMPLES:
sage: M = sage.modular.hecke.ambient_module.AmbientHeckeModule(QQ, 3, 11, 2); M Generic ambient Hecke module of rank 3, level 11 and weight 2 over Rational Field sage: M.rank() 3
- submodule(M, Mdual=None, check=True)#
Return the Hecke submodule of
selfgenerated by \(M\), which may be a submodule of the free module of self, or a list of elements of self.EXAMPLES:
sage: M = ModularForms(37, 2) sage: A = M.submodule([M.newforms()[0].element(), M.newforms()[1].element()]); A Modular Forms subspace of dimension 2 of Modular Forms space of dimension 3 for Congruence Subgroup Gamma0(37) of weight 2 over Rational Field
- submodule_from_nonembedded_module(V, Vdual=None, check=True)#
Create a submodule of this module, from a submodule of an ambient free module of the same rank as the rank of self.
INPUT:
V- submodule of ambient free module of the same rank as the rank of self.Vdual- used to pass in dual submodule (may be None)check- whether to check that submodule is Hecke equivariant
OUTPUT: Hecke submodule of self
EXAMPLES:
sage: V = QQ^8 sage: ModularForms(24, 2).submodule_from_nonembedded_module(V.submodule([0])) Modular Forms subspace of dimension 0 of Modular Forms space of dimension 8 for Congruence Subgroup Gamma0(24) of weight 2 over Rational Field
- submodule_generated_by_images(M)#
Return the submodule of this ambient modular symbols space generated by the images under all degeneracy maps of M.
The space M must have the same weight, sign, and group or character as this ambient space.
EXAMPLES:
sage: ModularSymbols(6, 12).submodule_generated_by_images(ModularSymbols(1,12)) Modular Symbols subspace of dimension 12 of Modular Symbols space of dimension 22 for Gamma_0(6) of weight 12 with sign 0 over Rational Field
- sage.modular.hecke.ambient_module.is_AmbientHeckeModule(x)#
Return
Trueifxis of typeAmbientHeckeModule.EXAMPLES:
sage: from sage.modular.hecke.ambient_module import is_AmbientHeckeModule sage: is_AmbientHeckeModule(ModularSymbols(6)) True sage: is_AmbientHeckeModule(ModularSymbols(6).cuspidal_subspace()) False sage: is_AmbientHeckeModule(ModularForms(11)) True sage: is_AmbientHeckeModule(BrandtModule(2, 3)) True