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

""" 

Abelian varieties attached to newforms 

 

TESTS:: 

 

sage: A = AbelianVariety('23a') 

sage: loads(dumps(A)) == A 

True 

""" 

from __future__ import absolute_import 

 

 

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

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

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

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

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

 

from sage.databases.cremona import cremona_letter_code 

 

from sage.rings.all import QQ, ZZ 

 

from sage.modular.modform.element import Newform 

from sage.modular.arithgroup.all import is_Gamma0, is_Gamma1, is_GammaH 

 

 

from .abvar import ModularAbelianVariety_modsym_abstract 

from . import homspace 

 

class ModularAbelianVariety_newform(ModularAbelianVariety_modsym_abstract): 

""" 

A modular abelian variety attached to a specific newform. 

""" 

def __init__(self, f, internal_name=False): 

""" 

Create the modular abelian variety `A_f` attached to the 

newform `f`. 

 

INPUT: 

f -- a newform 

 

EXAMPLES:: 

 

sage: f = CuspForms(37).newforms('a')[0] 

sage: f.abelian_variety() 

Newform abelian subvariety 37a of dimension 1 of J0(37) 

 

sage: AbelianVariety(Newforms(1, 12)[0]) 

Traceback (most recent call last): 

... 

TypeError: f must have weight 2 

""" 

if not isinstance(f, Newform): 

raise TypeError("f must be a newform") 

if f.weight() != 2: 

raise TypeError("f must have weight 2") 

self.__f = f 

self._is_hecke_stable = True 

K = f.qexp().base_ring() 

if K == QQ: 

variable_name = None 

else: 

variable_name = K.variable_name() 

self.__named_newforms = { variable_name: self.__f } 

if not internal_name: 

self.__named_newforms[None] = self.__f 

ModularAbelianVariety_modsym_abstract.__init__(self, (f.group(),), QQ, 

is_simple=True, newform_level = (f.level(), f.group()), 

isogeny_number=f.number(), number=0) 

 

def _modular_symbols(self,sign=0): 

""" 

EXAMPLES:: 

 

sage: f = CuspForms(52).newforms('a')[0] 

sage: A = f.abelian_variety() 

sage: A._modular_symbols() 

Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 15 for Gamma_0(52) of weight 2 with sign 0 over Rational Field 

sage: A._modular_symbols(1) 

Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 10 for Gamma_0(52) of weight 2 with sign 1 over Rational Field 

sage: A._modular_symbols(-1) 

Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 5 for Gamma_0(52) of weight 2 with sign -1 over Rational Field 

""" 

return self.__f.modular_symbols(sign=sign) 

 

def newform(self, names=None): 

r""" 

Return the newform that this modular abelian variety is attached to. 

 

EXAMPLES:: 

 

sage: f = Newform('37a') 

sage: A = f.abelian_variety() 

sage: A.newform() 

q - 2*q^2 - 3*q^3 + 2*q^4 - 2*q^5 + O(q^6) 

sage: A.newform() is f 

True 

 

If the a variable name has not been specified, we must specify one:: 

 

sage: A = AbelianVariety('67b') 

sage: A.newform() 

Traceback (most recent call last): 

... 

TypeError: You must specify the name of the generator. 

sage: A.newform('alpha') 

q + alpha*q^2 + (-alpha - 3)*q^3 + (-3*alpha - 3)*q^4 - 3*q^5 + O(q^6) 

 

If the eigenform is actually over `\QQ` then we don't have to specify 

the name:: 

 

sage: A = AbelianVariety('67a') 

sage: A.newform() 

q + 2*q^2 - 2*q^3 + 2*q^4 + 2*q^5 + O(q^6) 

""" 

try: 

return self.__named_newforms[names] 

except KeyError: 

self.__named_newforms[names] = Newform(self.__f.parent().change_ring(QQ), self.__f.modular_symbols(1), names=names, check=False) 

return self.__named_newforms[names] 

 

def label(self): 

""" 

Return canonical label that defines this newform modular 

abelian variety. 

 

OUTPUT: 

string 

 

EXAMPLES:: 

 

sage: A = AbelianVariety('43b') 

sage: A.label() 

'43b' 

""" 

G = self.__f.group() 

if is_Gamma0(G): 

group = '' 

elif is_Gamma1(G): 

group = 'G1' 

elif is_GammaH(G): 

group = 'GH[' + ','.join([str(z) for z in G._generators_for_H()]) + ']' 

return '%s%s%s'%(self.level(), cremona_letter_code(self.factor_number()), group) 

 

def factor_number(self): 

""" 

Return factor number. 

 

OUTPUT: 

int 

 

EXAMPLES:: 

 

sage: A = AbelianVariety('43b') 

sage: A.factor_number() 

1 

""" 

try: 

return self.__factor_number 

except AttributeError: 

self.__factor_number = self.__f.number() 

return self.__factor_number 

 

def _repr_(self): 

""" 

String representation of this modular abelian variety. 

 

EXAMPLES:: 

 

sage: AbelianVariety('37a')._repr_() 

'Newform abelian subvariety 37a of dimension 1 of J0(37)' 

""" 

return "Newform abelian subvariety %s of dimension %s of %s" % ( 

self.newform_label(), self.dimension(), self._ambient_repr()) 

 

def endomorphism_ring(self): 

""" 

Return the endomorphism ring of this newform abelian variety. 

 

EXAMPLES:: 

 

sage: A = AbelianVariety('23a') 

sage: E = A.endomorphism_ring(); E 

Endomorphism ring of Newform abelian subvariety 23a of dimension 2 of J0(23) 

 

We display the matrices of these two basis matrices:: 

 

sage: E.0.matrix() 

[1 0 0 0] 

[0 1 0 0] 

[0 0 1 0] 

[0 0 0 1] 

sage: E.1.matrix() 

[ 0 1 -1 0] 

[ 0 1 -1 1] 

[-1 2 -2 1] 

[-1 1 0 -1] 

 

The result is cached:: 

 

sage: E is A.endomorphism_ring() 

True 

""" 

try: 

return self.__endomorphism_ring 

except AttributeError: 

pass 

 

E = homspace.EndomorphismSubring(self) 

self.__endomorphism_ring = E 

return self.__endomorphism_ring 

 

def _calculate_endomorphism_generators(self): 

""" 

EXAMPLES:: 

 

sage: A = AbelianVariety('43b') 

sage: B = A.endomorphism_ring(); B # indirect doctest 

Endomorphism ring of Newform abelian subvariety 43b of dimension 2 of J0(43) 

sage: [b.matrix() for b in B.gens()] 

[ 

[1 0 0 0] [ 0 1 0 0] 

[0 1 0 0] [ 1 -2 0 0] 

[0 0 1 0] [ 1 0 -2 -1] 

[0 0 0 1], [ 0 1 -1 0] 

] 

""" 

M = self.modular_symbols() 

bound = M.sturm_bound() 

 

d = self.dimension() 

T1list = self.hecke_operator(1).matrix().list() 

EndVecZ = ZZ**(len(T1list)) 

V = EndVecZ.submodule([T1list]) 

n = 2 

 

while V.dimension() < d: 

W = EndVecZ.submodule([((self.hecke_operator(n).matrix())**i).list() 

for i in range(1,d+1)]) 

V = V+W 

n += 1 

 

return V.saturation().basis()