Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
241782 views
1
#################################################################################
2
#
3
# (c) Copyright 2010 William Stein
4
#
5
# This file is part of PSAGE
6
#
7
# PSAGE is free software: you can redistribute it and/or modify
8
# it under the terms of the GNU General Public License as published by
9
# the Free Software Foundation, either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# PSAGE is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with this program. If not, see <http://www.gnu.org/licenses/>.
19
#
20
#################################################################################
21
22
23
"""
24
This module implement a class that represents the collection of
25
newforms.
26
27
The code in this module defines classes both for working with the
28
collection of all newforms in the database, and for populating this
29
collection with new data about newforms. The NewformCollection
30
class is instantiated by the main MFDB database object.
31
The classes for populating the newforms table further or in
32
turn instantiated by the NewformCollection object.
33
34
The newform collection has documents that contain data about newforms.
35
It also has a subcollection 'counts', which records the number of
36
newforms with given level, weight, and character. """
37
38
from collection import Collection
39
40
class NewformCollection(Collection):
41
"""
42
"""
43
def __repr__(self):
44
return "Collection of newforms"
45
46
def count(self):
47
"""Return number of newforms in the newforms collection."""
48
return self.find().count()
49
50
def spaces(self, key=0):
51
"""Return sorted (by either level (key=0), weight (key=1), etc.)
52
list of triples
53
(level, weight, character.order(), count)
54
for which all count newforms in the corresponding space are known."""
55
key = int(key)
56
C = self.collection.counts
57
# Query C for the 4-tuples, as described in the docstring above.
58
Q = [(x['level'], x['weight'], x['character']['order'], x['count']) for x in
59
C.find({},['level','weight','character.order','count'])]
60
Q.sort(lambda x,y: cmp(x[key],y[key]))
61
return Q
62
63
def normalize(self, level, weight, character):
64
"""
65
Return normalized level, weight, character, and a MongoDB
66
document representing them. Normalized means the level and
67
weight are Python ints, and the character is a Sage Dirichlet
68
character (in particular, it is not None).
69
"""
70
from converter import to_db
71
level = to_db(level)
72
weight = to_db(weight)
73
if character is None:
74
from sage.all import trivial_character
75
character = trivial_character(level)
76
e = to_db(character)
77
return level, weight, character, {'level':level, 'weight':weight, 'character':e}
78
79
def populate_newform_eigenvalue_field(self):
80
"""Return object that organizes populating the eigenvalue field
81
property of newform documents."""
82
return PopulateNewformEigenvalueField(self)
83
84
def populate_newforms(self):
85
"""Return object that organizes populating the newform
86
documents. Get this object if you want to add new newforms to
87
the database."""
88
return PopulateNewforms(self)
89
90
91
92
from populate import Populate
93
94
class PopulateNewforms(Populate):
95
def __repr__(self):
96
return "Populate Newforms"
97
98
def count(self):
99
"""Return number of newforms in the database (with degree field set)."""
100
return self.collection.newforms.find({'degree':{'$exists':True}}).count()
101
102
def populate(self, level, weight=2, character=None, verbose=True):
103
nc = self.collection # newform collection
104
level, weight, character, D = nc.normalize(level, weight, character)
105
if verbose: print D
106
# Check the counts subcollection
107
if nc.collection.counts.find(D).count() > 0:
108
# Don't bother
109
if verbose: print "Skipping since counts subcollection already has an entry."
110
return
111
from psage.modform.rational.newforms import degrees
112
degs = degrees(level, weight, character)
113
for num, d in enumerate(degs):
114
deg = int(d)
115
# Update the document for the given newform
116
query = dict(D)
117
query['number'] = num
118
nc.collection.update(query, {'$set':{'degree':deg}},
119
upsert=True, safe=True)
120
D['count'] = len(degs)
121
nc.collection.counts.insert(D, safe=True)
122
123
def populate_all_characters(self, level, weight, verbose=True):
124
from sage.all import DirichletGroup
125
G = DirichletGroup(level)
126
B = G.galois_orbits()
127
B = [character[0].minimize_base_ring() for character in B]
128
for character in B:
129
self.populate(level, weight, character, verbose)
130
131
def populate_quadratic_characters(self, level, weight, verbose=True):
132
from sage.all import DirichletGroup, QQ
133
G = DirichletGroup(level,QQ)
134
B = G.galois_orbits()
135
B = [character[0].minimize_base_ring() for character in B
136
if character[0].order()==2]
137
for character in B:
138
self.populate(level, weight, character, verbose)
139
140
141
class PopulateNewformEigenvalueField(Populate):
142
def __repr__(self):
143
return "Populating newform Hecke eigenvalue fields"
144
145
def count(self):
146
"""Return number of newforms with eigenvalue field computed."""
147
return self.collection.collection.find({'eigenvalue_field':{'$exists':True}}).count()
148
149
def populate_one(self, verbose=True):
150
"""
151
Compute Hecke eigenvalues for one unknown level,weight,character.
152
If all data is known, raise a ValueError.
153
"""
154
A = self.collection.collection.find_one({'eigenvalue_field':{'$exists':False}})
155
if A is None:
156
raise ValueError, "All Hecke eigenvalue fields are currently known."
157
from converter import db_converter
158
self.populate(A['level'], A['weight'],
159
db_converter.to_dirichlet_character(A['character']),
160
verbose=verbose)
161
162
def populate(self, level, weight, character=None, verbose=True):
163
nc = self.collection
164
level, weight, character, D = nc.normalize(level, weight, character)
165
if verbose: print D
166
C = nc.collection.counts.find(D)
167
if C.count() == 0:
168
if verbose: print "Skipping -- no newforms known yet (counts=0)"
169
return
170
cnt = C.next()['count']
171
if cnt == 0:
172
# There are no newforms, so don't do any further work.
173
if verbose: print "No newforms"
174
return
175
# Now check to see if all of the eigenvalue fields are known
176
# by doing a query for all forms of the given level, weight, and
177
# character for which the eigenvalue_field key is set.
178
E = dict(D)
179
E['eigenvalue_field'] = {'$exists':True}
180
if nc.collection.find(E).count() == cnt:
181
if verbose: print "All eigenvalue fields already known"
182
return
183
184
from psage.modform.rational.newforms import eigenvalue_fields
185
from sage.all import set_random_seed, QQ
186
187
set_random_seed(0)
188
fields = eigenvalue_fields(level, weight, character)
189
190
for num, K in enumerate(fields):
191
# Update the document for the given newform
192
query = dict(D)
193
query['number'] = num
194
if K == QQ:
195
f = 'x-1'
196
else:
197
f = str(K.defining_polynomial()).replace(' ','')
198
if verbose:
199
print f
200
nc.collection.update(query, {'$set':{'eigenvalue_field':f}}, safe=True)
201
202