def len_as_printed(s,format='latex'): r""" Returns the length of s, as it will appear after being math_jax'ed """ lenq=1 lendig=1 lenpm=1.5 lenpar=0.5 lenexp=0.75 lensub=0.75 ## remove all html first since it is not displayed ss = re.sub("<[^>]*>","",s) logger.debug("ss=%s" % ss) ss = re.sub(" ","",ss) # remove white-space ss = re.sub("\*","",ss) # remove * num_exp = s.count("^") # count number of exponents exps = re.findall("\^{?(\d*)",s) # a list of all exponents sexps = "".join(exps) num_subs = s.count("_") # count number of exponents subs = re.findall("_{?(\d*)",s) # a list of all subscripts ssubs = "".join(subs) ss = re.sub("\^{?(\d*)}?","",ss) # remove exponenents logger.debug(join([ss,ssubs,sexps])) tot_len=(ss.count(")")+ss.count("("))*lenpar tot_len+=ss.count("q")*lenq tot_len+=len(re.findall("\d",s))*lendig tot_len+=len(re.findall("\w",s))*lenq tot_len+=(s.count("+")+s.count("-"))*lenpm tot_len+=num_subs*lensub tot_len+=num_exp*lenexp # #tot_len = len(ss)+ceil((len(ssubs)+len(sexps))*0.67) return tot_len
def len_as_printed(s, format='latex'): r""" Returns the length of s, as it will appear after being math_jax'ed """ lenq = 1 lendig = 1 lenpm = 1.5 lenpar = 0.5 lenexp = 0.75 lensub = 0.75 ## remove all html first since it is not displayed ss = re.sub("<[^>]*>", "", s) logger.debug("ss=%s" % ss) ss = re.sub(" ", "", ss) # remove white-space ss = re.sub("\*", "", ss) # remove * num_exp = s.count("^") # count number of exponents exps = re.findall("\^{?(\d*)", s) # a list of all exponents sexps = "".join(exps) num_subs = s.count("_") # count number of exponents subs = re.findall("_{?(\d*)", s) # a list of all subscripts ssubs = "".join(subs) ss = re.sub("\^{?(\d*)}?", "", ss) # remove exponenents logger.debug(join([ss, ssubs, sexps])) tot_len = (ss.count(")") + ss.count("(")) * lenpar tot_len += ss.count("q") * lenq tot_len += len(re.findall("\d", s)) * lendig tot_len += len(re.findall("\w", s)) * lenq tot_len += (s.count("+") + s.count("-")) * lenpm tot_len += num_subs * lensub tot_len += num_exp * lenexp # #tot_len = len(ss)+ceil((len(ssubs)+len(sexps))*0.67) return tot_len
def render_elliptic_modular_form_space(info): r""" Render the webpage for a elliptic modular forms space. """ level = my_get(info, 'level', -1, int) weight = my_get(info, 'weight', -1, int) character = my_get(info, 'character', '', str) # int(info.get('weight',0)) label = my_get(info, 'label', 'a', str) if character == '': character = 0 properties = list() parents = list() friends = list() lifts = list() siblings = list() sbar = (properties, parents, friends, siblings, lifts) if character == 0: dimtbl = DimensionTable() else: dimtbl = DimensionTable(1) emf_logger.debug("Created dimension table in render_elliptic_modular_form_space") if 'character' in info and info['character'] == '*': return render_elliptic_modular_form_space_list_chars(level, weight) if not dimtbl.is_in_db(level, weight, character): emf_logger.debug("Data not available") return render_template("not_available.html") info = set_info_for_modular_form_space(info) emf_logger.debug("keys={0}".format(info.keys())) if 'download' in info and 'error' not in info: return send_file(info['tempfile'], as_attachment=True, attachment_filename=info['filename']) if 'dimension_newspace' in info and info['dimension_newspace'] == 1: # if there is only one orbit we list it emf_logger.debug("Dimension of newforms is one!") info = dict() info['level'] = level info['weight'] = weight info['label'] = 'a' info['character'] = character return redirect(url_for('emf.render_elliptic_modular_forms', **info)) info['title'] = "Holomorphic Cusp Forms of weight %s on \(\Gamma_{0}(%s)\)" % (weight, level) bread = [(MF_TOP, url_for('mf.modular_form_main_page'))] bread.append((EMF_TOP, url_for('emf.render_elliptic_modular_forms'))) bread.append(("Level %s" % level, url_for('emf.render_elliptic_modular_forms', level=level))) bread.append( ("Weight %s" % weight, url_for('emf.render_elliptic_modular_forms', level=level, weight=weight))) emf_logger.debug("friends={0}".format(friends)) info['bread'] = bread if info['dimension_newspace'] == 0: return render_template("emf_space.html", **info) else: return render_template("emf_space.html", **info)
def ajax_once(callback,*arglist,**kwds): r""" """ text = kwds.get('text', 'more') emf_logger.debug("text={0}".format(text)) emf_logger.debug("arglist={0}".format(arglist)) emf_logger.debug("kwds={0}".format(kwds)) #emf_logger.debug("req={0}".format(request.args nonce = hex(random.randint(0, 1<<128)) res = callback() url = ajax_url(ajax_once,arglist,kwds,inline=True) s0 = """<span id='%(nonce)s'>%(res)s """ % locals() # s1 = """[<a onclick="$('#%(nonce)s').load('%(url)s', {'level':22,'weight':4},function() { MathJax.Hub.Queue(['Typeset',MathJax.Hub,'%(nonce)s']);}); return false;" href="#">%(text)s</a>""" % locals() s1 = """[<a onclick="$('#%(nonce)s').load('%(url)s', {a:1},function() { MathJax.Hub.Queue(['Typeset',MathJax.Hub,'%(nonce)s']);}); return false;" href="#">%(text)s</a>""" % locals() return s0+s1
def set_table_browsing(self,skip=[0,0],limit=[(2,16),(1,50)],keys=['Weight','Level'],character=0,dimension_fun=dimension_new_cusp_forms,title='Dimension of newforms'): r""" Table of Holomorphic modular forms spaces. Skip tells you how many chunks of data you want to skip (from the geginning) and limit tells you how large each chunk is. INPUT: - dimension_fun should be a function which gives you the desired dimensions, as functions of level N and weight k - character = 0 for trivial character and 1 for Kronecker symbol. set to 'all' for all characters. """ self._keys=keys self._skip=skip self._limit=limit self._metadata=[] self._title='' self._cols=[] self.table={} self._character = character emf_logger.debug("skip= {0}".format(self._skip)) emf_logger.debug("limit= {0}".format(self._limit)) il = self._keys.index('Level') iwt = self._keys.index('Weight') level_len = self._limit[il][1]-self._limit[il][0]+1 level_ll=self._skip[il]*level_len+self._limit[il][0]; level_ul=self._skip[il]*level_len+self._limit[il][1] wt_len = self._limit[iwt][1]-self._limit[iwt][0]+1 wt_ll=self._skip[iwt]*wt_len+self._limit[iwt][0]; wt_ul=self._skip[iwt]*wt_len+self._limit[iwt][1] if level_ll<1: level_l=1 self._table={} self._table['rows']=[] self._table['col_heads']=[] #range(wt_ll,wt_ul+1) self._table['row_heads']=[] #range(level_ll,level_ul+1) emf_logger.debug("wt_range: {0} -- {1}".format(wt_ll,wt_ul)) emf_logger.debug("level_range: {0} -- {1}".format(level_ll,level_ul)) if character in [0,1]: if level_ll == level_ul: N=level_ll self._table['rowhead']='Weight' if character==0: self._table['row_heads']=['Trivial character'] else: self._table['row_heads']=['\( \\( \frac{\cdot}{N} \\)\)'] row=[] for k in range(wt_ll,wt_ul+1): if character == 0 and is_odd(k): continue try: if character==0: d = dimension_fun(N,k) elif character==1: x = kronecker_character_upside_down(N) d = dimension_fun(x,k) except Exception as ex: emf_logger.critical("Exception: {0}. \n Could not compute the dimension with function {0}".format(ex,dimension_fun)) url = url_for('emf.render_elliptic_modular_form_browsing',level=N,weight=k) if not k in self._table['col_heads']: self._table['col_heads'].append(k) row.append({'N':N,'k':k,'url':url,'dim':d}) self._table['rows'].append(row) else: for N in range(level_ll,level_ul+1): if not N in self._table['row_heads']: self._table['row_heads'].append(N) row=[] for k in range(wt_ll,wt_ul+1): if character == 0 and is_odd(k): continue try: if character==0: d = dimension_fun(N,k) elif character==1: x = kronecker_character_upside_down(N) d = dimension_fun(x,k) except Exception as ex: emf_logger.critical("Exception: {0}. \n Could not compute the dimension with function {0}".format(ex,dimension_fun)) url = url_for('emf.render_elliptic_modular_form_browsing',level=N,weight=k) if not k in self._table['col_heads']: self._table['col_heads'].append(k) row.append({'N':N,'k':k,'url':url,'dim':d}) self._table['rows'].append(row) elif character=='all': # make table with all characters. self._table['characters']=dict() if level_ll == level_ul: N = level_ll D = DirichletGroup(N) emf_logger.debug("I am here!") self._table['rowhead']='Character \ Weight' for x in D: xi = D.list().index(x) row=[] self._table['row_heads'].append(xi) for k in range(wt_ll,wt_ul+1): if not k in self._table['col_heads']: self._table['col_heads'].append(k) try: d = dimension_fun(x,k) except Exception as ex: emf_logger.critical("Exception: {0} \n Could not compute the dimension with function {0}".format(ex,dimension_fun)) d = -1 url = url_for('emf.render_elliptic_modular_form_space',level=N,weight=k,character=xi) row.append({'N':N,'k':k,'chi':xi,'url':url,'dim':d}) self._table['rows'].append(row) else: for N in range(level_ll,level_ul+1): self._table['row_heads'].append(N) self._table['characters'][N]=list() row=[] if N==0: continue D = DirichletGroup(N) for k in range(wt_ll,wt_ul+1): tbl=[] for x in D: xi = D.list().index(x) if not N in self._table['characters'][N]: self._table['characters'][N].append(xi) if x.is_even() and is_odd(k): continue if x.is_odd() and is_even(k): continue try: d = dimension_fun(x,k) except Exception as ex: emf_logger.critical("Exception: {0} \n Could not compute the dimension with function {0}".format(ex,dimension_fun)) url = url_for('emf.render_elliptic_modular_form_browsing',level=N,weight=k) if not k in self._table['col_heads']: self._table['col_heads'].append(k) tbl.append({'N':N,'k':k,'chi':xi,'url':url,'dim':d}) row.append(tbl) self._table['rows'].append(row)
def find_inverse_images_of_twists(k, N=1, chi=0, fi=0, prec=10, verbose=0): r""" Checks if f is minimal and if not, returns the associated minimal form to precision prec. INPUT: - ''k'' -- positive integer : the weight - ''N'' -- positive integer (default 1) : level - ''chi'' -- non-neg. integer (default 0) use character nr. chi - ''fi'' -- non-neg. integer (default 0) We want to use the element nr. fi f=Newforms(N,k)[fi] - ''prec'' -- integer (the number of coefficients to get) - ''verbose'' -- integer OUTPUT: -''[t,l]'' -- tuple of a Bool t and a list l. The list l contains all tuples of forms which twists to the given form. The actual minimal one is the first element of this list. EXAMPLES:: """ (t, f) = _get_newform(k, N, chi, fi) if (not t): return f if (is_squarefree(ZZ(N))): return [True, f] # We need to check all square factors of N logger.info("investigating: %s" % f) N_sqfree = squarefree_part(ZZ(N)) Nsq = ZZ(N / N_sqfree) twist_candidates = list() KF = f.base_ring() # check how many Hecke eigenvalues we need to check max_nump = number_of_hecke_to_check(f) maxp = max(primes_first_n(max_nump)) for d in divisors(N): # we look at all d such that d^2 divdes N if (not ZZ(d**2).divides(ZZ(N))): continue D = DirichletGroup(d) # check possible candidates to twist into f # g in S_k(M,chi) wit M=N/d^2 M = ZZ(N / d**2) logger.info("Checking level %s" % M) for xig in range(euler_phi(M)): (t, glist) = _get_newform(k, M, xig) if (not t): return glist for g in glist: logger.debug("Comparing to function %s" % g) KG = g.base_ring() # we now see if twisting of g by xi in D gives us f for xi in D: try: for p in primes_first_n(max_nump): if (ZZ(p).divides(ZZ(N))): continue bf = f.q_expansion(maxp + 1)[p] bg = g.q_expansion(maxp + 1)[p] if (bf == 0 and bg == 0): continue elif (bf == 0 and bg <> 0 or bg == 0 and bf <> 0): raise StopIteration() if (ZZ(p).divides(xi.conductor())): raise ArithmeticError, "" xip = xi(p) # make a preliminary check that the base rings match with respect to being real or not try: QQ(xip) XF = QQ if (KF <> QQ or KG <> QQ): raise StopIteration except TypeError: # we have a non-rational (i.e. complex) value of the character XF = xip.parent() if ((KF == QQ or KF.is_totally_real()) and (KG == QQ or KG.is_totally_real())): raise StopIteration ## it is diffcult to compare elements from diferent rings in general but we make some checcks ## is it possible to see if there is a larger ring which everything can be coerced into? ok = False try: a = KF(bg / xip) b = KF(bf) ok = True if (a <> b): raise StopIteration() except TypeError: pass try: a = KG(bg) b = KG(xip * bf) ok = True if (a <> b): raise StopIteration() except TypeError: pass if ( not ok ): # we could coerce and the coefficients were equal return "Could not compare against possible candidates!" # otherwise if we are here we are ok and found a candidate twist_candidates.append([dd, g.q_expansion(prec), xi]) except StopIteration: # they are not equal pass #logger.debug("Candidates=%s" % twist_candidates) if (len(twist_candidates) == 0): return (True, None) else: return (False, twist_candidates)
def get_values_at_CM_points(k, N=1, chi=0, fi=0, digits=12, verbose=0): r""" Computes and returns a list of values of f at a collection of CM points as complex floating point numbers. INPUT: - ''k'' -- positive integer : the weight - ''N'' -- positive integer (default 1) : level - ''chi'' -- non-neg. integer (default 0) use character nr. chi - ''fi'' -- non-neg. integer (default 0) We want to use the element nr. fi f=Newforms(N,k)[fi] -''digits'' -- we want this number of corrrect digits in the value OUTPUT: -''s'' string representation of a dictionary {I:f(I):rho:f(rho)}. TODO: Get explicit, algebraic values if possible! """ (t, f) = _get_newform(k, N, chi, fi) if (not t): return f bits = max(53, ceil(digits * 4)) CF = ComplexField(bits) RF = ComplexField(bits) eps = RF(10**-(digits + 1)) logger.debug("eps=" % eps) K = f.base_ring() cm_vals = dict() # the points we want are i and rho. More can be added later... rho = CyclotomicField(3).gen() zi = CyclotomicField(4).gen() points = [rho, zi] maxprec = 1000 # max size of q-expansion minprec = 10 # max size of q-expansion for tau in points: q = CF(exp(2 * pi * I * tau)) fexp = dict() if (K == QQ): v1 = CF(0) v2 = CF(1) try: for prec in range(minprec, maxprec, 10): logger.debug("prec=%s" % prec) v2 = f.q_expansion(prec)(q) err = abs(v2 - v1) logger.debug("err=%s" % err) if (err < eps): raise StopIteration() v1 = v2 cm_vals[tau] = "" except StopIteration: cm_vals[tau] = str(fq) else: v1 = dict() v2 = dict() err = dict() cm_vals[tau] = dict() for h in range(K.degree()): v1[h] = 1 v2[h] = 0 try: for prec in range(minprec, maxprec, 10): logger.debug("prec=%s" % prec) for h in range(K.degree()): fexp[h] = list() v2[h] = 0 for n in range(prec): c = f.coefficients(ZZ(prec))[n] cc = c.complex_embeddings(CF.prec())[h] v2[h] = v2[h] + cc * q**n err[h] = abs(v2[h] - v1[h]) logger.debug("v1[%s]=%s" % (h, v1[h])) logger.debug("v2[%s]=%s" % (h, v2[h])) logger.debug("err[%s]=%s" % (h, err[h])) if (max(err.values()) < eps): raise StopIteration() v1[h] = v2[h] except StopIteration: pass for h in range(K.degree()): if (err[h] < eps): cm_vals[tau][h] = v2[h] else: cm_vals[tau][h] = "" logger.debug("vals=%s" % cm_vals) logger.debug("errs=%s" % err) tbl = dict() tbl['corner_label'] = ['$\tau$'] tbl['headersh'] = ['$\\rho=\zeta_{3}$', '$i$'] if (K == QQ): tbl['headersv'] = ['$f(\\tau)$'] tbl['data'] = [cm_vals] else: tbl['data'] = list() tbl['headersv'] = list() for h in range(K.degree()): tbl['headersv'].append("$\sigma_{%s}(f(\\tau))$" % h) row = list() for tau in points: row.append(cm_vals[tau][h]) tbl['data'].append(row) s = html_table(tbl) #s=html.table([cm_vals.keys(),cm_vals.values()]) return s
def find_inverse_images_of_twists(k,N=1,chi=0,fi=0,prec=10,verbose=0): r""" Checks if f is minimal and if not, returns the associated minimal form to precision prec. INPUT: - ''k'' -- positive integer : the weight - ''N'' -- positive integer (default 1) : level - ''chi'' -- non-neg. integer (default 0) use character nr. chi - ''fi'' -- non-neg. integer (default 0) We want to use the element nr. fi f=Newforms(N,k)[fi] - ''prec'' -- integer (the number of coefficients to get) - ''verbose'' -- integer OUTPUT: -''[t,l]'' -- tuple of a Bool t and a list l. The list l contains all tuples of forms which twists to the given form. The actual minimal one is the first element of this list. EXAMPLES:: """ (t,f) = _get_newform(k,N,chi,fi) if(not t): return f if(is_squarefree(ZZ(N))): return [True,f] # We need to check all square factors of N logger.info("investigating: %s" % f) N_sqfree=squarefree_part(ZZ(N)) Nsq=ZZ(N/N_sqfree) twist_candidates=list() KF=f.base_ring() # check how many Hecke eigenvalues we need to check max_nump=number_of_hecke_to_check(f) maxp=max(primes_first_n(max_nump)) for d in divisors(N): # we look at all d such that d^2 divdes N if(not ZZ(d**2).divides(ZZ(N))): continue D=DirichletGroup(d) # check possible candidates to twist into f # g in S_k(M,chi) wit M=N/d^2 M=ZZ(N/d**2) logger.info("Checking level %s"%M) for xig in range(euler_phi(M)): (t,glist) = _get_newform(k,M,xig) if(not t): return glist for g in glist: logger.debug("Comparing to function %s" %g) KG=g.base_ring() # we now see if twisting of g by xi in D gives us f for xi in D: try: for p in primes_first_n(max_nump): if(ZZ(p).divides(ZZ(N))): continue bf=f.q_expansion(maxp+1)[p] bg=g.q_expansion(maxp+1)[p] if(bf == 0 and bg == 0): continue elif(bf==0 and bg<>0 or bg==0 and bf<>0): raise StopIteration() if(ZZ(p).divides(xi.conductor())): raise ArithmeticError,"" xip=xi(p) # make a preliminary check that the base rings match with respect to being real or not try: QQ(xip) XF=QQ if( KF<>QQ or KG<>QQ): raise StopIteration except TypeError: # we have a non-rational (i.e. complex) value of the character XF=xip.parent() if( (KF == QQ or KF.is_totally_real()) and (KG == QQ or KG.is_totally_real())): raise StopIteration ## it is diffcult to compare elements from diferent rings in general but we make some checcks ## is it possible to see if there is a larger ring which everything can be coerced into? ok=False try: a=KF(bg/xip); b=KF(bf) ok=True if(a<>b): raise StopIteration() except TypeError: pass try: a=KG(bg); b=KG(xip*bf) ok=True if(a<>b): raise StopIteration() except TypeError: pass if(not ok): # we could coerce and the coefficients were equal return "Could not compare against possible candidates!" # otherwise if we are here we are ok and found a candidate twist_candidates.append([dd,g.q_expansion(prec),xi]) except StopIteration: # they are not equal pass #logger.debug("Candidates=%s" % twist_candidates) if(len(twist_candidates)==0): return (True,None) else: return (False,twist_candidates)
def get_values_at_CM_points(k,N=1,chi=0,fi=0,digits=12,verbose=0): r""" Computes and returns a list of values of f at a collection of CM points as complex floating point numbers. INPUT: - ''k'' -- positive integer : the weight - ''N'' -- positive integer (default 1) : level - ''chi'' -- non-neg. integer (default 0) use character nr. chi - ''fi'' -- non-neg. integer (default 0) We want to use the element nr. fi f=Newforms(N,k)[fi] -''digits'' -- we want this number of corrrect digits in the value OUTPUT: -''s'' string representation of a dictionary {I:f(I):rho:f(rho)}. TODO: Get explicit, algebraic values if possible! """ (t,f) = _get_newform(k,N,chi,fi) if(not t): return f bits=max(53,ceil(digits*4)) CF=ComplexField(bits) RF=ComplexField(bits) eps=RF(10**-(digits+1)) logger.debug("eps=" % eps) K=f.base_ring() cm_vals=dict() # the points we want are i and rho. More can be added later... rho=CyclotomicField(3).gen() zi=CyclotomicField(4).gen() points=[rho,zi] maxprec=1000 # max size of q-expansion minprec=10 # max size of q-expansion for tau in points: q=CF(exp(2*pi*I*tau)) fexp=dict() if(K==QQ): v1=CF(0); v2=CF(1) try: for prec in range(minprec,maxprec,10): logger.debug("prec=%s" % prec) v2=f.q_expansion(prec)(q) err=abs(v2-v1) logger.debug("err=%s"%err) if(err< eps): raise StopIteration() v1=v2 cm_vals[tau]="" except StopIteration: cm_vals[tau]=str(fq) else: v1=dict() v2=dict() err=dict() cm_vals[tau]=dict() for h in range(K.degree()): v1[h]=1 v2[h]=0 try: for prec in range(minprec,maxprec,10): logger.debug("prec=%s"%prec) for h in range(K.degree()): fexp[h]=list() v2[h]=0 for n in range(prec): c=f.coefficients(ZZ(prec))[n] cc=c.complex_embeddings(CF.prec())[h] v2[h]=v2[h]+cc*q**n err[h]=abs(v2[h]-v1[h]) logger.debug("v1[%s]=%s"% (h,v1[h])) logger.debug("v2[%s]=%s"% (h,v2[h])) logger.debug("err[%s]=%s"% (h,err[h])) if(max(err.values()) < eps): raise StopIteration() v1[h]=v2[h] except StopIteration: pass for h in range(K.degree()): if(err[h] < eps): cm_vals[tau][h]=v2[h] else: cm_vals[tau][h]="" logger.debug("vals=%s"%cm_vals) logger.debug("errs=%s"%err) tbl=dict() tbl['corner_label']=['$\tau$'] tbl['headersh']=['$\\rho=\zeta_{3}$','$i$'] if(K==QQ): tbl['headersv']=['$f(\\tau)$'] tbl['data']=[cm_vals] else: tbl['data']=list() tbl['headersv']=list() for h in range(K.degree()): tbl['headersv'].append("$\sigma_{%s}(f(\\tau))$" % h) row=list() for tau in points: row.append(cm_vals[tau][h]) tbl['data'].append(row) s=html_table(tbl) #s=html.table([cm_vals.keys(),cm_vals.values()]) return s
def set_table_browsing(self, skip=[0, 0], limit=[(2, 16), (1, 50)], keys=['Weight', 'Level'], character=0, dimension_fun=dimension_new_cusp_forms, title='Dimension of newforms'): r""" Table of Holomorphic modular forms spaces. Skip tells you how many chunks of data you want to skip (from the geginning) and limit tells you how large each chunk is. INPUT: - dimension_fun should be a function which gives you the desired dimensions, as functions of level N and weight k - character = 0 for trivial character and 1 for Kronecker symbol. set to 'all' for all characters. """ self._keys = keys self._skip = skip self._limit = limit self._metadata = [] self._title = '' self._cols = [] self.table = {} self._character = character emf_logger.debug("skip= {0}".format(self._skip)) emf_logger.debug("limit= {0}".format(self._limit)) il = self._keys.index('Level') iwt = self._keys.index('Weight') level_len = self._limit[il][1] - self._limit[il][0] + 1 level_ll = self._skip[il] * level_len + self._limit[il][0] level_ul = self._skip[il] * level_len + self._limit[il][1] wt_len = self._limit[iwt][1] - self._limit[iwt][0] + 1 wt_ll = self._skip[iwt] * wt_len + self._limit[iwt][0] wt_ul = self._skip[iwt] * wt_len + self._limit[iwt][1] if level_ll < 1: level_l = 1 self._table = {} self._table['rows'] = [] self._table['col_heads'] = [] #range(wt_ll,wt_ul+1) self._table['row_heads'] = [] #range(level_ll,level_ul+1) emf_logger.debug("wt_range: {0} -- {1}".format(wt_ll, wt_ul)) emf_logger.debug("level_range: {0} -- {1}".format(level_ll, level_ul)) if character in [0, 1]: if level_ll == level_ul: N = level_ll self._table['rowhead'] = 'Weight' if character == 0: self._table['row_heads'] = ['Trivial character'] else: self._table['row_heads'] = ['\( \\( \frac{\cdot}{N} \\)\)'] row = [] for k in range(wt_ll, wt_ul + 1): if character == 0 and is_odd(k): continue try: if character == 0: d = dimension_fun(N, k) elif character == 1: x = kronecker_character_upside_down(N) d = dimension_fun(x, k) except Exception as ex: emf_logger.critical( "Exception: {0}. \n Could not compute the dimension with function {0}" .format(ex, dimension_fun)) url = url_for('emf.render_elliptic_modular_form_browsing', level=N, weight=k) if not k in self._table['col_heads']: self._table['col_heads'].append(k) row.append({'N': N, 'k': k, 'url': url, 'dim': d}) self._table['rows'].append(row) else: for N in range(level_ll, level_ul + 1): if not N in self._table['row_heads']: self._table['row_heads'].append(N) row = [] for k in range(wt_ll, wt_ul + 1): if character == 0 and is_odd(k): continue try: if character == 0: d = dimension_fun(N, k) elif character == 1: x = kronecker_character_upside_down(N) d = dimension_fun(x, k) except Exception as ex: emf_logger.critical( "Exception: {0}. \n Could not compute the dimension with function {0}" .format(ex, dimension_fun)) url = url_for( 'emf.render_elliptic_modular_form_browsing', level=N, weight=k) if not k in self._table['col_heads']: self._table['col_heads'].append(k) row.append({'N': N, 'k': k, 'url': url, 'dim': d}) self._table['rows'].append(row) elif character == 'all': # make table with all characters. self._table['characters'] = dict() if level_ll == level_ul: N = level_ll D = DirichletGroup(N) emf_logger.debug("I am here!") self._table['rowhead'] = 'Character \ Weight' for x in D: xi = D.list().index(x) row = [] self._table['row_heads'].append(xi) for k in range(wt_ll, wt_ul + 1): if not k in self._table['col_heads']: self._table['col_heads'].append(k) try: d = dimension_fun(x, k) except Exception as ex: emf_logger.critical( "Exception: {0} \n Could not compute the dimension with function {0}" .format(ex, dimension_fun)) d = -1 url = url_for('emf.render_elliptic_modular_form_space', level=N, weight=k, character=xi) row.append({ 'N': N, 'k': k, 'chi': xi, 'url': url, 'dim': d }) self._table['rows'].append(row) else: for N in range(level_ll, level_ul + 1): self._table['row_heads'].append(N) self._table['characters'][N] = list() row = [] if N == 0: continue D = DirichletGroup(N) for k in range(wt_ll, wt_ul + 1): tbl = [] for x in D: xi = D.list().index(x) if not N in self._table['characters'][N]: self._table['characters'][N].append(xi) if x.is_even() and is_odd(k): continue if x.is_odd() and is_even(k): continue try: d = dimension_fun(x, k) except Exception as ex: emf_logger.critical( "Exception: {0} \n Could not compute the dimension with function {0}" .format(ex, dimension_fun)) url = url_for( 'emf.render_elliptic_modular_form_browsing', level=N, weight=k) if not k in self._table['col_heads']: self._table['col_heads'].append(k) tbl.append({ 'N': N, 'k': k, 'chi': xi, 'url': url, 'dim': d }) row.append(tbl) self._table['rows'].append(row)
def ajax_more2(callback, *arg_list, **kwds): r""" Like ajax_more but accepts increase in two directions. Call with ajax_more2(function,{'arg1':[x1,x2,...,],'arg2':[y1,y2,...]},'text1','text2') where function takes two named argument 'arg1' and 'arg2' """ inline = kwds.get('inline', True) text = kwds.get('text', 'more') emf_logger.debug("inline={0}".format(inline)) emf_logger.debug("text={0}".format(text)) text0 = text[0] text1 = text[1] emf_logger.debug("arglist={0}".format(arg_list)) nonce = hex(random.randint(0, 1<<128)) if inline: args = arg_list[0] emf_logger.debug("args={0}".format(args)) key1,key2=args.keys() l1=args[key1] l2=args[key2] emf_logger.debug("key1={0}".format(key1)) emf_logger.debug("key2={0}".format(key2)) emf_logger.debug("l1={0}".format(l1)) emf_logger.debug("l2={0}".format(l2)) args={key1:l1[0],key2:l2[0]} l11=l1[1:]; l21=l2[1:] #arg_list = arg_list[1:] arg_list1 = {key1:l1,key2:l21} arg_list2 = {key1:l11,key2:l2} #emf_logger.debug("arglist1={0}".format(arg_list)) if isinstance(args, tuple): res = callback(*arg_list) elif isinstance(args, dict): res = callback(**args) else: res = callback(args) res = web_latex(res) else: res = '' emf_logger.debug("arg_list1={0}".format(arg_list1)) emf_logger.debug("arg_list2={0}".format(arg_list2)) arg_list1=(arg_list1,) arg_list2=(arg_list2,) if arg_list1 or arg_list2: url1 = ajax_url(ajax_more2, callback, *arg_list1, inline=True, text=text) url2 = ajax_url(ajax_more2, callback, *arg_list2, inline=True, text=text) emf_logger.debug("arg_list1={0}".format(url1)) emf_logger.debug("arg_list2={0}".format(url2)) s0 = """<span id='%(nonce)s'>%(res)s """ % locals() s1 = """[<a onclick="$('#%(nonce)s').load('%(url1)s', function() { MathJax.Hub.Queue(['Typeset',MathJax.Hub,'%(nonce)s']);}); return false;" href="#">%(text0)s</a>""" % locals() t = """| <a onclick="$('#%(nonce)s').load('%(url2)s', function() { MathJax.Hub.Queue(['Typeset',MathJax.Hub,'%(nonce)s']);}); return false;" href="#">%(text1)s</a>]</span>""" % locals() return (s0+s1+t) else: return res
def ajax_later(callback,*arglist,**kwds): r""" Try to make a function that gets called after displaying the page. """ text = kwds.get('text', 'more') text = 'more' emf_logger.debug("text={0}".format(text)) emf_logger.debug("arglist={0}".format(arglist)) emf_logger.debug("kwds={0}".format(kwds)) emf_logger.debug("callback={0}".format(callback)) #emf_logger.debug("req={0}".format(request.args nonce = hex(random.randint(0, 1<<128)) # do not call the first time around if kwds.has_key("do_now"): if kwds['do_now']==1: do_now=0 else: do_now=1 else: do_now=0 if not do_now: url = ajax_url(ajax_later,callback,*arglist,inline=True,do_now=do_now,_ajax_sticky=True) emf_logger.debug("ajax_url={0}".format(url)) s0 = """<span id='%(nonce)s'></span>""" % locals() s1 = """<a class='later' href=# id='%(nonce)s' onclick='this_fun()'>%(text)s</a>""" % locals() s2= """<script> function this_fun(){ $.getJSON('%(url)s',{do_now:1}, function(data) { $(\"span#%(nonce)s\").text(data.result); }); return true; }; </script> """ % locals() emf_logger.debug("s0+s1={0}".format(s2+s0)) return s2+s0+s1 else: res = callback(do_now=do_now) return jsonify(result=res)