source: sage/modular/modform/ambient.py @ 6088:c68c474f3434

Revision 6088:c68c474f3434, 22.2 KB checked in by William Stein <wstein@…>, 6 years ago (diff)

Finish improving coverage of documentation for modular forms -- ambient.py

Line 
1r"""
2Ambient Spaces of Modular Forms.
3
4EXAMPLES:
5
6We compute a basis for the ambient space $M_2(\Gamma_1(25),\chi)$,
7where $\chi$ is quadratic.
8
9    sage: chi = DirichletGroup(25,QQ).0; chi
10    [-1]
11    sage: n = ModularForms(chi,2); n
12    Modular Forms space of dimension 6, character [-1] and weight 2 over Rational Field
13    sage: type(n)
14    <class 'sage.modular.modform.ambient_eps.ModularFormsAmbient_eps'>
15
16Compute a basis:
17    sage: n.basis()
18    [
19    1 + O(q^6),
20    q + O(q^6),
21    q^2 + O(q^6),
22    q^3 + O(q^6),
23    q^4 + O(q^6),
24    q^5 + O(q^6)
25    ]
26
27Compute the same basis but to higher precision:
28    sage: n.set_precision(20)
29    sage: n.basis()
30    [
31    1 + 10*q^10 + 20*q^15 + O(q^20),
32    q + 5*q^6 + q^9 + 12*q^11 - 3*q^14 + 17*q^16 + 8*q^19 + O(q^20),
33    q^2 + 4*q^7 - q^8 + 8*q^12 + 2*q^13 + 10*q^17 - 5*q^18 + O(q^20),
34    q^3 + q^7 + 3*q^8 - q^12 + 5*q^13 + 3*q^17 + 6*q^18 + O(q^20),
35    q^4 - q^6 + 2*q^9 + 3*q^14 - 2*q^16 + 4*q^19 + O(q^20),
36    q^5 + q^10 + 2*q^15 + O(q^20)
37    ]
38
39TESTS:
40    sage: m = ModularForms(Gamma1(20),2,GF(7))
41    sage: loads(dumps(m)) == m
42    True
43
44    sage: m = ModularForms(GammaH(11,[2]), 2); m
45    Modular Forms space of dimension 2 for Congruence Subgroup Gamma_H(11) with H generated by [2] of weight 2 over Rational Field
46    sage: type(m)
47    <class 'sage.modular.modform.ambient.ModularFormsAmbient'>
48   
49"""
50
51#########################################################################
52#       Copyright (C) 2006 William Stein <wstein@gmail.com>
53#
54#  Distributed under the terms of the GNU General Public License (GPL)
55#
56#                  http://www.gnu.org/licenses/
57#########################################################################
58
59# system packages
60import math
61import weakref
62
63# SAGE packages
64import sage.rings.all as rings
65import sage.modular.congroup as congroup
66import sage.misc.db as db
67import sage.modular.dims as dims
68import sage.modular.dirichlet as dirichlet
69import sage.modular.hecke.all as hecke
70import sage.misc.misc as misc
71import sage.modular.modsym.all as modsym
72import sage.modules.free_module as free_module
73import sage.modules.free_module_element as free_module_element
74import sage.rings.all as rings
75
76from sage.structure.sequence import Sequence
77
78from sage.misc.all import latex
79
80import cuspidal_submodule
81import defaults
82import eisenstein_submodule
83import eis_series
84import space
85import submodule
86
87
88class ModularFormsAmbient(space.ModularFormsSpace,
89                          hecke.AmbientHeckeModule):
90    """
91    An ambient space of modular forms.
92    """   
93    def __init__(self, group, weight, base_ring, character=None):
94        """
95        Create an ambient space of modular forms.
96       
97        EXAMPLES:
98            sage: m = ModularForms(Gamma1(20),20); m
99            Modular Forms space of dimension 238 for Congruence Subgroup Gamma1(20) of weight 20 over Rational Field
100            sage: m.is_ambient()
101            True
102        """
103        if not isinstance(group, congroup.CongruenceSubgroup):
104            raise TypeError, 'group (=%s) must be a congruence subgroup'%group
105        weight = rings.Integer(weight)
106
107        if character is None and isinstance(group, congroup.Gamma0):
108            character = dirichlet.TrivialCharacter(group.level(), base_ring)
109           
110        space.ModularFormsSpace.__init__(self, group, weight, character, base_ring)
111        hecke.AmbientHeckeModule.__init__(self, base_ring, self.dimension(), group.level(), weight)
112
113    def _repr_(self):
114        """
115        Return string representation of self.
116
117        EXAMPLES:
118            sage: m = ModularForms(Gamma1(20),100); m._repr_()
119            'Modular Forms space of dimension 1198 for Congruence Subgroup Gamma1(20) of weight 100 over Rational Field'
120
121        The output of _repr_ is not affected by renaming the space:
122            sage: m.rename('A big modform space')
123            sage: m
124            A big modform space
125            sage: m._repr_()
126            'Modular Forms space of dimension 1198 for Congruence Subgroup Gamma1(20) of weight 100 over Rational Field'
127        """
128        return "Modular Forms space of dimension %s for %s of weight %s over %s"%(
129                self.dimension(), self.group(), self.weight(), self.base_ring())
130
131    def _submodule_class(self):
132        """
133        Return the Python class of submodules of this modular forms space.
134
135        EXAMPLES:
136            sage: m = ModularForms(Gamma0(20),2)
137            sage: m._submodule_class()
138            <class 'sage.modular.modform.submodule.ModularFormsSubmodule'>
139        """
140        return submodule.ModularFormsSubmodule
141
142    def change_ring(self, base_ring):
143        """
144        Change the base ring of this space of modular forms.
145
146        INPUT:
147            R -- ring
148           
149        EXAMPLES:
150            sage: M = ModularForms(Gamma0(37),2)
151            sage: M.basis()
152            [
153            q + q^3 - 2*q^4 + O(q^6),
154            q^2 + 2*q^3 - 2*q^4 + q^5 + O(q^6),
155            1 + 2/3*q + 2*q^2 + 8/3*q^3 + 14/3*q^4 + 4*q^5 + O(q^6)
156            ]
157
158        The basis after changing the base ring is the reduction modulo
159        $3$ of an integral basis.
160            sage: M3 = M.change_ring(GF(3))
161            sage: M3.basis()
162            [
163            1 + q^3 + q^4 + 2*q^5 + O(q^6),
164            q + q^3 + q^4 + O(q^6),
165            q^2 + 2*q^3 + q^4 + q^5 + O(q^6)
166            ]
167        """
168        import constructor
169        M = constructor.ModularForms(self.group(), self.weight(), base_ring, prec=self.prec())
170        return M
171
172    def dimension(self):
173        """
174        Return the dimension of this ambient space of modular forms, computed
175        using a dimension formula (so it should be reasonably fast).
176
177        EXAMPLES:
178            sage: m = ModularForms(Gamma1(20),20)
179            sage: m.dimension()
180            238
181        """
182        try:
183            return self.__dimension
184        except AttributeError:
185            self.__dimension = self._dim_eisenstein() + self._dim_cuspidal()
186            return self.__dimension
187
188    def rank(self):
189        r"""
190        This is a synonym for \code{self.dimension()}.
191
192        EXAMPLES:
193            sage: m = ModularForms(Gamma0(20),4)
194            sage: m.rank()
195            12
196            sage: m.dimension()
197            12
198        """
199        return self.dimension()
200
201    def ambient_space(self):
202        """
203        Return the ambient space that contains this ambient space.  This is,
204        of course, just this space again.
205
206        EXAMPLES:
207            sage: m = ModularForms(Gamma0(3),30)
208            sage: m.ambient_space() is m
209            True
210        """
211        return self
212   
213    def is_ambient(self):
214        """
215        Return True if this an ambient space of modular forms.
216
217        This is an ambient space, so this function always returns True.
218
219        EXAMPLES:
220            sage: ModularForms(11).is_ambient()
221            True
222            sage: CuspForms(11).is_ambient()
223            False
224        """
225        return True
226
227    def modular_symbols(self, sign=0):
228        """
229        Return the corresponding space of modular symbols with the given sign.
230       
231        EXAMPLES:
232            sage: S = ModularForms(11,2)
233            sage: S.modular_symbols()
234            Modular Symbols space of dimension 3 for Gamma_0(11) of weight 2 with sign 0 over Rational Field
235            sage: S.modular_symbols(sign=1)
236            Modular Symbols space of dimension 2 for Gamma_0(11) of weight 2 with sign 1 over Rational Field
237            sage: S.modular_symbols(sign=-1)
238            Modular Symbols space of dimension 1 for Gamma_0(11) of weight 2 with sign -1 over Rational Field
239
240            sage: ModularForms(1,12).modular_symbols()
241            Modular Symbols space of dimension 3 for Gamma_0(1) of weight 12 with sign 0 over Rational Field
242        """
243        sign = rings.Integer(sign)
244        try:
245            return self.__modular_symbols[sign]
246        except AttributeError:
247            self.__modular_symbols = {}
248        except KeyError:
249            pass
250        M = modsym.ModularSymbols(group = self.group(),
251                                  weight = self.weight(),
252                                  sign = sign,
253                                  base_ring = self.base_ring())
254        self.__modular_symbols[sign] = M
255        return M
256   
257    def module(self):
258        """
259        Return the underlying free module corresponding to this space
260        of modular forms.  This is a free module (viewed as a tuple
261        space) of the same dimension as this space over the same base
262        ring.
263
264        EXAMPLES:
265            sage: m = ModularForms(Gamma1(13),10)
266            sage: m.free_module()
267            Vector space of dimension 69 over Rational Field
268            sage: ModularForms(Gamma1(13),4, GF(49,'b')).free_module()
269            Vector space of dimension 27 over Finite Field in b of size 7^2
270        """
271        if hasattr(self, "__module"): return self.__module
272        self.__module = free_module.VectorSpace(self.base_ring(),
273                                                 self.dimension())
274        return self.__module
275
276    def prec(self, new_prec=None):
277        """
278        Set or get default initial precision for printing modular forms.
279
280        INPUT:
281            new_prec -- positive integer (default: None)
282
283        OUTPUT:
284            if new_prec is None, returns the current precision.
285
286        EXAMPLES:
287            sage: M = ModularForms(1,12, prec=3)
288            sage: M.prec()
289            3
290
291            sage: M.basis()
292            [
293            q - 24*q^2 + O(q^3),
294            1 + 65520/691*q + 134250480/691*q^2 + O(q^3)
295            ]
296
297            sage: M.prec(5)
298            5
299            sage: M.basis()
300            [
301            q - 24*q^2 + 252*q^3 - 1472*q^4 + O(q^5),
302            1 + 65520/691*q + 134250480/691*q^2 + 11606736960/691*q^3 + 274945048560/691*q^4 + O(q^5)
303            ]
304        """
305        if new_prec:
306            self.__prec = new_prec
307        try:
308            return self.__prec
309        except AttributeError:
310            self.__prec = defaults.DEFAULT_PRECISION
311        return self.__prec
312
313    def set_precision(self, n):
314        """
315        Set the default precision for displaying elements of this space.
316
317        EXAMPLES:
318            sage: m = ModularForms(Gamma1(5),2)
319            sage: m.set_precision(10)
320            sage: m.basis()
321            [
322            1 + 60*q^3 - 120*q^4 + 240*q^5 - 300*q^6 + 300*q^7 - 180*q^9 + O(q^10),
323            q + 6*q^3 - 9*q^4 + 27*q^5 - 28*q^6 + 30*q^7 - 11*q^9 + O(q^10),
324            q^2 - 4*q^3 + 12*q^4 - 22*q^5 + 30*q^6 - 24*q^7 + 5*q^8 + 18*q^9 + O(q^10)
325            ]
326            sage: m.set_precision(5)
327            sage: m.basis()
328            [
329            1 + 60*q^3 - 120*q^4 + O(q^5),
330            q + 6*q^3 - 9*q^4 + O(q^5),
331            q^2 - 4*q^3 + 12*q^4 + O(q^5)
332            ]
333        """
334        if n < 0:
335            raise ValueError, "n (=%s) must be >= 0"%n
336        self.__prec = rings.Integer(n)
337
338    ####################################################################
339    # Computation of Special Submodules                               
340    ####################################################################
341    def cuspidal_submodule(self):
342        """
343        Return the cuspidal submodule of this ambient module.
344       
345        EXAMPLES:
346            sage: ModularForms(Gamma1(13)).cuspidal_submodule()
347            Cuspidal subspace of dimension 2 of Modular Forms space of dimension 13 for
348            Congruence Subgroup Gamma1(13) of weight 2 over Rational Field
349        """
350        try:
351            return self.__cuspidal_submodule
352        except AttributeError:
353            self.__cuspidal_submodule = cuspidal_submodule.CuspidalSubmodule(self)
354        return self.__cuspidal_submodule
355
356    def eisenstein_submodule(self):
357        """
358        Return the Eisenstein submodule of this ambient module.
359
360        EXAMPLES:
361            sage: m = ModularForms(Gamma1(13),2); m
362            Modular Forms space of dimension 13 for Congruence Subgroup Gamma1(13) of weight 2 over Rational Field
363            sage: m.eisenstein_submodule()
364            Eisenstein subspace of dimension 11 of Modular Forms space of dimension 13 for Congruence Subgroup Gamma1(13) of weight 2 over Rational Field       
365        """
366        try:
367            return self.__eisenstein_submodule
368        except AttributeError:
369            self.__eisenstein_submodule = eisenstein_submodule.EisensteinSubmodule(self)
370        return self.__eisenstein_submodule
371
372    def new_submodule(self, p=None):
373        """
374        Return the new or $p$-new submodule of this ambient module.
375
376        INPUT:
377            p -- (default: None), if specified return only the $p$-new submodule.
378
379        EXAMPLES:
380            sage: m = ModularForms(Gamma0(33),2); m
381            Modular Forms space of dimension 6 for Congruence Subgroup Gamma0(33) of weight 2 over Rational Field
382            sage: m.new_submodule()
383            Modular Forms subspace of dimension 1 of Modular Forms space of dimension 6 for Congruence Subgroup Gamma0(33) of weight 2 over Rational Field
384
385        Unfortunaely (TODO) -- $p$-new submodules aren't yet implemented:
386            sage: m.new_submodule(3)
387            Traceback (most recent call last):
388            ...
389            NotImplementedError
390            sage: m.new_submodule(11)
391            Traceback (most recent call last):
392            ...
393            NotImplementedError
394        """
395        try:
396            return self.__new_submodule[p]
397        except AttributeError:
398            self.__new_submodule = {}
399        except KeyError:
400            pass
401        if not p is None:
402            p = rings.Integer(p)
403            if not p.is_prime():
404                raise ValueError, "p (=%s) must be a prime or None."%p
405       
406        if p is None:
407            M = self._full_new_submodule()
408            self.__new_submodule[None] = M
409            return M
410        else:
411            M = self._new_submodule(p)
412            self.__new_submodule[p] = M
413            return M
414           
415           
416
417    def _full_new_submodule(self):
418        """
419        Return the cuspidal new submodule plus the Eisenstein new submodule.
420
421        EXAMPLES:
422            sage: m = ModularForms(Gamma0(54),2); m
423            Modular Forms space of dimension 15 for Congruence Subgroup Gamma0(54) of weight 2 over Rational Field
424            sage: m._full_new_submodule()
425            Modular Forms subspace of dimension 2 of Modular Forms space of dimension 15 for Congruence Subgroup Gamma0(54) of weight 2 over Rational Field
426        """
427        s = self._dim_new_cuspidal()
428        e = self._dim_new_eisenstein()
429        d = self._dim_cuspidal()
430        B = range(s) + range(d, d+e)
431        V = self.module()
432        W = V.submodule([V.gen(i) for i in B])
433        return submodule.ModularFormsSubmodule(self, W)
434
435    def _new_submodule(self, p):
436        """
437        Return the $p$-new submodule of self.
438
439        NOTE: This most be defined in the derived class.
440
441        EXAMPLES:
442        Unfortunaely this is not implemented yet.
443            sage: m = ModularForms(Gamma0(100),2); m
444            Modular Forms space of dimension 24 for Congruence Subgroup Gamma0(100) of weight 2 over Rational Field
445            sage: m._new_submodule(2)
446            Traceback (most recent call last):
447            ...
448            NotImplementedError
449        """
450        raise NotImplementedError
451           
452    def _q_expansion(self, element, prec):
453        """
454        Return the q-expansion of a particular element of this space of modular forms,
455        where telement should be a vector of list (not a ModularFormElement).
456
457        INPUT:
458            element -- vector, list or tuple
459            prec -- desired precision of q-expansion
460
461        EXAMPLES:
462            sage: m = ModularForms(Gamma0(23),2); m
463            Modular Forms space of dimension 3 for Congruence Subgroup Gamma0(23) of weight 2 over Rational Field
464            sage: m.basis()
465            [
466            q - q^3 - q^4 + O(q^6),
467            q^2 - 2*q^3 - q^4 + 2*q^5 + O(q^6),
468            1 + 12/11*q + 36/11*q^2 + 48/11*q^3 + 84/11*q^4 + 72/11*q^5 + O(q^6)
469            ]
470            sage: m._q_expansion([1,2,0], 5)
471            q + 2*q^2 - 5*q^3 - 3*q^4 + O(q^5)
472        """
473        B = self.q_expansion_basis(prec)
474        f = self._q_expansion_zero()
475        for i in range(len(element)):
476            if element[i]:
477                f += element[i] * B[i]
478        return f
479
480
481    ####################################################################
482    # Computations of Dimensions                                     
483    ####################################################################
484    def _dim_cuspidal(self):
485        """
486        Return the dimension of the cuspidal subspace of this ambient modular forms
487        space, computed using a dimension formula.
488
489        EXAMPLES:
490            sage: m = ModularForms(GammaH(11,[2]), 2); m
491            Modular Forms space of dimension 2 for Congruence Subgroup Gamma_H(11) with H generated by [2] of weight 2 over Rational Field
492            sage: m._dim_cuspidal()
493            1
494        """
495        try:
496            return self.__the_dim_cuspidal
497        except AttributeError:
498            self.__the_dim_cuspidal = dims.dimension_cusp_forms(self.group(), self.weight())
499        return self.__the_dim_cuspidal
500
501    def _dim_eisenstein(self):
502        """
503        Return the dimension of the Eisenstein subspace of this modular symbols space,
504        computed using a dimension formula.
505       
506        EXAMPLES:
507            sage: m = ModularForms(GammaH(13,[2]), 2); m
508            Modular Forms space of dimension 1 for Congruence Subgroup Gamma_H(13) with H generated by [2] of weight 2 over Rational Field
509            sage: m._dim_eisenstein()
510            1
511        """
512        try:
513            return self.__the_dim_eisenstein
514        except AttributeError:
515            if self.weight() == 1:
516                self.__the_dim_eisenstein = len(self.eisenstein_params())
517            else:
518                self.__the_dim_eisenstein = dims.dimension_eis(self.group(), self.weight())
519        return self.__the_dim_eisenstein
520   
521    def _dim_new_cuspidal(self):
522        """
523        Return the dimension of the new cuspidal subspace, computed using dimension formulas.
524       
525        EXAMPLES:
526            sage: m = ModularForms(GammaH(11,[2]), 2); m._dim_new_cuspidal()
527            1
528        """
529        try:
530            return self.__the_dim_new_cuspidal
531        except AttributeError:
532            self.__the_dim_new_cuspidal = dims.dimension_new_cusp_forms_group(
533                self.group(), self.weight())
534        return self.__the_dim_new_cuspidal
535   
536    def _dim_new_eisenstein(self):
537        """
538        Compute the dimension of the Eisenstein submodule.
539       
540        EXAMPLES:
541            sage: m = ModularForms(Gamma0(11), 4)
542            sage: m._dim_new_eisenstein()
543            0
544            sage: m = ModularForms(Gamma0(11), 2)
545            sage: m._dim_new_eisenstein()
546            1           
547        """
548        try:
549            return self.__the_dim_new_eisenstein
550        except AttributeError:
551            if isinstance(self.group(), congroup.Gamma0) and self.weight() == 2:
552                if rings.is_prime(self.level()):
553                    d = 1
554                else:
555                    d = 0
556            else:
557                E = self.eisenstein_series()           
558                d = len([g for g in E if g.new_level() == self.level()])
559            self.__the_dim_new_eisenstein = d
560        return self.__the_dim_new_eisenstein
561
562
563    ####################################################################
564    # Computations of all Eisenstein series in self
565    ####################################################################
566
567    def eisenstein_params(self):
568        """
569        Return parameters that define all Eisenstein series in self.
570
571        OUTPUT:
572            -- an immutable Sequenc
573       
574        EXAMPLES:
575            sage: m = ModularForms(Gamma0(22), 2)
576            sage: v = m.eisenstein_params(); v
577            [([1, 1], [1, 1], 2), ([1, 1], [1, 1], 11), ([1, 1], [1, 1], 22)]
578            sage: type(v)
579            <class 'sage.structure.sequence.Sequence'>
580        """
581        try:
582            return self.__eisenstein_params
583        except AttributeError:
584            eps = self.character()
585            if eps == None:
586                if isinstance(self.group(), congroup.Gamma1):
587                    eps = self.level()
588                else:
589                    raise NotImplementedError
590            params = eis_series.compute_eisenstein_params(eps, self.weight())
591            self.__eisenstein_params = Sequence(params, immutable=True)
592        return self.__eisenstein_params
593       
594    def eisenstein_series(self):
595        """
596        Return all Eisenstein series associated to this space.
597       
598            sage: ModularForms(27,2).eisenstein_series()
599            [
600            q^3 + O(q^6),
601            q - 3*q^2 + 7*q^4 - 6*q^5 + O(q^6),
602            1/12 + q + 3*q^2 + q^3 + 7*q^4 + 6*q^5 + O(q^6),
603            1/3 + q + 3*q^2 + 4*q^3 + 7*q^4 + 6*q^5 + O(q^6),
604            13/12 + q + 3*q^2 + 4*q^3 + 7*q^4 + 6*q^5 + O(q^6)
605            ]
606           
607            sage: ModularForms(Gamma1(5),3).eisenstein_series()
608            [
609            -1/5*zeta4 - 2/5 + q + (4*zeta4 + 1)*q^2 + (-9*zeta4 + 1)*q^3 + (4*zeta4 - 15)*q^4 + q^5 + O(q^6),
610            q + (zeta4 + 4)*q^2 + (-zeta4 + 9)*q^3 + (4*zeta4 + 15)*q^4 + 25*q^5 + O(q^6),
611            1/5*zeta4 - 2/5 + q + (-4*zeta4 + 1)*q^2 + (9*zeta4 + 1)*q^3 + (-4*zeta4 - 15)*q^4 + q^5 + O(q^6),
612            q + (-zeta4 + 4)*q^2 + (zeta4 + 9)*q^3 + (-4*zeta4 + 15)*q^4 + 25*q^5 + O(q^6)
613            ]
614
615            sage: eps = DirichletGroup(13).0^2
616            sage: ModularForms(eps,2).eisenstein_series()
617            [
618            -7/13*zeta6 - 11/13 + q + (2*zeta6 + 1)*q^2 + (-3*zeta6 + 1)*q^3 + (6*zeta6 - 3)*q^4 + -4*q^5 + O(q^6),
619            q + (zeta6 + 2)*q^2 + (-zeta6 + 3)*q^3 + (3*zeta6 + 3)*q^4 + 4*q^5 + O(q^6)
620            ]
621        """
622        return self.eisenstein_submodule().eisenstein_series()
623
624    def _compute_q_expansion_basis(self, prec):
625        """
626        EXAMPLES:
627            sage: m = ModularForms(11,4)
628            sage: m._compute_q_expansion_basis(5)
629            [q + 3*q^3 - 6*q^4 + O(q^5), q^2 - 4*q^3 + 2*q^4 + O(q^5), 1 + O(q^5), q + 9*q^2 + 28*q^3 + 73*q^4 + O(q^5)]
630        """
631        S = self.cuspidal_submodule()
632        E = self.eisenstein_submodule()
633        B_S = S._compute_q_expansion_basis(prec)
634        B_E = E._compute_q_expansion_basis(prec)
635        return B_S + B_E
Note: See TracBrowser for help on using the repository browser.