def import_table(address, aplists_txt_filename, max_level=None): """ Import a text table of eigenvalues, using upsert to avoid replication of data. """ from psage.lmfdb.auth import userpass user, password = userpass() from sage.databases.cremona import cremona_letter_code from psage.modform.hilbert.sqrt5.sqrt5 import F labels, primes = labeled_primes_of_bounded_norm(F, 100) from pymongo import Connection C = Connection(address).research if not C.authenticate(user, password): raise RuntimeError, "failed to authenticate" e = C.ellcurves_sqrt5 for X in open(aplists_txt_filename).read().splitlines(): if X.startswith('#'): continue Nlevel, level, iso_class, ap = X.split('\t') ap = str_to_apdict(ap, labels) Nlevel = int(Nlevel) iso_class = cremona_letter_code(int(iso_class)) v = {'level':level, 'iso_class':iso_class, 'number':1, 'Nlevel':Nlevel, 'ap':ap} if max_level and Nlevel > max_level: break print v spec = dict(v) del spec['ap'] e.update(spec, v, upsert=True, safe=True) return e
def make_webchar(args, get_bread=False): modulus = int(args['modulus']) number = int(args['number']) if 'number' in args else None orbit_label = args.get('orbit_label', None) if modulus <= 10000: if number is None: if get_bread: bread_crumbs = bread( [('%s' % modulus, url_for(".render_Dirichletwebpage", modulus=modulus)), ('%s' % orbit_label, url_for(".render_Dirichletwebpage", modulus=modulus, orbit_label=orbit_label))]) return WebDBDirichletOrbit(**args), bread_crumbs return WebDBDirichletOrbit(**args) if args.get('orbit_label') is None: db_orbit_label = db.char_dir_values.lookup("{}.{}".format(modulus, number), projection='orbit_label') orbit_label = cremona_letter_code(int(db_orbit_label.partition('.')[-1]) - 1) args['orbit_label'] = orbit_label if get_bread: bread_crumbs = bread( [('%s' % modulus, url_for(".render_Dirichletwebpage", modulus=modulus)), ('%s' % orbit_label, url_for(".render_Dirichletwebpage", modulus=modulus, orbit_label=orbit_label)), ('%s' % number, url_for(".render_Dirichletwebpage", modulus=modulus, orbit_label=orbit_label, number=number))]) return WebDBDirichletCharacter(**args), bread_crumbs return WebDBDirichletCharacter(**args) else: if get_bread: bread_crumbs = bread( [('%s' % modulus, url_for(".render_Dirichletwebpage", modulus=modulus)), ('%s' % number, url_for(".render_Dirichletwebpage", modulus=modulus, number=number))]) return WebSmallDirichletCharacter(**args), bread_crumbs return WebSmallDirichletCharacter(**args)
def _link(self, N, i=None, form=None, typ="new", label=True): if form is not None: form = cremona_letter_code(form - 1) if label: if i is None: name = "{N}.{k}".format(N=N, k=self.weight) elif form is None: name = "{N}.{k}.{i}".format(N=N, k=self.weight, i=i) else: name = "{N}.{k}.{i}.{f}".format(N=N, k=self.weight, i=i, f=form) else: t = 1 if i is None else 0 name = r"\(%s\)" % common_latex(N, self.weight, i, t=t, typ=typ) if i is None: url = url_for(".by_url_full_gammma1_space_label", level=N, weight=self.weight) elif form is None: url = url_for(".by_url_space_label", level=N, weight=self.weight, char_orbit_label=i) else: url = url_for(".by_url_newform_label", level=N, weight=self.weight, char_orbit_label=i, hecke_orbit=form) return r"<a href={url}>{name}</a>".format(url=url, name=name)
def oldspace_decomposition(self): # Returns a latex string giving the decomposition of the old part. These come from levels M dividing N, with the conductor of the character dividing M. template = r"<a href={url}>\({old}\)</a>\(^{{\oplus {mult}}}\)" return r"\(\oplus\)".join( template.format( old=common_latex(N, self.weight, conrey, typ="new"), url=url_for(".by_url_space_label", level=N, weight=self.weight, char_orbit_label=cremona_letter_code(i - 1)), mult=mult) for N, i, conrey, mult in self.oldspaces)
def import_table(address, table_filename, max_level=None): """ Import a text table of weq's, using upsert to avoid replication of data. Format is like this: :: 31 5*a-2 0 -3 2 -2 2 4 -4 4 -4 -2 -2 ? ? -6 -6 12 -4 6 -2 -8 0 0 16 10 -6 [1,a+1,a,a,0] 31 5*a-3 0 -3 2 -2 2 -4 4 -4 4 -2 -2 ? ? -6 -6 -4 12 -2 6 0 -8 16 0 -6 10 [1,-a-1,a,0,0] 36 6 0 ? ? -4 10 2 2 0 0 0 0 -8 -8 2 2 -10 -10 2 2 12 12 0 0 10 10 [a,a-1,a,-1,-a+1] """ from psage.modform.hilbert.sqrt5.sqrt5 import F from sage.databases.cremona import cremona_letter_code from aplists import labeled_primes_of_bounded_norm, str_to_apdict labels, primes = labeled_primes_of_bounded_norm(F, 100) from psage.lmfdb.auth import userpass user, password = userpass() from pymongo import Connection C = Connection(address).research if not C.authenticate(user, password): raise RuntimeError, "failed to authenticate" e = C.ellcurves_sqrt5 for X in open(table_filename).read().splitlines(): if X.startswith('#'): continue z = X.split() Nlevel = z[0] level = z[1] iso_class = z[2] weq = z[-1] ap = ' '.join(z[3:-1]) ap = str_to_apdict(ap, labels) Nlevel = int(Nlevel) iso_class = cremona_letter_code(int(iso_class)) v = { 'level': level, 'iso_class': iso_class, 'number': 1, 'Nlevel': Nlevel, 'ap': ap, 'weq': weq } if max_level and Nlevel > max_level: break print v spec = dict(v) del spec['weq'] e.update(spec, v, upsert=True, safe=True)
def info_from_db_orbit(orbit): mod = orbit['modulus'] conductor = orbit['conductor'] orbit_index = orbit['orbit_index'] orbit_letter = cremona_letter_code(orbit_index - 1) orbit_label = "{}.{}".format(mod, orbit_letter) order = orbit['order'] is_odd = parity_string(orbit['parity']) is_prim = _is_primitive(orbit['is_primitive']) results = [] for num in orbit['galois_orbit']: results.append( (mod, num, conductor, orbit_label, order, is_odd, is_prim, WebDirichlet.char2tex(mod, num))) return results
def display_inner_twists(self): if self.inner_twist_count == -1: # Only CM data available if self.is_cm: discriminant = self.cm_discs[0] return '<p>Only self twists have been computed for this newform, which has CM by %s.</p>' % (quad_field_knowl(discriminant)) else: return '<p>This newform does not have CM; other inner twists have not been computed.</p>' def th_wrap(kwl, title): return ' <th>%s</th>' % display_knowl(kwl, title=title) def td_wrap(val): return ' <td>%s</th>' % val twists = ['<table class="ntdata">', '<thead>', ' <tr>', th_wrap('character.dirichlet.galois_orbit_label', 'Char. orbit'), th_wrap('character.dirichlet.parity', 'Parity'), #th_wrap('character.dirichlet.order', 'Order'), th_wrap('cmf.inner_twist_multiplicity', 'Mult.'), th_wrap('cmf.self_twist_col', 'Type'), th_wrap('cmf.inner_twist_proved', 'Proved'), ' </tr>', '</thead>', '<tbody>'] trivial = [elt for elt in self.inner_twists if elt[6] == 1] CMRM = sorted([elt for elt in self.inner_twists if elt[6] not in [0,1]], key = lambda elt: elt[2]) other = sorted([elt for elt in self.inner_twists if elt[6] == 0], key = lambda elt: (elt[2],elt[3])) self.inner_twists = trivial + CMRM + other for proved, mult, modulus, char_orbit_index, parity, order, discriminant in self.inner_twists: label = '%s.%s' % (modulus, cremona_letter_code(char_orbit_index-1)) parity = 'Even' if parity == 1 else 'Odd' proved = 'yes' if proved == 1 else 'no' link = display_knowl('character.dirichlet.orbit_data', title=label, kwargs={'label':label}) if discriminant == 0: field = '' elif discriminant == 1: field = 'trivial' else: cmrm = 'CM by ' if discriminant < 0 else 'RM by ' field = cmrm + quad_field_knowl(discriminant) twists.append(' <tr>') twists.extend(map(td_wrap, [link, parity, mult, field, proved])) # add order back eventually twists.append(' </tr>') twists.extend(['</tbody>', '</table>']) return '\n'.join(twists)
def add_row(self, c): """ Add a row to _contents for display on the webpage. Each row of content takes the form character_name, (header..data), (several..values) where `header..data` is expected to be a tuple of length the same size as `len(headers)`, and given in the same order as in `headers`, and where `several..values` are the values of the character on self.groupelts, in order. """ mod = self.modulus num = c prim, order, orbit_label, valuepairs = self.char_dbdata(mod, num) letter = cremona_letter_code(int(orbit_label.partition(".")[-1]) - 1) formatted_orbit_label = "{}.{}".format(mod, letter) self._contents.append( (self._char_desc(num, mod=mod, prim=prim), (mod, letter, formatted_orbit_label), (order, bool_string(prim)), self._determine_values(valuepairs, order)))
def import_table(address, table_filename, max_level=None): """ Import a text table of weq's, using upsert to avoid replication of data. Format is like this: :: 31 5*a-2 0 -3 2 -2 2 4 -4 4 -4 -2 -2 ? ? -6 -6 12 -4 6 -2 -8 0 0 16 10 -6 [1,a+1,a,a,0] 31 5*a-3 0 -3 2 -2 2 -4 4 -4 4 -2 -2 ? ? -6 -6 -4 12 -2 6 0 -8 16 0 -6 10 [1,-a-1,a,0,0] 36 6 0 ? ? -4 10 2 2 0 0 0 0 -8 -8 2 2 -10 -10 2 2 12 12 0 0 10 10 [a,a-1,a,-1,-a+1] """ from psage.modform.hilbert.sqrt5.sqrt5 import F from sage.databases.cremona import cremona_letter_code from aplists import labeled_primes_of_bounded_norm, str_to_apdict labels, primes = labeled_primes_of_bounded_norm(F, 100) from psage.lmfdb.auth import userpass user, password = userpass() from pymongo import Connection C = Connection(address).research if not C.authenticate(user, password): raise RuntimeError, "failed to authenticate" e = C.ellcurves_sqrt5 for X in open(table_filename).read().splitlines(): if X.startswith('#'): continue z = X.split() Nlevel = z[0]; level = z[1]; iso_class = z[2]; weq = z[-1] ap = ' '.join(z[3:-1]) ap = str_to_apdict(ap, labels) Nlevel = int(Nlevel) iso_class = cremona_letter_code(int(iso_class)) v = {'level':level, 'iso_class':iso_class, 'number':1, 'Nlevel':Nlevel, 'ap':ap, 'weq':weq} if max_level and Nlevel > max_level: break print v spec = dict(v) del spec['weq'] e.update(spec, v, upsert=True, safe=True)
def labeled_primes_of_bounded_norm(F, B): """ Return a list [prime][letter code] of strings, corresponding to the primes of F of bounded norm of F, ordered by residue characteristic (not norm). """ from sage.databases.cremona import cremona_letter_code from psage.modform.hilbert.sqrt5.sqrt5 import primes_of_bounded_norm labels = [] last_c = 1 number = 0 primes = primes_of_bounded_norm(F, B) for p in primes: c = p.smallest_integer() # residue characteristic if c != last_c: last_c = c number = 0 else: number += 1 labels.append('%s%s' % (c, cremona_letter_code(number))) return labels, primes
def labeled_primes_of_bounded_norm(F, B): """ Return a list [prime][letter code] of strings, corresponding to the primes of F of bounded norm of F, ordered by residue characteristic (not norm). """ from sage.databases.cremona import cremona_letter_code from psage.modform.hilbert.sqrt5.sqrt5 import primes_of_bounded_norm labels = [] last_c = 1 number = 0 primes = primes_of_bounded_norm(F, B) for p in primes: c = p.smallest_integer() # residue characteristic if c != last_c: last_c = c number = 0 else: number += 1 labels.append('%s%s'%(c,cremona_letter_code(number))) return labels, primes
def get_orbit_data(self, orbit_label): mod_and_label = "{}.{}".format(self.modulus, orbit_label) orbit_data = db.char_dir_orbits.lucky( {'modulus': self.modulus, 'label': mod_and_label} ) if orbit_data is None: raise ValueError # Since we've got this, might as well set a bunch of stuff self.conductor = orbit_data['conductor'] self.order = orbit_data['order'] self.degree = orbit_data['char_degree'] self.isprimitive = bool_string(orbit_data['is_primitive']) self.isminimal = bool_string(orbit_data['is_minimal']) self.parity = parity_string(int(orbit_data['parity'])) self._set_kernel_field_poly(orbit_data) self.ind_orbit_label = cremona_letter_code(int(orbit_data['prim_orbit_index']) - 1) self.inducing = "{}.{}".format(self.conductor, self.ind_orbit_label) return orbit_data
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 info_from_db_orbit(orbit): mod = orbit['modulus'] conductor = orbit['conductor'] orbit_index = orbit['orbit_index'] orbit_letter = cremona_letter_code(orbit_index - 1) orbit_label = "{}.{}".format(mod, orbit_letter) order = orbit['order'] is_odd = 'Odd' if _is_odd(orbit['parity']) else 'Even' is_prim = _is_primitive(orbit['is_primitive']) results = [] for num in orbit['galois_orbit']: results.append(( mod, num, conductor, orbit_label, order, is_odd, is_prim, WebDirichlet.char2tex(mod, num) )) return results
def get_hecke_cc(): # if field_poly exists then compute the corresponding embedding of the root # add the conrey label hecke_cc = {} for key, label in labels.iteritems(): # key = (chi,j) # label = (chi, a, n) chi, a, n = label ol = cremona_letter_code(orbit_labels[chi] - 1) lfuntion_label = ".".join( map(str, [level, weight] + [ol, a, chi, n])) hecke_cc[key] = [ int(hecke_orbit_code[key]), lfuntion_label, # N.k.c.x.n int(label[0]), # conrey_label int(label[2]), # embedding_index int(embedding_m[key]), '\N', # embedding_root_real '\N', # embedding_root_imag coeffs_f[key][1:], angles[key], ] return hecke_cc
def _populate_from_db(self): values_data = db.char_dir_values.lookup( "{}.{}".format(self.modulus, self.number) ) self.orbit_index = int(values_data['orbit_label'].partition('.')[-1]) # The -1 in the line below is because labels index at 1, while # the Cremona letter code indexes at 0 self.orbit_label = cremona_letter_code(self.orbit_index - 1) self.order = int(values_data['order']) self.indlabel = int(values_data['prim_label'].partition('.')[-1]) self._set_values_and_groupelts(values_data) self._set_generators_and_genvalues(values_data) orbit_data = db.char_dir_orbits.lucky( {'modulus': self.modulus, 'orbit_index': self.orbit_index} ) self.conductor = int(orbit_data['conductor']) self._set_isprimitive(orbit_data) self._set_isminimal(orbit_data) self._set_parity(orbit_data) self._set_galoisorbit(orbit_data) self._set_kernel_field_poly(orbit_data)
def decode_hecke_orbit(code): level = str(code % 2**24) weight = str((code >> 24) % 2**12) char_orbit_label = cremona_letter_code((code >> 36) % 2**16) hecke_orbit_label = cremona_letter_code(code >> 52) return '.'.join([level, weight, char_orbit_label, hecke_orbit_label])
def extended_code(c): if c < 0: return 'a' + cremona_letter_code(-c) return cremona_letter_code(c)
def rational_origin(chi, a): return "ModularForm/GL2/Q/holomorphic/%d/%d/%s/%s" % ( level, weight, cremona_letter_code(orbit_labels[chi] - 1), a)
def check_unproven_ranks(jobs=1, jobid=0, use_weak_bsd=False, skip_real_char=False): todo = list( db.mf_newforms.search({ u'analytic_rank': { '$gt': int(1) }, u'analytic_rank_proved': False })) todo2 = [] todo3 = [] todo4 = [] cnt = 0 vcnt = 0 for i in range(len(todo)): if i % jobs != jobid: continue start = cputime() data = todo[i] if skip_real_char and data[u"char_is_real"]: continue if use_weak_bsd and data[u'weight'] == 2 and data[ u'dim'] == 1 and data[u'char_orbit_index'] == 1: ec_label = "%d.%s1" % ( data[u'level'], cremona_letter_code(data[u'hecke_orbit'] - 1)) r = db.ec_curves.lookup(ec_label)[u'rank'] if data[u'analytic_rank'] != r: print "*** winding element is nonzero, positive analytic rank %d for newform %s appears to be wrong ***" % ( data[u'rank'], data[u'label']) print data[u'label'] todo2.append(data[u'label']) else: print "verified that analytic rank %d of newform %s matches Mordell-Weil rank of elliptic curve %s" % ( data[u'analytic_rank'], data[u'label'], ec_label) continue print "Checking newform %s of dimension %d with analytic rank <= %d..." % ( data[u'label'], data[u'dim'], data[u'analytic_rank']) w = windingelement_hecke_cutter_projected(data, extra_cutter_bound=100) if w != 0: print "*** winding element is nonzero, positive analytic rank %d for newform %s appears to be wrong ***" % ( data[u'rank'], data[u'label']) print data[u'label'] todo2.append(data[u'label']) else: if data[u'analytic_rank'] == 2 and data["is_self_dual"]: print "Verified analytic rank is 2." vcnt += 1 else: print "Verified analytic rank > 0" todo3.append(data[u'label']) print "Processed newform %s in %.3f CPU seconds" % (data[u'label'], cputime() - start) cnt += 1 todo = list( db.mf_newforms.search({ u'analytic_rank': int(1), u'is_self_dual': False, u'analytic_rank_proved': False })) for i in range(len(todo)): if i % jobs != jobid: continue start = cputime() data = todo[i] if skip_real_char and data[u"char_is_real"]: continue print "Checking non-self-dual newform %s of dimension %d with analytic rank <= %d..." % ( data[u'label'], data[u'dim'], data[u'analytic_rank']) w = windingelement_hecke_cutter_projected(data, extra_cutter_bound=100) if w != 0: print "*** winding element is nonzero, positive analytic rank appears to be wrong ***" print data[u'label'] todo4.append(data[u'label']) else: print "Verified analytic rank is 1." vcnt += 1 print "Processed newform %s in %.3f CPU seconds" % (data[u'label'], cputime() - start) cnt += 1 print "Checked analytic ranks of %d newforms, of which %d were verified" % ( cnt, vcnt) if len(todo2) > 0 or len(todo4) > 0: print "The following newforms appear to have the wrong analytic rank:" for r in todo2: print " %s (claimed analytic rank %d)" % (r[u'lable'], r[u'analytic_rank']) for r in todo4: print " %s (claimed analytic rank %d)" % (r[u'lable'], r[u'analytic_rank']) if len(todo3) > 0: print "The following newforms have positive but unverified analytic ranks:" for r in todo2: print " %s (claimed analytic rank %d, proved nonzero)" % ( r[u'lable'], r[u'analytic_rank'])
def oldspace_decomposition(self): # Returns a latex string giving the decomposition of the old part. These come from levels M dividing N, with the conductor of the character dividing M. template = r"<a href={url}>\({old}\)</a>\(^{{\oplus {mult}}}\)" return r"\(\oplus\)".join(template.format(old=common_latex(N, self.weight, conrey, typ="new"), url=url_for(".by_url_space_label",level=N,weight=self.weight,char_orbit_label=cremona_letter_code(i-1)), mult=mult) for N, i, conrey, mult in self.oldspaces)
def render_Dirichletwebpage(modulus=None, orbit_label=None, number=None): if number is None and orbit_label is None and re.match(r'^[1-9][0-9]*\.[1-9][0-9]*$', modulus): modulus, number = modulus.split('.') return redirect(url_for(".render_Dirichletwebpage", modulus=modulus, number=number), 301) args = {} args['type'] = 'Dirichlet' args['modulus'] = modulus args['orbit_label'] = orbit_label args['number'] = number try: modulus = int(modulus) except ValueError: modulus = 0 if modulus <= 0: flash_error("%s is not a valid modulus for a Dirichlet character. It should be a positive integer.", args['modulus']) return redirect(url_for(".render_DirichletNavigation")) if modulus > 10**20: flash_error("specified modulus %s is too large, it should be less than $10^{20}$.", modulus) return redirect(url_for(".render_DirichletNavigation")) if number is None: if orbit_label is None: if modulus <= 10000: info = WebDBDirichletGroup(**args).to_dict() info['show_orbit_label'] = True else: info = WebSmallDirichletGroup(**args).to_dict() info['title'] = 'Group of Dirichlet characters of modulus ' + str(modulus) info['bread'] = bread([('%s' % modulus, url_for(".render_Dirichletwebpage", modulus=modulus))]) info['learnmore'] = learn() info['code'] = dict([(k[4:], info[k]) for k in info if k[0:4] == "code"]) info['code']['show'] = {lang: '' for lang in info['codelangs']} # use default show names if 'gens' in info: info['generators'] = ', '.join(r'<a href="%s">$\chi_{%s}(%s,\cdot)$' % (url_for(".render_Dirichletwebpage", modulus=modulus, number=g), modulus, g) for g in info['gens']) return render_template('CharGroup.html', **info) else: if modulus <= 10000: try: info = WebDBDirichletOrbit(**args).to_dict() except ValueError: flash_error( "No Galois orbit of Dirichlet characters with label %s.%s was found in the database.", modulus, orbit_label ) return redirect(url_for(".render_DirichletNavigation")) info['show_orbit_label'] = True info['learnmore'] = learn() info['code'] = dict([(k[4:], info[k]) for k in info if k[0:4] == "code"]) info['code']['show'] = {lang: '' for lang in info['codelangs']} # use default show names info['bread'] = bread( [('%s' % modulus, url_for(".render_Dirichletwebpage", modulus=modulus)), ('%s' % orbit_label, url_for(".render_Dirichletwebpage", modulus=modulus, orbit_label=orbit_label))]) return render_template('CharacterGaloisOrbit.html', **info) else: flash_error( "Galois orbits have only been computed for modulus up to 10,000, but you entered %s", modulus) return redirect(url_for(".render_DirichletNavigation")) try: number = label_to_number(modulus, number) except ValueError: flash_error( "the value %s is invalid. It should either be a positive integer " "coprime to and no greater than the modulus %s, or a letter that " "corresponds to a valid orbit index.", args['number'], args['modulus'] ) return redirect(url_for(".render_DirichletNavigation")) if modulus <= 10000: db_orbit_label = db.char_dir_values.lookup("{}.{}".format(modulus, number), projection='orbit_label') # The -1 in the line below is because labels index at 1, not 0 real_orbit_label = cremona_letter_code(int(db_orbit_label.partition('.')[-1]) - 1) if orbit_label is not None: if orbit_label != real_orbit_label: flash_warning( "The supplied character orbit label %s.%s was wrong. " "The correct orbit label is %s.%s. The URL has been duly corrected.", modulus, orbit_label, modulus, real_orbit_label) return redirect(url_for("characters.render_Dirichletwebpage", modulus=modulus, orbit_label=real_orbit_label, number=number)) args['orbit_label'] = real_orbit_label else: if orbit_label is not None: flash_warning( "You entered the character orbit label %s.%s. However, such labels " "have not been computed for this modulus. The supplied orbit " "label has therefore been ignored and expunged from the URL.", modulus, orbit_label) return redirect(url_for("characters.render_Dirichletwebpage", modulus=modulus, number=number)) args['number'] = number webchar, bread_crumbs = make_webchar(args, get_bread=True) info = webchar.to_dict() info['bread'] = bread_crumbs info['learnmore'] = learn() info['code'] = dict([(k[4:], info[k]) for k in info if k[0:4] == "code"]) info['code']['show'] = {lang: '' for lang in info['codelangs']} # use default show names info['KNOWL_ID'] = 'character.dirichlet.%s.%s' % (modulus, number) return render_template('Character.html', **info)
def do(level, weight, lfun_filename=None, instances_filename=None, hecke_filename=None, traces_filename=None, only_traces=False, only_orbit=None): print "N = %s, k = %s" % (level, weight) polyinfile = os.path.join(base_import, 'polydb/{}.{}.polydb'.format(level, weight)) mfdbinfile = os.path.join(base_import, 'mfdb/{}.{}.mfdb'.format(level, weight)) Ldbinfile = os.path.join(base_import, 'mfldb/{}.{}.mfldb'.format(level, weight)) notfound = False if not os.path.exists(polyinfile): print '{} not found'.format(polyinfile) notfound = True if not os.path.exists(mfdbinfile): print '{} not found'.format(mfdbinfile) notfound = True if not os.path.exists(Ldbinfile): print '{} not found'.format(Ldbinfile) notfound = True if only_orbit is not None: print "N = %s, k = %s, orbit = %s" % (level, weight, only_orbit) if lfun_filename is None: lfun_filename = os.path.join( base_export, 'CMF_Lfunctions_%d_%d_%d.txt' % (level, weight, only_orbit)) if instances_filename is None: instances_filename = os.path.join( base_export, 'CMF_instances_%d_%d_%d.txt' % (level, weight, only_orbit)) if hecke_filename is None: hecke_filename = os.path.join( base_export, 'CMF_hecke_cc_%d_%d_%d.txt' % (level, weight, only_orbit)) if traces_filename is None: traces_filename = os.path.join( base_export, 'CMF_traces_%d_%d_%d.txt' % (level, weight, only_orbit)) if lfun_filename is None: lfun_filename = os.path.join( base_export, 'CMF_Lfunctions_%d.txt' % (level * weight**2)) if instances_filename is None: instances_filename = os.path.join( base_export, 'CMF_instances_%d.txt' % (level * weight**2)) if hecke_filename is None: hecke_filename = os.path.join( base_export, 'CMF_hecke_cc_%d.txt' % (level * weight**2)) if traces_filename is None: traces_filename = os.path.join( base_export, 'CMF_traces_%d.txt' % (level * weight**2)) def write_traces(traces_filename): with open(traces_filename, 'a') as F: for ol in Set(orbit_labels.values()): if only_orbit is not None: if ol != only_orbit: continue F.write('{}:{}:{}:{}:{}\n'.format(level, weight, ol, degrees_sorted[ol], traces_sorted[ol]).replace( ' ', '')) #level_list = set() #level_weight_list = [] #for dirpath, dirnames, filenames in os.walk(inpath): # for filename in filenames: # if not filename.endswith('.polydb'): # continue # level, weight, _ = filename.split('.') # level = int(level) # weight = int(weight) # level_weight_list.append( (level, weight, os.path.join(dirpath, filename)) ) # level_list.add(level) # #level_list = sorted(level_list) orbit_labels = {} G = DirichletGroup_conrey(level) orbits = G._galois_orbits() for k, orbit in enumerate(orbits): for chi in orbit: # we are starting at 1 orbit_labels[chi] = k + 1 if level == 1: k = 0 orbit_labels = {1: 1} degrees_sorted = [[] for _ in range(k + 2)] traces_sorted = [[] for _ in range(k + 2)] dim = dimension_new_cusp_forms(Gamma1(level), weight) if notfound: assert dim == 0, "dim = %s" % dim write_traces(traces_filename) return 1 degree_lists = {} traces_lists = {} db = sqlite3.connect(polyinfile) db.row_factory = sqlite3.Row ''' expected schema: CREATE TABLE heckepolys (level INTEGER, weight INTEGER, chi INTEGER, whatevernumber INTEGER, labelnumber INTEGER, operator BLOB, degree INTEGER, mforbit BLOB, polynomial BLOB); ''' mfdb = sqlite3.connect(os.path.join(mfdbinfile)) mfdb.row_factory = sqlite3.Row ''' expected schema: CREATE TABLE modforms (level INTEGER, weight INTEGER, chi INTEGER, orbit INTEGER, j INTEGER, prec INTEGER, exponent INTEGER, ncoeffs INTEGER, coefficients BLOB) ''' coeffs = {} for result in mfdb.execute( 'SELECT prec, exponent, ncoeffs, coefficients, chi, j FROM modforms WHERE level={} AND weight={};' .format(level, weight)): chi = result['chi'] chibar = inverse_mod(chi, level) if only_orbit is not None and only_orbit not in [ orbit_labels[chi], orbit_labels[chibar] ]: continue is_trivial = False #is_quadratic = False if chi == 1: is_trivial = True #elif (chi*chi) % level == 1: # is_quadratic = True j = result['j'] offset = 0 coeffblob = result['coefficients'] exponent = QQ(result['exponent']) prec = QQ(result['prec']) # print prec, exponent _coeffs = [CCC(0)] * (to_compute + 1) #for k in range(35): # number of prime powers < 100 for pp in prime_powers(to_compute): z, bytes_read = read_gmp_int(coeffblob, offset) #print z offset = offset + bytes_read real_part = CCC(z) * 2**exponent if prec != MF_PREC_EXACT: real_part = real_part.add_error(2**prec) imag_part = 0 if not is_trivial: z, bytes_read = read_gmp_int(coeffblob, offset) offset = offset + bytes_read imag_part = CCC.gens()[0] * CCC(z) * 2**exponent if prec != MF_PREC_EXACT: imag_part = imag_part.add_error(2**prec) #print real_part + imag_part _coeffs[pp] = real_part + imag_part #print coeffs _coeffs[1] = CCC(1) extend_multiplicatively(_coeffs) coeffs[(chi, j)] = _coeffs if chibar > chi: coeffs[(chibar, j)] = [elt.conjugate() for elt in _coeffs] if only_orbit is None: assert len(coeffs) == dim, "%s != %s, keys = %s" % (len(coeffs), dim, coeffs.keys()) if not only_traces: bad_euler_factors = {} euler_factors = {} angles = {} coeffs_f = {} for key, coeff in coeffs.iteritems(): chi, j = key coeffs_f[key], angles[key], euler_factors[key], bad_euler_factors[ key] = angles_euler_factors(coeff, level, weight, chi) #mforbits = {} for result in db.execute( 'SELECT level, weight, chi, whatevernumber, labelnumber, degree, mforbit from heckepolys;' ): level = result['level'] weight = result['weight'] chi = result['chi'] original_chi = chi if only_orbit is not None and only_orbit != orbit_labels[original_chi]: continue if (level, weight, chi) not in degree_lists: degree_lists[(level, weight, chi)] = [] traces_lists[(level, weight, chi)] = [] degree_lists[(level, weight, chi)].append(result['degree']) #whatever = result['whatevernumber'] label = result['labelnumber'] #degree = result['degree'] mforbit = read_orbit(result['mforbit']) #mforbits[original_chi] = mforbit #print level, weight, chi, whatever, label, degree, mforbit #is_trivial = False #is_quadratic = False #if chi == 1: # is_trivial = True #elif (chi*chi) % level == 1: # is_quadratic = True traces_bound = to_compute + 1 traces = [RRR(0)] * traces_bound for chi, j in mforbit: #if inverse_mod(chi, level) < chi: # continue for k, z in enumerate(coeffs[(chi, j)][:traces_bound]): traces[k] += RRR(z.real()) for i, z in enumerate(traces): try: traces[i] = z.unique_integer() except ValueError: traces = traces[:i] #print (level, weight, original_chi, orbit_labels[original_chi]) #print degree_lists[(level, weight, original_chi)] #print i, z #print traces[:i] break traces_lists[(level, weight, original_chi)].append( (traces[1:], mforbit)) Ldb = sqlite3.connect(os.path.join(Ldbinfile)) Ldb.row_factory = sqlite3.Row ''' expected schema: CREATE TABLE modformLfunctions (level INTEGER, weight INTEGER, chi INTEGER, orbit INTEGER, j INTEGER, rank INTEGER, rankverified INTEGER, signarg REAL gamma1 REAL, gamma2 REAL, gamma3 REAL, zeroprec INTEGER, nzeros INTEGER, zeros BLOB, valuesdelta REAL, nvalues INTEGER, Lvalues BLOB); ''' zeros = {} Ldbresults = {} if only_traces: cur = [] else: cur = Ldb.execute( 'SELECT level, weight, chi, j, rank, zeroprec, nzeros, zeros, valuesdelta, nvalues, Lvalues, signarg from modformLfunctions' ) for result in cur: nzeros = result['nzeros'] prec = result['zeroprec'] chi = result['chi'] if only_orbit is not None and only_orbit != orbit_labels[chi]: continue j = result['j'] #print result['level'], result['weight'], chi, j _zeros = [] offset = 0 for k in range(nzeros): nlimbs = struct.unpack_from(">I", result['zeros'], offset)[0] offset = offset + 4 zdata = struct.unpack_from("B" * nlimbs, result['zeros'], offset) offset = offset + nlimbs z = sum([x * 2**(8 * k) for (k, x) in enumerate(reversed(zdata))]) _zeros.append(z) zeros[(chi, j)] = map(ZZ, _zeros) Ldbresults[(chi, j)] = result ''' for level, weight, chi in sorted(degree_lists.keys()): toprint = '{}:{}:{}:[{}]:[{}]'.format(level, weight, orbit_labels[chi], sorted(degree_lists[(level, weight, chi)]), sorted(traces_lists[(level, weight, chi)])) print ''.join(toprint.split()) for chi2, j in mforbits[chi]: print chi2, j, zeros[(chi2, j)] ''' labels = {} original_pair = {} conjugates = {} selfduals = {} hecke_orbit_code = {} all_the_labels = {} embedding_m = {} for level, weight, originalchi in sorted(degree_lists.keys()): #toprint = '{}:{}:{}:{}'.format(level, weight, orbit_labels[originalchi], sorted(degree_lists[(level, weight, originalchi)])) #print ''.join(toprint.split()) degrees_sorted[orbit_labels[originalchi]] = sorted( degree_lists[(level, weight, originalchi)]) for mforbitlabel, (traces, mforbit) in enumerate( sorted(traces_lists[(level, weight, originalchi)])): selfdual = False if originalchi == 1: selfdual = True if (originalchi * originalchi) % level == 1: Z = coeffs[mforbit[0]] selfdual = True for z in Z: if not z.imag().contains_zero(): selfdual = False break #if selfdual: # print '*', #print mforbit, traces traces_sorted[orbit_labels[originalchi]].append(traces[:to_store]) if only_traces: continue chi_list = sorted(set(chi for (chi, j) in mforbit)) coeffs_list = {} for chi in chi_list: j_list = [elt for (_, elt) in mforbit if _ == chi] coeffs_list[chi] = [(chi, elt, coeffs[(chi, elt)]) for elt in j_list] coeffs_list[chi].sort(cmp=CBFlistcmp, key=lambda z: z[-1]) d = len(j_list) m = 1 for chi in chi_list: chibar = inverse_mod(chi, level) for k, _coeffs in enumerate(coeffs_list[chi]): j = _coeffs[1] assert chi == _coeffs[0] sa, sn = cremona_letter_code(mforbitlabel), k + 1 ol = cremona_letter_code(orbit_labels[chi] - 1) an_conjugate = [elt.conjugate() for elt in _coeffs[2]] if selfdual: chibar = chi ca, cn = sa, sn else: ca = sa # first try the obvious for elt in [k] + list(range(0, k)) + list( range(k + 1, d)): if CBFlisteq(coeffs_list[chibar][elt][2], an_conjugate): cn = elt + 1 break else: assert False assert CBFlisteq(coeffs_list[chibar][cn - 1][2], an_conjugate) # orbit_labels[chi] start at 1 # mforbitlabel starts at 0 hecke_orbit_code[(chi, j)] = int(level + (weight << 24) + ( (orbit_labels[chi] - 1) << 36) + (mforbitlabel << 52)) all_the_labels[(chi, j)] = (level, weight, ol, sa, chi, sn) converted_label = (chi, sa, sn) labels[(chi, j)] = converted_label original_pair[converted_label] = (chi, j) selfduals[converted_label] = selfdual conjugates[converted_label] = (chibar, ca, cn) embedding_m[(chi, j)] = m m += 1 if only_traces: write_traces(traces_filename) return 0 #for key, val in labels.iteritems(): # print key," \t-new->\t", val #for key, val in conjugates.iteritems(): # print key,"\t--c-->\t", val #for key, val in all_the_labels.iteritems(): # print key," \t--->\t" + "\t".join( map(str, [val,hecke_orbit_code[key]])) def origin(chi, a, n): return "ModularForm/GL2/Q/holomorphic/%d/%d/%s/%s/%d/%d" % ( level, weight, cremona_letter_code(orbit_labels[chi] - 1), a, chi, n) def rational_origin(chi, a): return "ModularForm/GL2/Q/holomorphic/%d/%d/%s/%s" % ( level, weight, cremona_letter_code(orbit_labels[chi] - 1), a) def label(chi, j): return labels[(chi, j)] def self_dual(chi, a, n): return selfduals[(chi, a, n)] Lhashes = {} instances = {} # the function below assumes this order assert schema_instances == ['url', 'Lhash', 'type'] def tuple_instance(row): return (row['origin'], row['Lhash'], default_type) real_zeros = {} rows = {} def populate_complex_row(Ldbrow): row = dict(constant_lf(level, weight, 2)) chi = int(Ldbrow['chi']) j = int(Ldbrow['j']) chil, a, n = label(chi, j) assert chil == chi row['order_of_vanishing'] = int(Ldbrow['rank']) zeros_as_int = zeros[(chi, j)][row['order_of_vanishing']:] prec = row['accuracy'] = Ldbrow['zeroprec'] two_power = 2**prec double_zeros = [float(z / two_power) for z in zeros_as_int] zeros_as_real = [ RealNumber(z.str() + ".") / two_power for z in zeros_as_int ] real_zeros[(chi, a, n)] = zeros_as_real zeros_as_str = [z.str(truncate=False) for z in zeros_as_real] for i, z in enumerate(zeros_as_str): assert float(z) == double_zeros[i] assert (RealNumber(z) * two_power).round() == zeros_as_int[i] row['positive_zeros'] = str(zeros_as_str).replace("'", "\"") row['origin'] = origin(chi, a, n) row['central_character'] = "%s.%s" % (level, chi) row['self_dual'] = self_dual(chi, a, n) row['conjugate'] = None row['Lhash'] = str((zeros_as_int[0] * 2**(100 - prec)).round()) if prec < 100: row['Lhash'] = '_' + row['Lhash'] Lhashes[(chi, a, n)] = row['Lhash'] row['sign_arg'] = float(Ldbrow['signarg'] / (2 * pi)) for i in range(0, 3): row['z' + str(i + 1)] = (RealNumber(str(zeros_as_int[i]) + ".") / 2**prec).str() row['plot_delta'] = Ldbrow['valuesdelta'] row['plot_values'] = [ float(CDF(elt).real_part()) for elt in struct.unpack('{}d'.format(len(Ldbrow['Lvalues']) / 8), Ldbrow['Lvalues']) ] row['leading_term'] = '\N' if row['self_dual']: row['root_number'] = str( RRR(CDF(exp(2 * pi * I * row['sign_arg'])).real()).unique_integer()) if row['root_number'] == str(1): row['sign_arg'] = 0 elif row['root_number'] == str(-1): row['sign_arg'] = 0.5 else: row['root_number'] = str(CDF(exp(2 * pi * I * row['sign_arg']))) #row['dirichlet_coefficients'] = [None] * 10 #print label(chi,j) for i, ai in enumerate(coeffs[(chi, j)][2:12]): if i + 2 <= 10: row['a' + str(i + 2)] = CBF_to_pair(ai) # print 'a' + str(i+2), ai_jsonb #row['dirichlet_coefficients'][i] = ai_jsonb row['coefficient_field'] = 'CDF' # only 30 row['euler_factors'] = map(lambda x: map(CBF_to_pair, x), euler_factors[(chi, j)][:30]) row['bad_lfactors'] = map( lambda x: [int(x[0]), map(CBF_to_pair, x[1])], bad_euler_factors[(chi, j)]) for key in schema_lf: assert key in row, "%s not in row = %s" % (key, row) assert len(row) == len(schema_lf), "%s != %s" % (len(row), len(schema_lf)) #rewrite row as a list rows[(chi, a, n)] = [row[key] for key in schema_lf] instances[(chi, a, n)] = tuple_instance(row) def populate_complex_rows(): for key, row in Ldbresults.iteritems(): populate_complex_row(row) def populate_conjugates(): # print Lhashes.keys() for key, row in rows.iteritems(): # print "key = %s" % (key,) row[schema_lf_dict['conjugate']] = Lhashes[conjugates[key]] row_conj = rows[conjugates[key]] zero_val_conj = row_conj[schema_lf_dict['plot_values']][0] assert (row[schema_lf_dict['plot_values']][0] - zero_val_conj) < 1e-10, "%s, %s: %s - %s = %s" % ( key, conjugates[key], row[schema_lf_dict['plot_values']][0], zero_val_conj, row[schema_lf_dict['plot_values']][0] - zero_val_conj) diff = (row[schema_lf_dict['sign_arg']] + row_conj[schema_lf_dict['sign_arg']]) % 1 assert min(diff, 1 - diff) < 1e-10, "%s + %s = %s" % ( row[schema_lf_dict['sign_arg']], row_conj[schema_lf_dict['sign_arg']], diff) rational_rows = {} def populate_rational_rows(): order_of_vanishing = schema_lf_dict['order_of_vanishing'] accuracy = schema_lf_dict['accuracy'] sign_arg = schema_lf_dict['sign_arg'] Lhash = schema_lf_dict['Lhash'] plot_delta = schema_lf_dict['plot_delta'] plot_values = schema_lf_dict['plot_values'] central_character = schema_lf_dict['central_character'] # reverse euler factors from the table for p^d < 1000 rational_keys = {} for chi, a, n in rows.keys(): orbit_label = orbit_labels[chi] if (orbit_label, a) not in rational_keys: rational_keys[(orbit_label, a)] = [] rational_keys[(orbit_label, a)].append((chi, a, n)) for (orbit_label, a), triples in rational_keys.iteritems(): # for now skip degree >= 100 if len(triples) > 80: # the real limit is 87 continue pairs = [original_pair[elt] for elt in triples] #print a, pairs, triples chi = triples[0][0] degree = 2 * len(triples) row = constant_lf(level, weight, degree) row['origin'] = rational_origin(chi, a) print row['origin'] row['self_dual'] = 't' row['conjugate'] = '\N' row['order_of_vanishing'] = sum( [rows[elt][order_of_vanishing] for elt in triples]) row['accuracy'] = min([rows[elt][accuracy] for elt in triples]) ### zeros_as_real = [] for elt in triples: zeros_as_real.extend(real_zeros[elt]) zeros_as_real.sort() zeros_as_str = [z.str(truncate=False) for z in zeros_as_real] row['positive_zeros'] = str(zeros_as_str).replace("'", "\"") zeros_hash = sorted([(rows[elt][Lhash], real_zeros[elt][0]) for elt in triples], key=lambda x: x[1]) row['Lhash'] = ",".join([elt[0] for elt in zeros_hash]) # character if degree == 2: row['central_character'] = rows[triples[0]][central_character] else: G = DirichletGroup_conrey(level) chiprod = prod([ G[int(rows[elt][central_character].split(".")[-1])] for elt in triples ]) chiprod_index = chiprod.number() row['central_character'] = "%s.%s" % (level, chiprod_index) row['sign_arg'] = sum([rows[elt][sign_arg] for elt in triples]) while row['sign_arg'] > 0.5: row['sign_arg'] -= 1 while row['sign_arg'] <= -0.5: row['sign_arg'] += 1 zeros_zi = [] for i in range(0, 3): for elt in triples: zeros_zi.append(rows[elt][schema_lf_dict['z' + str(i + 1)]]) zeros_zi.sort(key=lambda x: RealNumber(x)) for i in range(0, 3): row['z' + str(i + 1)] = zeros_zi[i] deltas = [rows[elt][plot_delta] for elt in triples] values = [rows[elt][plot_values] for elt in triples] row['plot_delta'], row['plot_values'] = prod_plot_values( deltas, values) row['leading_term'] = '\N' row['root_number'] = str( RRR(CDF(exp(2 * pi * I * row['sign_arg'])).real()).unique_integer()) if row['root_number'] == str(1): row['sign_arg'] = 0 elif row['root_number'] == str(-1): row['sign_arg'] = 0.5 row['coefficient_field'] = '1.1.1.1' for chi, _, _ in triples: if (level, weight, chi) in traces_lists: for elt in traces_lists[(level, weight, chi)]: if set(elt[1]) <= set(pairs): traces = elt[0] break else: print pairs print traces_lists[(level, weight, chi)] assert False break else: print pairs print traces_lists assert False euler_factors_cc = [euler_factors[elt] for elt in pairs] row['euler_factors'], row[ 'bad_lfactors'], dirichlet = rational_euler_factors( traces, euler_factors_cc, level, weight) #handling Nones row['euler_factors'] = json.dumps(row['euler_factors']) row['bad_lfactors'] = json.dumps(row['bad_lfactors']) # fill in ai for i, ai in enumerate(dirichlet): if i > 1: row['a' + str(i)] = int(dirichlet[i]) #print 'a' + str(i), dirichlet[i] for key in schema_lf: assert key in row, "%s not in row = %s" % (key, row.keys()) for key in row.keys(): assert key in schema_lf, "%s unexpected" % key assert len(row) == len(schema_lf), "%s != %s" % (len(row), len(schema_lf)) #rewrite row as a list rational_rows[(orbit_label, a)] = [row[key] for key in schema_lf] instances[(orbit_label, a)] = tuple_instance(row) # if dim == 1, drop row if len(triples) == 1: rows.pop(triples[0]) instances.pop(triples[0]) def get_hecke_cc(): # if field_poly exists then compute the corresponding embedding of the root # add the conrey label hecke_cc = {} for key, label in labels.iteritems(): # key = (chi,j) # label = (chi, a, n) chi, a, n = label ol = cremona_letter_code(orbit_labels[chi] - 1) lfuntion_label = ".".join( map(str, [level, weight] + [ol, a, chi, n])) hecke_cc[key] = [ int(hecke_orbit_code[key]), lfuntion_label, # N.k.c.x.n int(label[0]), # conrey_label int(label[2]), # embedding_index int(embedding_m[key]), '\N', # embedding_root_real '\N', # embedding_root_imag coeffs_f[key][1:], angles[key], ] return hecke_cc def json_hack(elt): if isinstance(elt, str): return elt else: return json.dumps(elt) def write_hecke_cc(hecke_filename): write_header_hecke_file(hecke_filename) with open(hecke_filename, 'a') as HF: for v in get_hecke_cc().values(): try: HF.write("\t".join(map(json_hack, v)).replace( '[', '{').replace(']', '}') + "\n") except TypeError: for elt in v: print elt print json_hack(elt) raise def export_complex_rows(lfunctions_filename, instances_filename): write_header(lfunctions_filename, instances_filename) #str_parsing_lf = '\t'.join(['%r'] * len(schema_lf)) + '\n' #str_parsing_instances = '\t'.join(['%r'] * len(schema_instances)) + '\n' with open(lfunctions_filename, 'a') as LF: for key, row in rows.iteritems(): try: LF.write("\t".join(map(json_hack, row)) + "\n") except TypeError: for i, elt in enumerate(row): print schema_lf[i] print elt print json_hack(elt) raise for key, row in rational_rows.iteritems(): try: LF.write("\t".join(map(json_hack, row)) + "\n") except TypeError: for elt in row: print elt print json_hack(elt) raise with open(instances_filename, 'a') as IF: for key, row in instances.iteritems(): IF.write("\t".join(map(json_hack, row)) + "\n") populate_complex_rows() #populate_conjugates() #populate_rational_rows() #export_complex_rows(lfun_filename, instances_filename) write_hecke_cc(hecke_filename) #write_traces(traces_filename) return 0
def bread(self): kwds = dict(level=self.level, weight=self.weight, char_orbit_label=self.char_orbit_label, hecke_orbit=cremona_letter_code(self.hecke_orbit - 1)) if self.embedding_label is not None: kwds['embedding_label'] = self.embedding_label return get_bread(**kwds)
def __init__(self, data, space=None, all_m = False, all_n = False, embedding_label = None): #TODO validate data # Need to set level, weight, character, num_characters, degree, has_exact_qexp, has_complex_qexp, hecke_ring_index, is_twist_minimal # Make up for db_backend currently deleting Nones for elt in db.mf_newforms.col_type: if elt not in data: data[elt] = None self.__dict__.update(data) self._data = data self.embedding_label = embedding_label self.hecke_orbit_label = cremona_letter_code(self.hecke_orbit - 1) if self.level == 1 or ZZ(self.level).is_prime(): self.factored_level = '' else: self.factored_level = ' = ' + ZZ(self.level).factor()._latex_() if 'field_disc_factorization' not in data: # Until we have search results include nulls self.field_disc_factorization = None elif self.field_disc_factorization: self.field_disc_factorization = [(ZZ(p), ZZ(e)) for p, e in self.field_disc_factorization] self.rel_dim = self.dim // self.char_degree self.has_analytic_rank = data.get('analytic_rank') is not None self.texp = [0] + self.traces self.texp_prec = len(self.texp) #self.char_conrey = self.conrey_indexes[0] #self.char_conrey_str = '\chi_{%s}(%s,\cdot)' % (self.level, self.char_conrey) self.character_label = "\(" + str(self.level) + "\)." + self.char_orbit_label self.hecke_ring_character_values = None self.single_generator = None self.has_exact_qexp = False if self.embedding_label is None: hecke_cols = ['hecke_ring_numerators', 'hecke_ring_denominators', 'hecke_ring_inverse_numerators', 'hecke_ring_inverse_denominators', 'hecke_ring_cyclotomic_generator', 'hecke_ring_character_values', 'hecke_ring_power_basis', 'maxp'] eigenvals = db.mf_hecke_nf.lucky({'hecke_orbit_code':self.hecke_orbit_code}, ['an'] + hecke_cols) if eigenvals and eigenvals.get('an'): self.has_exact_qexp = True for attr in hecke_cols: setattr(self, attr, eigenvals.get(attr)) m = self.hecke_ring_cyclotomic_generator if m is None or m == 0: zero = [0] * self.dim else: zero = [] self.qexp = [zero] + eigenvals['an'] self.qexp_prec = len(self.qexp) self.single_generator = self.hecke_ring_power_basis or (self.dim == 2) else: hecke_cols = ['hecke_ring_cyclotomic_generator', 'hecke_ring_power_basis'] hecke_data = db.mf_hecke_nf.lucky({'hecke_orbit_code':self.hecke_orbit_code}, hecke_cols) if hecke_data: for attr in hecke_cols: setattr(self, attr, hecke_data.get(attr)) self.single_generator = self.hecke_ring_power_basis or (self.dim == 2) # get data from char_dir_values self.char_conrey = self.embedding_label.split('.')[0] char_values = db.char_dir_values.lucky({'label': '%s.%s' % (self.level, self.char_conrey)},['order','values_gens']) if char_values is None: raise ValueError("Invalid Conrey label") self.hecke_ring_character_values = char_values['values_gens'] # [[i,[[1, m]]] for i, m in char_values['values_gens']] self.hecke_ring_cyclotomic_generator = char_values['order'] # sort by the generators if self.hecke_ring_character_values: self.hecke_ring_character_values.sort(key = lambda elt: elt[0]) ## CC_DATA self.has_complex_qexp = False # stub, overwritten by setup_cc_data. self.plot = db.mf_newform_portraits.lookup(self.label, projection = "portrait") # properties box if embedding_label is None: self.properties = [('Label', self.label)] else: self.properties = [('Label', '%s.%s' % (self.label, self.embedding_label))] if self.plot is not None: self.properties += [(None, '<img src="{0}" width="200" height="200"/>'.format(self.plot))] self.properties += [('Level', str(self.level)), ('Weight', str(self.weight))] if self.embedding_label is None: self.properties.append(('Character orbit', '%s.%s' % (self.level, self.char_orbit_label))) else: self.properties.append(('Character', '%s.%s' % (self.level, self.char_conrey))) if self.is_self_dual != 0: self.properties += [('Self dual', 'Yes' if self.is_self_dual == 1 else 'No')] self.properties += [('Analytic conductor', '%.3f'%(self.analytic_conductor))] if self.analytic_rank is not None: self.properties += [('Analytic rank', str(int(self.analytic_rank)))] self.properties += [('Dimension', str(self.dim))] if self.projective_image: self.properties += [('Projective image', '\(%s\)' % self.projective_image_latex)] # Artin data would make the property box scroll #if self.artin_degree: # artin_degree > 0 # self.properties += [('Artin image size', str(self.artin_degree))] #if self.artin_image: # self.properties += [('Artin image', '\(%s\)' % self.artin_image_display)] if self.is_cm and self.is_rm: disc = ', '.join([ str(d) for d in self.self_twist_discs ]) self.properties += [('CM/RM disc.', disc)] elif self.is_cm: disc = ' and '.join([ str(d) for d in self.self_twist_discs if d < 0 ]) self.properties += [('CM disc.', disc)] elif self.is_rm: disc = ' and '.join([ str(d) for d in self.self_twist_discs if d > 0 ]) self.properties += [('RM disc.', disc)] elif self.weight == 1: self.properties += [('CM/RM', 'No')] else: self.properties += [('CM', 'No')] if self.inner_twist_count >= 1: self.properties += [('Inner twists', str(self.inner_twist_count))] self.title = "Newform %s"%(self.label)
def __init__(self, level=1, weight=12, character=1, label='a', prec=0, parent=None, update_from_db=True,**kwargs): emf_logger.debug("In WebNewForm {0}".format((level,weight,character,label,parent,update_from_db))) if isinstance(level,basestring) or kwargs.has_key('hecke_orbit_label'): hecke_orbit_label = kwargs.get('hecke_orbit_label', level) level,weight,character,label = parse_newform_label(hecke_orbit_label) self._reduction = (type(self),(level,weight,character,label),{'parent':parent,'update_from_db':update_from_db}) if isinstance(character, WebChar): character_number = character.number else: character_number = character character = None if parent is None else parent.character if not isinstance(label,basestring): if isinstance(label,(int,Integer)): label = cremona_letter_code(label) else: raise ValueError,"Need label either string or integer! We got:{0}".format(label) emf_logger.debug("Before init properties 0") self._properties = WebProperties( WebInt('level', value=level), WebInt('weight', value=weight), WebCharProperty('character', modulus=level, number=character_number, value = character, include_in_update = True if character is None else False), WebStr('character_naming_scheme', value='Conrey'), WebStr('sage_version', value=''), WebStr('hecke_orbit_label', default_value=newform_label(level, weight, character_number, label)), WebStr('label', default_value=label), WebInt('dimension'), WebqExp('q_expansion'), WebCoeffs('_coefficients'), WebDict('_embeddings'), WebInt('prec',value=0, save_to_db=False, save_to_fs=True), WebNumberField('base_ring'), WebNumberField('coefficient_field'), WebInt('coefficient_field_degree'), WebList('twist_info', required = False), WebInt('is_cm', required = False), WebInt('cm_disc', required = False, default_value=0), WebDict('_cm_values',required=False), WebBool('is_cuspidal',default_value=True), WebDict('satake', required=False), WebDict('_atkin_lehner_eigenvalues', required=False), WebBool('is_rational'), WebPoly('absolute_polynomial'), WebFloat('version', value=float(emf_version), save_to_fs=True), WebDict('explicit_formulas',required=False), WebDate('creation_date',value=None), WebModFormSpaceProperty('parent', value=parent, level = level, weight = weight, character = character_number, update_hecke_orbits=False, update_from_db=update_from_db) # include_in_update = True if parent is None # else False), ) self._add_to_fs_query = {'prec': {'$gt': int(prec-1)}} super(WebNewForm, self).__init__( update_from_db=update_from_db, **kwargs ) self._add_to_fs_query = {'prec': {'$gt': int(self.prec-1)}} # We're setting the WebEigenvalues property after calling __init__ of the base class # because it will set hecke_orbit_label from the db first ## ## We don't init the eigenvalues (since E*v is slow) ## unless we (later) request a coefficient which is not ## in self._coefficients self.eigenvalues = WebEigenvalues(self.hecke_orbit_label, prec = self.prec, \ init_dynamic_properties=False, \ update_from_db = False) self.make_code_snippets()
def __init__(self, data, space=None, all_m = False, all_n = False): #TODO validate data # Need to set level, weight, character, num_characters, degree, has_exact_qexp, has_complex_qexp, hecke_ring_index, is_twist_minimal # Make up for db_backend currently deleting Nones for elt in db.mf_newforms.col_type: if elt not in data: data[elt] = None self.__dict__.update(data) self._data = data self.hecke_orbit_label = cremona_letter_code(self.hecke_orbit - 1) if self.level == 1 or ZZ(self.level).is_prime(): self.factored_level = '' else: self.factored_level = ' = ' + ZZ(self.level).factor()._latex_() # We always print analytic conductor with 1 decimal digit self.analytic_conductor = '%.1f'%(self.analytic_conductor) self.single_generator = self.hecke_ring_power_basis or (self.dim == 2) if self.has_inner_twist != 0: if self.inner_twist_proved: if len(self.inner_twist == 1): self.star_twist = 'inner twist' else: self.star_twist = 'inner twists' elif len(self.inner_twist) == 1: self.star_twist = 'inner twist*' else: self.star_twist = 'inner twists*' self.has_analytic_rank = data.get('analytic_rank') is not None eigenvals = db.mf_hecke_nf.search({'hecke_orbit_code':self.hecke_orbit_code, 'n':{'$lt':100}}, ['n','an','trace_an'], sort=['n']) if eigenvals: # this should always be true self.has_exact_qexp = True zero = [0] * self.dim self.qexp = [zero] self.texp = [0] for i, ev in enumerate(eigenvals, 1): if ev['n'] != i: raise ValueError("Missing eigenvalue") self.texp.append(ev['trace_an']) if ev.get('an'): self.qexp.append(ev['an']) else: # only had traces self.has_exact_qexp = False self.qexp_prec = len(self.qexp) self.texp_prec = len(self.texp) else: self.has_exact_qexp = False self.rel_dim = self.dim // self.char_degree ## CC_DATA self.cqexp_prec = 1001 # Initial estimate for error messages in render_newform_webpage. # Should get updated in setup_cc_data. self.has_complex_qexp = False # stub, overwritten by setup_cc_data. self.char_conrey = self.char_labels[0] self.char_conrey_str = '\chi_{%s}(%s,\cdot)' % (self.level, self.char_conrey) self.char_conrey_link = url_character(type='Dirichlet', modulus=self.level, number=self.char_conrey) if self.has_inner_twist: self.inner_twist = [(chi,url_character(type='Dirichlet', modulus=self.level, number=chi)) for chi in self.inner_twist] self.character_label = "\(" + str(self.level) + "\)." + self.char_orbit_label self.has_further_properties = (self.is_cm != 0 or self.__dict__.get('is_twist_minimal') or self.has_inner_twist != 0 or self.char_orbit_index == 1 and self.level != 1 or self.hecke_cutters) self.plot = db.mf_newform_portraits.lookup(self.label, projection = "portrait") # properties box self.properties = [('Label', self.label)] if self.plot is not None: self.properties += [(None, '<a href="{0}"><img src="{0}" width="200" height="200"/></a>'.format(self.plot))] self.properties += [('Level', str(self.level)), ('Weight', str(self.weight)), ('Character orbit', '%s.%s' % (self.level, self.char_orbit_label))] if self.is_self_dual != 0: self.properties += [('Self dual', 'Yes' if self.is_self_dual == 1 else 'No')] self.properties += [('Analytic conductor', self.analytic_conductor)] if self.analytic_rank is not None: self.properties += [('Analytic rank', str(int(self.analytic_rank)))] self.properties += [('Dimension', str(self.dim))] if self.projective_image: self.properties += [('Projective image', '\(%s\)' % self.projective_image_latex)] if self.artin_degree: # artin_degree > 0 self.properties += [('Artin image size', str(self.artin_degree))] if self.artin_image: self.properties += [('Artin image', '\(%s\)' % self.artin_image_display)] if self.is_self_twist ==1: if self.is_cm == 1: disc = ' and '.join([ str(d) for d in self.self_twist_discs if d < 0 ]) self.properties += [('CM discriminant', disc)] elif self.is_cm == -1: self.properties += [('CM', 'No')] if self.weight == 1: if self.is_rm == 1: disc = ' and '.join([ str(d) for d in self.self_twist_discs if d > 0 ]) self.properties += [('RM discriminant', disc)] elif self.is_rm == -1: self.properties += [('RM', 'No')] # Breadcrumbs self.bread = get_bread(level=self.level, weight=self.weight, char_orbit_label=self.char_orbit_label, hecke_orbit=cremona_letter_code(self.hecke_orbit - 1)) self.title = "Newform %s"%(self.label)
def __init__(self, level=1, weight=12, character=1, label='a', prec=10, parent=None, update_from_db=True,**kwargs): emf_logger.debug("In WebNewForm {0}".format((level,weight,character,label,parent,update_from_db))) if isinstance(level,basestring) or kwargs.has_key('hecke_orbit_label'): hecke_orbit_label = kwargs.get('hecke_orbit_label', level) level,weight,character,label = parse_newform_label(hecke_orbit_label) self._reduction = (type(self),(level,weight,character,label),{'parent':parent,'update_from_db':update_from_db}) if isinstance(character, WebChar): character_number = character.number else: character_number = character character = None if parent is None else parent.character if not isinstance(label,basestring): if isinstance(label,(int,Integer)): label = cremona_letter_code(label) else: raise ValueError,"Need label either string or integer! We got:{0}".format(label) emf_logger.debug("Before init properties 0") self._properties = WebProperties( WebInt('level', value=level), WebInt('weight', value=weight), WebCharProperty('character', modulus=level, number=character_number, value = character, include_in_update = True if character is None else False), WebStr('character_naming_scheme', value='Conrey'), WebStr('sage_version', value=''), WebStr('hecke_orbit_label', default_value=newform_label(level, weight, character_number, label)), WebStr('label', default_value=label), WebInt('dimension'), WebqExp('q_expansion'), WebDict('_coefficients'), WebDict('_embeddings'), WebInt('prec',value=0, save_to_db=False, save_to_fs=True), WebNumberField('base_ring'), WebNumberField('coefficient_field'), WebInt('coefficient_field_degree'), WebList('twist_info', required = False), WebInt('is_cm', required = False), WebInt('cm_disc', required = False, default_value=0), WebDict('_cm_values',required=False), WebBool('is_cuspidal',default_value=True), WebDict('satake', required=False), WebDict('_atkin_lehner_eigenvalues', required=False), WebBool('is_rational'), WebPoly('absolute_polynomial'), WebFloat('version', value=float(emf_version), save_to_fs=True), WebDict('explicit_formulas',required=False), WebDate('creation_date',value=None), WebModFormSpaceProperty('parent', value=parent, level = level, weight = weight, character = character_number, update_hecke_orbits=False, update_from_db=update_from_db) # include_in_update = True if parent is None # else False), ) emf_logger.debug("After init properties 1, update_from_db = {}".format(update_from_db)) self._add_to_fs_query = {'prec': {'$gt': int(prec-1)}} emf_logger.debug("add_to_fs_query = {}".format(self._add_to_fs_query)) super(WebNewForm, self).__init__( update_from_db=update_from_db, **kwargs ) emf_logger.debug("After init properties 2") self._add_to_fs_query = {'prec': {'$gt': int(self.prec-1)}} # We're setting the WebEigenvalues property after calling __init__ of the base class # because it will set hecke_orbit_label from the db first ## ## We don't init the eigenvalues (since E*v is slow) ## unless we (later) request a coefficient which is not ## in self._coefficients self.eigenvalues = WebEigenvalues(self.hecke_orbit_label, prec = self.prec, \ init_dynamic_properties=False, \ update_from_db = update_from_db) emf_logger.debug("After init properties 3")
def paintSvgHolo(Nmin, Nmax, kmin, kmax): # the import must be here to avoid circular import from lmfdb.classical_modular_forms.web_space import WebGamma1Space xfactor = 90 yfactor = 30 extraSpace = 20 ticlength = 4 radius = 3.3 xdotspacing = 0.11 # horizontal spacing of dots ydotspacing = 0.28 # vertical spacing of dots colourplus = signtocolour(1) colourminus = signtocolour(-1) maxdots = 5 # max number of dots to display ans = svgBegin() xMax = int(Nmax) yMax = int(kmax) width = xfactor * xMax + extraSpace height = yfactor * yMax + extraSpace ans += paintCSHolo(width, height, xMax, yMax, xfactor, yfactor, ticlength) # alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'] # loop over levels and weights for x in range(int(Nmin), int(Nmax) + 1): # x is the level for y in range(int(kmin), int(kmax) + 1): # y is the weight # lid = "(" + str(x) + "," + str(y) + ")" # not used linkurl = "/L/ModularForm/GL2/Q/holomorphic/" + str(x) + "/" + str( y) + "/1/" try: WS = WebGamma1Space(level=x, weight=y) except ValueError: continue newspaces = WS.decomp # numlabels = len(WS.decomp) # one label per Galois orbit # thelabels = alphabet[0:numlabels] # list of labels for the Galois orbits for weight y, level x # countplus = 0 # count how many Galois orbits have sign Plus (+ 1) # not used # countminus = 0 # count how many Galois orbits have sign Minus (- 1) # not used ybaseplus = y # baseline y-coord for plus cases ybaseminus = y # baseline y-coord for minus cases numpluslabels = 0 numminuslabels = 0 for newsp in newspaces: # looping over Galois orbit for MF in newsp[1]: print(MF) linkurl = "/L/ModularForm/GL2/Q/holomorphic/%d/%d/%s/%s/" % ( x, y, MF['char_orbit_label'], cremona_letter_code(MF['hecke_orbit'] - 1)) numberwithlabel = MF[ 'dim'] # number of forms in the Galois orbit # frickeeigenvalue = prod(MF.atkin_lehner_eigenvalues().values()) # gives Fricke eigenvalue self_dual = MF['char_is_real'] * (-1)**float( y / 2) # sign of functional equation xbase = x - self_dual * (xdotspacing / 2.0) if self_dual > 0: # go to right in BLUE if plus ybase = ybaseplus ybaseplus += ydotspacing thiscolour = colourplus numpluslabels += 1 else: # go to the left in RED of minus ybase = ybaseminus ybaseminus += ydotspacing thiscolour = colourminus numminuslabels += 1 if numberwithlabel > maxdots: # if more than maxdots in orbit, use number as symbol xbase += 1.5 * self_dual * xdotspacing if self_dual < 0: # move over more to position numbers on minus side. xbase += self_dual * xdotspacing ybase += -0.5 * ydotspacing if (self_dual > 0 and numpluslabels > 1) or ( self_dual < 0 and numminuslabels > 1): ybase += ydotspacing ans += "<a xlink:href='" + url_for( 'not_yet_implemented') + "' target='_top'>\n" # TODO: Implement when there is more than maxdots forms ans += ("<text x='" + str(float(xbase) * xfactor)[0:7] + "' y='" + str(height - float(ybase) * yfactor)[0:7] + "' style='fill:" + thiscolour + ";font-size:14px;font-weight:bold;'>" + str(numberwithlabel) + "</text>\n") ans += "</a>\n" if self_dual < 0: ybaseminus += 1.5 * ydotspacing else: ybaseplus += 1.5 * ydotspacing else: # otherwise, use one dot per form in orbit, connected with a line if numberwithlabel > 1: # join dots if there are at least two # add lines first and then dots to prevent line from hiding link firstcenterx = xbase + self_dual * xdotspacing firstcentery = ybase lastcenterx = xbase + (numberwithlabel * self_dual * xdotspacing) lastcentery = ybase ans += "<line x1='%s' " % str( float(firstcenterx) * xfactor)[0:7] ans += "y1='%s' " % str( float(height - firstcentery * yfactor))[0:7] ans += "x2='%s' " % str( float(lastcenterx) * xfactor)[0:7] ans += "y2='%s' " % str( float(height - lastcentery * yfactor))[0:7] ans += "style='stroke:%s;stroke-width:2.4'/>" % thiscolour for number in range(0, numberwithlabel): xbase += self_dual * xdotspacing ans += "<a xlink:href='" + linkurl + str( number + 1) + "/' target='_top'>\n" ans += "<circle cx='" + str( float(xbase) * xfactor)[0:7] ans += "' cy='" + str(height - float(ybase) * yfactor)[0:7] ans += "' r='" + str(radius) ans += "' style='fill:" + thiscolour + "'>" ans += "<title>" + str((x, y)).replace( "u", "").replace("'", "") + "</title>" ans += "</circle></a>\n" ans += svgEnd() return ans