Ticket #11601: trac_11601-congroups.patch

File trac_11601-congroups.patch, 46.9 KB (added by David Loeffler, 11 years ago)

Patch against 4.7.1.alpha4 + dependencies as in ticket description

  • 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 98f6d126cc94cba4237f2045c00a58bb7b90513c
    # Parent  a3a935fa388c7c17b6f7ce606395eacf71547e01
    #11601: general congruence subgroups of modular group
    
    diff -r a3a935fa388c -r 98f6d126cc94 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 -r a3a935fa388c -r 98f6d126cc94 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 -r a3a935fa388c -r 98f6d126cc94 sage/modular/abvar/constructor.py
    a b  
    129129   
    130130    EXAMPLES::
    131131   
    132         sage: JH(389,[2])
    133         Abelian variety JH(389,[2]) of dimension 32
     132        sage: JH(389,[16])
     133        Abelian variety JH(389,[16]) of dimension 64
    134134    """
    135135    key = 'JH(%s,%s)'%(N,H)
    136136    try:
  • sage/modular/all.py

    diff -r a3a935fa388c -r 98f6d126cc94 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, CongruenceSubgroup, ArithmeticSubgroup_Permutation)
    1616
    1717from cusps import Cusp, Cusps
    1818
  • sage/modular/arithgroup/all.py

    diff -r a3a935fa388c -r 98f6d126cc94 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 -r a3a935fa388c -r 98f6d126cc94 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 -r a3a935fa388c -r 98f6d126cc94 sage/modular/arithgroup/arithgroup_perm.py
    a b  
    12511251        """
    12521252        return arith.lcm(self.cusp_widths())
    12531253
     1254    def congruence_closure(self):
     1255        r"""
     1256        Returns the smallest congruence subgroup containing self. If self is
     1257        congruence, this is just self, but represented as a congruence subgroup
     1258        data type. If self is not congruence, then it may be larger.
     1259
     1260        In practice, we use the following criterion: let `m` be the generalised
     1261        level of self. If this subgroup is even, let `n = m`, else let `n =
     1262        2m`. Then any congruence subgroup containing self contains `\Gamma(n)`
     1263        (a generalisation of Wohlfahrt's theorem due to Kiming, Verrill and
     1264        Schuett). So we compute the image of self modulo `n` and return the
     1265        preimage of that.
     1266       
     1267        EXAMPLE::
     1268       
     1269            sage: Gamma1(3).as_permutation_group().congruence_closure()
     1270            Congruence subgroup of SL(2,Z) of level 3, preimage of:
     1271             Matrix group over Ring of integers modulo 3 with 2 generators:
     1272              [[[1, 2], [0, 1]], [[1, 1], [0, 1]]]
     1273            sage: sage.modular.arithgroup.arithgroup_perm.HsuExample10().congruence_closure() # long time (40 sec)
     1274            Modular Group SL(2,Z)
     1275        """
     1276        if self.is_even():
     1277            N = self.generalised_level()
     1278        else:
     1279            N = 2*self.generalised_level()
     1280
     1281        from congroup_generic import CongruenceSubgroup_constructor as CS
     1282        return CS(N, [x.matrix() for x in self.gens()])
     1283
    12541284class OddArithmeticSubgroup_Permutation(ArithmeticSubgroup_Permutation_class):
    12551285    def __init__(self, S2, S3, L, R, canonical_labels=False):
    12561286        r"""
  • sage/modular/arithgroup/congroup_gamma.py

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

    diff -r a3a935fa388c -r 98f6d126cc94 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 -r a3a935fa388c -r 98f6d126cc94 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))
     
    626626       
    627627        EXAMPLES::
    628628       
    629             sage: m = ModularForms(GammaH(11,[2]), 2); m
    630             Modular Forms space of dimension 2 for Congruence Subgroup Gamma_H(11) with H generated by [2] of weight 2 over Rational Field
     629            sage: m = ModularForms(GammaH(11,[4]), 2); m
     630            Modular Forms space of dimension 2 for Congruence Subgroup Gamma_H(11) with H generated by [4] of weight 2 over Rational Field
    631631            sage: m._dim_cuspidal()
    632632            1
    633633        """
     
    647647       
    648648        EXAMPLES::
    649649       
    650             sage: m = ModularForms(GammaH(13,[2]), 2); m
    651             Modular Forms space of dimension 1 for Congruence Subgroup Gamma_H(13) with H generated by [2] of weight 2 over Rational Field
     650            sage: m = ModularForms(GammaH(13,[4]), 2); m
     651            Modular Forms space of dimension 3 for Congruence Subgroup Gamma_H(13) with H generated by [4] of weight 2 over Rational Field
    652652            sage: m._dim_eisenstein()
    653             1
     653            3
    654654        """
    655655        try:
    656656            return self.__the_dim_eisenstein
  • sage/modular/modform/ambient_g1.py

    diff -r a3a935fa388c -r 98f6d126cc94 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 -r a3a935fa388c -r 98f6d126cc94 sage/modular/modsym/ambient.py
    a b  
    33763376       
    33773377            sage: M = ModularSymbols(GammaH(15,[7]),6)
    33783378            sage: M.modular_symbols_of_level(5)
    3379             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
     3379            Modular Symbols space of dimension 4 for Gamma_0(5) of weight 6 with sign 0 over Rational Field
    33803380            sage: M.modular_symbols_of_level(30)
    33813381            Traceback (most recent call last):
    33823382            ...
  • sage/modular/modsym/boundary.py

    diff -r a3a935fa388c -r 98f6d126cc94 sage/modular/modsym/boundary.py
    a b  
    398398       
    399399        EXAMPLES::
    400400       
    401             sage: ModularSymbols(GammaH(14,[3]), 2).boundary_space().group()
    402             Congruence Subgroup Gamma_H(14) with H generated by [3]
     401            sage: ModularSymbols(GammaH(14,[9]), 2).boundary_space().group()
     402            Congruence Subgroup Gamma_H(14) with H generated by [9]
    403403        """
    404404        return self.__group
    405405
  • sage/modular/modsym/ghlist.py

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

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