Ambient Hecke modules - General Hecke Algebras and Hecke Modules

Skip to content
Back to top
View this page
Edit this page

# Ambient Hecke modules

class sage.modular.hecke.ambient_module.AmbientHeckeModule(base_ring, rank, level, weight, category=None)

  Bases: `HeckeModule_free_module`

  An 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

        sage: M = ModularForms(11, 4); M.ambient_hecke_module() is M
        True

    Python

        >>> from sage.all import *
        >>> M = ModularForms(Integer(11), Integer(4)); M.ambient_hecke_module() is M
        True

  complement()

    Return the largest Hecke-stable complement of this space.

    EXAMPLES:

    Sage

        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

    Python

        >>> from sage.all import *
        >>> M = ModularSymbols(Integer(11),Integer(2),Integer(1)); M
        Modular Symbols space of dimension 2 for Gamma_0(11) of weight 2 with sign 1 over Rational Field
        >>> 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
        >>> 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
        >>> 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 `self` coming 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

        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]

    Python

        >>> from sage.all import *
        >>> S = ModularSymbols(Integer(37), Integer(2))
        >>> 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

        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

    Python

        >>> from sage.all import *
        >>> S = ModularSymbols(Integer(37), Integer(2))
        >>> 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]
        >>> t * S.decomposition_matrix() == Integer(1)
        True

  degeneracy_map(codomain, t=1)

    The \(t\)-th degeneracy map from `self` to the module `codomain`.

    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 use `hecke_module_of_level()` to find the “natural” module of the corresponding level).

    - `t` – integer; the parameter of the degeneracy map, i.e., the map is related to \(f(q)\) - \(f(q^t)\)

    OUTPUT: a morphism from `self` to `codomain`

    EXAMPLES:

    Sage

        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]

    Python

        >>> from sage.all import *
        >>> M = ModularSymbols(Integer(11),sign=Integer(1))
        >>> d1 = M.degeneracy_map(Integer(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 ...
        >>> M.degeneracy_map(Integer(33), Integer(3)).matrix()
        [ 3  2  0  2 -2  1]
        [ 0  0 -1  1  0  0]
        >>> M = ModularSymbols(Integer(33), sign=Integer(1))
        >>> d2 = M.degeneracy_map(Integer(11)); d2.matrix()
        [ 1  0]
        [ 0 -2]
        [ 0  2]
        [ 0  1]
        [-1  0]
        [-1  0]
        >>> (d2*d1).matrix()
        [4 0]
        [0 4]

    Sage

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

    [Python]

        >>> from sage.all import *
        >>> M = ModularSymbols(Integer(3), Integer(12), sign=Integer(1))
        >>> M.degeneracy_map(Integer(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

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

    Python

        >>> from sage.all import *
        >>> S = M.cuspidal_submodule()
        >>> S.degeneracy_map(Integer(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

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

    [Python]

        >>> from sage.all import *
        >>> D = ModularSymbols(Integer(10),Integer(4)).cuspidal_submodule().decomposition()
        >>> 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]
        >>> D[Integer(1)].degeneracy_map(Integer(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 Issue #10453:

    Sage

        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

    Python

        >>> from sage.all import *
        >>> loads(dumps(J0(Integer(33)).decomposition()[Integer(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

        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

    [Python]

        >>> from sage.all import *
        >>> chi = kronecker_character(Integer(7))
        >>> ModularSymbols(Gamma0(Integer(7)), Integer(4)).degeneracy_map(ModularSymbols(chi, Integer(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

        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

    Python

        >>> from sage.all import *
        >>> M = ModularForms(Integer(2),Integer(8)); M.dual_free_module()
        Vector space of dimension 3 over Rational Field
        >>> 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\)

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

        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)

    Python

        >>> from sage.all import *
        >>> m = ModularSymbols(Integer(23), Integer(2), sign=Integer(1))
        >>> m.fcp(Integer(2))
        (x - 3) * (x^2 + x - 1)
        >>> m.hecke_operator(Integer(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

        sage: ModularForms(59, 2).free_module()
        Vector space of dimension 6 over Rational Field

    Python

        >>> from sage.all import *
        >>> ModularForms(Integer(59), Integer(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

        sage: ModularSymbols(17, 4).hecke_bound()
        15
        sage: ModularSymbols(Gamma1(17), 4).hecke_bound()  # wrong!
        15

    Python

        >>> from sage.all import *
        >>> ModularSymbols(Integer(17), Integer(4)).hecke_bound()
        15
        >>> ModularSymbols(Gamma1(Integer(17)), Integer(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 integer

    - `v` – list of positive integer

    OUTPUT: `matrix` – whose rows are the Hecke images

    EXAMPLES:

    Sage

        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]

    Python

        >>> from sage.all import *
        >>> M = ModularSymbols(DirichletGroup(Integer(13)).gen(0), Integer(3))
        >>> M.T(Integer(2))(M.gen(0)).element()
        (zeta12 + 4, 0, -1, 1)
        >>> M.hecke_images(Integer(0), [Integer(1),Integer(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: sage.modular.hecke.ambient_module.AmbientHeckeModule.hecke_module_of_level(ModularForms(2, 8),6)
        Traceback (most recent call last):
        ...
        NotImplementedError

    Python

        >>> from sage.all import *
        >>> sage.modular.hecke.ambient_module.AmbientHeckeModule.hecke_module_of_level(ModularForms(Integer(2), Integer(8)),Integer(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

        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

    Python

        >>> from sage.all import *
        >>> M = ModularSymbols(Integer(43), sign=Integer(1))
        >>> A = M[Integer(0)] + M[Integer(1)]
        >>> B = M[Integer(1)] + M[Integer(2)]
        >>> A.rank(), B.rank()
        (2, 3)
        >>> C = A.intersection(B); C.rank()  # TODO
        1

  is_ambient()

    Return `True` if and only if `self` is 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

        sage: m = ModularSymbols(10)
        sage: m.is_ambient()
        True

    Python

        >>> from sage.all import *
        >>> m = ModularSymbols(Integer(10))
        >>> m.is_ambient()
        True

    Sage

        sage: a = m[0]  # the unique simple factor
        sage: a == m
        True
        sage: a.is_ambient()
        False

    [Python]

        >>> from sage.all import *
        >>> a = m[Integer(0)]  # the unique simple factor
        >>> a == m
        True
        >>> a.is_ambient()
        False

  is_full_hecke_module(compute=True)

    Return `True` if 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 return `True`.

    EXAMPLES:

    Sage

        sage: ModularSymbols(11, 4).is_full_hecke_module()
        True

    Python

        >>> from sage.all import *
        >>> ModularSymbols(Integer(11), Integer(4)).is_full_hecke_module()
        True

  is_new(p=None)

    Return `True` if this module is entirely new.

    EXAMPLES:

    Sage

        sage: ModularSymbols(11, 4).is_new()
        False
        sage: ModularSymbols(1, 12).is_new()
        True

    Python

        >>> from sage.all import *
        >>> ModularSymbols(Integer(11), Integer(4)).is_new()
        False
        >>> ModularSymbols(Integer(1), Integer(12)).is_new()
        True

  is_old(p=None)

    Return `True` if this module is entirely old.

    EXAMPLES:

    Sage

        sage: ModularSymbols(22).is_old()
        True
        sage: ModularSymbols(3, 12).is_old()
        False

    Python

        >>> from sage.all import *
        >>> ModularSymbols(Integer(22)).is_old()
        True
        >>> ModularSymbols(Integer(3), Integer(12)).is_old()
        False

  is_submodule(V)

    Return `True` if and only if `self` is a submodule of `V`.

    Since this is an ambient space, this returns `True` if and only if `V` is equal to `self`.

    EXAMPLES:

    Sage

        sage: ModularSymbols(1, 4).is_submodule(ModularSymbols(11,4))
        False
        sage: ModularSymbols(11, 4).is_submodule(ModularSymbols(11,4))
        True

    Python

        >>> from sage.all import *
        >>> ModularSymbols(Integer(1), Integer(4)).is_submodule(ModularSymbols(Integer(11),Integer(4)))
        False
        >>> ModularSymbols(Integer(11), Integer(4)).is_submodule(ModularSymbols(Integer(11),Integer(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

        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)

    Python

        >>> from sage.all import *
        >>> ModularForms(Integer(3), Integer(12)).linear_combination_of_basis([Integer(1),Integer(0),Integer(0),Integer(0),Integer(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

        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

    Python

        >>> from sage.all import *
        >>> m = ModularSymbols(Integer(33)); m.rank()
        9
        >>> m.new_submodule().rank()
        3
        >>> m.new_submodule(Integer(3)).rank()
        4
        >>> m.new_submodule(Integer(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

        sage: M = ModularSymbols(11, 2)
        sage: M.nonembedded_free_module() is M.free_module()
        True

    Python

        >>> from sage.all import *
        >>> M = ModularSymbols(Integer(11), Integer(2))
        >>> 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

        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

    Python

        >>> from sage.all import *
        >>> m = ModularSymbols(Integer(33)); m.rank()
        9
        >>> m.old_submodule().rank()
        7
        >>> m.old_submodule(Integer(3)).rank()
        6
        >>> m.new_submodule(Integer(11)).rank()
        8

    Sage

        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

    [Python]

        >>> from sage.all import *
        >>> e = DirichletGroup(Integer(16))([-Integer(1), Integer(1)])
        >>> M = ModularSymbols(e, Integer(3), sign=Integer(1)); M
        Modular Symbols space of dimension 4 and level 16, weight 3,
         character [-1, 1], sign 1, over Rational Field
        >>> 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 Issue #10664 is fixed:

    Sage

        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

    Python

        >>> from sage.all import *
        >>> ModularSymbols(DirichletGroup(Integer(42))[Integer(7)], Integer(6), sign=Integer(1)).old_subspace(Integer(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

        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

    Python

        >>> from sage.all import *
        >>> M = sage.modular.hecke.ambient_module.AmbientHeckeModule(QQ, Integer(3), Integer(11), Integer(2)); M
        Generic ambient Hecke module of rank 3, level 11 and weight 2 over Rational Field
        >>> M.rank()
        3

  submodule(M, Mdual=None, check=True)

    Return the Hecke submodule of `self` generated by \(M\), which may be a submodule of the free module of `self`, or a list of elements of `self`.

    EXAMPLES:

    Sage

        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

    Python

        >>> from sage.all import *
        >>> M = ModularForms(Integer(37), Integer(2))
        >>> A = M.submodule([M.newforms()[Integer(0)].element(), M.newforms()[Integer(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

        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

    Python

        >>> from sage.all import *
        >>> V = QQ**Integer(8)
        >>> ModularForms(Integer(24), Integer(2)).submodule_from_nonembedded_module(V.submodule([Integer(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

        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

    Python

        >>> from sage.all import *
        >>> ModularSymbols(Integer(6), Integer(12)).submodule_generated_by_images(ModularSymbols(Integer(1),Integer(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