Ticket #11601: 11601.4.patch

File 11601.4.patch, 46.0 KB (added by Johan Bosman, 11 years ago)
  • doc/en/bordeaux_2008/modular_forms_and_hecke_operators.rst

    # HG changeset patch
    # User David Loeffler <d.loeffler.01@cantab.net>
    # Date 1310742384 -3600
    # Node ID 1db93626b12bc3445a366e2c384998accb8e877c
    # Parent  18b1983d298deb35d47d17b1b81f6b6e36fb1fec
    #11601: general congruence subgroups of modular group
    
    diff --git a/doc/en/bordeaux_2008/modular_forms_and_hecke_operators.rst b/doc/en/bordeaux_2008/modular_forms_and_hecke_operators.rst
    a b  
    4040    Congruence Subgroup Gamma0(8)
    4141    sage: Gamma1(13)
    4242    Congruence Subgroup Gamma1(13)
    43     sage: GammaH(11,[2])
    44     Congruence Subgroup Gamma_H(11) with H generated by [2]
     43    sage: GammaH(11,[4])
     44    Congruence Subgroup Gamma_H(11) with H generated by [4]
    4545
    4646The second argument to the GammaH command is a list of generators of
    4747the subgroup :math:`H` of :math:`(\ZZ/N\ZZ)^*`.
  • sage/modular/abvar/abvar_ambient_jacobian.py

    diff --git a/sage/modular/abvar/abvar_ambient_jacobian.py b/sage/modular/abvar/abvar_ambient_jacobian.py
    a b  
    144144            J_0(37)
    145145            sage: J1(13)._latex_()
    146146            'J_1(13)'
    147             sage: latex(JH(389,[2]))
    148             J_H(389,[2])
     147            sage: latex(JH(389,[16]))
     148            J_H(389,[16])
    149149        """
    150150        return self._ambient_latex_repr()
    151151
  • sage/modular/abvar/constructor.py

    diff --git a/sage/modular/abvar/constructor.py b/sage/modular/abvar/constructor.py
    a b  
    128128   
    129129    EXAMPLES::
    130130   
    131         sage: JH(389,[2])
    132         Abelian variety JH(389,[2]) of dimension 32
     131        sage: JH(389,[16])
     132        Abelian variety JH(389,[16]) of dimension 64
    133133    """
    134134    key = 'JH(%s,%s)'%(N,H)
    135135    try:
  • sage/modular/all.py

    diff --git a/sage/modular/all.py b/sage/modular/all.py
    a b  
    1212                       kronecker_character, kronecker_character_upside_down,
    1313                       trivial_character)
    1414
    15 from arithgroup.all import (Gamma0, Gamma1, GammaH, Gamma, SL2Z, ArithmeticSubgroup_Permutation)
     15from arithgroup.all import (Gamma0, Gamma1, GammaH, Gamma, SL2Z,
     16                            ArithmeticSubgroup_Permutation,
     17                            CongruenceSubgroup)
    1618
    1719from cusps import Cusp, Cusps
    1820
  • sage/modular/arithgroup/all.py

    diff --git a/sage/modular/arithgroup/all.py b/sage/modular/arithgroup/all.py
    a b  
    22# they are invisible to the user but easy to import all in one go by other code that needs them.
    33
    44from arithgroup_generic import is_ArithmeticSubgroup
    5 from congroup_generic import is_CongruenceSubgroup
     5from congroup_generic import is_CongruenceSubgroup, CongruenceSubgroup_constructor as CongruenceSubgroup
    66from congroup_gammaH import GammaH_constructor as GammaH, is_GammaH
    77from congroup_gamma1 import Gamma1_constructor as Gamma1, is_Gamma1
    88from congroup_gamma0 import Gamma0_constructor as Gamma0, is_Gamma0
  • sage/modular/arithgroup/arithgroup_generic.py

    diff --git a/sage/modular/arithgroup/arithgroup_generic.py b/sage/modular/arithgroup/arithgroup_generic.py
    a b  
    504504        """
    505505        return [-1, 0, 0, -1] in self
    506506
     507    def to_even_subgroup(self):
     508        r"""
     509        Return the smallest even subgroup of `SL(2, \ZZ)` containing self.
     510
     511        EXAMPLE::
     512
     513            sage: sage.modular.arithgroup.arithgroup_generic.ArithmeticSubgroup().to_even_subgroup()
     514            Traceback (most recent call last):
     515            ...
     516            NotImplementedError
     517        """
     518        if self.is_even():
     519            return self
     520        else:
     521            raise NotImplementedError
     522
    507523    def order(self):
    508524        r"""
    509525        Return the number of elements in this arithmetic subgroup.
     
    747763    def generalised_level(self):
    748764        r"""
    749765        Return the generalised level of self, i.e. the least common multiple of
    750         the widths of all cusps. Wohlfart's theorem tells us that this is equal
    751         to the (conventional) level of self when self is a congruence subgroup.
     766        the widths of all cusps.
     767       
     768        If self is *even*, Wohlfart's theorem tells us that this is equal to
     769        the (conventional) level of self when self is a congruence subgroup.
     770        This can fail if self is odd, but the actual level is at most twice the
     771        generalised level. See the paper by Kiming, Schuett and Verrill for
     772        more examples.
    752773       
    753774        EXAMPLE::
    754775
     
    758779            Traceback (most recent call last):
    759780            ...
    760781            NotImplementedError
     782
     783        In the following example, the actual level is twice the generalised
     784        level. This is the group `G_2` from Example 17 of K-S-V.
     785       
     786        ::
     787
     788            sage: G = CongruenceSubgroup(8, [ [1,1,0,1], [3,-1,4,-1] ])
     789            sage: G.level()
     790            8
     791            sage: G.generalised_level()
     792            4
    761793        """
    762794        return arith.lcm([self.cusp_width(c) for c in self.cusps()])
    763795
  • sage/modular/arithgroup/arithgroup_perm.py

    diff --git a/sage/modular/arithgroup/arithgroup_perm.py b/sage/modular/arithgroup/arithgroup_perm.py
    a b  
    13121312        """
    13131313        return arith.lcm(self.cusp_widths())
    13141314
     1315    def congruence_closure(self):
     1316        r"""
     1317        Returns the smallest congruence subgroup containing self. If self is
     1318        congruence, this is just self, but represented as a congruence subgroup
     1319        data type. If self is not congruence, then it may be larger.
     1320
     1321        In practice, we use the following criterion: let `m` be the generalised
     1322        level of self. If this subgroup is even, let `n = m`, else let `n =
     1323        2m`. Then any congruence subgroup containing self contains `\Gamma(n)`
     1324        (a generalisation of Wohlfahrt's theorem due to Kiming, Verrill and
     1325        Schuett). So we compute the image of self modulo `n` and return the
     1326        preimage of that.
     1327       
     1328        EXAMPLE::
     1329       
     1330            sage: Gamma1(3).as_permutation_group().congruence_closure()
     1331            Congruence subgroup of SL(2,Z) of level 3, preimage of:
     1332             Matrix group over Ring of integers modulo 3 with 2 generators:
     1333              [[[1, 2], [0, 1]], [[1, 1], [0, 1]]]
     1334            sage: sage.modular.arithgroup.arithgroup_perm.HsuExample10().congruence_closure() # long time (40 sec)
     1335            Modular Group SL(2,Z)
     1336        """
     1337        if self.is_even():
     1338            N = self.generalised_level()
     1339        else:
     1340            N = 2*self.generalised_level()
     1341
     1342        from congroup_generic import CongruenceSubgroup_constructor as CS
     1343        return CS(N, [x.matrix() for x in self.gens()])
     1344
    13151345class OddArithmeticSubgroup_Permutation(ArithmeticSubgroup_Permutation_class):
    13161346    def __init__(self, S2, S3, L, R, canonical_labels=False):
    13171347        r"""
  • sage/modular/arithgroup/congroup_gamma.py

    diff --git a/sage/modular/arithgroup/congroup_gamma.py b/sage/modular/arithgroup/congroup_gamma.py
    a b  
    1717from congroup_generic import CongruenceSubgroup
    1818from arithgroup_element import ArithmeticSubgroupElement
    1919from sage.misc.misc import prod
    20 from sage.rings.all import ZZ
     20from sage.rings.all import ZZ, Zmod
     21from sage.groups.matrix_gps.matrix_group import MatrixGroup
     22from sage.matrix.constructor import matrix
    2123
    2224_gamma_cache = {}
    2325def Gamma_constructor(N):
     
    167169            return ZZ(3)
    168170        return prod([p**(2*e) - p**(2*e-2) for (p,e) in n.factor()])//2
    169171       
     172    def nu3(self):
     173        r"""
     174        Return the number of elliptic points of order 3 for this arithmetic
     175        subgroup. Since this subgroup is `\Gamma(N)` for `N \ge 2`, there are
     176        no such points, so we return 0.
     177
     178        EXAMPLE::
     179
     180            sage: Gamma(89).nu3()
     181            0
     182        """
     183        return 0
     184
     185    # We don't need to override nu2, since the default nu2 implementation knows
     186    # that nu2 = 0 for odd subgroups.
     187
     188    def image_mod_n(self):
     189        r"""
     190        Return the image of this group modulo `N`, as a subgroup of `SL(2, \ZZ
     191        / N\ZZ)`. This is just the trivial subgroup.
     192
     193        EXAMPLE::
     194
     195            sage: Gamma(3).image_mod_n()
     196            Matrix group over Ring of integers modulo 3 with 1 generators:
     197             [[[1, 0], [0, 1]]]
     198        """
     199        return MatrixGroup([matrix(Zmod(self.level()), 2, 2, 1)])
     200
    170201
    171202def is_Gamma(x):
    172203    r"""
  • sage/modular/arithgroup/congroup_gamma0.py

    diff --git a/sage/modular/arithgroup/congroup_gamma0.py b/sage/modular/arithgroup/congroup_gamma0.py
    a b  
    235235        """
    236236        if self.level() in [1, 2]:
    237237            return []
    238         return [int(x) for x in IntegerModRing(self.level()).unit_gens()]
     238        return [ZZ(x) for x in IntegerModRing(self.level()).unit_gens()]
    239239
    240240    @cached_method
    241241    def _list_of_elements_in_H(self):
     
    415415
    416416            sage: G = Gamma0(11)
    417417            sage: G.gamma_h_subgroups()
    418             [Congruence Subgroup Gamma_H(11) with H generated by [2], Congruence Subgroup Gamma_H(11) with H generated by [4], Congruence Subgroup Gamma_H(11) with H generated by [10], Congruence Subgroup Gamma_H(11) with H generated by []]
     418            [Congruence Subgroup Gamma0(11), Congruence Subgroup Gamma_H(11) with H generated by [4], Congruence Subgroup Gamma_H(11) with H generated by [10], Congruence Subgroup Gamma1(11)]
    419419            sage: G = Gamma0(12)
    420420            sage: G.gamma_h_subgroups()
    421             [Congruence Subgroup Gamma_H(12) with H generated by [5, 7], Congruence Subgroup Gamma_H(12) with H generated by [7], Congruence Subgroup Gamma_H(12) with H generated by [11], Congruence Subgroup Gamma_H(12) with H generated by [5], Congruence Subgroup Gamma_H(12) with H generated by []]
     421            [Congruence Subgroup Gamma0(12), Congruence Subgroup Gamma_H(12) with H generated by [7], Congruence Subgroup Gamma_H(12) with H generated by [11], Congruence Subgroup Gamma_H(12) with H generated by [5], Congruence Subgroup Gamma1(12)]
    422422        """
    423423        from all import GammaH
    424424        N = self.level()
  • sage/modular/arithgroup/congroup_gamma1.py

    diff --git a/sage/modular/arithgroup/congroup_gamma1.py b/sage/modular/arithgroup/congroup_gamma1.py
    a b  
    1919from sage.misc.misc import prod
    2020from congroup_generic import is_CongruenceSubgroup
    2121from congroup_gammaH import GammaH_class, is_GammaH, GammaH_constructor
     22#from congroup_gamma0 import Gamma0_constructor -- circular!
    2223from arithgroup_element import ArithmeticSubgroupElement
    2324from sage.rings.all import ZZ, euler_phi as phi, moebius, divisors
    2425from sage.modular.dirichlet import DirichletGroup
     
    4142        True
    4243        sage: is_Gamma1(Gamma0(6))
    4344        False
    44         sage: is_Gamma1(GammaH(12, []))
     45        sage: is_Gamma1(GammaH(12, [])) # trick question!
     46        True
     47        sage: is_Gamma1(GammaH(12, [5]))
    4548        False
    4649    """
    4750    #from congroup_sl2z import is_SL2Z
     
    6568        sage: G is loads(dumps(G))
    6669        True
    6770    """
     71    if N == 1 or N == 2:
     72        from congroup_gamma0 import Gamma0_constructor
     73        return Gamma0_constructor(N)
    6874    try:
    6975        return _gamma1_cache[N]
    7076    except KeyError:
  • sage/modular/arithgroup/congroup_gammaH.py

    diff --git a/sage/modular/arithgroup/congroup_gammaH.py b/sage/modular/arithgroup/congroup_gammaH.py
    a b  
    44AUTHORS:
    55
    66- Jordi Quer
    7 
    87- David Loeffler
    98"""
    109
     
    2928
    3029# Just for now until we make an SL_2 group type.
    3130from sage.rings.integer_ring import ZZ
    32 from sage.rings.finite_rings.integer_mod_ring import IntegerModRing
     31from sage.rings.finite_rings.integer_mod_ring import Zmod
    3332from sage.matrix.matrix_space import MatrixSpace
     33from sage.groups.matrix_gps.matrix_group import MatrixGroup
     34from sage.matrix.constructor import matrix
    3435
    3536Mat2Z = MatrixSpace(ZZ,2)
    3637
     
    5960        Congruence Subgroup Gamma0(11)
    6061        sage: GammaH(11,1)
    6162        Congruence Subgroup Gamma1(11)
    62         sage: GammaH(11,[2])
    63         Congruence Subgroup Gamma_H(11) with H generated by [2]
    64         sage: GammaH(11,[2,1])
    65         Congruence Subgroup Gamma_H(11) with H generated by [2]
     63        sage: GammaH(11,[10])
     64        Congruence Subgroup Gamma_H(11) with H generated by [10]
     65        sage: GammaH(11,[10,1])
     66        Congruence Subgroup Gamma_H(11) with H generated by [10]
    6667        sage: GammaH(14,[10])
    6768        Traceback (most recent call last):
    6869        ...
     
    7778        return Gamma1(level)
    7879
    7980    H = _normalize_H(H, level)
     81    if H == []:
     82        return Gamma1(level)
     83
     84    Hlist = _list_subgroup(level, H)
     85    if len(Hlist) == euler_phi(level):
     86        return Gamma0(level)
    8087
    8188    key = (level, tuple(H))
    8289    try:
    8390        return _gammaH_cache[key]
    8491    except KeyError:
    85         _gammaH_cache[key] = GammaH_class(level, H)
     92        _gammaH_cache[key] = GammaH_class(level, H, Hlist)
    8693        return _gammaH_cache[key]
    8794   
    8895def is_GammaH(x):
     
    96103        True
    97104        sage: is_GammaH(Gamma0(6))
    98105        True
     106        sage: is_GammaH(Gamma1(6))
     107        True
    99108        sage: is_GammaH(sage.modular.arithgroup.congroup_generic.CongruenceSubgroup(5))
    100109        False
    101110    """
     
    182191
    183192    """
    184193
    185     def __init__(self, level, H):
     194    def __init__(self, level, H, Hlist=None):
    186195        r"""
    187196        The congruence subgroup `\Gamma_H(N)`. The subgroup H
    188197        must be input as a list.
     
    198207            True
    199208        """
    200209        CongruenceSubgroup.__init__(self, level)
    201         self.__H = _normalize_H(H, level)
     210        self.__H = H
     211        if Hlist is None: Hlist = _list_subgroup(level, H)
     212        self.__Hlist = Hlist
    202213
    203214    def restrict(self, M):
    204215        r"""
     
    209220
    210221            sage: G = GammaH(33,[2])
    211222            sage: G.restrict(11)
    212             Congruence Subgroup Gamma_H(11) with H generated by [2]
     223            Congruence Subgroup Gamma0(11)
    213224            sage: G.restrict(1)
    214225            Modular Group SL(2,Z)
    215226            sage: G.restrict(15)
     
    250261
    251262        EXAMPLES::
    252263
    253             sage: GammaH(92,[5,11]).__reduce__()
    254             (<function GammaH_constructor at ...>, (92, [5, 11]))
     264            sage: GammaH(92,[45,47]).__reduce__()
     265            (<function GammaH_constructor at ...>, (92, [45, 47]))
    255266        """
    256267        return GammaH_constructor, (self.level(), self.__H)
    257268
     
    269280            [1, 2, 4, 8, 16, 17, 25, 29, 31, 32]
    270281            sage: G.divisor_subgroups()
    271282            [Modular Group SL(2,Z),
    272              Congruence Subgroup Gamma_H(3) with H generated by [2],
    273              Congruence Subgroup Gamma_H(11) with H generated by [2],
     283             Congruence Subgroup Gamma0(3),
     284             Congruence Subgroup Gamma0(11),
    274285             Congruence Subgroup Gamma_H(33) with H generated by [2]]
    275286        """
    276287        v = self.__H
     
    280291            ans.append(GammaH_constructor(M, w))
    281292        return ans
    282293
     294    def to_even_subgroup(self):
     295        r"""
     296        Return the smallest even subgroup of `SL(2, \ZZ)` containing self.
     297
     298        EXAMPLE::
     299
     300            sage: GammaH(11, [4]).to_even_subgroup()
     301            Congruence Subgroup Gamma0(11)
     302            sage: Gamma1(11).to_even_subgroup()
     303            Congruence Subgroup Gamma_H(11) with H generated by [10]
     304
     305        """
     306        if self.is_even(): return self
     307        else:
     308            return GammaH_constructor(self.level(), self._generators_for_H() + [-1])
     309
    283310    def __cmp__(self, other):
    284311        """
    285312        Compare self to other.
     
    303330            sage: Gamma0(11) == GammaH(11, [2])
    304331            True
    305332        """
    306         if not is_CongruenceSubgroup(other):
    307             return cmp(type(self), type(other))
    308 
    309         c = cmp(self.level(), other.level())
    310         if c: return c
    311 
    312333        if is_GammaH(other):
    313             return cmp(self._list_of_elements_in_H(), other._list_of_elements_in_H())
    314         return cmp(type(self), type(other))
     334            t = cmp(self.level(), other.level())
     335            if t:
     336                return t
     337            else:
     338                return cmp(self._list_of_elements_in_H(), other._list_of_elements_in_H())
     339        else:
     340            return CongruenceSubgroup.__cmp__(self, other)
    315341
    316342    def _generators_for_H(self):
    317343        """
     
    344370       
    345371        EXAMPLES::
    346372
    347             sage: GammaH(3,[2])._latex_()
    348             '\\Gamma_H(3)'
     373            sage: GammaH(5,[4])._latex_()
     374            '\\Gamma_H(5)'
    349375        """
    350376        return "\\Gamma_H(%s)"%self.level()
    351377
    352     @cached_method
    353378    def _list_of_elements_in_H(self):
    354379        """
    355380        Returns a sorted list of Python ints that are representatives
     
    364389            sage: G._list_of_elements_in_H()
    365390            [1, 3, 4, 5, 9]       
    366391        """
    367         N = self.level()
    368         if N == 1:
    369             return [1]
    370         gens = self.__H
    371        
    372         H = set([1])
    373         N = int(N)
    374         for g in gens:
    375             if gcd(g, N) != 1:
    376                 raise ValueError, "gen (=%s) is not in (Z/%sZ)^*"%(g,N)
    377             gk = int(g) % N
    378             sbgrp = [gk]
    379             while not (gk in H):
    380                 gk = (gk * g)%N
    381                 sbgrp.append(gk)
    382             H = set([(x*h)%N for x in sbgrp for h in H])
    383         H = list(H)
    384         H.sort()
    385         return H
     392        return self.__Hlist
    386393
    387394    def is_even(self):
    388395        """
     
    458465
    459466        EXAMPLES::
    460467
    461             sage: G = GammaH(12,[-1,5]); G
    462             Congruence Subgroup Gamma_H(12) with H generated by [5, 11]
    463             sage: G._coset_reduction_data_first_coord()
     468            sage: G = Gamma0(12)
     469            sage: sage.modular.arithgroup.congroup_gammaH.GammaH_class._coset_reduction_data_first_coord(G)
    464470            [(0, 12, 0), (1, 1, 1), (2, 2, 1), (3, 3, 1), (4, 4, 1), (1, 1, 5), (6, 6, 1),
    465471            (1, 1, 7), (4, 4, 5), (3, 3, 7), (2, 2, 5), (1, 1, 11)]
    466472        """
     
    557563
    558564        EXAMPLES::
    559565
    560             sage: G = GammaH(12,[-1,7]); G
    561             Congruence Subgroup Gamma_H(12) with H generated by [7, 11]
     566            sage: G = GammaH(13, [-1]); G
     567            Congruence Subgroup Gamma_H(13) with H generated by [12]
    562568            sage: G._coset_reduction_data()
    563             ([(0, 12, 0), (1, 1, 1), (2, 2, 1), (3, 3, 1), (4, 4, 1), (1, 1, 5), (6, 6, 1), (1, 1, 7), (4, 4, 5), (3, 3, 7), (2, 2, 5), (1, 1, 11)],
    564             {1: [1], 2: [1, 7], 3: [1, 5],  4: [1, 7], 6: [1, 5, 7, 11], 12: [1, 5, 7, 11]})
     569            ([(0, 13, 0), (1, 1, 1), (2, 1, 1), (3, 1, 1), (4, 1, 1), (5, 1, 1), (6, 1, 1), (6, 1, 12), (5, 1, 12), (4, 1, 12), (3, 1, 12), (2, 1, 12), (1, 1, 12)], {1: [1], 13: [1, 12]})
    565570        """
    566571        return (self._coset_reduction_data_first_coord(),
    567572                                       self._coset_reduction_data_second_coord())
     
    11591164        else:
    11601165            return self.dimension_cusp_forms(k) - \
    11611166                   2*self.restrict(N//p).dimension_new_cusp_forms(k)
     1167   
     1168    def image_mod_n(self):
     1169        r"""
     1170        Return the image of this group in `SL(2, \ZZ / N\ZZ)`.
     1171
     1172        EXAMPLE::
     1173
     1174            sage: Gamma0(3).image_mod_n()
     1175            Matrix group over Ring of integers modulo 3 with 2 generators:
     1176             [[[2, 0], [0, 2]], [[1, 1], [0, 1]]]
     1177
     1178        TEST::
     1179
     1180            sage: for n in [2..20]:
     1181            ...     for g in Gamma0(n).gamma_h_subgroups():
     1182            ...       G = g.image_mod_n()
     1183            ...       assert G.order() == Gamma(n).index() / g.index()
     1184        """
     1185        N = self.level()
     1186        if N == 1:
     1187            raise NotImplementedError, "Matrix groups over ring of integers modulo 1 not implemented"
     1188        gens = [matrix(Zmod(N), 2, 2, [x, 0, 0, Zmod(N)(1)/x]) for x in self._generators_for_H()]
     1189        gens += [matrix(Zmod(N),2,[1,1,0,1])]
     1190        return MatrixGroup(gens)
     1191       
     1192def _list_subgroup(N, gens):   
     1193    r"""
     1194    Given an integer ``N`` and a list of integers ``gens``, return a list of
     1195    the elements of the subgroup of `(\ZZ / N\ZZ)^\times` generated by the
     1196    elements of ``gens``.
     1197
     1198    EXAMPLE::
     1199
     1200        sage: sage.modular.arithgroup.congroup_gammaH._list_subgroup(11, [3])
     1201        [1, 3, 4, 5, 9]
     1202    """
     1203    H = set([1])
     1204    N = int(N)
     1205    for g in gens:
     1206        if gcd(g, N) != 1:
     1207            raise ValueError, "gen (=%s) is not in (Z/%sZ)^*"%(g,N)
     1208        gk = int(g) % N
     1209        sbgrp = [gk]
     1210        while not (gk in H):
     1211            gk = (gk * g)%N
     1212            sbgrp.append(gk)
     1213        H = set([(x*h)%N for x in sbgrp for h in H])
     1214    H = list(H)
     1215    H.sort()
     1216    return H
    11621217
    11631218def _GammaH_coset_helper(N, H):
    11641219    r"""
     
    11701225        sage: _GammaH_coset_helper(108, [1, 107])
    11711226        [1, 5, 7, 11, 13, 17, 19, 23, 25, 29, 31, 35, 37, 41, 43, 47, 49, 53]
    11721227    """
    1173     t = [IntegerModRing(N)(1)]
    1174     W = [IntegerModRing(N)(h) for h in H]
    1175     HH = [IntegerModRing(N)(h) for h in H]
     1228    t = [Zmod(N)(1)]
     1229    W = [Zmod(N)(h) for h in H]
     1230    HH = [Zmod(N)(h) for h in H]
    11761231    k = euler_phi(N)
    11771232   
    11781233    for i in xrange(1, N):
  • sage/modular/arithgroup/congroup_generic.py

    diff --git a/sage/modular/arithgroup/congroup_generic.py b/sage/modular/arithgroup/congroup_generic.py
    a b  
    2222#
    2323################################################################################
    2424
    25 from sage.rings.all import QQ, ZZ
     25from sage.rings.all import QQ, ZZ, Zmod
    2626from sage.rings.arith import gcd
    27 #import sage.modular.cusps # circular!
     27from sage.sets.set import Set
     28from sage.groups.matrix_gps.matrix_group import MatrixGroup, MatrixGroup_generic
     29from sage.matrix.matrix_space import MatrixSpace
     30from sage.misc.misc_c import prod
    2831
    2932from arithgroup_element import ArithmeticSubgroupElement
    30 from arithgroup_generic import ArithmeticSubgroup
     33from arithgroup_generic import ArithmeticSubgroup, is_ArithmeticSubgroup
     34
     35def CongruenceSubgroup_constructor(*args):
     36    r"""
     37    Attempt to create a congruence subgroup from the given data.
     38
     39    The allowed inputs are as follows:
     40
     41    - A :class:`~sage.groups.matrix_gps.matrix_group.MatrixGroup` object. This
     42      must be a group of matrices over `\ZZ / N\ZZ` for some `N`, with
     43      determinant 1, in which case the function will return the group of
     44      matrices in `SL(2, \ZZ)` whose reduction mod `N` is in the given group. 
     45
     46    - A list of matrices over `\ZZ / N\ZZ` for some `N`. The function will then
     47      compute the subgroup of `SL(2, \ZZ)` generated by these matrices, and
     48      proceed as above.
     49
     50    - An integer `N` and a list of matrices (over any ring coercible to `\ZZ /
     51      N\ZZ`, e.g. over `\ZZ`). The matrices will then be coerced to `\ZZ /
     52      N\ZZ`.
     53
     54    The function checks that the input G is valid. It then tests to see if
     55    `G` is the preimage mod `N` of some group of matrices modulo a proper
     56    divisor `M` of `N`, in which case it replaces `G` with this group before
     57    continuing.
     58
     59    EXAMPLES::
     60
     61        sage: from sage.modular.arithgroup.congroup_generic import CongruenceSubgroup_constructor as CS
     62        sage: CS(2, [[1,1,0,1]])
     63        Congruence subgroup of SL(2,Z) of level 2, preimage of:
     64         Matrix group over Ring of integers modulo 2 with 1 generators:
     65         [[[1, 1], [0, 1]]]
     66        sage: CS([matrix(Zmod(2), 2, [1,1,0,1])])
     67        Congruence subgroup of SL(2,Z) of level 2, preimage of:
     68         Matrix group over Ring of integers modulo 2 with 1 generators:
     69         [[[1, 1], [0, 1]]]
     70        sage: CS(MatrixGroup([matrix(Zmod(2), 2, [1,1,0,1])]))
     71        Congruence subgroup of SL(2,Z) of level 2, preimage of:
     72         Matrix group over Ring of integers modulo 2 with 1 generators:
     73         [[[1, 1], [0, 1]]]
     74        sage: CS(SL(2, 2))
     75        Modular Group SL(2,Z)
     76
     77    Some invalid inputs::
     78
     79        sage: CS(SU(2, 7))
     80        Traceback (most recent call last):
     81        ...
     82        TypeError: Ring of definition must be Z / NZ for some N
     83    """
     84    if isinstance(args[0], MatrixGroup_generic):
     85        G = args[0]
     86
     87    elif type(args[0]) == type([]):
     88        G = MatrixGroup(args[0])
     89
     90    elif args[0] in ZZ:
     91        M = MatrixSpace(Zmod(args[0]), 2)
     92        G = MatrixGroup([M(x) for x in args[1]])   
     93
     94    R = G.matrix_space().base_ring()
     95    if not hasattr(R, "cover_ring") or R.cover_ring() != ZZ:
     96        raise TypeError, "Ring of definition must be Z / NZ for some N"
     97       
     98    if not all([x.matrix().det() == 1 for x in G.gens()]):
     99        raise ValueError, "Group must be contained in SL(2, Z / N)"
     100    GG = _minimize_level(G)
     101    if GG in ZZ:
     102        from all import Gamma
     103        return Gamma(GG)
     104    else:
     105        return CongruenceSubgroupFromGroup(GG)
    31106
    32107def is_CongruenceSubgroup(x):
    33108    """
    34109    Return True if x is of type CongruenceSubgroup.
    35110
     111    Note that this may be False even if `x` really is a congruence subgroup --
     112    it tests whether `x` is "obviously" congruence, i.e.~whether it has a
     113    congruence subgroup datatype. To test whether or not an arithmetic subgroup
     114    of `SL(2, \ZZ)` is congruence, use the ``is_congruence()`` method instead.
     115
    36116    EXAMPLES::
    37117
    38118        sage: from sage.modular.arithgroup.congroup_generic import is_CongruenceSubgroup
     
    44124        True
    45125        sage: is_CongruenceSubgroup(GammaH(11, [3]))
    46126        True
     127        sage: G = ArithmeticSubgroup_Permutation(L = "(1, 2)", R = "(1, 2)"); is_CongruenceSubgroup(G)
     128        False
     129        sage: G.is_congruence()
     130        True
    47131        sage: is_CongruenceSubgroup(SymmetricGroup(3))
    48132        False
    49133    """
    50     return isinstance(x, CongruenceSubgroup)
     134    return isinstance(x, CongruenceSubgroupBase)
    51135
    52 class CongruenceSubgroup(ArithmeticSubgroup):
     136class CongruenceSubgroupBase(ArithmeticSubgroup):
     137
    53138    def __init__(self, level):
    54139        """
    55140        Create a congruence subgroup with given level.
     
    64149            raise ArithmeticError, "Congruence groups only defined for positive levels."
    65150        self.__level = level
    66151        ArithmeticSubgroup.__init__(self)
    67 
    68     def _repr_(self):
    69         """
    70         Return the string representation of self.
    71 
    72         NOTE: This function should be overridden by all subclasses.
    73 
    74         EXAMPLES::
    75 
    76             sage: sage.modular.arithgroup.congroup_generic.CongruenceSubgroup(5)._repr_()
    77             'Generic congruence subgroup'
    78         """
    79         return "Generic congruence subgroup"
    80 
     152   
    81153    def is_congruence(self):
    82154        r"""
    83155        Return True, since this is a congruence subgroup.
     
    90162
    91163        return True
    92164
     165    def level(self):
     166        """
     167        Return the level of this congruence subgroup.
     168
     169        EXAMPLES::
     170
     171            sage: SL2Z.level()
     172            1
     173            sage: Gamma0(20).level()
     174            20
     175            sage: Gamma1(11).level()
     176            11
     177            sage: GammaH(14, [5]).level()
     178            14
     179        """
     180        return self.__level
     181
     182    def __cmp__(self, other):
     183        r"""
     184        EXAMPLE::
     185
     186            sage: CongruenceSubgroup(3,[ [1,1,0,1] ]) == Gamma1(3)
     187            True
     188            sage: CongruenceSubgroup(3,[ [1,1,0,1] ]) == Gamma(3)
     189            False
     190            sage: CongruenceSubgroup(3,[ [1,1,0,1] ]) == QQ
     191            False
     192        """
     193       
     194        if is_CongruenceSubgroup(other):
     195            t = cmp(self.level(), other.level())
     196            if t: return t
     197            if self.level() == 1: return 0 # shouldn't come up except with pickling/unpickling
     198            t = cmp(self.index(), other.index())
     199            if t: return t
     200            return cmp(self.image_mod_n(),other.image_mod_n())
     201
     202        elif is_ArithmeticSubgroup(other):
     203            return cmp(self.as_permutation_group(), other)
     204
     205        else:
     206            return cmp(type(self), type(other))
     207
     208class CongruenceSubgroupFromGroup(CongruenceSubgroupBase):
     209    r"""
     210    A congruence subgroup, defined by the data of an integer `N` and a subgroup
     211    `G` of the finite group `SL(2, \ZZ / N\ZZ)`; the congruence subgroup
     212    consists of all the matrices in `SL(2, \ZZ)` whose reduction modulo `N`
     213    lies in `G`.
     214
     215    This class should not be instantiated directly, but created using the
     216    factory function
     217    :func:`~sage.modular.arithgroup.congroup_generic.CongruenceSubgroup_constructor`,
     218    which accepts much more flexible input, and checks the input to make sure
     219    it is valid.
     220
     221    TESTS::
     222
     223        sage: G = CongruenceSubgroup(5, [[0,-1,1,0]]); G
     224        Congruence subgroup of SL(2,Z) of level 5, preimage of:
     225         Matrix group over Ring of integers modulo 5 with 1 generators:
     226         [[[0, 4], [1, 0]]]
     227        sage: G == loads(dumps(G))
     228        True
     229    """
     230
     231    def __init__(self, G):
     232        r"""
     233        Standard init function.
     234
     235        TESTS::
     236
     237            sage: from sage.modular.arithgroup.congroup_generic import CongruenceSubgroupFromGroup
     238            sage: G = MatrixGroup([matrix(Zmod(2), 2, [1,1,1,0])])
     239            sage: CongruenceSubgroupFromGroup(G).index() # indirect doctest
     240            2
     241        """
     242        N = G.base_ring().characteristic()
     243        self.__G = G
     244        CongruenceSubgroupBase.__init__(self, N)
     245
     246    def __reduce__(self):
     247        r"""
     248        Data defining self (for pickling).
     249
     250        EXAMPLE::
     251
     252            sage: G = CongruenceSubgroup(5, [[0,-1,1,0]])
     253            sage: G.__reduce__()
     254            (<function CongruenceSubgroup_constructor at ...>, (Matrix group over Ring of integers modulo 5 with 1 generators:
     255                 [[[0, 4], [1, 0]]],))
     256        """
     257        return CongruenceSubgroup_constructor, (self.image_mod_n(),)
     258
     259    def __call__(self, x, check=True):
     260        r"""
     261        Attempt to convert `x` into an element of self. This converts `x` into
     262        an element of `SL(2, \ZZ)`. If ``check`` is True (the default) it
     263        checks if the resulting element is in self, and otherwise raises an
     264        error.
     265
     266        EXAMPLE::
     267
     268            sage: G = MatrixGroup([matrix(Zmod(2), 2, [1,1,1,0])])
     269            sage: H = sage.modular.arithgroup.congroup_generic.CongruenceSubgroupFromGroup(G)
     270            sage: H(1)
     271            [1 0]
     272            [0 1]
     273            sage: H([0,-1,1,0])
     274            Traceback (most recent call last):
     275            ...
     276            TypeError: Element [ 0 -1]
     277            [ 1 0] not in group
     278            sage: H([1,2,0,1])
     279            [1 2]
     280            [0 1]
     281            sage: H(SL2Z([0,-1,1,0]), check=False)
     282            [ 0 -1]
     283            [ 1  0]
     284            sage: H([1,2,0,1]).parent()
     285            Modular Group SL(2,Z)
     286        """
     287        from sage.modular.arithgroup.all import SL2Z
     288        x = SL2Z(x,check=check)
     289        if not check:
     290            return x
     291        else:
     292            y = x.matrix().change_ring(Zmod(self.level()))
     293            if y in self.image_mod_n():
     294                return x
     295            else:
     296                raise TypeError, "Element %s not in group" % x
     297
     298    def to_even_subgroup(self):
     299        r"""
     300        Return the smallest even subgroup of `SL(2, \ZZ)` containing self.
     301
     302        EXAMPLE::
     303
     304            sage: G = Gamma(3)
     305            sage: G.to_even_subgroup()
     306            Congruence subgroup of SL(2,Z) of level 3, preimage of:
     307             Matrix group over Ring of integers modulo 3 with 1 generators:
     308             [[[2, 0], [0, 2]]]
     309        """
     310        if self.is_even():
     311            return self
     312        else:
     313            G = self.image_mod_n()
     314            H = MatrixGroup(G.gens() + [G.matrix_space()(-1)])
     315            return CongruenceSubgroup_constructor(H)
     316
     317    def _repr_(self):
     318        r"""
     319        String representation of self.
     320
     321        EXAMPLE::
     322
     323            sage: sage.modular.arithgroup.congroup_generic.CongruenceSubgroupFromGroup(MatrixGroup([matrix(Zmod(2), 2, [1,1,1,0])]))._repr_()
     324            'Congruence subgroup of SL(2,Z) of level 2, preimage of:\n Matrix group over Ring of integers modulo 2 with 1 generators: \n [[[1, 1], [1, 0]]]'
     325        """
     326        return "Congruence subgroup of SL(2,Z) of level %s, preimage of:\n %s" % (self.level(), self.image_mod_n())
     327
     328    def index(self):
     329        r"""
     330        Return the index of self in the full modular group. This is equal to
     331        the index in `SL(2, \ZZ / N\ZZ)` of the image of this group modulo
     332        `\Gamma(N)`.
     333
     334        EXAMPLE::
     335
     336            sage: sage.modular.arithgroup.congroup_generic.CongruenceSubgroupFromGroup(MatrixGroup([matrix(Zmod(2), 2, [1,1,1,0])])).index()
     337            2
     338        """
     339        return prod([p**(3*e-2)*(p*p-1) for (p,e) in self.level().factor()]) // self.image_mod_n().order()
     340
     341    def image_mod_n(self):
     342        r"""
     343        Return the subgroup of `SL(2, \ZZ / N\ZZ)` of which this is the preimage, where `N` is the level of self.
     344
     345        EXAMPLE::
     346
     347            sage: G = MatrixGroup([matrix(Zmod(2), 2, [1,1,1,0])])
     348            sage: H = sage.modular.arithgroup.congroup_generic.CongruenceSubgroupFromGroup(G); H.image_mod_n()
     349            Matrix group over Ring of integers modulo 2 with 1 generators:
     350             [[[1, 1], [1, 0]]]
     351            sage: H.image_mod_n() == G
     352            True
     353        """
     354        return self.__G
     355
     356class CongruenceSubgroup(CongruenceSubgroupFromGroup):
     357    r"""
     358    One of the "standard" congruence subgroups `\Gamma_0(N)`, `\Gamma_1(N)`,
     359    `\Gamma(N)`, or `\Gamma_H(N)` (for some `H`).
     360
     361    This class is not intended to be instantiated directly. Derived subclasses
     362    must override ``__call__``, ``_repr_``, and ``image_mod_n``.
     363    """
     364
     365    def image_mod_n(self):
     366        r"""
     367        Raise an error: all derived subclasses should override this function.
     368
     369        EXAMPLE:
     370
     371            sage: sage.modular.arithgroup.congroup_generic.CongruenceSubgroup(5).image_mod_n()
     372            Traceback (most recent call last):
     373            ...
     374            NotImplementedError
     375        """
     376        raise NotImplementedError
     377
     378    def __init__(self,*args, **kwds):
     379        r"""
     380        Bypass the init function of the CongruenceSubgroupFromGroup class.
     381
     382        EXAMPLE::
     383
     384            sage: sage.modular.arithgroup.congroup_generic.CongruenceSubgroup(5) # indirect doctest
     385            Generic congruence subgroup of level 5
     386        """
     387        return CongruenceSubgroupBase.__init__(self, *args, **kwds)
     388
     389    def _repr_(self):
     390        """
     391        Return the string representation of self.
     392
     393        NOTE: This function should be overridden by all subclasses.
     394
     395        EXAMPLES::
     396
     397            sage: sage.modular.arithgroup.congroup_generic.CongruenceSubgroup(5)._repr_()
     398            'Generic congruence subgroup of level 5'
     399        """
     400        return "Generic congruence subgroup of level %s" % self.level()
     401
    93402    def modular_symbols(self, sign=0, weight=2, base_ring=QQ):
    94403        """
    95404        Return the space of modular symbols of the specified weight and sign
     
    127436        from sage.modular.abvar.abvar_ambient_jacobian import ModAbVar_ambient_jacobian
    128437        return ModAbVar_ambient_jacobian(self)
    129438
    130     def level(self):
    131         """
    132         Return the level of this congruence subgroup.
    133 
    134         EXAMPLES::
    135 
    136             sage: SL2Z.level()
    137             1
    138             sage: Gamma0(20).level()
    139             20
    140             sage: Gamma1(11).level()
    141             11
    142             sage: GammaH(14, [5]).level()
    143             14
    144         """
    145         return self.__level
    146 
    147439    def _new_group_from_level(self, level):
    148440        r"""
    149441        Return a new group of the same type (Gamma0, Gamma1, or
    150         GammaH) as self of the given level. In the case that self is
    151         of type GammaH, we take the largest H inside
    152         $(Z/\text{level}Z)^\times$ which maps to H, namely its inverse
    153         image under the natural reduction map.
     442        GammaH) as self of the given level. In the case that self is of type
     443        GammaH, we take the largest H inside `(\ZZ/ \text{level}\ZZ)^\times`
     444        which maps to H, namely its inverse image under the natural reduction
     445        map.
    154446
    155447        EXAMPLES::
    156448
     
    166458            ...
    167459            ValueError: one level must divide the other
    168460
    169             sage: G = GammaH(50,[3,37])
    170             sage: G
    171             Congruence Subgroup Gamma_H(50) with H generated by [3, 37]
     461            sage: G = GammaH(50,[7]); G
     462            Congruence Subgroup Gamma_H(50) with H generated by [7]
    172463            sage: G._new_group_from_level(25)
    173             Congruence Subgroup Gamma_H(25) with H generated by [3, 12]
     464            Congruence Subgroup Gamma_H(25) with H generated by [7]
     465            sage: G._new_group_from_level(10)
     466            Congruence Subgroup Gamma0(10)
    174467            sage: G._new_group_from_level(100)
    175             Congruence Subgroup Gamma_H(100) with H generated by [3, 37, 53, 87]
    176             sage: G._new_group_from_level(150)
    177             Congruence Subgroup Gamma_H(150) with H generated by [37, 53, 103, 137]
     468            Congruence Subgroup Gamma_H(100) with H generated by [7, 57]
    178469        """
    179470        from congroup_gamma0 import is_Gamma0
    180471        from congroup_gamma1 import is_Gamma1
     
    199490        else:
    200491            raise NotImplementedError
    201492
     493def _minimize_level(G):
     494    r"""
     495    Utility function. Given a matrix group `G` contained in `SL(2, \ZZ / N\ZZ)`
     496    for some `N`, test whether or not `G` is the preimage of a subgroup of
     497    smaller level, and if so, return that subgroup.
     498
     499    The trivial group is handled specially: instead of returning a group, it
     500    returns an integer `N`, representing the trivial subgroup of `SL(2, \ZZ /
     501    N\ZZ)`.
     502
     503    EXAMPLE::
     504
     505        sage: M = MatrixSpace(Zmod(9), 2, 2)
     506        sage: G = MatrixGroup([M(x) for x in [[1,1,0,1],[1,3,0,1],[1,0,3,1],[4,0,0,7]]]); G
     507        Matrix group over Ring of integers modulo 9 with 4 generators:
     508         [[[1, 1], [0, 1]], [[1, 3], [0, 1]], [[1, 0], [3, 1]], [[4, 0], [0, 7]]]
     509        sage: sage.modular.arithgroup.congroup_generic._minimize_level(G)
     510        Matrix group over Ring of integers modulo 3 with 1 generators:
     511         [[[1, 1], [0, 1]]]
     512
     513        sage: G = MatrixGroup([M(x) for x in [[1,3,0,1],[1,0,3,1],[4,0,0,7]]]); G
     514        Matrix group over Ring of integers modulo 9 with 3 generators:
     515         [[[1, 3], [0, 1]], [[1, 0], [3, 1]], [[4, 0], [0, 7]]]
     516        sage: sage.modular.arithgroup.congroup_generic._minimize_level(G)
     517        3
     518    """
     519    from congroup_gamma import Gamma_constructor as Gamma
     520    Glist = list(G)
     521    N = G.base_ring().characteristic()
     522    i = Gamma(N).index()
     523
     524    for p in N.prime_divisors():
     525        j = Gamma(N // p).index()
     526        k = len([g for g in Glist if g.matrix().change_ring(Zmod(N // p)) == 1])
     527        if k == i // j:
     528            if N // p == 1:
     529                return ZZ(1)
     530            H = MatrixGroup([g.matrix().change_ring(Zmod(N//p)) for g in G.gens()])
     531            return _minimize_level(H)
     532
     533    # now sanitize the generators (remove duplicates and copies of the identity)
     534    new_gens = [x.matrix() for x in G.gens() if x.matrix() != 1]
     535    all([x.set_immutable() for x in new_gens])
     536    new_gens = list(Set(new_gens))
     537    if new_gens == []:
     538        return ZZ(G.base_ring().characteristic())
     539    return MatrixGroup(new_gens)
  • sage/modular/arithgroup/congroup_sl2z.py

    diff --git a/sage/modular/arithgroup/congroup_sl2z.py b/sage/modular/arithgroup/congroup_sl2z.py
    a b  
    9797        r"""
    9898        Create an element of self from x. If check=True (the default), check
    9999        that x really defines a 2x2 integer matrix of det 1.
     100
     101        EXAMPLE::
     102
     103            sage: SL2Z([1,0,0,1])
     104            [1 0]
     105            [0 1]
     106            sage: SL2Z([1, QQ, False], check=False) # don't do this!
     107            [1, Rational Field, False]
    100108        """
    101109        return ArithmeticSubgroupElement(self, x, check=check)
    102110
  • sage/modular/modform/ambient.py

    diff --git a/sage/modular/modform/ambient.py b/sage/modular/modform/ambient.py
    a b  
    5050
    5151::
    5252
    53     sage: m = ModularForms(GammaH(11,[2]), 2); m
    54     Modular Forms space of dimension 2 for Congruence Subgroup Gamma_H(11) with H generated by [2] of weight 2 over Rational Field
     53    sage: m = ModularForms(GammaH(11,[4]), 2); m
     54    Modular Forms space of dimension 2 for Congruence Subgroup Gamma_H(11) with H generated by [4] of weight 2 over Rational Field
    5555    sage: type(m)
    5656    <class 'sage.modular.modform.ambient_g1.ModularFormsAmbient_gH_Q_with_category'>
    5757    sage: m == loads(dumps(m))
     
    620620       
    621621        EXAMPLES::
    622622       
    623             sage: m = ModularForms(GammaH(11,[2]), 2); m
    624             Modular Forms space of dimension 2 for Congruence Subgroup Gamma_H(11) with H generated by [2] of weight 2 over Rational Field
     623            sage: m = ModularForms(GammaH(11,[4]), 2); m
     624            Modular Forms space of dimension 2 for Congruence Subgroup Gamma_H(11) with H generated by [4] of weight 2 over Rational Field
    625625            sage: m._dim_cuspidal()
    626626            1
    627627        """
     
    641641       
    642642        EXAMPLES::
    643643       
    644             sage: m = ModularForms(GammaH(13,[2]), 2); m
    645             Modular Forms space of dimension 1 for Congruence Subgroup Gamma_H(13) with H generated by [2] of weight 2 over Rational Field
     644            sage: m = ModularForms(GammaH(13,[4]), 2); m
     645            Modular Forms space of dimension 3 for Congruence Subgroup Gamma_H(13) with H generated by [4] of weight 2 over Rational Field
    646646            sage: m._dim_eisenstein()
    647             1
     647            3
    648648        """
    649649        try:
    650650            return self.__the_dim_eisenstein
  • sage/modular/modform/ambient_g1.py

    diff --git a/sage/modular/modform/ambient_g1.py b/sage/modular/modform/ambient_g1.py
    a b  
    1313    q^2 - 2*q^3 - q^4 + 2*q^5 + O(q^6)
    1414    ]
    1515   
    16     sage: M = ModularForms(GammaH(50, [27])); M
    17     Modular Forms space of dimension 13 for Congruence Subgroup Gamma_H(50) with H generated by [27] of weight 2 over Rational Field
    18     sage: M.q_expansion_basis(25)
     16    sage: M = ModularForms(GammaH(11, [4])); M
     17    Modular Forms space of dimension 2 for Congruence Subgroup Gamma_H(11) with H generated by [4] of weight 2 over Rational Field
     18    sage: M.q_expansion_basis(8)
    1919    [
    20     q + q^4 - q^6 - 2*q^9 - 3*q^11 - 2*q^14 + q^16 + 5*q^19 + 2*q^21 - q^24 + O(q^25),
    21     q^2 - q^3 - 2*q^7 + q^8 - q^12 + 4*q^13 + 3*q^17 - 2*q^18 - 3*q^22 - 6*q^23 + O(q^25),
    22     1 + O(q^25),
    23     q + 12*q^11 + 8*q^14 + q^16 - 6*q^19 + 19*q^21 + 5*q^24 + O(q^25),
    24     q^2 + 5*q^12 - q^18 + 12*q^22 + O(q^25),
    25     q^3 - 3/2*q^12 + 9/2*q^13 - 1/2*q^17 + q^18 + 8*q^23 + O(q^25),
    26     q^4 + 4*q^14 + q^16 + 8*q^24 + O(q^25),
    27     q^5 + 4*q^15 - 2*q^20 + O(q^25),
    28     q^6 - q^14 + 3*q^16 + q^24 + O(q^25),
    29     q^7 + 1/2*q^12 - 1/2*q^13 + 5/2*q^17 + q^18 - q^23 + O(q^25),
    30     q^8 + q^12 + 2*q^18 + O(q^25),
    31     q^9 - q^16 + 2*q^19 + q^21 - q^24 + O(q^25),
    32     q^10 + 3*q^20 + O(q^25)
     20    q - 2*q^2 - q^3 + 2*q^4 + q^5 + 2*q^6 - 2*q^7 + O(q^8),
     21    1 + 12/5*q + 36/5*q^2 + 48/5*q^3 + 84/5*q^4 + 72/5*q^5 + 144/5*q^6 + 96/5*q^7 + O(q^8)
    3322    ]
    34     sage: M.q_integral_basis(25)
    35     [
    36     1 + O(q^25),
    37     q - 4*q^14 + q^16 + 6*q^19 + 7*q^21 - 7*q^24 + O(q^25),
    38     q^2 + 5*q^13 + 5*q^17 - q^18 + 2*q^22 + O(q^25),
    39     q^3 + 3*q^13 - 2*q^17 + q^18 + 3*q^22 + 8*q^23 + O(q^25),
    40     q^4 + 4*q^14 + q^16 + 8*q^24 + O(q^25),
    41     q^5 + 4*q^15 - 2*q^20 + O(q^25),
    42     q^6 - q^14 + 3*q^16 + q^24 + O(q^25),
    43     q^7 + 3*q^17 + q^18 - q^22 - q^23 + O(q^25),
    44     q^8 + q^13 + q^17 + 2*q^18 - 2*q^22 + O(q^25),
    45     q^9 - q^16 + 2*q^19 + q^21 - q^24 + O(q^25),
    46     q^10 + 3*q^20 + O(q^25),
    47     q^11 + q^14 - q^19 + q^21 + q^24 + O(q^25),
    48     q^12 - q^13 - q^17 + 2*q^22 + O(q^25)
    49     ]
     23
    5024   
    5125TESTS::
    5226
  • sage/modular/modsym/ambient.py

    diff --git a/sage/modular/modsym/ambient.py b/sage/modular/modsym/ambient.py
    a b  
    33753375       
    33763376            sage: M = ModularSymbols(GammaH(15,[7]),6)
    33773377            sage: M.modular_symbols_of_level(5)
    3378             Modular Symbols space of dimension 4 for Congruence Subgroup Gamma_H(5) with H generated by [2] of weight 6 with sign 0 and over Rational Field
     3378            Modular Symbols space of dimension 4 for Gamma_0(5) of weight 6 with sign 0 over Rational Field
    33793379            sage: M.modular_symbols_of_level(30)
    33803380            Traceback (most recent call last):
    33813381            ...
  • sage/modular/modsym/boundary.py

    diff --git a/sage/modular/modsym/boundary.py b/sage/modular/modsym/boundary.py
    a b  
    394394       
    395395        EXAMPLES::
    396396       
    397             sage: ModularSymbols(GammaH(14,[3]), 2).boundary_space().group()
    398             Congruence Subgroup Gamma_H(14) with H generated by [3]
     397            sage: ModularSymbols(GammaH(14,[9]), 2).boundary_space().group()
     398            Congruence Subgroup Gamma_H(14) with H generated by [9]
    399399        """
    400400        return self.__group
    401401
  • sage/modular/modsym/ghlist.py

    diff --git a/sage/modular/modsym/ghlist.py b/sage/modular/modsym/ghlist.py
    a b  
    9595
    9696        EXAMPLE::
    9797
    98             sage: L = sage.modular.modsym.ghlist.GHlist(GammaH(3,[])); L.__repr__()
    99             'List of coset representatives for Congruence Subgroup Gamma_H(3) with H generated by []'
     98            sage: L = sage.modular.modsym.ghlist.GHlist(GammaH(11,[4])); L.__repr__()
     99            'List of coset representatives for Congruence Subgroup Gamma_H(11) with H generated by [4]'
    100100        """
    101101        return "List of coset representatives for %s"%self.__group
    102102       
  • sage/modular/modsym/modsym.py

    diff --git a/sage/modular/modsym/modsym.py b/sage/modular/modsym/modsym.py
    a b  
    124124        # TODO -- implement minimize_base_ring over finite fields
    125125            eps = group
    126126        G = eps.parent()
    127         group = (eps, G)
     127        if eps.is_trivial():
     128            group = arithgroup.Gamma0(eps.modulus())
     129        else:
     130            group = (eps, G)
    128131        if base_ring is None: base_ring = eps.base_ring()
    129132
    130133    if base_ring is None: base_ring = rational_field.RationalField()