def download_newform(self, label, lang='text'): data = db.mf_newforms.lookup(label) if data is None: return abort(404, "Label not found: %s" % label) form = WebNewform(data) form.setup_cc_data({'m': '1-%s' % form.dim}) if form.has_exact_qexp: data['qexp'] = form.qexp data['traces'] = form.texp if form.has_complex_qexp: data['complex_embeddings'] = form.cc_data return self._wrap(Json.dumps(data), label, lang=lang, title='Stored data for newform %s,' % (label))
def download_newform(self, label, lang='text'): data = db.mf_newforms.lookup(label) if data is None: return abort(404, "Label not found: %s"%label) form = WebNewform(data) form.setup_cc_data({'m':'1-%s'%form.dim}) if form.has_exact_qexp: data['qexp'] = form.qexp data['traces'] = form.texp if form.has_complex_qexp: data['complex_embeddings'] = form.cc_data return self._wrap(Json.dumps(data), label, lang=lang, title='Stored data for newform %s,'%(label))
def galois_rep_from_path(p): if p[0]=='EllipticCurve': # create the sage elliptic curve then create Galois rep object ainvs = db.ec_curves.lucky({'lmfdb_label':p[2]+"."+p[3]+p[4]}, 'ainvs') E = EllipticCurve(ainvs) return GaloisRepresentation(E) elif (p[0]=='Character' and p[1]=='Dirichlet'): dirichletArgs = {'type':'Dirichlet', 'modulus':int(p[2]), 'number':int(p[3])} chi = WebDirichletCharacter(**dirichletArgs) return GaloisRepresentation(chi) elif (p[0]=='ModularForm'): level = int(p[4]) weight = int(p[5]) conrey_label = p[6] # this should be zero; TODO check this is the case hecke_orbit = p[7] # this is a, b, c, etc.; chooses the galois orbit embedding = p[8] # this is the embedding of that galois orbit label = convert_newformlabel_from_conrey(str(level)+"."+str(weight)+"."+str(conrey_label)+"."+hecke_orbit) form = WebNewform(label) return GaloisRepresentation([form, ZZ(embedding)]) elif (p[0]=='ArtinRepresentation'): dim = p[1] conductor = p[2] index = p[3] rho = ArtinRepresentation(dim, conductor, index) return GaloisRepresentation(rho) else: return
def download_newform_to_magma(self, label, lang='magma'): data = db.mf_newforms.lookup(label) if data is None: return abort(404, "Label not found: %s" % label) newform = WebNewform(data) hecke_nf = self._get_hecke_nf(label) out = [] newlines = [''] * 2 if newform.has_exact_qexp: out += self._magma_ConvertToHeckeField(newform, hecke_nf) + newlines out += self._magma_MakeCharacters(newform, hecke_nf) + newlines if newform.has_exact_qexp: # to return errors # this line will never be ran if the data is correct if not isinstance(hecke_nf, dict): # pragma: no cover return hecke_nf # pragma: no cover out += self._magma_ExtendMultiplicatively() + newlines out += self._magma_qexpCoeffs(newform, hecke_nf) + newlines # The Sturm bound is not enough precision; see Github issue 4354 # prec = db.mf_newspaces.lucky({'label': newform.space_label}, 'sturm_bound') out += self._magma_MakeNewformModFrm(newform, hecke_nf) + newlines if newform.hecke_cutters is not None and newform.weight > 1: out += self._magma_MakeNewformModSym(newform, hecke_nf) outstr = "\n".join(out) return self._wrap(outstr, label, lang=lang, title='Make newform %s in Magma,' % (label))
def download_newform(self, label, lang='text'): data = db.mf_newforms.lookup(label) if data is None: return abort(404, "Label not found: %s" % label) form = WebNewform(data) if form.has_exact_qexp: data['qexp'] = form.qexp data['traces'] = form.texp return self._wrap(Json.dumps(data), label, lang=lang, title='Stored data for newform %s,' % (label))
def windingelement_hecke_cutter_projected(data, extra_cutter_bound=None): "Creates winding element projected to the subspace where the hecke cutter condition of the data is satisfied" M = modular_symbols_ambient_from_lmfdb_mf(data) #dim = M.dimension() S = M.cuspidal_subspace() K = M.base_ring() R = PolynomialRing(K, "x") cutters = data[u'hecke_cutters'] cutters_maxp = cutters[-1][0] if cutters else 1 weight = data[u'weight'] assert weight % 2 == 0 cuts_eisenstein = False winding_element = M.modular_symbol([weight // 2 - 1, 0, oo]).element() if extra_cutter_bound: N = data[u'level'] wn = WebNewform(data) #qexp = qexp_as_nf_elt(wn,prec=extra_cutter_bound) for p in prime_range(cutters_maxp, extra_cutter_bound): if N % p == 0: continue cutters.append([p, qexp_as_nf_elt(wn)[p].minpoly().list()]) for c in cutters: p = c[0] fM = M.hecke_polynomial(p) fS = S.hecke_polynomial(p) cutter = gcd(R(c[1]), fS) assert not cutter.is_constant() for cp, ce in cutter.factor(): assert ce == 1 e = fM.valuation(cp) if fS.valuation(cp) == e: cuts_eisenstein = True winding_element = polynomial_matrix_apply(fM // cp**e, M.hecke_matrix(p), winding_element) if winding_element == 0: return winding_element #print fS.valuation(cp),fM.valuation(cp),ce assert cuts_eisenstein return winding_element
def render_newform_webpage(label): try: newform = WebNewform.by_label(label) except (KeyError, ValueError) as err: return abort(404, err.args) info = to_dict(request.args) info['format'] = info.get('format', 'embed' if newform.dim > 1 else 'satake') p, maxp = 2, 10 if info['format'] in ['satake', 'satake_angle']: while p <= maxp: if newform.level % p == 0: maxp = next_prime(maxp) p = next_prime(p) errs = [] info['n'] = info.get('n', '2-%s' % maxp) try: info['CC_n'] = integer_options(info['n'], 1000) except (ValueError, TypeError) as err: info['n'] = '2-%s' % maxp info['CC_n'] = range(2, maxp + 1) if err.args and err.args[0] == 'Too many options': errs.append(r"Only \(a_n\) up to %s are available" % (newform.cqexp_prec - 1)) else: errs.append( "<span style='color:black'>n</span> must be an integer, range of integers or comma separated list of integers" ) maxm = min(newform.dim, 20) info['m'] = info.get('m', '1-%s' % maxm) try: info['CC_m'] = integer_options(info['m'], 1000) except (ValueError, TypeError) as err: info['m'] = '1-%s' % maxm info['CC_m'] = range(1, maxm + 1) if err.args and err.args[0] == 'Too many options': errs.append( 'Web interface only supports 1000 embeddings at a time. Use download link to get more (may take some time).' ) else: errs.append( "<span style='color:black'>Embeddings</span> must be an integer, range of integers or comma separated list of integers" ) try: info['prec'] = int(info.get('prec', 6)) if info['prec'] < 1 or info['prec'] > 15: raise ValueError except (ValueError, TypeError): info['prec'] = 6 errs.append( "<span style='color:black'>Precision</span> must be a positive integer, at most 15 (for higher precision, use the download button)" ) newform.setup_cc_data(info) if newform.cqexp_prec != 0 and max(info['CC_n']) >= newform.cqexp_prec: errs.append(r"Only \(a_n\) up to %s are available" % (newform.cqexp_prec - 1)) if errs: flash(Markup("<br>".join(errs)), "error") return render_template("cmf_newform.html", info=info, newform=newform, properties2=newform.properties, downloads=newform.downloads, credit=credit(), bread=newform.bread, learnmore=learnmore_list(), title=newform.title, friends=newform.friends)
def get_forms(N, k, ell, max_dim=50, verbose=False): """ Input: N (level), k (weight), ell (prime); and a verbosity flag Output: 2 lists of newforms of level N, weight k, whose character chi has order compatible with ell. (1) forms for which we have the Hecke field and which have at least one mod-ell reduction. The reductions are stored as an attribute (.reductions) for each of these newforms. (2) forms for which we do not have the Hecke field in the database, for which we currently do nothing. """ if N%ell==0: return [], [] nfs = db.mf_newforms heckes = db.mf_hecke_nf # for more ap forms = [WebNewform.by_label(f_label) for f_label in nfs.search({'level':N, 'weight':k}, projection='label')] if verbose: print("forms with (N,k)=({},{}): {}".format(N,k,[f.label for f in forms])) # omit forms whose character order is invalid: forms = [f for f in forms if char_order_valid(f.char_order, ell)] if verbose: print("After char order check, forms with (N,k,ell)=({},{},{}): {}".format(N,k,ell,[(f.label,f.dim) for f in forms])) # for forms with no Hecke field, try to read from a data file forms_with_no_field = [f for f in forms if f.field_poly is None] if forms_with_no_field: if verbose: print("Before reading data files, {} forms have no Hecke field data: {}".format(len(forms_with_no_field), [f.label for f in forms_with_no_field])) for f in forms: if f.field_poly is None and f.dim <= max_dim: if verbose: print("looking for a data file for form {}".format(f.label)) f = get_form_data_from_file(f, max_dim=max_dim, verbose=verbose) forms_with_no_field = [(f.label,f.dim,ell) for f in forms if f.field_poly is None] if verbose: print("After reading data files, {} forms have no Hecke field data".format(len(forms_with_no_field))) # Now exclude any forms which still have no Hecke data: forms = [f for f in forms if f.field_poly] # find all mod-ell reduction maps from the Hecke order Qx = PolynomialRing(QQ,'x') for f in forms: f.hecke_field = NumberField(Qx(f.field_poly), 'a_') if verbose: print("making reductions for {} mod {}".format(f.label, ell)) print("Hecke field is {}".format(f.hecke_field)) f.reductions = make_reductions(f, ell, verbose) if verbose: print("finished making reductions for {} mod {}".format(f.label, ell)) try: assert f.an except AttributeError: # get extra ap from the second table: anap = heckes.lucky({'label':f.label}, projection=['ap','an']) f.an = anap['an'] f.ap = anap['ap'] if verbose: nap = len(f.ap) print("Found {} ap and {} an in the second table".format(nap,len(f.an))) # Exclude forms with no mod-ell reductions: forms = [f for f in forms if f.reductions] if forms and verbose: print("{}.{} forms with mod-{} reductions:".format(N,k,ell)) for f in forms: print("{} has {} reductions mod {}".format(f.label,len(f.reductions), ell)) return forms, forms_with_no_field
def paintSvgHoloGeneral(Nmin, Nmax, kmin, kmax, imagewidth, imageheight): # the import must be here to avoid circular import from lmfdb.classical_modular_forms.web_newform import WebNewform from lmfdb.classical_modular_forms.web_space import WebGamma1Space xfactor = 90 yfactor = 30 extraSpace = 20 ticlength = 4 radius = 3.3 xdotspacing = 0.30 # horizontal spacing of dots ydotspacing = 0.11 # vertical spacing of dots # colourplus = signtocolour(1) # not used # colourminus = signtocolour(-1) # not used maxdots = 5 # max number of dots to display ans = svgBegin() xMax = int(Nmax) yMax = int(kmax) width = xfactor * xMax + extraSpace height = yfactor * yMax + extraSpace # make the coordinate system ans += paintCSHoloTMP(width, height, xMax, yMax, xfactor, yfactor, ticlength) alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'] # create appearanceinfo, common to all points appearanceinfo = [] # loop over levels and weights, using plotsector to put the appropriate dots at each lattice point for x in range(int(Nmin), int(Nmax) + 1): # x is the level for y in range(int(kmin), int(kmax) + 1, 2): # y is the weight # lid = "(" + str(x) + "," + str(y) + ")" # not used # linkurl = "/L/ModularForm/GL2/Q/holomorphic/" + str(y) + "/" + str(x) + "/1/" # not used WS = WebGamma1Space( level=x, weight=y) # space of modular forms of weight y, level x galois_orbits = WS.decomp # make a list of Galois orbits numlabels = len(galois_orbits) # 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 (not used) # ybaseminus = y # baseline y-coord for minus cases (not used) # numpluslabels = 0 # not used # numminuslabels = 0 # not used # plotsector requires three dictionaries: dimensioninfo, appearanceinfo, and urlinfo # create dimensioninfo dimensioninfo = {} dimensioninfo['offset'] = [0, height] dimensioninfo['scale'] = [xfactor, -1 * yfactor] dimensioninfo['vertexlocation'] = [x, y] dimensioninfo['maxdots'] = maxdots dimensioninfo['dotspacing'] = [xdotspacing, ydotspacing] dimensioninfo['edge'] = [[0, 1], [1, 0] ] # unit vectors defining edges of sector # dimensioninfo['edgelength'] = [float(dimensioninfo['scale'][0])/float(Nmax), float(dimensioninfo['scale'][1])/float(kmax)] #add comment dimensioninfo['edgelength'] = [0.5, 0.5] dimensioninfo['dotradius'] = radius dimensioninfo[ 'connectinglinewidth'] = dimensioninfo['dotradius'] / 1.5 dimensioninfo['firstdotoffset'] = [0.0, 0.0] # appearanceinfo = {} # appearanceinfo['edgewidth'] = dimensioninfo['dotspacing'][0]/1.0 #just a guess appearanceinfo['edgewidth'] = [0, 0] # remove the sector edges appearanceinfo['edgestyle'] = 'stroke-dasharray:3,3' appearanceinfo['edgecolor'] = 'rgb(202,202,102)' appearanceinfo['fontsize'] = 'font-size:11px' appearanceinfo['fontweight'] = "" # urlinfo = {'base': '/L/ModularForm/GL2/Q/holomorphic?'} urlinfo['space'] = {'weight': y} urlinfo['space']['level'] = x urlinfo['space']['character'] = 0 # # scale = 1 # not used # Symmetry types: +1 or -1 symmetrytype = [1, -1] for signtmp in symmetrytype: # urlinfo['space']['orbits'] = [ [] for label in thelabels ] # initialise # an empty list for each orbit urlinfo['space']['orbits'] = [] for label in thelabels: # looping over Galois orbit: one label per orbit # do '+' case first MF = WebNewform.by_label( label=label ) # one of the Galois orbits for weight y, level x numberwithlabel = MF.degree( ) # number of forms in the Galois orbit if x == 1: # For level 1, the sign is always plus signfe = 1 else: # signfe = -1 frickeeigenvalue = prod(MF.atkin_lehner_eigenvalues( ).values()) # gives Fricke eigenvalue signfe = frickeeigenvalue * (-1)**float( y / 2) # sign of functional equation if signfe == signtmp: # we find an orbit with sign of "signtmp" if signfe == 1: dimensioninfo['edge'] = [[0, 1], [1, 0]] # unit vectors defining edges of sector for signfe positive else: # dimensioninfo['edge'] = [[0,1],[-1,0]] # unit vectors defining edges # of sector for signfe negative dimensioninfo['edge'] = [[0, -1], [-1, 0]] # unit vectors defining edges of sector for signfe negative dimensioninfo['dotspacing'] = [ signfe * xdotspacing, ydotspacing ] dimensioninfo['firstdotoffset'] = [ 0.5 * (dimensioninfo['dotspacing'][0] * dimensioninfo['edge'][0][0] + dimensioninfo['dotspacing'][1] * dimensioninfo['edge'][1][0]), 0 ] signcolour = signtocolour(signfe) appearanceinfo['edgecolor'] = signcolour orbitdescriptionlist = [] for n in range(numberwithlabel): orbitdescriptionlist.append({ 'label': label, 'number': n, 'color': signcolour }) urlinfo['space']['orbits'].append(orbitdescriptionlist) # urlinfo['space']['orbits'][0][0]['color'] = signtocolour(-1) # appearanceinfo['orbitcolor'] = 'rgb(102,102,102)' ans += plotsector(dimensioninfo, appearanceinfo, urlinfo) ans += svgEnd() return (ans)