Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

# -*- coding: utf-8 -*- 

r""" 

Modular Forms with Character 

 

EXAMPLES:: 

 

sage: eps = DirichletGroup(13).0 

sage: M = ModularForms(eps^2, 2); M 

Modular Forms space of dimension 3, character [zeta6] and weight 2 over Cyclotomic Field of order 6 and degree 2 

 

sage: S = M.cuspidal_submodule(); S 

Cuspidal subspace of dimension 1 of Modular Forms space of dimension 3, character [zeta6] and weight 2 over Cyclotomic Field of order 6 and degree 2 

sage: S.modular_symbols() 

Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 4 and level 13, weight 2, character [zeta6], sign 0, over Cyclotomic Field of order 6 and degree 2 

 

We create a spaces associated to Dirichlet characters of modulus 225:: 

 

sage: e = DirichletGroup(225).0 

sage: e.order() 

6 

sage: e.base_ring() 

Cyclotomic Field of order 60 and degree 16 

sage: M = ModularForms(e,3) 

 

Notice that the base ring is "minimized":: 

 

sage: M 

Modular Forms space of dimension 66, character [zeta6, 1] and weight 3 

over Cyclotomic Field of order 6 and degree 2 

 

If we don't want the base ring to change, we can explicitly specify it:: 

 

sage: ModularForms(e, 3, e.base_ring()) 

Modular Forms space of dimension 66, character [zeta6, 1] and weight 3 

over Cyclotomic Field of order 60 and degree 16 

 

Next we create a space associated to a Dirichlet character of order 20:: 

 

sage: e = DirichletGroup(225).1 

sage: e.order() 

20 

sage: e.base_ring() 

Cyclotomic Field of order 60 and degree 16 

sage: M = ModularForms(e,17); M 

Modular Forms space of dimension 484, character [1, zeta20] and 

weight 17 over Cyclotomic Field of order 20 and degree 8 

 

We compute the Eisenstein subspace, which is fast even though 

the dimension of the space is large (since an explicit basis 

of `q`-expansions has not been computed yet). 

 

:: 

 

sage: M.eisenstein_submodule() 

Eisenstein subspace of dimension 8 of Modular Forms space of 

dimension 484, character [1, zeta20] and weight 17 over Cyclotomic Field of order 20 and degree 8 

 

sage: M.cuspidal_submodule() 

Cuspidal subspace of dimension 476 of Modular Forms space of dimension 484, character [1, zeta20] and weight 17 over Cyclotomic Field of order 20 and degree 8 

 

TESTS:: 

 

sage: m = ModularForms(DirichletGroup(20).1,5) 

sage: m == loads(dumps(m)) 

True 

sage: type(m) 

<class 'sage.modular.modform.ambient_eps.ModularFormsAmbient_eps_with_category'> 

""" 

from __future__ import absolute_import 

 

######################################################################### 

# Copyright (C) 2006 William Stein <wstein@gmail.com> 

# 

# Distributed under the terms of the GNU General Public License (GPL) 

# 

# http://www.gnu.org/licenses/ 

######################################################################### 

 

import sage.rings.all as rings 

 

import sage.modular.arithgroup.all as arithgroup 

import sage.modular.dirichlet as dirichlet 

import sage.modular.modsym.modsym as modsym 

from sage.misc.cachefunc import cached_method 

 

from .ambient import ModularFormsAmbient 

 

from . import ambient_R 

from . import cuspidal_submodule 

from . import eisenstein_submodule 

 

class ModularFormsAmbient_eps(ModularFormsAmbient): 

""" 

A space of modular forms with character. 

""" 

def __init__(self, character, weight=2, base_ring=None, eis_only=False): 

""" 

Create an ambient modular forms space with character. 

 

.. note:: 

 

The base ring must be of characteristic 0. The ambient_R 

Python module is used for computing in characteristic p, 

which we view as the reduction of characteristic 0. 

 

INPUT: 

 

- ``weight`` - int 

 

- ``character`` - dirichlet.DirichletCharacter 

 

- ``base_ring`` - base field 

 

EXAMPLES:: 

 

sage: m = ModularForms(DirichletGroup(11).0,3); m 

Modular Forms space of dimension 3, character [zeta10] and weight 3 over Cyclotomic Field of order 10 and degree 4 

sage: type(m) 

<class 'sage.modular.modform.ambient_eps.ModularFormsAmbient_eps_with_category'> 

""" 

if not dirichlet.is_DirichletCharacter(character): 

raise TypeError("character (=%s) must be a Dirichlet character"%character) 

if base_ring is None: base_ring=character.base_ring() 

if character.base_ring() != base_ring: 

character = character.change_ring(base_ring) 

if base_ring.characteristic() != 0: 

raise ValueError("the base ring must have characteristic 0.") 

group = arithgroup.Gamma1(character.modulus()) 

base_ring = character.base_ring() 

ModularFormsAmbient.__init__(self, group, weight, base_ring, character, eis_only) 

 

def _repr_(self): 

""" 

String representation of this space with character. 

 

EXAMPLES:: 

 

sage: m = ModularForms(DirichletGroup(8).1,2) 

sage: m._repr_() 

'Modular Forms space of dimension 2, character [1, -1] and weight 2 over Rational Field' 

 

You can rename the space with the rename command. 

 

:: 

 

sage: m.rename('Modforms of level 8') 

sage: m 

Modforms of level 8 

""" 

if self._eis_only: 

return "Modular Forms space of character %s and weight %s over %s" %( 

self.character()._repr_short_(), self.weight(), self.base_ring()) 

else: 

return "Modular Forms space of dimension %s, character %s and weight %s over %s"%( 

self.dimension(), self.character()._repr_short_(), self.weight(), self.base_ring()) 

 

def cuspidal_submodule(self): 

""" 

Return the cuspidal submodule of this ambient space of modular forms. 

 

EXAMPLES:: 

 

sage: eps = DirichletGroup(4).0 

sage: M = ModularForms(eps, 5); M 

Modular Forms space of dimension 3, character [-1] and weight 5 over Rational Field 

sage: M.cuspidal_submodule() 

Cuspidal subspace of dimension 1 of Modular Forms space of dimension 3, character [-1] and weight 5 over Rational Field 

""" 

try: 

return self.__cuspidal_submodule 

except AttributeError: 

if self.weight() > 1: 

self.__cuspidal_submodule = cuspidal_submodule.CuspidalSubmodule_eps(self) 

else: 

self.__cuspidal_submodule = cuspidal_submodule.CuspidalSubmodule_wt1_eps(self) 

return self.__cuspidal_submodule 

 

def change_ring(self, base_ring): 

""" 

Return space with same defining parameters as this ambient 

space of modular symbols, but defined over a different base 

ring. 

 

EXAMPLES:: 

 

sage: m = ModularForms(DirichletGroup(13).0^2,2); m 

Modular Forms space of dimension 3, character [zeta6] and weight 2 over Cyclotomic Field of order 6 and degree 2 

sage: m.change_ring(CyclotomicField(12)) 

Modular Forms space of dimension 3, character [zeta6] and weight 2 over Cyclotomic Field of order 12 and degree 4 

 

It must be possible to change the ring of the underlying Dirichlet character:: 

 

sage: m.change_ring(QQ) 

Traceback (most recent call last): 

... 

TypeError: Unable to coerce zeta6 to a rational 

""" 

if self.base_ring() == base_ring: 

return self 

return ambient_R.ModularFormsAmbient_R(self, base_ring = base_ring) 

 

@cached_method(key=lambda self,sign: rings.Integer(sign)) # convert sign to an Integer before looking this up in the cache 

def modular_symbols(self, sign=0): 

""" 

Return corresponding space of modular symbols with given sign. 

 

EXAMPLES:: 

 

sage: eps = DirichletGroup(13).0 

sage: M = ModularForms(eps^2, 2) 

sage: M.modular_symbols() 

Modular Symbols space of dimension 4 and level 13, weight 2, character [zeta6], sign 0, over Cyclotomic Field of order 6 and degree 2 

sage: M.modular_symbols(1) 

Modular Symbols space of dimension 3 and level 13, weight 2, character [zeta6], sign 1, over Cyclotomic Field of order 6 and degree 2 

sage: M.modular_symbols(-1) 

Modular Symbols space of dimension 1 and level 13, weight 2, character [zeta6], sign -1, over Cyclotomic Field of order 6 and degree 2 

sage: M.modular_symbols(2) 

Traceback (most recent call last): 

... 

ValueError: sign must be -1, 0, or 1 

""" 

sign = rings.Integer(sign) 

return modsym.ModularSymbols(self.character(), 

weight = self.weight(), 

sign = sign, 

base_ring = self.base_ring()) 

 

def eisenstein_submodule(self): 

""" 

Return the submodule of this ambient module with character that is 

spanned by Eisenstein series. This is the Hecke stable complement 

of the cuspidal submodule. 

 

EXAMPLES:: 

 

sage: m = ModularForms(DirichletGroup(13).0^2,2); m 

Modular Forms space of dimension 3, character [zeta6] and weight 2 over Cyclotomic Field of order 6 and degree 2 

sage: m.eisenstein_submodule() 

Eisenstein subspace of dimension 2 of Modular Forms space of dimension 3, character [zeta6] and weight 2 over Cyclotomic Field of order 6 and degree 2 

""" 

try: 

return self.__eisenstein_submodule 

except AttributeError: 

self.__eisenstein_submodule = eisenstein_submodule.EisensteinSubmodule_eps(self) 

return self.__eisenstein_submodule 

 

def hecke_module_of_level(self, N): 

r""" 

Return the Hecke module of level N corresponding to self, which is the 

domain or codomain of a degeneracy map from self. Here N must be either 

a divisor or a multiple of the level of self, and a multiple of the 

conductor of the character of self. 

 

EXAMPLES:: 

 

sage: M = ModularForms(DirichletGroup(15).0, 3); M.character().conductor() 

3 

sage: M.hecke_module_of_level(3) 

Modular Forms space of dimension 2, character [-1] and weight 3 over Rational Field 

sage: M.hecke_module_of_level(5) 

Traceback (most recent call last): 

... 

ValueError: conductor(=3) must divide M(=5) 

sage: M.hecke_module_of_level(30) 

Modular Forms space of dimension 16, character [-1, 1] and weight 3 over Rational Field 

""" 

from . import constructor 

if N % self.level() == 0: 

return constructor.ModularForms(self.character().extend(N), self.weight(), self.base_ring(), prec=self.prec()) 

elif self.level() % N == 0: 

return constructor.ModularForms(self.character().restrict(N), self.weight(), self.base_ring(), prec=self.prec()) 

else: 

raise ValueError("N (=%s) must be a divisor or a multiple of the level of self (=%s)" % (N, self.level()))