Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/modular/hecke/element.py
4056 views
1
"""
2
Elements of Hecke modules
3
4
AUTHORS:
5
6
- William Stein
7
"""
8
9
#*****************************************************************************
10
# Sage: System for Algebra and Geometry Experimentation
11
#
12
# Copyright (C) 2005 William Stein <[email protected]>
13
#
14
# Distributed under the terms of the GNU General Public License (GPL)
15
#
16
# This code is distributed in the hope that it will be useful,
17
# but WITHOUT ANY WARRANTY; without even the implied warranty of
18
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
# General Public License for more details.
20
#
21
# The full text of the GPL is available at:
22
#
23
# http://www.gnu.org/licenses/
24
#*****************************************************************************
25
26
import sage.modules.module_element
27
28
def is_HeckeModuleElement(x):
29
"""
30
Return True if x is a Hecke module element, i.e., of type HeckeModuleElement.
31
32
EXAMPLES::
33
34
sage: sage.modular.hecke.all.is_HeckeModuleElement(0)
35
False
36
sage: sage.modular.hecke.all.is_HeckeModuleElement(BrandtModule(37)([1,2,3]))
37
True
38
"""
39
return isinstance(x, HeckeModuleElement)
40
41
class HeckeModuleElement(sage.modules.module_element.ModuleElement):
42
"""
43
Element of a Hecke module.
44
"""
45
def __init__(self, parent, x=None):
46
"""
47
INPUT:
48
- ``parent`` - a Hecke module
49
- ``x`` - element of the free module associated to parent
50
51
EXAMPLES::
52
53
sage: v = sage.modular.hecke.all.HeckeModuleElement(BrandtModule(37), vector(QQ,[1,2,3])); v
54
(1, 2, 3)
55
sage: type(v)
56
<class 'sage.modular.hecke.element.HeckeModuleElement'>
57
58
TESTS::
59
60
sage: v = ModularSymbols(37).0
61
sage: loads(dumps(v))
62
(1,0)
63
sage: loads(dumps(v)) == v
64
True
65
"""
66
sage.modules.module_element.ModuleElement.__init__(self, parent)
67
if not x is None:
68
self.__element = x
69
70
def _repr_(self):
71
"""
72
Return string representation of this Hecke module element.
73
The default representation is just the representation of the
74
underlying vector.
75
76
EXAMPLES::
77
78
sage: BrandtModule(37)([0,1,-1])._repr_()
79
'(0, 1, -1)'
80
"""
81
return self.element()._repr_()
82
83
def _compute_element(self):
84
"""
85
Use internally to compute vector underlying this element.
86
87
EXAMPLES::
88
89
sage: f = EllipticCurve('11a').modular_form()
90
sage: hasattr(f, '_HeckeModuleElement__element')
91
False
92
sage: f._compute_element()
93
(1, 0)
94
sage: f.element()
95
(1, 0)
96
sage: hasattr(f, '_HeckeModuleElement__element')
97
True
98
"""
99
# You have to define this in the derived class if you ever set
100
# x=None in __init__ for your element class.
101
# The main reason for this is it allows for lazy constructors who
102
# compute the representation of an element (e.g., a q-expansion) in
103
# terms of the basis only when needed.
104
raise NotImplementedError, "_compute_element *must* be defined in the derived class if element is set to None in constructor"
105
106
def element(self):
107
"""
108
Return underlying vector space element that defines this Hecke module element.
109
110
EXAMPLES::
111
112
sage: z = BrandtModule(37)([0,1,-1]).element(); z
113
(0, 1, -1)
114
sage: type(z)
115
<type 'sage.modules.vector_rational_dense.Vector_rational_dense'>
116
"""
117
try:
118
return self.__element
119
except AttributeError:
120
self.__element = self._compute_element()
121
return self.__element
122
123
def _vector_(self, R=None):
124
"""
125
This makes it so vector(self) and vector(self, R) both work.
126
127
EXAMPLES::
128
129
sage: v = BrandtModule(37)([0,1,-1]); v
130
(0, 1, -1)
131
sage: type(v._vector_())
132
<type 'sage.modules.vector_rational_dense.Vector_rational_dense'>
133
sage: type(vector(v))
134
<type 'sage.modules.vector_rational_dense.Vector_rational_dense'>
135
sage: type(vector(v, GF(2)))
136
<type 'sage.modules.vector_mod2_dense.Vector_mod2_dense'>
137
"""
138
if R is None: return self.__element
139
return self.__element.change_ring(R)
140
141
def ambient_module(self):
142
"""
143
Return the ambient Hecke module that contains this element.
144
145
EXAMPLES::
146
147
sage: BrandtModule(37)([0,1,-1]).ambient_module()
148
Brandt module of dimension 3 of level 37 of weight 2 over Rational Field
149
"""
150
return self.parent().ambient_module()
151
152
def _lmul_(self, x):
153
"""
154
EXAMPLES::
155
156
sage: BrandtModule(37)([0,1,-1])._lmul_(3)
157
(0, 3, -3)
158
"""
159
return self.parent()(self.element()*x)
160
161
def _rmul_(self, x):
162
"""
163
EXAMPLES::
164
165
sage: BrandtModule(37)([0,1,-1])._rmul_(3)
166
(0, 3, -3)
167
"""
168
return self.parent()(x * self.element())
169
170
def _neg_(self):
171
"""
172
EXAMPLES::
173
174
sage: BrandtModule(37)([0,1,-1])._neg_()
175
(0, -1, 1)
176
"""
177
return self.parent()(-self.element())
178
179
def _pos_(self):
180
"""
181
EXAMPLES::
182
183
sage: BrandtModule(37)([0,1,-1])._pos_()
184
(0, 1, -1)
185
"""
186
return self
187
188
def _sub_(self, right):
189
"""
190
EXAMPLES::
191
192
sage: BrandtModule(37)([0,1,-1])._sub_(BrandtModule(37)([0,1,-5]))
193
(0, 0, 4)
194
"""
195
return self.parent()(self.element() - right.element())
196
197
def is_cuspidal(self):
198
r"""
199
Return True if this element is cuspidal.
200
201
EXAMPLES::
202
203
sage: M = ModularForms(2, 22); M.0.is_cuspidal()
204
True
205
sage: (M.0 + M.4).is_cuspidal()
206
False
207
sage: EllipticCurve('37a1').newform().is_cuspidal()
208
True
209
210
It works for modular symbols too::
211
212
sage: M = ModularSymbols(19,2)
213
sage: M.0.is_cuspidal()
214
False
215
sage: M.1.is_cuspidal()
216
True
217
"""
218
return (self in self.parent().ambient().cuspidal_submodule())
219
220
def is_eisenstein(self):
221
r"""
222
Return True if this element is Eisenstein. This makes sense for both
223
modular forms and modular symbols.
224
225
EXAMPLES::
226
227
sage: CuspForms(2,8).0.is_eisenstein()
228
False
229
sage: M = ModularForms(2,8);(M.0 + M.1).is_eisenstein()
230
False
231
sage: M.1.is_eisenstein()
232
True
233
sage: ModularSymbols(19,4).0.is_eisenstein()
234
False
235
sage: EllipticCurve('37a1').newform().is_eisenstein()
236
False
237
"""
238
return (self in self.parent().ambient().eisenstein_submodule())
239
240
def is_new(self, p=None):
241
r"""
242
Return True if this element is p-new. If p is None, return True if the
243
element is new.
244
245
EXAMPLE::
246
247
sage: CuspForms(22, 2).0.is_new(2)
248
False
249
sage: CuspForms(22, 2).0.is_new(11)
250
True
251
sage: CuspForms(22, 2).0.is_new()
252
False
253
"""
254
return (self in self.parent().new_submodule(p))
255
256
def is_old(self, p=None):
257
r"""
258
Return True if this element is p-old. If p is None, return True if the
259
element is old.
260
261
EXAMPLE::
262
263
sage: CuspForms(22, 2).0.is_old(11)
264
False
265
sage: CuspForms(22, 2).0.is_old(2)
266
True
267
sage: CuspForms(22, 2).0.is_old()
268
True
269
sage: EisensteinForms(144, 2).1.is_old() # long time (3s on sage.math, 2011)
270
False
271
sage: EisensteinForms(144, 2).1.is_old(2) # not implemented
272
False
273
"""
274
return (self in self.parent().old_submodule(p))
275
276
277