def compute_from_startpoints(self, points, p = None, cut_nonsimple_aniso = True, fast = 1, **kwds): self._reduction = kwds.get('reduction', self._reduction) if NCPUS0 == 1: for a in points: self._compute_simple_modules_graph_from_startpoint(a, p, cut_nonsimple_aniso, fast) else: computations = self._compute_simple_modules_graph_from_startpoint_parallel([(a, p, cut_nonsimple_aniso, fast) for a in points]) for r in computations: if not isinstance(r[1], SimpleModulesGraph): logger.error("Got something else... {0}".format(r)) # print r else: G = r[1] logger.debug("simple from G: {0}".format(len(G._simple))) logger.debug(G._simple) self.add_vertices(G.vertices()) self.add_edges(G.edges()) self._vertex_colors[ self._nonsimple_color] += G._vertex_colors[G._nonsimple_color] self._vertex_colors[ self._simple_color] += G._vertex_colors[G._simple_color] self._simple = uniq(self._simple + G._simple) for h in G._heights.keys(): if not self._heights.has_key(h): self._heights[h] = G._heights[h] else: self._heights[h] = uniq(self._heights[h] + G._heights[h]) logger.info("Found {0} {1}-simple module{2} so far.".format( len(self._simple), self._weight, "s" if len(self._simple) != 1 else "")) logger.info("Found in total {0} {1}-simple module{3} with p-rank <= {2}".format( len(self._simple), self._weight, self._rank_limit, "s" if len(self._simple) != 1 else "")) return 0
def aniso_dict_to_latex_table(d, max_per_table=10, include_weight=True): if include_weight: beginstr = r"\begin{tabularx}{llX} \toprule $k$ & signature & $k$-simple modules\\\midrule" + \ "\n" else: beginstr = r"\begin{tabular}{llX} \toprule $k$ & signature & $k$-simple modules\\\midrule" + \ "\n" endstr = r"\bottomrule\end{tabularx}" + "\n" s = beginstr ks = sorted(d.keys()) for i in range(len(d.keys())): k = ks[i] sigs = uniq([_.signature() for _ in d[k]]) for sig in sigs: if include_weight: s += "$" + str(k) + "$" + " & " s += " " + str(sig) + " & " ms = [m for m in d[k] if m.signature() == sig] ms = sorted( ms, lambda x, y: int(-1) if x.order() <= y.order() else int(1)) for m in ms: s += str(FQM_vertex(m)).strip() + ", " s = s[:-2] s += r"\\\midrule" + "\n" if (i + 1) % max_per_table == 0: s += endstr + beginstr s += endstr return s
def compute_from_startpoints(self, points, p=None, cut_nonsimple_aniso=True, fast=1, **kwds): self._reduction = kwds.get('reduction', self._reduction) if NCPUS0 == 1: for a in points: self._compute_simple_modules_graph_from_startpoint( a, p, cut_nonsimple_aniso, fast) else: computations = self._compute_simple_modules_graph_from_startpoint_parallel( [(a, p, cut_nonsimple_aniso, fast) for a in points]) for r in computations: if not isinstance(r[1], SimpleModulesGraph): logger.error("Got something else... {0}".format(r)) # print r else: G = r[1] logger.debug("simple from G: {0}".format(len(G._simple))) logger.debug(G._simple) self.add_vertices(G.vertices()) self.add_edges(G.edges()) self._vertex_colors[ self._nonsimple_color] += G._vertex_colors[ G._nonsimple_color] self._vertex_colors[ self._simple_color] += G._vertex_colors[ G._simple_color] self._simple = uniq(self._simple + G._simple) for h in G._heights.keys(): if not self._heights.has_key(h): self._heights[h] = G._heights[h] else: self._heights[h] = uniq(self._heights[h] + G._heights[h]) logger.info( "Found {0} {1}-simple module{2} so far.". format(len(self._simple), self._weight, "s" if len(self._simple) != 1 else "")) logger.info( "Found in total {0} {1}-simple module{3} with p-rank <= {2}". format(len(self._simple), self._weight, self._rank_limit, "s" if len(self._simple) != 1 else "")) return 0
def find_simple_anisotropic_parallel(num, s, weights=range(2, Integer(27) / 2), dynamic=True, lower=1, only_2_n=False, reduction=False): r""" Test for anisotropic $k$-simple fqm's for $k$ in weights. INPUT:: - num: upper bound - s: number of iterations - lower: lower bound """ simple = dict() for kk in weights: simple[kk] = list() m = round(RR(num) / s) args = [(m * a + lower, min(m * (a + lower), lower + num - 1), lower + num - 1, None, None, weights, True, dynamic, only_2_n, reduction) for a in range(s)] tests = find_simple_anisotropic_wrapper(args) done = 0 #starttime = walltime() for test in tests: done += 1 simple_part = test[1][0] if isinstance(simple_part, str): print "Result: ", test continue tt = test[1][1] for kk in simple_part.keys(): print "Result from process: ", simple_part[kk] simple[kk] = uniq(simple[kk] + simple_part[kk]) #tt = walltime(starttime) sl = [len(sp) for sp in simple.values()] num_simple = sum(sl) timeest = (s - done) * RR(tt) / RR(60) if timeest > 1: if timeest > 60: print("%g%% done, ETA: %d hour" + ("s" if timeest / 60 >= 2 else "") + ", %d minutes, simple lattices: %d") % ( RR(done) / RR(s) * 100, timeest / 60, (timeest / 60).frac() * 60, num_simple) else: print("%g%% done, ETA: %d minute" + ("s" if timeest >= 2 else "") + ", simple lattices: %d" ) % (RR(done) / RR(s) * 100, timeest, num_simple) else: print "%g%% done, ETA: %d seconds, simple lattices: %d" % ( RR(done) / RR(s) * 100, timeest * 60, num_simple) return simple
def set_info_for_modular_form_space(level=None, weight=None, character=None, label=None, **kwds): r""" Set information about a space of modular forms. """ info = dict() emf_logger.debug("info={0}".format(info)) WMFS = None if level <= 0: info["error"] = "Got wrong level: %s " % level return info try: WMFS = WebModFormSpace_cached(level=level, weight=weight, cuspidal=True, character=character) emf_logger.debug("Created WebModFormSpace %s" % WMFS) if "download" in info and "tempfile" in info: save(WNF, info["tempfile"]) info["filename"] = str(weight) + "-" + str(level) + "-" + str(character) + "-" + label + ".sobj" return info except ValueError as e: emf_logger.debug(e) emf_logger.debug(e.message) # if isinstance(e,IndexError): info["error"] = e.message WMFS = None if WMFS is None: info["error"] = ( "We are sorry. The sought space can not be found in the database. " + "<br> Detailed information: {0}".format(info.get("error", "")) ) return info else: ### Somehow the Hecke orbits are sometimes not in the space... # if WMFS.dimension_new_cusp_forms()!=len(WMFS.hecke_orbits): # ## Try to add them here... # for d in range(len(WMFS.dimension_new_cusp_forms())): # F = # WMFS.hecke_orbits.append(F) info = {"space": WMFS} # info['old_decomposition'] = WMFS.oldspace_decomposition() ## For side-bar lifts = list() lifts.append(("Half-Integral Weight Forms", "/ModularForm/Mp2/Q")) lifts.append(("Siegel Modular Forms", "/ModularForm/GSp4/Q")) info["lifts"] = lifts friends = list() for label in WMFS.hecke_orbits: f = WMFS.hecke_orbits[label] friends.append(("Number field " + f.base_field_label(), f.base_field_url())) if f.coefficient_field_label(check=True): friends.append(("Number field " + f.coefficient_field_label(), f.coefficient_field_url())) friends.append(("Dirichlet character \(" + WMFS.character.latex_name + "\)", WMFS.character.url())) friends = uniq(friends) info["friends"] = friends return info
def set_info_for_modular_form_space(level=None, weight=None, character=None, label=None, **kwds): r""" Set information about a space of modular forms. """ info = dict() emf_logger.debug("info={0}".format(info)) WMFS = None if level <= 0: info['error'] = "Got wrong level: %s " % level return info try: WMFS = WebModFormSpace_cached(level = level, weight = weight, cuspidal=True,character = character) emf_logger.debug("Created WebModFormSpace %s"%WMFS) if 'download' in info and 'tempfile' in info: save(WNF,info['tempfile']) info['filename'] = str(weight) + '-' + str(level) + '-' + str(character) + '-' + label + '.sobj' return info except ValueError as e: emf_logger.debug(e) emf_logger.debug(e.message) #if isinstance(e,IndexError): info['error'] = e.message WMFS = None if WMFS is None: info['error'] = "We are sorry. The sought space can not be found in the database. "+"<br> Detailed information: {0}".format(info.get('error','')) return info else: ### Somehow the Hecke orbits are sometimes not in the space... #if WMFS.dimension_new_cusp_forms()<>len(WMFS.hecke_orbits): # ## Try to add them here... # for d in range(len(WMFS.dimension_new_cusp_forms())): # F = # WMFS.hecke_orbits.append(F) info = {'space':WMFS} # info['old_decomposition'] = WMFS.oldspace_decomposition() ## For side-bar lifts = list() lifts.append(('Half-Integral Weight Forms', '/ModularForm/Mp2/Q')) lifts.append(('Siegel Modular Forms', '/ModularForm/GSp4/Q')) info['lifts'] = lifts friends = list() for label in WMFS.hecke_orbits: f = WMFS.hecke_orbits[label] friends.append(('Number field ' + f.base_field_label(), f.base_field_url())) if f.coefficient_field_label(check=True): friends.append(('Number field ' + f.coefficient_field_label(), f.coefficient_field_url())) friends.append(("Dirichlet character \(" + WMFS.character.latex_name + "\)", WMFS.character.url())) friends = uniq(friends) info['friends'] = friends return info
def set_info_for_web_newform(level=None, weight=None, character=None, label=None, **kwds): r""" Set the info for on modular form. """ info = to_dict(kwds) info['level'] = level info['weight'] = weight info['character'] = character info['label'] = label if level is None or weight is None or character is None or label is None: s = "In set info for one form but do not have enough args!" s += "level={0},weight={1},character={2},label={3}".format( level, weight, character, label) emf_logger.critical(s) emf_logger.debug("In set_info_for_one_mf: info={0}".format(info)) prec = my_get(info, 'prec', default_prec, int) bprec = my_get(info, 'bprec', default_display_bprec, int) emf_logger.debug("PREC: {0}".format(prec)) emf_logger.debug("BITPREC: {0}".format(bprec)) try: WNF = WebNewForm_cached(level=level, weight=weight, character=character, label=label) emf_logger.critical("defined webnewform for rendering!") # if info.has_key('download') and info.has_key('tempfile'): # WNF._save_to_file(info['tempfile']) # info['filename']=str(weight)+'-'+str(level)+'-'+str(character)+'-'+label+'.sobj' # return info except IndexError as e: WNF = None info['error'] = e.message url1 = url_for("emf.render_elliptic_modular_forms") url2 = url_for("emf.render_elliptic_modular_forms", level=level) url3 = url_for("emf.render_elliptic_modular_forms", level=level, weight=weight) url4 = url_for("emf.render_elliptic_modular_forms", level=level, weight=weight, character=character) bread = [(EMF_TOP, url1)] bread.append(("of level %s" % level, url2)) bread.append(("weight %s" % weight, url3)) if int(character) == 0: bread.append(("trivial character", url4)) else: bread.append(("\( %s \)" % (WNF.character.latex_name), url4)) info['bread'] = bread properties2 = list() friends = list() space_url = url_for('emf.render_elliptic_modular_forms', level=level, weight=weight, character=character) friends.append( ('\( S_{%s}(%s, %s)\)' % (WNF.weight, WNF.level, WNF.character.latex_name), space_url)) if WNF.coefficient_field_label(check=True): friends.append(('Number field ' + WNF.coefficient_field_label(), WNF.coefficient_field_url())) friends.append( ('Number field ' + WNF.base_field_label(), WNF.base_field_url())) friends = uniq(friends) friends.append(("Dirichlet character \(" + WNF.character.latex_name + "\)", WNF.character.url())) if WNF.dimension == 0: info['error'] = "This space is empty!" # emf_logger.debug("WNF={0}".format(WNF)) #info['name'] = name info['title'] = 'Modular Form ' + WNF.hecke_orbit_label if 'error' in info: return info # info['name']=WNF._name ## Until we have figured out how to do the embeddings correctly we don't display the Satake ## parameters for non-trivial characters.... cdeg = WNF.coefficient_field.absolute_degree() bdeg = WNF.base_ring.absolute_degree() if WNF.coefficient_field.absolute_degree() == 1: rdeg = 1 else: rdeg = WNF.coefficient_field.relative_degree() if cdeg == 1: info['satake'] = WNF.satake info['qexp'] = WNF.q_expansion_latex(prec=10, name='a') info['qexp_display'] = url_for(".get_qexp_latex", level=level, weight=weight, character=character, label=label) # info['qexp'] = WNF.q_expansion_latex(prec=prec) #c_pol_st = str(WNF.absolute_polynomial) #b_pol_st = str(WNF.polynomial(type='base_ring',format='str')) #b_pol_ltx = str(WNF.polynomial(type='base_ring',format='latex')) #print "c=",c_pol_ltx #print "b=",b_pol_ltx if cdeg > 1: ## Field is QQ if bdeg > 1 and rdeg > 1: p1 = WNF.coefficient_field.relative_polynomial() c_pol_ltx = latex(p1) lgc = p1.variables()[0] c_pol_ltx = c_pol_ltx.replace(lgc, 'a') z = p1.base_ring().gens()[0] p2 = z.minpoly() b_pol_ltx = latex(p2) b_pol_ltx = b_pol_ltx.replace(latex(p2.variables()[0]), latex(z)) info['polynomial_st'] = 'where \({0}=0\) and \({1}=0\).'.format( c_pol_ltx, b_pol_ltx) else: c_pol_ltx = latex(WNF.coefficient_field.relative_polynomial()) lgc = str( latex(WNF.coefficient_field.relative_polynomial().variables() [0])) c_pol_ltx = c_pol_ltx.replace(lgc, 'a') info['polynomial_st'] = 'where \({0}=0\)'.format(c_pol_ltx) else: info['polynomial_st'] = '' info['degree'] = int(cdeg) if cdeg == 1: info['is_rational'] = 1 else: info['is_rational'] = 0 # info['q_exp_embeddings'] = WNF.print_q_expansion_embeddings() # if(int(info['degree'])>1 and WNF.dimension()>1): # s = 'One can embed it into \( \mathbb{C} \) as:' # bprec = 26 # print s # info['embeddings'] = ajax_more2(WNF.print_q_expansion_embeddings,{'prec':[5,10,25,50],'bprec':[26,53,106]},text=['more coeffs.','higher precision']) # elif(int(info['degree'])>1): # s = 'There are '+str(info['degree'])+' embeddings into \( \mathbb{C} \):' # bprec = 26 # print s # info['embeddings'] = ajax_more2(WNF.print_q_expansion_embeddings,{'prec':[5,10,25,50],'bprec':[26,53,106]},text=['more coeffs.','higher precision']) # else: # info['embeddings'] = '' emf_logger.debug("PREC2: {0}".format(prec)) info['embeddings'] = WNF._embeddings[ 'values'] #q_expansion_embeddings(prec, bprec,format='latex') info['embeddings_len'] = len(info['embeddings']) properties2 = [] if (ZZ(level)).is_squarefree(): info['twist_info'] = WNF.twist_info if isinstance(info['twist_info'], list) and len(info['twist_info']) > 0: info['is_minimal'] = info['twist_info'][0] if (info['twist_info'][0]): s = '- Is minimal<br>' else: s = '- Is a twist of lower level<br>' properties2 = [('Twist info', s)] else: info['twist_info'] = 'Twist info currently not available.' properties2 = [('Twist info', 'not available')] args = list() for x in range(5, 200, 10): args.append({'digits': x}) alev = None CM = WNF._cm_values if CM is not None: if CM.has_key('tau') and len(CM['tau']) != 0: info['CM_values'] = CM info['is_cm'] = WNF.is_cm if WNF.is_cm is None: s = '- Unknown (insufficient data)<br>' elif WNF.is_cm is True: s = '- Is a CM-form<br>' else: s = '- Is not a CM-form<br>' properties2.append(('CM info', s)) alev = WNF.atkin_lehner_eigenvalues() info['atkinlehner'] = None if isinstance(alev, dict) and len(alev.keys()) > 0 and level != 1: s1 = " Atkin-Lehner eigenvalues " s2 = "" for Q in alev.keys(): s2 += "\( \omega_{ %s } \) : %s <br>" % (Q, alev[Q]) properties2.append((s1, s2)) emf_logger.debug("properties={0}".format(properties2)) # alev = WNF.atkin_lehner_eigenvalues_for_all_cusps() # if isinstance(alev,dict) and len(alev.keys())>0: # emf_logger.debug("alev={0}".format(alev)) # info['atkinlehner'] = list() # for Q in alev.keys(): # s = "\(" + latex(c) + "\)" # Q = alev[c][0] # ev = alev[c][1] # info['atkinlehner'].append([Q, c, ev]) if (level == 1): poly = WNF.explicit_formulas.get('as_polynomial_in_E4_and_E6', '') if poly <> '': d, monom, coeffs = poly emf_logger.critical("poly={0}".format(poly)) info['explicit_formulas'] = '\(' for i in range(d): c = QQ(coeffs[i]) s = "" if d > 1 and i > 0 and c > 0: s = "+" if c < 0: s = "-" if c.denominator() > 1: cc = "\\frac{{ {0} }}{{ {1} }}".format( abs(c.numerator()), c.denominator()) else: cc = str(abs(c)) s += "{0} \cdot ".format(cc) a = monom[i][0] b = monom[i][1] if a == 0 and b <> 0: s += "E_6^{{ {0} }}".format(b) elif b == 0 and a <> 0: s += "E_4^{{ {0} }}".format(a) else: s += "E_4^{{ {0} }}E_6^{{ {1} }}".format(a, b) info['explicit_formulas'] += s info['explicit_formulas'] += " \)" cur_url = '?&level=' + str(level) + '&weight=' + str(weight) + '&character=' + str(character) + \ '&label=' + str(label) if len(WNF.parent.hecke_orbits) > 1: for label_other in WNF.parent.hecke_orbits.keys(): if (label_other != label): s = 'Modular form ' if character: s = s + str(level) + '.' + str(weight) + '.' + str( character) + str(label_other) else: s = s + str(level) + '.' + str(weight) + str(label_other) url = url_for('emf.render_elliptic_modular_forms', level=level, weight=weight, character=character, label=label_other) friends.append((s, url)) s = 'L-Function ' if character: s = s + str(level) + '.' + str(weight) + '.' + str(character) + str( label) else: s = s + str(level) + '.' + str(weight) + str(label) # url = # "/L/ModularForm/GL2/Q/holomorphic?level=%s&weight=%s&character=%s&label=%s&number=%s" # %(level,weight,character,label,0) url = '/L' + url_for('emf.render_elliptic_modular_forms', level=level, weight=weight, character=character, label=label) if WNF.coefficient_field_degree > 1: for h in range(WNF.coefficient_field_degree): s0 = s + ".{0}".format(h) url0 = url + "{0}/".format(h) friends.append((s0, url0)) else: friends.append((s, url)) # if there is an elliptic curve over Q associated to self we also list that if WNF.weight == 2 and WNF.coefficient_field_degree == 1: llabel = str(level) + '.' + label s = 'Elliptic curve isogeny class ' + llabel url = '/EllipticCurve/Q/' + llabel friends.append((s, url)) info['properties2'] = properties2 info['friends'] = friends info['max_cn'] = WNF.max_cn() return info
def set_info_for_web_newform(level=None, weight=None, character=None, label=None, **kwds): r""" Set the info for on modular form. """ info = to_dict(kwds) info['level'] = level info['weight'] = weight info['character'] = character info['label'] = label if level is None or weight is None or character is None or label is None: s = "In set info for one form but do not have enough args!" s += "level={0},weight={1},character={2},label={3}".format(level, weight, character, label) emf_logger.critical(s) emf_logger.debug("In set_info_for_one_mf: info={0}".format(info)) prec = my_get(info, 'prec', default_prec, int) bprec = my_get(info, 'bprec', default_display_bprec, int) emf_logger.debug("PREC: {0}".format(prec)) emf_logger.debug("BITPREC: {0}".format(bprec)) try: WNF = WebNewForm_cached(level=level, weight=weight, character=character, label=label) if not WNF.has_updated(): raise IndexError("Unfortunately, we do not have this newform in the database.") info['character_order'] = WNF.character.order info['code'] = WNF.code emf_logger.debug("defined webnewform for rendering!") except IndexError as e: info['error'] = e.message url0 = url_for("mf.modular_form_main_page") url1 = url_for("emf.render_elliptic_modular_forms") url2 = url_for("emf.render_elliptic_modular_forms", level=level) url3 = url_for("emf.render_elliptic_modular_forms", level=level, weight=weight) url4 = url_for("emf.render_elliptic_modular_forms", level=level, weight=weight, character=character) bread = [(MF_TOP, url0), (EMF_TOP, url1)] bread.append(("Level %s" % level, url2)) bread.append(("Weight %s" % weight, url3)) bread.append(("Character \( %s \)" % (WNF.character.latex_name), url4)) bread.append(("Newform %d.%d.%d.%s" % (level, weight, int(character), label),'')) info['bread'] = bread properties2 = list() friends = list() space_url = url_for('emf.render_elliptic_modular_forms',level=level, weight=weight, character=character) friends.append(('\( S_{%s}(%s, %s)\)'%(WNF.weight, WNF.level, WNF.character.latex_name), space_url)) if hasattr(WNF.base_ring, "lmfdb_url") and WNF.base_ring.lmfdb_url: friends.append(('Number field ' + WNF.base_ring.lmfdb_pretty, WNF.base_ring.lmfdb_url)) if hasattr(WNF.coefficient_field, "lmfdb_url") and WNF.coefficient_field.lmfdb_label: friends.append(('Number field ' + WNF.coefficient_field.lmfdb_pretty, WNF.coefficient_field.lmfdb_url)) friends = uniq(friends) friends.append(("Dirichlet character \(" + WNF.character.latex_name + "\)", WNF.character.url())) if WNF.dimension==0 and not info.has_key('error'): info['error'] = "This space is empty!" info['title'] = 'Newform ' + WNF.hecke_orbit_label info['learnmore'] = [('History of modular forms', url_for('.holomorphic_mf_history'))] if 'error' in info: return info ## Until we have figured out how to do the embeddings correctly we don't display the Satake ## parameters for non-trivial characters.... ## Example to illustrate the different cases ## base = CyclotomicField(n) -- of degree phi(n) ## coefficient_field = NumberField( p(x)) for some p in base['x'] of degree m ## we would then have cdeg = m*phi(n) and bdeg = phi(n) ## and rdeg = m ## Unfortunately, for e.g. base = coefficient_field = CyclotomicField(6) ## we get coefficient_field.relative_degree() == 2 although it should be 1 cdeg = WNF.coefficient_field.absolute_degree() bdeg = WNF.base_ring.absolute_degree() if cdeg == 1: rdeg = 1 else: ## just setting rdeg = WNF.coefficient_field.relative_degree() does not give correct result... ## rdeg = QQ(cdeg)/QQ(bdeg) cf_is_QQ = (cdeg == 1) br_is_QQ = (bdeg == 1) if cf_is_QQ: info['satake'] = WNF.satake if WNF.complexity_of_first_nonvanishing_coefficients() > default_max_height: info['qexp'] = "" info['qexp_display'] = '' info['hide_qexp'] = True n,c = WNF.first_nonvanishing_coefficient() info['trace_nv'] = latex(WNF.first_nonvanishing_coefficient_trace()) info['norm_nv'] = '\\approx ' + latex(WNF.first_nonvanishing_coefficient_norm().n()) info['index_nv'] = n else: if WNF.prec < prec: #get WNF record at larger prec WNF.prec = prec WNF.update_from_db() info['qexp'] = WNF.q_expansion_latex(prec=10, name='\\alpha ') info['qexp_display'] = url_for(".get_qexp_latex", level=level, weight=weight, character=character, label=label) info["hide_qexp"] = False info['max_cn_qexp'] = WNF.q_expansion.prec() ## All combinations should be tested... ## 13/4/4/a -> base ring = coefficient_field = QQ(zeta_6) ## 13/3/8/a -> base_ring = QQ(zeta_4), coefficient_field has poly x^2+(2\zeta_4+2x-3\zeta_$ over base_ring ## 13/4/3/a -> base_ring = coefficient_field = QQ(zeta_3) ## 13/4/1/a -> all rational ## 13/6/1/a/ -> base_ring = QQ, coefficient_field = Q(sqrt(17)) ## These are variables which needs to be set properly below info['polvars'] = {'base_ring':'x','coefficient_field':'\\alpha'} if not cf_is_QQ: if rdeg>1: # not WNF.coefficient_field == WNF.base_ring: ## Here WNF.base_ring should be some cyclotomic field and we have an extension over this. p1 = WNF.coefficient_field.relative_polynomial() c_pol_ltx = web_latex_poly(p1, '\\alpha') # make the variable \alpha c_pol_ltx_x = web_latex_poly(p1, 'x') zeta = p1.base_ring().gens()[0] # p2 = zeta.minpoly() #this is not used anymore # b_pol_ltx = web_latex_poly(p2, latex(zeta)) #this is not used anymore z1 = zeta.multiplicative_order() info['coeff_field'] = [ WNF.coefficient_field.absolute_polynomial_latex('x'),c_pol_ltx_x, z1] if hasattr(WNF.coefficient_field, "lmfdb_url") and WNF.coefficient_field.lmfdb_url: info['coeff_field_pretty'] = [ WNF.coefficient_field.lmfdb_url, WNF.coefficient_field.lmfdb_pretty, WNF.coefficient_field.lmfdb_label] if z1==4: info['polynomial_st'] = '<div class="where">where</div> {0}\(\mathstrut=0\) and \(\zeta_4=i\).</div><br/>'.format(c_pol_ltx) info['polvars']['base_ring']='i' elif z1<=2: info['polynomial_st'] = '<div class="where">where</div> {0}\(\mathstrut=0\).</div><br/>'.format(c_pol_ltx) else: info['polynomial_st'] = '<div class="where">where</div> %s\(\mathstrut=0\) and \(\zeta_{%s}=e^{\\frac{2\\pi i}{%s}}\) '%(c_pol_ltx, z1,z1) info['polvars']['base_ring']='\zeta_{{ {0} }}'.format(z1) if z1==3: info['polynomial_st'] += 'is a primitive cube root of unity.' else: info['polynomial_st'] += 'is a primitive {0}-th root of unity.'.format(z1) elif not br_is_QQ: ## Now we have base and coefficient field being equal, meaning that since the coefficient field is not QQ it is some cyclotomic field ## generated by some \zeta_n p1 = WNF.coefficient_field.absolute_polynomial() z1 = WNF.coefficient_field.gens()[0].multiplicative_order() c_pol_ltx = web_latex_poly(p1, '\\zeta_{{{0}}}'.format(z1)) c_pol_ltx_x = web_latex_poly(p1, 'x') info['coeff_field'] = [ WNF.coefficient_field.absolute_polynomial_latex('x'), c_pol_ltx_x] if hasattr(WNF.coefficient_field, "lmfdb_url") and WNF.coefficient_field.lmfdb_url: info['coeff_field_pretty'] = [ WNF.coefficient_field.lmfdb_url, WNF.coefficient_field.lmfdb_pretty, WNF.coefficient_field.lmfdb_label] if z1==4: info['polynomial_st'] = '<div class="where">where \(\zeta_4=e^{{\\frac{{\\pi i}}{{ 2 }} }}=i \).</div>'.format(c_pol_ltx) info['polvars']['coefficient_field']='i' elif z1<=2: info['polynomial_st'] = '' else: info['polynomial_st'] = '<div class="where">where \(\zeta_{{{0}}}=e^{{\\frac{{2\\pi i}}{{ {0} }} }}\) '.format(z1) info['polvars']['coefficient_field']='\zeta_{{{0}}}'.format(z1) if z1==3: info['polynomial_st'] += 'is a primitive cube root of unity.</div>' else: info['polynomial_st'] += 'is a primitive {0}-th root of unity.</div>'.format(z1) else: info['polynomial_st'] = '' if info["hide_qexp"]: info['polynomial_st'] = '' info['degree'] = int(cdeg) if cdeg==1: info['is_rational'] = 1 info['coeff_field_pretty'] = [ WNF.coefficient_field.lmfdb_url, WNF.coefficient_field.lmfdb_pretty ] else: info['is_rational'] = 0 emf_logger.debug("PREC2: {0}".format(prec)) info['embeddings'] = WNF._embeddings['values'] #q_expansion_embeddings(prec, bprec,format='latex') info['embeddings_len'] = len(info['embeddings']) properties2 = [('Level', str(level)), ('Weight', str(weight)), ('Character', '$' + WNF.character.latex_name + '$'), ('Label', WNF.hecke_orbit_label), ('Dimension of Galois orbit', str(WNF.dimension))] if (ZZ(level)).is_squarefree(): info['twist_info'] = WNF.twist_info if isinstance(info['twist_info'], list) and len(info['twist_info'])>0: info['is_minimal'] = info['twist_info'][0] if(info['twist_info'][0]): s = 'Is minimal<br>' else: s = 'Is a twist of lower level<br>' properties2 += [('Twist info', s)] else: info['twist_info'] = 'Twist info currently not available.' properties2 += [('Twist info', 'not available')] args = list() for x in range(5, 200, 10): args.append({'digits': x}) alev = None CM = WNF._cm_values if CM is not None: if CM.has_key('tau') and len(CM['tau']) != 0: info['CM_values'] = CM info['is_cm'] = WNF.is_cm if WNF.is_cm == 1: info['cm_field'] = "2.0.{0}.1".format(-WNF.cm_disc) info['cm_disc'] = WNF.cm_disc info['cm_field_knowl'] = nf_display_knowl(info['cm_field'], getDBConnection(), field_pretty(info['cm_field'])) info['cm_field_url'] = url_for("number_fields.by_label", label=info["cm_field"]) if WNF.is_cm is None or WNF.is_cm==-1: s = '- Unknown (insufficient data)<br>' elif WNF.is_cm == 1: s = 'Yes<br>' else: s = 'No<br>' properties2.append(('CM', s)) alev = WNF.atkin_lehner_eigenvalues() info['atkinlehner'] = None if isinstance(alev,dict) and len(alev.keys())>0 and level != 1: s1 = " Atkin-Lehner eigenvalues " s2 = "" for Q in alev.keys(): s2 += "\( \omega_{ %s } \) : %s <br>" % (Q, alev[Q]) properties2.append((s1, s2)) emf_logger.debug("properties={0}".format(properties2)) # alev = WNF.atkin_lehner_eigenvalues_for_all_cusps() # if isinstance(alev,dict) and len(alev.keys())>0: # emf_logger.debug("alev={0}".format(alev)) # info['atkinlehner'] = list() # for Q in alev.keys(): # s = "\(" + latex(c) + "\)" # Q = alev[c][0] # ev = alev[c][1] # info['atkinlehner'].append([Q, c, ev]) if(level == 1): poly = WNF.explicit_formulas.get('as_polynomial_in_E4_and_E6','') if poly != '': d,monom,coeffs = poly emf_logger.critical("poly={0}".format(poly)) info['explicit_formulas'] = '\(' for i in range(len(coeffs)): c = QQ(coeffs[i]) s = "" if d>1 and i >0 and c>0: s="+" if c<0: s="-" if c.denominator()>1: cc = "\\frac{{ {0} }}{{ {1} }}".format(abs(c.numerator()),c.denominator()) else: cc = str(abs(c)) s += "{0} \cdot ".format(cc) a = monom[i][0]; b = monom[i][1] if a == 0 and b != 0: s+="E_6^{{ {0} }}".format(b) elif b ==0 and a != 0: s+="E_4^{{ {0} }}".format(a) else: s+="E_4^{{ {0} }}E_6^{{ {1} }}".format(a,b) info['explicit_formulas'] += s info['explicit_formulas'] += " \)" # cur_url = '?&level=' + str(level) + '&weight=' + str(weight) + '&character=' + str(character) + '&label=' + str(label) # never used if len(WNF.parent.hecke_orbits) > 1: for label_other in WNF.parent.hecke_orbits.keys(): if(label_other != label): s = 'Modular form ' if character: s += newform_label(level,weight,character,label_other) else: s += newform_label(level,weight,1,label_other) url = url_for('emf.render_elliptic_modular_forms', level=level, weight=weight, character=character, label=label_other) friends.append((s, url)) s = 'L-Function ' if character: s += newform_label(level,weight,character,label) else: s += newform_label(level,weight,1,label) # url = # "/L/ModularForm/GL2/Q/holomorphic?level=%s&weight=%s&character=%s&label=%s&number=%s" # %(level,weight,character,label,0) url = '/L' + url_for( 'emf.render_elliptic_modular_forms', level=level, weight=weight, character=character, label=label) if WNF.coefficient_field_degree > 1: for h in range(WNF.coefficient_field_degree): s0 = s + ".{0}".format(h) url0 = url + "{0}/".format(h) friends.append((s0, url0)) else: friends.append((s, url)) # if there is an elliptic curve over Q associated to self we also list that if WNF.weight == 2 and WNF.coefficient_field_degree == 1: llabel = str(level) + '.' + label s = 'Elliptic curve isogeny class ' + llabel url = '/EllipticCurve/Q/' + llabel friends.append((s, url)) info['properties2'] = properties2 info['friends'] = friends info['max_cn'] = WNF.max_available_prec() return info
def set_info_for_modular_form_space(level=None, weight=None, character=None, label=None, **kwds): r""" Set information about a space of modular forms. """ info = dict() emf_logger.debug("info={0}".format(info)) WMFS = None if info.has_key('error'): return info if level <= 0: info['error'] = "Got wrong level: %s " % level return info try: WMFS = WebModFormSpace_cached(level = level, weight = weight, cuspidal=True, character = character, update_from_db=True) WMFS.update_from_db() ## Need to call an extra time for some reason... if not WMFS.has_updated(): stop = False orbit = WMFS.character.character.galois_orbit() while not stop: if len(orbit) == 0: stop = True continue c = orbit.pop() if c.number() == WMFS.character.number: continue print c.number() WMFS_rep = WebModFormSpace_cached(level = level, weight = weight, cuspidal=True, character = c.number(), update_from_db=True) if WMFS_rep.has_updated_from_db(): stop = True info['wmfs_rep_url'] = url_for('emf.render_elliptic_modular_forms', level=level, weight=weight, character = c.number()) info['wmfs_rep_number'] = c.number() emf_logger.debug("Created WebModFormSpace %s"%WMFS) if 'download' in info and 'tempfile' in info: save(WNF,info['tempfile']) info['filename'] = str(weight) + '-' + str(level) + '-' + str(character) + '-' + label + '.sobj' return info except ValueError as e: emf_logger.debug(e) emf_logger.debug(e.message) #if isinstance(e,IndexError): info['error'] = e.message WMFS = None if WMFS is None: info['error'] = "We are sorry. The sought space can not be found in the database. "+"<br> Detailed information: {0}".format(info.get('error','')) return info else: ### Somehow the Hecke orbits are sometimes not in the space... #if WMFS.dimension_new_cusp_forms()!=len(WMFS.hecke_orbits): # ## Try to add them here... # for d in range(len(WMFS.dimension_new_cusp_forms())): # F = # WMFS.hecke_orbits.append(F) info['space'] = WMFS # info['old_decomposition'] = WMFS.oldspace_decomposition() info['oldspace_decomposition']='' try: emf_logger.debug("Oldspace = {0}".format(WMFS.oldspace_decomposition)) if WMFS.oldspace_decomposition != []: emf_logger.debug("oldspace={0}".format(WMFS.oldspace_decomposition)) l = [] for t in WMFS.oldspace_decomposition: emf_logger.debug("t={0}".format(t)) N,k,chi,mult,d = t url = url_for('emf.render_elliptic_modular_forms', level=N, weight=k, character=chi) if chi != 1: sname = "S^{{ new }}_{{ {k} }}(\\Gamma_0({N}),\\chi_{{ {N} }}({chi},\\cdot))".format(k=k,N=N,chi=chi) else: sname = "S^{{ new }}_{{ {k} }}(\\Gamma_0({N}))".format(k=k,N=N) l.append("\href{{ {url} }}{{ {sname} }}^{{\oplus {mult} }}".format(sname=sname,mult=mult,url=url)) if l != []: s = "\\oplus ".join(l) info['oldspace_decomposition']=' $ {0} $'.format(s) except Exception as e: emf_logger.critical("Oldspace decomposition failed. Error:{0}".format(e)) ## For side-bar lifts = list() lifts.append(('Half-Integral Weight Forms', '/ModularForm/Mp2/Q')) lifts.append(('Siegel Modular Forms', '/ModularForm/GSp4/Q')) info['lifts'] = lifts friends = list() for label in WMFS.hecke_orbits: f = WMFS.hecke_orbits[label] # catch the url being None or set to '': if hasattr(f.base_ring, "lmfdb_url") and f.base_ring.lmfdb_url: friends.append(('Number field ' + f.base_ring.lmfdb_pretty, f.base_ring.lmfdb_url)) if hasattr(f.coefficient_field, "lmfdb_url") and f.coefficient_field.lmfdb_url: friends.append(('Number field ' + f.coefficient_field.lmfdb_pretty, f.coefficient_field.lmfdb_url)) friends.append(("Dirichlet character \(" + WMFS.character.latex_name + "\)", WMFS.character.url())) friends = uniq(friends) info['friends'] = friends return info
def set_info_for_web_newform(level=None, weight=None, character=None, label=None, **kwds): r""" Set the info for on modular form. """ info = to_dict(kwds) info['level'] = level info['weight'] = weight info['character'] = character info['label'] = label if level is None or weight is None or character is None or label is None: s = "In set info for one form but do not have enough args!" s += "level={0},weight={1},character={2},label={3}".format( level, weight, character, label) emf_logger.critical(s) emf_logger.debug("In set_info_for_one_mf: info={0}".format(info)) prec = my_get(info, 'prec', default_prec, int) bprec = my_get(info, 'bprec', default_display_bprec, int) emf_logger.debug("PREC: {0}".format(prec)) emf_logger.debug("BITPREC: {0}".format(bprec)) try: WNF = WebNewForm_cached(level=level, weight=weight, character=character, label=label) if not WNF.has_updated(): raise IndexError( "Unfortunately, we do not have this newform in the database.") info['character_order'] = WNF.character.order info['code'] = WNF.code emf_logger.debug("defined webnewform for rendering!") except IndexError as e: info['error'] = e.message url0 = url_for("mf.modular_form_main_page") url1 = url_for("emf.render_elliptic_modular_forms") url2 = url_for("emf.render_elliptic_modular_forms", level=level) url3 = url_for("emf.render_elliptic_modular_forms", level=level, weight=weight) url4 = url_for("emf.render_elliptic_modular_forms", level=level, weight=weight, character=character) bread = [(MF_TOP, url0), (EMF_TOP, url1)] bread.append(("Level %s" % level, url2)) bread.append(("Weight %s" % weight, url3)) bread.append(("Character \( %s \)" % (WNF.character.latex_name), url4)) bread.append( ("Newform %d.%d.%d.%s" % (level, weight, int(character), label), '')) info['bread'] = bread properties2 = list() friends = list() space_url = url_for('emf.render_elliptic_modular_forms', level=level, weight=weight, character=character) friends.append( ('\( S_{%s}(%s, %s)\)' % (WNF.weight, WNF.level, WNF.character.latex_name), space_url)) if hasattr(WNF.base_ring, "lmfdb_url") and WNF.base_ring.lmfdb_url: friends.append(('Number field ' + WNF.base_ring.lmfdb_pretty, WNF.base_ring.lmfdb_url)) if hasattr(WNF.coefficient_field, "lmfdb_url") and WNF.coefficient_field.lmfdb_label: friends.append(('Number field ' + WNF.coefficient_field.lmfdb_pretty, WNF.coefficient_field.lmfdb_url)) friends = uniq(friends) friends.append(("Dirichlet character \(" + WNF.character.latex_name + "\)", WNF.character.url())) if WNF.dimension == 0 and not info.has_key('error'): info['error'] = "This space is empty!" info['title'] = 'Newform ' + WNF.hecke_orbit_label info['learnmore'] = [('History of modular forms', url_for('.holomorphic_mf_history'))] if 'error' in info: return info ## Until we have figured out how to do the embeddings correctly we don't display the Satake ## parameters for non-trivial characters.... ## Example to illustrate the different cases ## base = CyclotomicField(n) -- of degree phi(n) ## coefficient_field = NumberField( p(x)) for some p in base['x'] of degree m ## we would then have cdeg = m*phi(n) and bdeg = phi(n) ## and rdeg = m ## Unfortunately, for e.g. base = coefficient_field = CyclotomicField(6) ## we get coefficient_field.relative_degree() == 2 although it should be 1 cdeg = WNF.coefficient_field.absolute_degree() bdeg = WNF.base_ring.absolute_degree() if cdeg == 1: rdeg = 1 else: ## just setting rdeg = WNF.coefficient_field.relative_degree() does not give correct result... ## rdeg = QQ(cdeg) / QQ(bdeg) cf_is_QQ = (cdeg == 1) br_is_QQ = (bdeg == 1) if cf_is_QQ: info['satake'] = WNF.satake if WNF.complexity_of_first_nonvanishing_coefficients( ) > default_max_height: info['qexp'] = "" info['qexp_display'] = '' info['hide_qexp'] = True n, c = WNF.first_nonvanishing_coefficient() info['trace_nv'] = latex(WNF.first_nonvanishing_coefficient_trace()) info['norm_nv'] = '\\approx ' + latex( WNF.first_nonvanishing_coefficient_norm().n()) info['index_nv'] = n else: if WNF.prec < prec: #get WNF record at larger prec WNF.prec = prec WNF.update_from_db() info['qexp'] = WNF.q_expansion_latex(prec=10, name='\\alpha ') info['qexp_display'] = url_for(".get_qexp_latex", level=level, weight=weight, character=character, label=label) info["hide_qexp"] = False info['max_cn_qexp'] = WNF.q_expansion.prec() ## All combinations should be tested... ## 13/4/4/a -> base ring = coefficient_field = QQ(zeta_6) ## 13/3/8/a -> base_ring = QQ(zeta_4), coefficient_field has poly x^2+(2\zeta_4+2x-3\zeta_$ over base_ring ## 13/4/3/a -> base_ring = coefficient_field = QQ(zeta_3) ## 13/4/1/a -> all rational ## 13/6/1/a/ -> base_ring = QQ, coefficient_field = Q(sqrt(17)) ## These are variables which needs to be set properly below info['polvars'] = {'base_ring': 'x', 'coefficient_field': '\\alpha'} if not cf_is_QQ: if rdeg > 1: # not WNF.coefficient_field == WNF.base_ring: ## Here WNF.base_ring should be some cyclotomic field and we have an extension over this. p1 = WNF.coefficient_field.relative_polynomial() c_pol_ltx = web_latex_poly(p1, '\\alpha') # make the variable \alpha c_pol_ltx_x = web_latex_poly(p1, 'x') zeta = p1.base_ring().gens()[0] # p2 = zeta.minpoly() #this is not used anymore # b_pol_ltx = web_latex_poly(p2, latex(zeta)) #this is not used anymore z1 = zeta.multiplicative_order() info['coeff_field'] = [ WNF.coefficient_field.absolute_polynomial_latex('x'), c_pol_ltx_x, z1 ] if hasattr(WNF.coefficient_field, "lmfdb_url") and WNF.coefficient_field.lmfdb_url: info['coeff_field_pretty'] = [ WNF.coefficient_field.lmfdb_url, WNF.coefficient_field.lmfdb_pretty, WNF.coefficient_field.lmfdb_label ] if z1 == 4: info[ 'polynomial_st'] = '<div class="where">where</div> {0}\(\mathstrut=0\) and \(\zeta_4=i\).</div><br/>'.format( c_pol_ltx) info['polvars']['base_ring'] = 'i' elif z1 <= 2: info[ 'polynomial_st'] = '<div class="where">where</div> {0}\(\mathstrut=0\).</div><br/>'.format( c_pol_ltx) else: info[ 'polynomial_st'] = '<div class="where">where</div> %s\(\mathstrut=0\) and \(\zeta_{%s}=e^{\\frac{2\\pi i}{%s}}\) ' % ( c_pol_ltx, z1, z1) info['polvars']['base_ring'] = '\zeta_{{ {0} }}'.format(z1) if z1 == 3: info[ 'polynomial_st'] += 'is a primitive cube root of unity.' else: info[ 'polynomial_st'] += 'is a primitive {0}-th root of unity.'.format( z1) elif not br_is_QQ: ## Now we have base and coefficient field being equal, meaning that since the coefficient field is not QQ it is some cyclotomic field ## generated by some \zeta_n p1 = WNF.coefficient_field.absolute_polynomial() z1 = WNF.coefficient_field.gens()[0].multiplicative_order() c_pol_ltx = web_latex_poly(p1, '\\zeta_{{{0}}}'.format(z1)) c_pol_ltx_x = web_latex_poly(p1, 'x') info['coeff_field'] = [ WNF.coefficient_field.absolute_polynomial_latex('x'), c_pol_ltx_x ] if hasattr(WNF.coefficient_field, "lmfdb_url") and WNF.coefficient_field.lmfdb_url: info['coeff_field_pretty'] = [ WNF.coefficient_field.lmfdb_url, WNF.coefficient_field.lmfdb_pretty, WNF.coefficient_field.lmfdb_label ] if z1 == 4: info[ 'polynomial_st'] = '<div class="where">where \(\zeta_4=e^{{\\frac{{\\pi i}}{{ 2 }} }}=i \).</div>'.format( c_pol_ltx) info['polvars']['coefficient_field'] = 'i' elif z1 <= 2: info['polynomial_st'] = '' else: info[ 'polynomial_st'] = '<div class="where">where \(\zeta_{{{0}}}=e^{{\\frac{{2\\pi i}}{{ {0} }} }}\) '.format( z1) info['polvars']['coefficient_field'] = '\zeta_{{{0}}}'.format( z1) if z1 == 3: info[ 'polynomial_st'] += 'is a primitive cube root of unity.</div>' else: info[ 'polynomial_st'] += 'is a primitive {0}-th root of unity.</div>'.format( z1) else: info['polynomial_st'] = '' if info["hide_qexp"]: info['polynomial_st'] = '' info['degree'] = int(cdeg) if cdeg == 1: info['is_rational'] = 1 info['coeff_field_pretty'] = [ WNF.coefficient_field.lmfdb_url, WNF.coefficient_field.lmfdb_pretty ] else: info['is_rational'] = 0 emf_logger.debug("PREC2: {0}".format(prec)) info['embeddings'] = WNF._embeddings[ 'values'] #q_expansion_embeddings(prec, bprec,format='latex') info['embeddings_len'] = len(info['embeddings']) properties2 = [('Level', str(level)), ('Weight', str(weight)), ('Character', '$' + WNF.character.latex_name + '$'), ('Label', WNF.hecke_orbit_label), ('Dimension of Galois orbit', str(WNF.dimension))] if (ZZ(level)).is_squarefree(): info['twist_info'] = WNF.twist_info if isinstance(info['twist_info'], list) and len(info['twist_info']) > 0: info['is_minimal'] = info['twist_info'][0] if (info['twist_info'][0]): s = 'Is minimal<br>' else: s = 'Is a twist of lower level<br>' properties2 += [('Twist info', s)] else: info['twist_info'] = 'Twist info currently not available.' properties2 += [('Twist info', 'not available')] args = list() for x in range(5, 200, 10): args.append({'digits': x}) alev = None CM = WNF._cm_values if CM is not None: if CM.has_key('tau') and len(CM['tau']) != 0: info['CM_values'] = CM info['is_cm'] = WNF.is_cm if WNF.is_cm == 1: info['cm_field'] = "2.0.{0}.1".format(-WNF.cm_disc) info['cm_disc'] = WNF.cm_disc info['cm_field_knowl'] = nf_display_knowl( info['cm_field'], getDBConnection(), field_pretty(info['cm_field'])) info['cm_field_url'] = url_for("number_fields.by_label", label=info["cm_field"]) if WNF.is_cm is None or WNF.is_cm == -1: s = '- Unknown (insufficient data)<br>' elif WNF.is_cm == 1: s = 'Yes<br>' else: s = 'No<br>' properties2.append(('CM', s)) alev = WNF.atkin_lehner_eigenvalues() info['atkinlehner'] = None if isinstance(alev, dict) and len(alev.keys()) > 0 and level != 1: s1 = " Atkin-Lehner eigenvalues " s2 = "" for Q in alev.keys(): s2 += "\( \omega_{ %s } \) : %s <br>" % (Q, alev[Q]) properties2.append((s1, s2)) emf_logger.debug("properties={0}".format(properties2)) # alev = WNF.atkin_lehner_eigenvalues_for_all_cusps() # if isinstance(alev,dict) and len(alev.keys())>0: # emf_logger.debug("alev={0}".format(alev)) # info['atkinlehner'] = list() # for Q in alev.keys(): # s = "\(" + latex(c) + "\)" # Q = alev[c][0] # ev = alev[c][1] # info['atkinlehner'].append([Q, c, ev]) if (level == 1): poly = WNF.explicit_formulas.get('as_polynomial_in_E4_and_E6', '') if poly != '': d, monom, coeffs = poly emf_logger.critical("poly={0}".format(poly)) info['explicit_formulas'] = '\(' for i in range(len(coeffs)): c = QQ(coeffs[i]) s = "" if d > 1 and i > 0 and c > 0: s = "+" if c < 0: s = "-" if c.denominator() > 1: cc = "\\frac{{ {0} }}{{ {1} }}".format( abs(c.numerator()), c.denominator()) else: cc = str(abs(c)) s += "{0} \cdot ".format(cc) a = monom[i][0] b = monom[i][1] if a == 1: a = "" if b == 1: b = "" if a == 0 and b != 0: s += "E_6^{{ {0} }}(z)".format(b) elif b == 0 and a != 0: s += "E_4^{{ {0} }}(z)".format(a) else: s += "E_4^{{ {0} }}(z) \cdot E_6^{{ {1} }}(z)".format(a, b) info['explicit_formulas'] += s info['explicit_formulas'] += " \)" # cur_url = '?&level=' + str(level) + '&weight=' + str(weight) + '&character=' + str(character) + '&label=' + str(label) # never used if len(WNF.parent.hecke_orbits) > 1: for label_other in WNF.parent.hecke_orbits.keys(): if (label_other != label): s = 'Modular form ' if character: s += newform_label(level, weight, character, label_other) else: s += newform_label(level, weight, 1, label_other) url = url_for('emf.render_elliptic_modular_forms', level=level, weight=weight, character=character, label=label_other) friends.append((s, url)) s = 'L-Function ' if character: s += newform_label(level, weight, character, label) else: s += newform_label(level, weight, 1, label) # url = # "/L/ModularForm/GL2/Q/holomorphic?level=%s&weight=%s&character=%s&label=%s&number=%s" # %(level,weight,character,label,0) url = '/L' + url_for('emf.render_elliptic_modular_forms', level=level, weight=weight, character=character, label=label) if WNF.coefficient_field_degree > 1: for h in range(WNF.coefficient_field_degree): s0 = s + ".{0}".format(h) url0 = url + "{0}/".format(h) friends.append((s0, url0)) else: friends.append((s, url)) # if there is an elliptic curve over Q associated to self we also list that if WNF.weight == 2 and WNF.coefficient_field_degree == 1: llabel = str(level) + '.' + label s = 'Elliptic curve isogeny class ' + llabel url = '/EllipticCurve/Q/' + llabel friends.append((s, url)) info['properties2'] = properties2 info['friends'] = friends info['max_cn'] = WNF.max_available_prec() return info
def submatrix_configurations(S): configs = orbit(S) [m.set_immutable() for m in configs] return uniq(configs)
def set_info_for_modular_form_space(level=None, weight=None, character=None, label=None, **kwds): r""" Set information about a space of modular forms. """ info = dict() emf_logger.debug("info={0}".format(info)) WMFS = None if info.has_key('error'): return info if level <= 0: info['error'] = "Got wrong level: %s " % level return info try: WMFS = WebModFormSpace_cached(level = level, weight = weight, cuspidal=True, character = character, update_from_db=True) emf_logger.debug("Created WebModFormSpace %s"%WMFS) if not WMFS.has_updated(): #get the representative we have in the db for this space (Galois conjugate) #note that this does not use the web_object infrastructure at all right now #which should be changed for sure! dimension_table_name = WebModFormSpace._dimension_table_name db_dim = getDBConnection()['modularforms2'][dimension_table_name] rep = db_dim.find_one({'level': level, 'weight': weight, 'character_orbit': {'$in': [character]}}) if not rep is None and not rep['cchi'] == character: # don't link back to myself! info['wmfs_rep_url'] = url_for('emf.render_elliptic_modular_forms', level=level, weight=weight, character=rep['cchi']) info['wmfs_rep_number'] = rep['cchi'] # FIXME: the variable WNF is not defined above, so the code below cannot work (I don't think it is ever used) # if 'download' in info and 'tempfile' in info: # save(WNF,info['tempfile']) # info['filename'] = str(weight) + '-' + str(level) + '-' + str(character) + '-' + label + '.sobj' # return info except ValueError as e: emf_logger.debug(e) emf_logger.debug(e.message) #if isinstance(e,IndexError): info['error'] = e.message WMFS = None if WMFS is None: info['error'] = "We are sorry. The sought space can not be found in the database. "+"<br> Detailed information: {0}".format(info.get('error','')) return info else: ### Somehow the Hecke orbits are sometimes not in the space... #if WMFS.dimension_new_cusp_forms()!=len(WMFS.hecke_orbits): # ## Try to add them here... # for d in range(len(WMFS.dimension_new_cusp_forms())): # F = # WMFS.hecke_orbits.append(F) info['space'] = WMFS info['max_height'] = default_max_height # info['old_decomposition'] = WMFS.oldspace_decomposition() info['oldspace_decomposition']='' try: emf_logger.debug("Oldspace = {0}".format(WMFS.oldspace_decomposition)) if WMFS.oldspace_decomposition != []: emf_logger.debug("oldspace={0}".format(WMFS.oldspace_decomposition)) l = [] for t in WMFS.oldspace_decomposition: emf_logger.debug("t={0}".format(t)) N,k,chi,mult,d = t url = url_for('emf.render_elliptic_modular_forms', level=N, weight=k, character=chi) if chi != 1: sname = "S^{{ new }}_{{ {k} }}(\\Gamma_0({N}),\\chi_{{ {N} }}({chi},\\cdot))".format(k=k,N=N,chi=chi) else: sname = "S^{{ new }}_{{ {k} }}(\\Gamma_0({N}))".format(k=k,N=N) l.append("\href{{ {url} }}{{ {sname} }}^{{\oplus {mult} }}".format(sname=sname,mult=mult,url=url)) if l != []: s = "\\oplus ".join(l) info['oldspace_decomposition']=' $ {0} $'.format(s) except Exception as e: emf_logger.critical("Oldspace decomposition failed. Error:{0}".format(e)) ## For side-bar lifts = list() lifts.append(('Half-Integral Weight Forms', '/ModularForm/Mp2/Q')) lifts.append(('Siegel Modular Forms', '/ModularForm/GSp4/Q')) info['lifts'] = lifts friends = list() for label in WMFS.hecke_orbits: f = WMFS.hecke_orbits[label] # catch the url being None or set to '': if hasattr(f.base_ring, "lmfdb_url") and f.base_ring.lmfdb_url: friends.append(('Number field ' + f.base_ring.lmfdb_pretty, f.base_ring.lmfdb_url)) if hasattr(f.coefficient_field, "lmfdb_url") and f.coefficient_field.lmfdb_url: friends.append(('Number field ' + f.coefficient_field.lmfdb_pretty, f.coefficient_field.lmfdb_url)) friends.append(("Dirichlet character \(" + WMFS.character.latex_name + "\)", WMFS.character.url())) friends = uniq(friends) info['friends'] = friends info['code'] = WMFS.code return info
def _compute_simple_modules_graph_from_startpoint(self, s, p=None, cut_nonsimple_aniso=True, fast=1): # for forking this is necessary logger = get_logger(s) # print logger k = self._weight ########################################################### # Determine which primes need to be checked # According to the proof of Proposition XX in [BEF], we # only need to check primesnot dividing the 6*level(s), # for which prime_pol(s,p,k) <= 0. # For those primes, we check if there is any # k-simple fqm in s.C(p) and if not, we do not have to # consider p anymore. ########################################################### if p == None: p = 2 N = Integer(6) * s.level() slp = N.prime_factors() for q in prime_range(next_prime(N) + 1): if not q in slp: logger.info( "Smallest prime not dividing 6*level({0}) = {1} is p = {2}".format(s, Integer(6) * s.level(), q)) p = q break while prime_pol(s, p, k) <= 0 or p in slp: p = next_prime(p) p = uniq(prime_range(p) + slp) logger.info("Starting with s = {0} and primes = {1}".format(s, p)) if isinstance(p, list): primes = p else: primes = [p] simple = s.is_simple(k, reduction = self._reduction, bound = self._bound) if not simple: logger.info("{0} is not simple.".format(s)) # print simple s = FQM_vertex(s) # print s self.add_vertex(s) # print "added vertex ", s ############################################################ # Starting from the list of primes we generated, # we now compute which primes we actually need to consider. # That is, the primes such that there is a fqm in s.C(p) # which is k-simple. ############################################################ np = list() if cut_nonsimple_aniso and simple: for i in range(len(primes)): p = primes[i] fs = False for t in s.genus_symbol().C(p, False): if t.is_simple(k, bound = self._bound): fs = True logger.debug("Setting fs = True") break if fs: np.append(p) primes = np # print "here", primes logger.info("primes for graph for {0}: {1}".format(s, primes)) # if len(primes) == 0: # return heights = self._heights h = 0 if not heights.has_key(h): heights[h] = [s] else: if heights[h].count(s) == 0: heights[h].append(s) vertex_colors = self._vertex_colors nonsimple_color = self._nonsimple_color simple_color = self._simple_color # Bs contains the modules of the current level (= height = h) Bs = [s] # set the correct color for the vertex s if simple: if vertex_colors[simple_color].count(s) == 0: vertex_colors[simple_color].append(s) elif vertex_colors[nonsimple_color].count(s) == 0: vertex_colors[nonsimple_color].append(s) ################################################### # MAIN LOOP # we loop until we haven't found any simple fqm's ################################################### while simple: h = h + 1 if not heights.has_key(h): heights[h] = list() # the list Bss will contain the k-simple modules of the next height level # recall that Bs contains the modules of the current height level Bss = list() simple = False # checklist = modules that we need to check for with .is_simple(k) # we assemble this list because afterwards # we check them in parallel checklist = [] for s1 in Bs: Bs2 = list() for p in primes: # check if we really need to check p for s1 # otherwise none of the fqm's in s1.C(p) are simple # and we will not consider them. if prime_pol(s1.genus_symbol(), p, k) <= 0: Bs2 = Bs2 + s1.genus_symbol().C(p, False) else: logger.info( "Skipping p = {0} for s1 = {1}".format(p, s1)) # print "Skipping p = {0} for s1 = {1}".format(p, s1) # print "Bs2 = ", Bs2 # now we actually check the symbols in Bs2 for s2 in Bs2: if s2.max_rank() > self._rank_limit: # we skip s2 if its minimal number of generators # is > than the given rank_limit. continue s2 = FQM_vertex(s2) skip = False for v in self._heights[h]: # we skip symbols that correspond to isomorphic modules if v.genus_symbol().defines_isomorphic_module(s2.genus_symbol()): skip = True logger.debug( "skipping {0} b/c isomorphic to {1}".format(s2.genus_symbol(), v.genus_symbol())) s2 = v break if skip: continue if not skip: self.add_vertex(s2) heights[h].append(s2) self.update_edges(s2, h, fast=fast) # before using the actual dimension formula # we check if there is already a non-k-simple neighbor # (an incoming edge from a non-k-simple module) # which would imply that s2 is not k-simple. has_nonsimple_neighbor = False for e in self.incoming_edges(s2): if vertex_colors[nonsimple_color].count(e[0]) > 0: has_nonsimple_neighbor = True logger.debug( "Has nonsimple neighbor: {0}".format(s2.genus_symbol())) break if has_nonsimple_neighbor: #not simple if not vertex_colors[nonsimple_color].count(s2) > 0: vertex_colors[nonsimple_color].append(s2) else: checklist.append((s2, k, self._reduction, self._bound)) logger.debug("checklist = {0}".format(checklist)) # check the modules in checklist # for being k-simple # this is done in parallel # when a process returns # we add the vertex and give it its appropriate color if NCPUS1 == 1: checks = [([[s[0]]],check_simple(*s)) for s in checklist] else: checks = list(check_simple(checklist)) logger.info("checks = {0}".format(checks)) for check in checks: s2 = check[0][0][0] if check[1]: simple = True logger.info( "Found simple module: {0}".format(s2.genus_symbol())) Bss.append(s2) if not vertex_colors[simple_color].count(s2) > 0: vertex_colors[simple_color].append(s2) else: if not vertex_colors[nonsimple_color].count(s2) > 0: vertex_colors[nonsimple_color].append(s2) Bs = Bss simple = [v.genus_symbol() for v in vertex_colors[simple_color]] self._simple = uniq(simple)
def _compute_simple_modules_graph_from_startpoint(self, s, p=None, cut_nonsimple_aniso=True, fast=1): # for forking this is necessary logger = get_logger(s) # print logger k = self._weight ########################################################### # Determine which primes need to be checked # According to the proof of Proposition XX in [BEF], we # only need to check primesnot dividing the 6*level(s), # for which prime_pol(s,p,k) <= 0. # For those primes, we check if there is any # k-simple fqm in s.C(p) and if not, we do not have to # consider p anymore. ########################################################### if p == None: p = 2 N = Integer(6) * s.level() slp = N.prime_factors() for q in prime_range(next_prime(N) + 1): if not q in slp: logger.info( "Smallest prime not dividing 6*level({0}) = {1} is p = {2}" .format(s, Integer(6) * s.level(), q)) p = q break while prime_pol(s, p, k) <= 0 or p in slp: p = next_prime(p) p = uniq(prime_range(p) + slp) logger.info("Starting with s = {0} and primes = {1}".format(s, p)) if isinstance(p, list): primes = p else: primes = [p] simple = s.is_simple(k, reduction=self._reduction, bound=self._bound) if not simple: logger.info("{0} is not simple.".format(s)) # print simple s = FQM_vertex(s) # print s self.add_vertex(s) # print "added vertex ", s ############################################################ # Starting from the list of primes we generated, # we now compute which primes we actually need to consider. # That is, the primes such that there is a fqm in s.C(p) # which is k-simple. ############################################################ np = list() if cut_nonsimple_aniso and simple: for i in range(len(primes)): p = primes[i] fs = False for t in s.genus_symbol().C(p, False): if t.is_simple(k, bound=self._bound): fs = True logger.debug("Setting fs = True") break if fs: np.append(p) primes = np # print "here", primes logger.info("primes for graph for {0}: {1}".format(s, primes)) # if len(primes) == 0: # return heights = self._heights h = 0 if not heights.has_key(h): heights[h] = [s] else: if heights[h].count(s) == 0: heights[h].append(s) vertex_colors = self._vertex_colors nonsimple_color = self._nonsimple_color simple_color = self._simple_color # Bs contains the modules of the current level (= height = h) Bs = [s] # set the correct color for the vertex s if simple: if vertex_colors[simple_color].count(s) == 0: vertex_colors[simple_color].append(s) elif vertex_colors[nonsimple_color].count(s) == 0: vertex_colors[nonsimple_color].append(s) ################################################### # MAIN LOOP # we loop until we haven't found any simple fqm's ################################################### while simple: h = h + 1 if not heights.has_key(h): heights[h] = list() # the list Bss will contain the k-simple modules of the next height level # recall that Bs contains the modules of the current height level Bss = list() simple = False # checklist = modules that we need to check for with .is_simple(k) # we assemble this list because afterwards # we check them in parallel checklist = [] for s1 in Bs: Bs2 = list() for p in primes: # check if we really need to check p for s1 # otherwise none of the fqm's in s1.C(p) are simple # and we will not consider them. if prime_pol(s1.genus_symbol(), p, k) <= 0: Bs2 = Bs2 + s1.genus_symbol().C(p, False) else: logger.info("Skipping p = {0} for s1 = {1}".format( p, s1)) # print "Skipping p = {0} for s1 = {1}".format(p, s1) # print "Bs2 = ", Bs2 # now we actually check the symbols in Bs2 for s2 in Bs2: if s2.max_rank() > self._rank_limit: # we skip s2 if its minimal number of generators # is > than the given rank_limit. continue s2 = FQM_vertex(s2) skip = False for v in self._heights[h]: # we skip symbols that correspond to isomorphic modules if v.genus_symbol().defines_isomorphic_module( s2.genus_symbol()): skip = True logger.debug( "skipping {0} b/c isomorphic to {1}".format( s2.genus_symbol(), v.genus_symbol())) s2 = v break if skip: continue if not skip: self.add_vertex(s2) heights[h].append(s2) self.update_edges(s2, h, fast=fast) # before using the actual dimension formula # we check if there is already a non-k-simple neighbor # (an incoming edge from a non-k-simple module) # which would imply that s2 is not k-simple. has_nonsimple_neighbor = False for e in self.incoming_edges(s2): if vertex_colors[nonsimple_color].count(e[0]) > 0: has_nonsimple_neighbor = True logger.debug("Has nonsimple neighbor: {0}".format( s2.genus_symbol())) break if has_nonsimple_neighbor: #not simple if not vertex_colors[nonsimple_color].count(s2) > 0: vertex_colors[nonsimple_color].append(s2) else: checklist.append((s2, k, self._reduction, self._bound)) logger.debug("checklist = {0}".format(checklist)) # check the modules in checklist # for being k-simple # this is done in parallel # when a process returns # we add the vertex and give it its appropriate color if NCPUS1 == 1: checks = [([[s[0]]], check_simple(*s)) for s in checklist] else: checks = list(check_simple(checklist)) logger.info("checks = {0}".format(checks)) for check in checks: s2 = check[0][0][0] if check[1]: simple = True logger.info("Found simple module: {0}".format( s2.genus_symbol())) Bss.append(s2) if not vertex_colors[simple_color].count(s2) > 0: vertex_colors[simple_color].append(s2) else: if not vertex_colors[nonsimple_color].count(s2) > 0: vertex_colors[nonsimple_color].append(s2) Bs = Bss simple = [v.genus_symbol() for v in vertex_colors[simple_color]] self._simple = uniq(simple)
def set_info_for_modular_form_space(level=None, weight=None, character=None, label=None, **kwds): r""" Set information about a space of modular forms. """ info = dict() emf_logger.debug("info={0}".format(info)) WMFS = None if info.has_key('error'): return info if level <= 0: info['error'] = "Got wrong level: %s " % level return info try: WMFS = WebModFormSpace_cached(level = level, weight = weight, cuspidal=True, character = character, update_from_db=True) if not WMFS.has_updated(): stop = False orbit = WMFS.character.character.galois_orbit() while not stop: if len(orbit) == 0: stop = True continue c = orbit.pop() if c.number() == WMFS.character.number: continue print c.number() WMFS_rep = WebModFormSpace_cached(level = level, weight = weight, cuspidal=True, character = c.number(), update_from_db=True) if WMFS_rep.has_updated_from_db(): stop = True info['wmfs_rep_url'] = url_for('emf.render_elliptic_modular_forms', level=level, weight=weight, character = c.number()) info['wmfs_rep_number'] = c.number() emf_logger.debug("Created WebModFormSpace %s"%WMFS) if 'download' in info and 'tempfile' in info: save(WNF,info['tempfile']) info['filename'] = str(weight) + '-' + str(level) + '-' + str(character) + '-' + label + '.sobj' return info except ValueError as e: emf_logger.debug(e) emf_logger.debug(e.message) #if isinstance(e,IndexError): info['error'] = e.message WMFS = None if WMFS is None: info['error'] = "We are sorry. The sought space can not be found in the database. "+"<br> Detailed information: {0}".format(info.get('error','')) return info else: ### Somehow the Hecke orbits are sometimes not in the space... #if WMFS.dimension_new_cusp_forms()!=len(WMFS.hecke_orbits): # ## Try to add them here... # for d in range(len(WMFS.dimension_new_cusp_forms())): # F = # WMFS.hecke_orbits.append(F) info['space'] = WMFS # info['old_decomposition'] = WMFS.oldspace_decomposition() ## For side-bar lifts = list() lifts.append(('Half-Integral Weight Forms', '/ModularForm/Mp2/Q')) lifts.append(('Siegel Modular Forms', '/ModularForm/GSp4/Q')) info['lifts'] = lifts friends = list() for label in WMFS.hecke_orbits: f = WMFS.hecke_orbits[label] # catch the url being None or set to '': if hasattr(f.base_ring, "lmfdb_url") and f.base_ring.lmfdb_url: friends.append(('Number field ' + f.base_ring.lmfdb_pretty, f.base_ring.lmfdb_url)) if hasattr(f.coefficient_field, "lmfdb_url") and f.coefficient_field.lmfdb_url: friends.append(('Number field ' + f.coefficient_field.lmfdb_pretty, f.coefficient_field.lmfdb_url)) friends.append(("Dirichlet character \(" + WMFS.character.latex_name + "\)", WMFS.character.url())) friends = uniq(friends) info['friends'] = friends return info
def set_info_for_web_newform(level=None, weight=None, character=None, label=None, **kwds): r""" Set the info for on modular form. """ info = to_dict(kwds) info["level"] = level info["weight"] = weight info["character"] = character info["label"] = label if level is None or weight is None or character is None or label is None: s = "In set info for one form but do not have enough args!" s += "level={0},weight={1},character={2},label={3}".format(level, weight, character, label) emf_logger.critical(s) emf_logger.debug("In set_info_for_one_mf: info={0}".format(info)) prec = my_get(info, "prec", default_prec, int) bprec = my_get(info, "bprec", default_display_bprec, int) emf_logger.debug("PREC: {0}".format(prec)) emf_logger.debug("BITPREC: {0}".format(bprec)) try: WNF = WebNewForm_cached(level=level, weight=weight, character=character, label=label) emf_logger.critical("defined webnewform for rendering!") # if info.has_key('download') and info.has_key('tempfile'): # WNF._save_to_file(info['tempfile']) # info['filename']=str(weight)+'-'+str(level)+'-'+str(character)+'-'+label+'.sobj' # return info except IndexError as e: WNF = None info["error"] = e.message url1 = url_for("emf.render_elliptic_modular_forms") url2 = url_for("emf.render_elliptic_modular_forms", level=level) url3 = url_for("emf.render_elliptic_modular_forms", level=level, weight=weight) url4 = url_for("emf.render_elliptic_modular_forms", level=level, weight=weight, character=character) bread = [(EMF_TOP, url1)] bread.append(("of level %s" % level, url2)) bread.append(("weight %s" % weight, url3)) if int(character) == 0: bread.append(("trivial character", url4)) else: bread.append(("\( %s \)" % (WNF.character.latex_name), url4)) info["bread"] = bread properties2 = list() friends = list() space_url = url_for("emf.render_elliptic_modular_forms", level=level, weight=weight, character=character) friends.append(("\( S_{%s}(%s, %s)\)" % (WNF.weight, WNF.level, WNF.character.latex_name), space_url)) if WNF.coefficient_field_label(check=True): friends.append(("Number field " + WNF.coefficient_field_label(), WNF.coefficient_field_url())) friends.append(("Number field " + WNF.base_field_label(), WNF.base_field_url())) friends = uniq(friends) friends.append(("Dirichlet character \(" + WNF.character.latex_name + "\)", WNF.character.url())) if WNF.dimension == 0: info["error"] = "This space is empty!" # emf_logger.debug("WNF={0}".format(WNF)) # info['name'] = name info["title"] = "Modular Form " + WNF.hecke_orbit_label if "error" in info: return info # info['name']=WNF._name ## Until we have figured out how to do the embeddings correctly we don't display the Satake ## parameters for non-trivial characters.... cdeg = WNF.coefficient_field.absolute_degree() bdeg = WNF.base_ring.absolute_degree() if WNF.coefficient_field.absolute_degree() == 1: rdeg = 1 else: rdeg = WNF.coefficient_field.relative_degree() if cdeg == 1: info["satake"] = WNF.satake info["qexp"] = WNF.q_expansion_latex(prec=10, name="a") info["qexp_display"] = url_for(".get_qexp_latex", level=level, weight=weight, character=character, label=label) # info['qexp'] = WNF.q_expansion_latex(prec=prec) # c_pol_st = str(WNF.absolute_polynomial) # b_pol_st = str(WNF.polynomial(type='base_ring',format='str')) # b_pol_ltx = str(WNF.polynomial(type='base_ring',format='latex')) # print "c=",c_pol_ltx # print "b=",b_pol_ltx if cdeg > 1: ## Field is QQ if bdeg > 1 and rdeg > 1: p1 = WNF.coefficient_field.relative_polynomial() c_pol_ltx = latex(p1) lgc = p1.variables()[0] c_pol_ltx = c_pol_ltx.replace(lgc, "a") z = p1.base_ring().gens()[0] p2 = z.minpoly() b_pol_ltx = latex(p2) b_pol_ltx = b_pol_ltx.replace(latex(p2.variables()[0]), latex(z)) info["polynomial_st"] = "where \({0}=0\) and \({1}=0\).".format(c_pol_ltx, b_pol_ltx) else: c_pol_ltx = latex(WNF.coefficient_field.relative_polynomial()) lgc = str(latex(WNF.coefficient_field.relative_polynomial().variables()[0])) c_pol_ltx = c_pol_ltx.replace(lgc, "a") info["polynomial_st"] = "where \({0}=0\)".format(c_pol_ltx) else: info["polynomial_st"] = "" info["degree"] = int(cdeg) if cdeg == 1: info["is_rational"] = 1 else: info["is_rational"] = 0 # info['q_exp_embeddings'] = WNF.print_q_expansion_embeddings() # if(int(info['degree'])>1 and WNF.dimension()>1): # s = 'One can embed it into \( \mathbb{C} \) as:' # bprec = 26 # print s # info['embeddings'] = ajax_more2(WNF.print_q_expansion_embeddings,{'prec':[5,10,25,50],'bprec':[26,53,106]},text=['more coeffs.','higher precision']) # elif(int(info['degree'])>1): # s = 'There are '+str(info['degree'])+' embeddings into \( \mathbb{C} \):' # bprec = 26 # print s # info['embeddings'] = ajax_more2(WNF.print_q_expansion_embeddings,{'prec':[5,10,25,50],'bprec':[26,53,106]},text=['more coeffs.','higher precision']) # else: # info['embeddings'] = '' emf_logger.debug("PREC2: {0}".format(prec)) info["embeddings"] = WNF._embeddings["values"] # q_expansion_embeddings(prec, bprec,format='latex') info["embeddings_len"] = len(info["embeddings"]) properties2 = [] if (ZZ(level)).is_squarefree(): info["twist_info"] = WNF.twist_info if isinstance(info["twist_info"], list) and len(info["twist_info"]) > 0: info["is_minimal"] = info["twist_info"][0] if info["twist_info"][0]: s = "- Is minimal<br>" else: s = "- Is a twist of lower level<br>" properties2 = [("Twist info", s)] else: info["twist_info"] = "Twist info currently not available." properties2 = [("Twist info", "not available")] args = list() for x in range(5, 200, 10): args.append({"digits": x}) alev = None CM = WNF._cm_values if CM is not None: if CM.has_key("tau") and len(CM["tau"]) != 0: info["CM_values"] = CM info["is_cm"] = WNF.is_cm if WNF.is_cm is None: s = "- Unknown (insufficient data)<br>" elif WNF.is_cm is True: s = "- Is a CM-form<br>" else: s = "- Is not a CM-form<br>" properties2.append(("CM info", s)) alev = WNF.atkin_lehner_eigenvalues() info["atkinlehner"] = None if isinstance(alev, dict) and len(alev.keys()) > 0 and level != 1: s1 = " Atkin-Lehner eigenvalues " s2 = "" for Q in alev.keys(): s2 += "\( \omega_{ %s } \) : %s <br>" % (Q, alev[Q]) properties2.append((s1, s2)) emf_logger.debug("properties={0}".format(properties2)) # alev = WNF.atkin_lehner_eigenvalues_for_all_cusps() # if isinstance(alev,dict) and len(alev.keys())>0: # emf_logger.debug("alev={0}".format(alev)) # info['atkinlehner'] = list() # for Q in alev.keys(): # s = "\(" + latex(c) + "\)" # Q = alev[c][0] # ev = alev[c][1] # info['atkinlehner'].append([Q, c, ev]) if level == 1: poly = WNF.explicit_formulas.get("as_polynomial_in_E4_and_E6", "") if poly != "": d, monom, coeffs = poly emf_logger.critical("poly={0}".format(poly)) info["explicit_formulas"] = "\(" for i in range(d): c = QQ(coeffs[i]) s = "" if d > 1 and i > 0 and c > 0: s = "+" if c < 0: s = "-" if c.denominator() > 1: cc = "\\frac{{ {0} }}{{ {1} }}".format(abs(c.numerator()), c.denominator()) else: cc = str(abs(c)) s += "{0} \cdot ".format(cc) a = monom[i][0] b = monom[i][1] if a == 0 and b != 0: s += "E_6^{{ {0} }}".format(b) elif b == 0 and a != 0: s += "E_4^{{ {0} }}".format(a) else: s += "E_4^{{ {0} }}E_6^{{ {1} }}".format(a, b) info["explicit_formulas"] += s info["explicit_formulas"] += " \)" cur_url = ( "?&level=" + str(level) + "&weight=" + str(weight) + "&character=" + str(character) + "&label=" + str(label) ) if len(WNF.parent.hecke_orbits) > 1: for label_other in WNF.parent.hecke_orbits.keys(): if label_other != label: s = "Modular form " if character: s = s + str(level) + "." + str(weight) + "." + str(character) + str(label_other) else: s = s + str(level) + "." + str(weight) + str(label_other) url = url_for( "emf.render_elliptic_modular_forms", level=level, weight=weight, character=character, label=label_other, ) friends.append((s, url)) s = "L-Function " if character: s = s + str(level) + "." + str(weight) + "." + str(character) + str(label) else: s = s + str(level) + "." + str(weight) + str(label) # url = # "/L/ModularForm/GL2/Q/holomorphic?level=%s&weight=%s&character=%s&label=%s&number=%s" # %(level,weight,character,label,0) url = "/L" + url_for( "emf.render_elliptic_modular_forms", level=level, weight=weight, character=character, label=label ) if WNF.coefficient_field_degree > 1: for h in range(WNF.coefficient_field_degree): s0 = s + ".{0}".format(h) url0 = url + "{0}/".format(h) friends.append((s0, url0)) else: friends.append((s, url)) # if there is an elliptic curve over Q associated to self we also list that if WNF.weight == 2 and WNF.coefficient_field_degree == 1: llabel = str(level) + "." + label s = "Elliptic curve isogeny class " + llabel url = "/EllipticCurve/Q/" + llabel friends.append((s, url)) info["properties2"] = properties2 info["friends"] = friends info["max_cn"] = WNF.max_cn() return info
def set_info_for_web_newform(level=None, weight=None, character=None, label=None, **kwds): r""" Set the info for on modular form. """ info = to_dict(kwds) info['level'] = level info['weight'] = weight info['character'] = character info['label'] = label if level is None or weight is None or character is None or label is None: s = "In set info for one form but do not have enough args!" s += "level={0},weight={1},character={2},label={3}".format(level, weight, character, label) emf_logger.critical(s) emf_logger.debug("In set_info_for_one_mf: info={0}".format(info)) prec = my_get(info, 'prec', default_prec, int) bprec = my_get(info, 'bprec', default_display_bprec, int) emf_logger.debug("PREC: {0}".format(prec)) emf_logger.debug("BITPREC: {0}".format(bprec)) try: WNF = WebNewForm_cached(level=level, weight=weight, character=character, label=label) emf_logger.critical("defined webnewform for rendering!") # if info.has_key('download') and info.has_key('tempfile'): # WNF._save_to_file(info['tempfile']) # info['filename']=str(weight)+'-'+str(level)+'-'+str(character)+'-'+label+'.sobj' # return info except IndexError as e: WNF = None info['error'] = e.message url1 = url_for("emf.render_elliptic_modular_forms") url2 = url_for("emf.render_elliptic_modular_forms", level=level) url3 = url_for("emf.render_elliptic_modular_forms", level=level, weight=weight) url4 = url_for("emf.render_elliptic_modular_forms", level=level, weight=weight, character=character) bread = [(EMF_TOP, url1)] bread.append(("of level %s" % level, url2)) bread.append(("weight %s" % weight, url3)) if int(character) == 0: bread.append(("trivial character", url4)) else: bread.append(("\( %s \)" % (WNF.character.latex_name), url4)) info['bread'] = bread properties2 = list() friends = list() space_url = url_for('emf.render_elliptic_modular_forms',level=level, weight=weight, character=character) friends.append(('\( S_{%s}(%s, %s)\)'%(WNF.weight, WNF.level, WNF.character.latex_name), space_url)) if hasattr(WNF.base_ring, "lmfdb_url") and WNF.base_ring.lmfdb_url: friends.append(('Number field ' + WNF.base_ring.lmfdb_pretty, WNF.base_ring.lmfdb_url)) if hasattr(WNF.coefficient_field, "lmfdb_url") and WNF.coefficient_field.lmfdb_label: friends.append(('Number field ' + WNF.coefficient_field.lmfdb_pretty, WNF.coefficient_field.lmfdb_url)) friends = uniq(friends) friends.append(("Dirichlet character \(" + WNF.character.latex_name + "\)", WNF.character.url())) if WNF.dimension==0: info['error'] = "This space is empty!" # emf_logger.debug("WNF={0}".format(WNF)) #info['name'] = name info['title'] = 'Modular Form ' + WNF.hecke_orbit_label if 'error' in info: return info # info['name']=WNF._name ## Until we have figured out how to do the embeddings correctly we don't display the Satake ## parameters for non-trivial characters.... cdeg = WNF.coefficient_field.absolute_degree() bdeg = WNF.base_ring.absolute_degree() if cdeg == 1: rdeg = 1 else: rdeg = WNF.coefficient_field.relative_degree() cf_is_QQ = (cdeg == 1) br_is_QQ = (bdeg == 1) if cf_is_QQ: info['satake'] = WNF.satake info['qexp'] = WNF.q_expansion_latex(prec=10, name='\\alpha ') info['qexp_display'] = url_for(".get_qexp_latex", level=level, weight=weight, character=character, label=label) info['max_cn_qexp'] = WNF.q_expansion.prec() if not cf_is_QQ: if not br_is_QQ and rdeg>1: # not WNF.coefficient_field == WNF.base_ring: p1 = WNF.coefficient_field.relative_polynomial() c_pol_ltx = web_latex_poly(p1, '\\alpha') # make the variable \alpha c_pol_ltx_x = web_latex_poly(p1, 'x') zeta = p1.base_ring().gens()[0] # p2 = zeta.minpoly() #this is not used anymore # b_pol_ltx = web_latex_poly(p2, latex(zeta)) #this is not used anymore z1 = zeta.multiplicative_order() info['coeff_field'] = [ WNF.coefficient_field.absolute_polynomial_latex('x'),c_pol_ltx_x, z1] if hasattr(WNF.coefficient_field, "lmfdb_url") and WNF.coefficient_field.lmfdb_url: info['coeff_field_pretty'] = [ WNF.coefficient_field.lmfdb_url, WNF.coefficient_field.lmfdb_pretty, WNF.coefficient_field.lmfdb_label] if z1==4: info['polynomial_st'] = '<div class="where">where</div> {0}\(\mathstrut=0\) and \(\zeta_4=i\).</div><br/>'.format(c_pol_ltx) elif z1<=2: info['polynomial_st'] = '<div class="where">where</div> {0}\(\mathstrut=0\).</div><br/>'.format(c_pol_ltx) else: info['polynomial_st'] = '<div class="where">where</div> %s\(\mathstrut=0\) and \(\zeta_{%s}=e^{\\frac{2\\pi i}{%s}}\).'%(c_pol_ltx, z1,z1) else: p1 = WNF.coefficient_field.relative_polynomial() c_pol_ltx = web_latex_poly(p1, '\\alpha') c_pol_ltx_x = web_latex_poly(p1, 'x') z1 = p1.base_ring().gens()[0].multiplicative_order() info['coeff_field'] = [ WNF.coefficient_field.absolute_polynomial_latex('x'), c_pol_ltx_x, z1] if hasattr(WNF.coefficient_field, "lmfdb_url") and WNF.coefficient_field.lmfdb_url: info['coeff_field_pretty'] = [ WNF.coefficient_field.lmfdb_url, WNF.coefficient_field.lmfdb_pretty, WNF.coefficient_field.lmfdb_label] if z1==4: info['polynomial_st'] = '<div class="where">where</div> {0}\(\mathstrut=0\) and \(\zeta_4=i\).'.format(c_pol_ltx) elif z1<=2: info['polynomial_st'] = '<div class="where">where</div> {0}\(\mathstrut=0\).</div><br/>'.format(c_pol_ltx) else: info['polynomial_st'] = '<div class="where">where</div> %s\(\mathstrut=0\) and \(\zeta_{%s}=e^{\\frac{2\\pi i}{%s}}\).'%(c_pol_ltx, z1,z1) else: info['polynomial_st'] = '' info['degree'] = int(cdeg) if cdeg==1: info['is_rational'] = 1 info['coeff_field_pretty'] = [ WNF.coefficient_field.lmfdb_url, WNF.coefficient_field.lmfdb_pretty ] else: info['is_rational'] = 0 # info['q_exp_embeddings'] = WNF.print_q_expansion_embeddings() # if(int(info['degree'])>1 and WNF.dimension()>1): # s = 'One can embed it into \( \mathbb{C} \) as:' # bprec = 26 # print s # info['embeddings'] = ajax_more2(WNF.print_q_expansion_embeddings,{'prec':[5,10,25,50],'bprec':[26,53,106]},text=['more coeffs.','higher precision']) # elif(int(info['degree'])>1): # s = 'There are '+str(info['degree'])+' embeddings into \( \mathbb{C} \):' # bprec = 26 # print s # info['embeddings'] = ajax_more2(WNF.print_q_expansion_embeddings,{'prec':[5,10,25,50],'bprec':[26,53,106]},text=['more coeffs.','higher precision']) # else: # info['embeddings'] = '' emf_logger.debug("PREC2: {0}".format(prec)) info['embeddings'] = WNF._embeddings['values'] #q_expansion_embeddings(prec, bprec,format='latex') info['embeddings_len'] = len(info['embeddings']) properties2 = [] if (ZZ(level)).is_squarefree(): info['twist_info'] = WNF.twist_info if isinstance(info['twist_info'], list) and len(info['twist_info'])>0: info['is_minimal'] = info['twist_info'][0] if(info['twist_info'][0]): s = 'Is minimal<br>' else: s = 'Is a twist of lower level<br>' properties2 = [('Twist info', s)] else: info['twist_info'] = 'Twist info currently not available.' properties2 = [('Twist info', 'not available')] args = list() for x in range(5, 200, 10): args.append({'digits': x}) alev = None CM = WNF._cm_values if CM is not None: if CM.has_key('tau') and len(CM['tau']) != 0: info['CM_values'] = CM info['is_cm'] = WNF.is_cm if WNF.is_cm: info['cm_field'] = "2.0.{0}.1".format(-WNF.cm_disc) info['cm_disc'] = WNF.cm_disc info['cm_field_knowl'] = nf_display_knowl(info['cm_field'], getDBConnection(), field_pretty(info['cm_field'])) info['cm_field_url'] = url_for("number_fields.by_label", label=info["cm_field"]) if WNF.is_cm is None: s = '- Unknown (insufficient data)<br>' elif WNF.is_cm: s = 'Is a CM-form<br>' else: s = 'Is not a CM-form<br>' properties2.append(('CM info', s)) alev = WNF.atkin_lehner_eigenvalues() info['atkinlehner'] = None if isinstance(alev,dict) and len(alev.keys())>0 and level != 1: s1 = " Atkin-Lehner eigenvalues " s2 = "" for Q in alev.keys(): s2 += "\( \omega_{ %s } \) : %s <br>" % (Q, alev[Q]) properties2.append((s1, s2)) emf_logger.debug("properties={0}".format(properties2)) # alev = WNF.atkin_lehner_eigenvalues_for_all_cusps() # if isinstance(alev,dict) and len(alev.keys())>0: # emf_logger.debug("alev={0}".format(alev)) # info['atkinlehner'] = list() # for Q in alev.keys(): # s = "\(" + latex(c) + "\)" # Q = alev[c][0] # ev = alev[c][1] # info['atkinlehner'].append([Q, c, ev]) if(level == 1): poly = WNF.explicit_formulas.get('as_polynomial_in_E4_and_E6','') if poly != '': d,monom,coeffs = poly emf_logger.critical("poly={0}".format(poly)) info['explicit_formulas'] = '\(' for i in range(len(coeffs)): c = QQ(coeffs[i]) s = "" if d>1 and i >0 and c>0: s="+" if c<0: s="-" if c.denominator()>1: cc = "\\frac{{ {0} }}{{ {1} }}".format(abs(c.numerator()),c.denominator()) else: cc = str(abs(c)) s += "{0} \cdot ".format(cc) a = monom[i][0]; b = monom[i][1] if a == 0 and b != 0: s+="E_6^{{ {0} }}".format(b) elif b ==0 and a != 0: s+="E_4^{{ {0} }}".format(a) else: s+="E_4^{{ {0} }}E_6^{{ {1} }}".format(a,b) info['explicit_formulas'] += s info['explicit_formulas'] += " \)" cur_url = '?&level=' + str(level) + '&weight=' + str(weight) + '&character=' + str(character) + \ '&label=' + str(label) if len(WNF.parent.hecke_orbits) > 1: for label_other in WNF.parent.hecke_orbits.keys(): if(label_other != label): s = 'Modular form ' if character: s = s + str(level) + '.' + str(weight) + '.' + str(character) + str(label_other) else: s = s + str(level) + '.' + str(weight) + str(label_other) url = url_for('emf.render_elliptic_modular_forms', level=level, weight=weight, character=character, label=label_other) friends.append((s, url)) s = 'L-Function ' if character: s = s + str(level) + '.' + str(weight) + '.' + str(character) + str(label) else: s = s + str(level) + '.' + str(weight) + str(label) # url = # "/L/ModularForm/GL2/Q/holomorphic?level=%s&weight=%s&character=%s&label=%s&number=%s" # %(level,weight,character,label,0) url = '/L' + url_for( 'emf.render_elliptic_modular_forms', level=level, weight=weight, character=character, label=label) if WNF.coefficient_field_degree > 1: for h in range(WNF.coefficient_field_degree): s0 = s + ".{0}".format(h) url0 = url + "{0}/".format(h) friends.append((s0, url0)) else: friends.append((s, url)) # if there is an elliptic curve over Q associated to self we also list that if WNF.weight == 2 and WNF.coefficient_field_degree == 1: llabel = str(level) + '.' + label s = 'Elliptic curve isogeny class ' + llabel url = '/EllipticCurve/Q/' + llabel friends.append((s, url)) info['properties2'] = properties2 info['friends'] = friends info['max_cn'] = WNF.max_cn() return info
def set_info_for_modular_form_space(level=None, weight=None, character=None, label=None, **kwds): r""" Set information about a space of modular forms. """ info = dict() emf_logger.debug("info={0}".format(info)) WMFS = None if info.has_key('error'): return info if level <= 0: info['error'] = "Got wrong level: %s " % level return info try: WMFS = WebModFormSpace_cached(level = level, weight = weight, cuspidal=True, character = character, update_from_db=True) if not WMFS.has_updated(): WMFS.update_from_db() ## Need to call an extra time for some reason... if not WMFS.has_updated(): stop = False orbit = WMFS.character.character.galois_orbit() while not stop: if len(orbit) == 0: stop = True continue c = orbit.pop() if c.number() == WMFS.character.number: continue print c.number() WMFS_rep = WebModFormSpace_cached(level = level, weight = weight, cuspidal=True, character = c.number(), update_from_db=True) if WMFS_rep.has_updated_from_db(): stop = True info['wmfs_rep_url'] = url_for('emf.render_elliptic_modular_forms', level=level, weight=weight, character = c.number()) info['wmfs_rep_number'] = c.number() emf_logger.debug("Created WebModFormSpace %s"%WMFS) if 'download' in info and 'tempfile' in info: save(WNF,info['tempfile']) info['filename'] = str(weight) + '-' + str(level) + '-' + str(character) + '-' + label + '.sobj' return info except ValueError as e: emf_logger.debug(e) emf_logger.debug(e.message) #if isinstance(e,IndexError): info['error'] = e.message WMFS = None if WMFS is None: info['error'] = "We are sorry. The sought space can not be found in the database. "+"<br> Detailed information: {0}".format(info.get('error','')) return info else: ### Somehow the Hecke orbits are sometimes not in the space... #if WMFS.dimension_new_cusp_forms()!=len(WMFS.hecke_orbits): # ## Try to add them here... # for d in range(len(WMFS.dimension_new_cusp_forms())): # F = # WMFS.hecke_orbits.append(F) info['space'] = WMFS info['max_height'] = default_max_height # info['old_decomposition'] = WMFS.oldspace_decomposition() info['oldspace_decomposition']='' try: emf_logger.debug("Oldspace = {0}".format(WMFS.oldspace_decomposition)) if WMFS.oldspace_decomposition != []: emf_logger.debug("oldspace={0}".format(WMFS.oldspace_decomposition)) l = [] for t in WMFS.oldspace_decomposition: emf_logger.debug("t={0}".format(t)) N,k,chi,mult,d = t url = url_for('emf.render_elliptic_modular_forms', level=N, weight=k, character=chi) if chi != 1: sname = "S^{{ new }}_{{ {k} }}(\\Gamma_0({N}),\\chi_{{ {N} }}({chi},\\cdot))".format(k=k,N=N,chi=chi) else: sname = "S^{{ new }}_{{ {k} }}(\\Gamma_0({N}))".format(k=k,N=N) l.append("\href{{ {url} }}{{ {sname} }}^{{\oplus {mult} }}".format(sname=sname,mult=mult,url=url)) if l != []: s = "\\oplus ".join(l) info['oldspace_decomposition']=' $ {0} $'.format(s) except Exception as e: emf_logger.critical("Oldspace decomposition failed. Error:{0}".format(e)) ## For side-bar lifts = list() lifts.append(('Half-Integral Weight Forms', '/ModularForm/Mp2/Q')) lifts.append(('Siegel Modular Forms', '/ModularForm/GSp4/Q')) info['lifts'] = lifts friends = list() for label in WMFS.hecke_orbits: f = WMFS.hecke_orbits[label] # catch the url being None or set to '': if hasattr(f.base_ring, "lmfdb_url") and f.base_ring.lmfdb_url: friends.append(('Number field ' + f.base_ring.lmfdb_pretty, f.base_ring.lmfdb_url)) if hasattr(f.coefficient_field, "lmfdb_url") and f.coefficient_field.lmfdb_url: friends.append(('Number field ' + f.coefficient_field.lmfdb_pretty, f.coefficient_field.lmfdb_url)) friends.append(("Dirichlet character \(" + WMFS.character.latex_name + "\)", WMFS.character.url())) friends = uniq(friends) info['friends'] = friends return info