def generate_dimension_table_gamma1(maxN=100, maxk=12, minN=3, mink=2): C = pymongo.connection.Connection(port=int(37010)) ms = C['modularforms']['Modular_symbols.files'] print ms data = dict() for N in range(minN, maxN + 1): data[N] = dict() for k in range(mink, maxk + 1): data[N][k] = dict() if N > 2: D = DirichletGroup(N) G = D.galois_orbits(reps_only=True) dimall = 0 in_db_all = True for xi, x in enumerate(G): dim = dimension_new_cusp_forms(x, k) dimall += dim finds = ms.find({'t': [int(N), int(k), int(xi)]}) in_db = finds.count() > 0 if not in_db: in_db_all = False data[N][k][xi] = {'dimension': dim, 'in_db': in_db} else: in_db_all = True # we only have the trivial character finds = ms.find({'t': [int(N), int(k), int(0)]}) in_db = finds.count() > 0 if not in_db: in_db_all = False dimall = dimension_new_cusp_forms(N, k) data[N][k][0] = {'dimension': dimall, 'in_db': in_db} # print N,k,data[N][k] data[N][k][-1] = {'dimension': dimall, 'in_db': in_db_all} print "Computed data for level ", N return ms, data
def find_known(self): """ Return iterator of 5-tuples of Python ints, defined as follows: (N, k, i, newforms, maxp) (37, 2, 0, 2, 10000) Here N = level, k = weight, i = character, newforms = number of newforms, maxp = integer such that a_p is known for p<=maxp. If no newforms are known but there are newforms (they just haven't been computed), then newforms is set to -1. """ for Nki in os.listdir(self._data): z = Nki.split('-') if len(z) == 3: N, k, i = parse_Nki(z) newforms = [x for x in os.listdir(os.path.join(self._data, Nki)) if x.isdigit()] if len(newforms) == 0: # maybe nothing computed? if i == 0: # program around a bug in dimension_new_cusp_forms: Trac 12640 d = dimension_new_cusp_forms(N) else: chi = character(N, i) d = dimension_new_cusp_forms(chi, k) if d == 0: # definitely no newforms yield (N,k,i,0,0) else: # we just don't know the newforms yet yield (N,k,i,-1,0) else: maxp = None for n in newforms: v = set([]) this_maxp = 0 for X in os.listdir(os.path.join(self._data, Nki, n)): if X.startswith('aplist') and 'meta' not in X: args = [int(a) for a in X.rstrip('.sobj').split('-')[1:]] v.update(prime_range(*args)) this_maxp = max(this_maxp, max(args)) if len(v) != len(prime_range(this_maxp)): # something missing! print "data ranges are missing in the aplist data for %s"%Nki maxp = 100 else: maxp = this_maxp if maxp is None else min(this_maxp, maxp) yield (N,k,i,len(newforms),maxp)
def dim_and_orbit(n,k,number): G = DirichletGroup_conrey(n) char = G[number] go = char.galois_orbit() indexes = [elt.number() for elt in go] dim = sum([dimension_new_cusp_forms(char.sage_character(),k) for elt in go]) return dim, indexes
def return_dimension(level=None, weight=None, chi=None, **kwds): if request.method == 'GET': info = to_dict(request.args) else: info = to_dict(request.form) level = my_get(info, 'level', level, int) weight = my_get(info, 'weight', weight, int) chi = my_get(info, 'chi', chi, int) if level is None or weight is None: return emf_error("Please supply level weight (and optional character)!"), 500 ttype = my_get(kwds, 'ttype', info.get('ttype', 'new'), str) emf_logger.debug("level,weight,chi: {0},{1},{2}, type={3}".format(level, weight, chi, ttype)) if chi == 0 or chi is None: x = level else: x = DirichletGroup(level).list()[chi] if ttype == 'new': return str(dimension_new_cusp_forms(x, weight)) if ttype == 'cusp': return str(dimension_cusp_forms(x, weight)) if ttype == 'modular': return str(dimension_modular_forms(x, weight)) if ttype == 'eisenstein': return str(dimension_eis(x, weight)) s = "Please use one of the available table types: 'new', 'cusp','modular', 'eisenstein' Got:{0}".format( ttype) return emf_error(s), 500
def compare_formulas_2a(D, k): d1 = dimension_new_cusp_forms(kronecker_character(D), k) if D < 0: D = -D d2 = RR(1 / pi * sqrt(D) * sum([ log(d) * sigma(old_div(D, d), 0) for d in divisors(D) if Zmod(d) (old_div(D, d)).is_square() and is_fundamental_discriminant(-d) ])) return d1 - d2
def check_Sk_dim_formula(self, rec, verbose=False): """ check that dim = dim S_k^new(Gamma1(N)) """ # TIME about 60s return self._test_equality( rec['dim'], dimension_new_cusp_forms(Gamma1(rec['level']), rec['weight']), verbose)
def check_Skchi_dim_formula(self, rec, verbose=False): """ for k > 1 check that dim is the Q-dimension of S_k^new(N,chi) (using sage dimension formula) """ # sample: dimension_new_cusp_forms(DirichletGroup(100).1^2,4) # Work around a bug in sage for Dirichlet characters in level 1 and 2 if rec['level'] < 3: dirchar = rec['level'] else: dirchar = DirichletGroup_conrey(rec['level'])[rec['conrey_indexes'][0]].sage_character() return self._test_equality(rec['relative_dim'], dimension_new_cusp_forms(dirchar, rec['weight']), verbose)
def check_Skchi_dim_formula(self, rec, verbose=False): """ for k > 1 check that dim is the Q-dimension of S_k^new(N,chi) (using sage dimension formula) """ # sample: dimension_new_cusp_forms(DirichletGroup(100).1^2,4) # Work around a bug in sage for Dirichlet characters in level 1 and 2 if rec['level'] < 3: dirchar = rec['level'] else: dirchar = get_dirchar(rec['level'], rec['conrey_indexes'][0], rec['char_order']) return self._test_equality( rec['relative_dim'], dimension_new_cusp_forms(dirchar, rec['weight']), verbose)
def generate_dimension_table_gamma1(maxN=100, maxk=12, minN=3, mink=2): C = pymongo.connection.Connection(port=dbport) C = pymongo.connection.Connection(port=dbport) ms = C['modularforms']['Modular_symbols.files'] print ms data = dict() for N in range(minN, maxN + 1): data[N] = dict() for k in range(mink, maxk + 1): data[N][k] = dict() if N > 2: D = DirichletGroup(N) G = D.galois_orbits(reps_only=True) dimall = 0 in_db_all = True for xi, x in enumerate(G): dim = dimension_new_cusp_forms(x, k) dimall += dim finds = ms.find({'t': [int(N), int(k), int(xi)]}) in_db = finds.count() > 0 if not in_db: in_db_all = False data[N][k][xi] = {'dimension': dim, 'in_db': in_db} else: in_db_all = True # we only have the trivial character finds = ms.find({'t': [int(N), int(k), int(0)]}) in_db = finds.count() > 0 if not in_db: in_db_all = False dimall = dimension_new_cusp_forms(N, k) data[N][k][0] = {'dimension': dimall, 'in_db': in_db} # print N,k,data[N][k] data[N][k][-1] = {'dimension': dimall, 'in_db': in_db_all} print "Computed data for level ", N return ms, data
def generate_dimension_table_gamma0(maxN=100, maxk=12): C = pymongo.connection.Connection(port=int(37010)) ms = C['modularforms']['Modular_symbols.files'] print ms data = dict() for N in range(1, maxN): data[N] = dict() for k in range(2, maxk): dim = dimension_new_cusp_forms(N, k) finds = ms.find({'t': [int(N), int(k), int(0)]}) print finds.count() in_db = finds.count() > 0 data[N][k] = {'dimension': dim, 'in_db': in_db} # print N,k,data[N][k] return ms, data
def generate_dimension_table_gamma0(maxN=100, maxk=12): C = pymongo.connection.Connection(port=dbport) C = pymongo.connection.Connection(port=dbport) ms = C['modularforms']['Modular_symbols.files'] print ms data = dict() for N in range(1, maxN): data[N] = dict() for k in range(2, maxk): dim = dimension_new_cusp_forms(N, k) finds = ms.find({'t': [int(N), int(k), int(0)]}) print finds.count() in_db = finds.count() > 0 data[N][k] = {'dimension': dim, 'in_db': in_db} # print N,k,data[N][k] return ms, data
def degrees(N, k, eps=None): """ Return the degrees of the newforms of level N, weight k, with character eps. INPUT: - N -- level; positive integer or Dirichlet character - k -- weight; integer at least 2 - eps -- None or Dirichlet character; if specified N is ignored EXAMPLES:: sage: import psage sage: psage.modform.rational.degrees(11,2) [1] sage: psage.modform.rational.degrees(37,2) [1, 1] sage: psage.modform.rational.degrees(43,2) [1, 2] sage: psage.modform.rational.degrees(DirichletGroup(13).0^2,2) [1] sage: psage.modform.rational.degrees(13,2,DirichletGroup(13).0^2) [1] sage: psage.modform.rational.degrees(13,2) [] """ group = eps if eps else N from sage.all import ModularSymbols, dimension_new_cusp_forms d = dimension_new_cusp_forms(group, k) if d == 0: # A useful optimization! return [] M = ModularSymbols(group=group, weight=k, sign=1).cuspidal_subspace() N = M.new_subspace() D = N.decomposition() # TODO: put in a consistency check. degs = [f.dimension() for f in D] assert sum(degs) == d, "major consistency check failed in degrees" return degs
def set_dimensions(self): r""" The dimension of the subspace of newforms in self. """ if self._chi != 1: x = self.character().sage_character() else: x = self.level() k = self.weight() # Ambient modular formsspace if self._dimension_modular_forms is None: self._dimension_modular_forms = int(dimension_modular_forms(x,k)) # Cuspidal subspace if self._dimension_cusp_forms is None: self._dimension_cusp_forms = int(dimension_cusp_forms(x,k)) # New cuspidal subspace if self._dimension_new_cusp_forms is None: self._dimension_new_cusp_forms = int(dimension_new_cusp_forms(x,k)) # New subspace of ambient space if self._dimension_newspace is None: if self._cuspidal == 1: self._dimension_newspace = self.dimension_new_cusp_forms() else: self._dimension_newspace = self._newspace.dimension() # Old subspace of self. if self._dimension_oldspace is None: if self._cuspidal == 1: self._dimension_oldspace = self.dimension_cusp_forms() - self.dimension_new_cusp_forms() else: self._dimension_oldspace = self.dimension_modular_forms() - self.dimension_newforms() if self._dimension is None: if self._cuspidal == 1: self._dimension = self.dimension_cusp_forms() elif self._cuspidal == 0: self._dimension = self.dimension_modular_forms()
def compare_formulas_1(D, k): DG = DirichletGroup(abs(D)) chi = DG(kronecker_character(D)) d1 = dimension_new_cusp_forms(chi, k) #if D>0: # lvals=sage.lfunctions.all.lcalc.twist_values(1,2,D) #else: # lvals=sage.lfunctions.all.lcalc.twist_values(1,D,0) #s1=RR(sum([sqrt(abs(lv[0]))*lv[1]*2**len(prime_factors(D/lv[0])) for lv in lvals if lv[0].divides(D) and Zmod(lv[0])(abs(D/lv[0])).is_square()])) #d2=RR(1/pi*s1) d2 = 0 for d in divisors(D): if is_fundamental_discriminant(-d): K = QuadraticField(-d) DD = old_div(ZZ(D), ZZ(d)) ep = euler_phi((chi * DG(kronecker_character(-d))).conductor()) #ep=euler_phi(squarefree_part(abs(D*d))) print("ep=", ep, D, d) ids = [a for a in K.ideals_of_bdd_norm(-DD)[-DD]] eulers1 = [] for a in ids: e = a.euler_phi() if e != 1 and ep == 1: if K(-1).mod(a) != K(1).mod(a): e = old_div(e, (2 * ep)) else: e = old_div(e, ep) eulers1.append(e) print(eulers1, ep) s = sum(eulers1) if ep == 1 and not (d.divides(DD) or abs(DD) == 1): continue print(d, s) if len(eulers1) > 0: d2 += s * K.class_number() return d1 - d2
def verify_dimensions(n,k): totaldim = 0 for ns in db.mf_newspaces.search({'level':n, 'weight':k}, projection = ['hecke_orbit_dims', 'char_orbit_index','char_labels','label']): label = ns['label'] number = ns['char_labels'][0] hecke_orbit_dims = ns['hecke_orbit_dims'] hecke_orbit_dims.sort() dim = sum(hecke_orbit_dims) totaldim += dim char_labels = ns['char_labels'] # FIX label for trivial character if (n, number) == (1, 0): number = 1 assert char_labels == [0] # and fix them char_labels = [1] # end FIX sage_dim, sage_orbit = dim_and_orbit(n,k,number) assert dim == sage_dim, label assert sorted(sage_orbit) == sorted(char_labels), label hecke_orbit_dims_nf = sorted(list(db.mf_newforms.search({'space_label': ns['label']}, projection = 'dim'))) assert hecke_orbit_dims == hecke_orbit_dims_nf, label assert totaldim == dimension_new_cusp_forms(Gamma1(n), k), "n = %d k = %d --> %s != %s" % (n, k, totaldim, dimension_new_cusp_forms(Gamma1(n), k))
def dim_new(chi, k): if not isinstance(chi, (int, long, Integer)) and chi.is_trivial(): return dimension_new_cusp_forms(chi.modulus(), k) else: return dimension_new_cusp_forms(chi, k)
def check_Sk_dim_formula(self, rec, verbose=False): """ check that dim = dim S_k^new(Gamma1(N)) """ # TIME about 60s return self._test_equality(rec['dim'], dimension_new_cusp_forms(Gamma1(rec['level']), rec['weight']), verbose)
def set_oldspace_decomposition(self): r""" Get decomposition of the oldspace in self into submodules. """ if not (self._oldspace_decomposition is None or self._oldspace_decomposition == []): return N = self._N k = self._k M = self._modular_symbols.cuspidal_submodule() L = list() L = [] check_dim = self.dimension_newspace() if(check_dim == self.dimension()): return L if(self._verbose > 1): wmf_logger.debug("check_dim:={0}".format(check_dim)) for d in divisors(N): if(d == 1): continue q = N.divide_knowing_divisible_by(d) if(self._verbose > 1): wmf_logger.debug("d={0}".format(d)) # since there is a bug in the current version of sage # we have to try this... try: O = M.old_submodule(d) except AttributeError: O = M.zero_submodule() Od = O.dimension() if(self._verbose > 1): wmf_logger.debug("O={0}".format(O)) wmf_logger.debug("Od={0}".format(Od)) if(d == N and k == 2 or Od == 0): continue if self.character().is_trivial(): # S=ModularSymbols(ZZ(N/d),k,sign=1).cuspidal_submodule().new_submodule(); Sd=S.dimension() wmf_logger.debug("q={0},{1}".format(q, type(q))) wmf_logger.debug("k={0},{1}".format(k, type(k))) Sd = dimension_new_cusp_forms(q, k) if(self._verbose > 1): wmf_logger.debug("Sd={0}".format(Sd)) if Sd > 0: mult = len(divisors(ZZ(d))) check_dim = check_dim + mult * Sd L.append((q, 0, mult, Sd)) else: xd = self.character().decomposition() for xx in xd: if xx.modulus() == q: Sd = dimension_new_cusp_forms(xx, k) if Sd > 0: # identify this character for internal storage... should be optimized x_k = self.conrey_character(xx).number() mult = len(divisors(ZZ(d))) check_dim = check_dim + mult * Sd L.append((q, x_k, mult, Sd)) if(self._verbose > 1): wmf_logger.debug("mult={0},N/d={1},Sd={2}".format(mult, ZZ(N / d), Sd)) wmf_logger.debug("check_dim={0}".format(check_dim)) check_dim = check_dim - M.dimension() if(check_dim != 0): raise ArithmeticError("Something wrong! check_dim=%s" % check_dim) self._oldspace_decomposition = L
def do(level, weight, lfun_filename=None, instances_filename=None, hecke_filename=None, traces_filename=None, only_traces=False, only_orbit=None): print "N = %s, k = %s" % (level, weight) polyinfile = os.path.join(base_import, 'polydb/{}.{}.polydb'.format(level, weight)) mfdbinfile = os.path.join(base_import, 'mfdb/{}.{}.mfdb'.format(level, weight)) Ldbinfile = os.path.join(base_import, 'mfldb/{}.{}.mfldb'.format(level, weight)) notfound = False if not os.path.exists(polyinfile): print '{} not found'.format(polyinfile) notfound = True if not os.path.exists(mfdbinfile): print '{} not found'.format(mfdbinfile) notfound = True if not os.path.exists(Ldbinfile): print '{} not found'.format(Ldbinfile) notfound = True if only_orbit is not None: print "N = %s, k = %s, orbit = %s" % (level, weight, only_orbit) if lfun_filename is None: lfun_filename = os.path.join( base_export, 'CMF_Lfunctions_%d_%d_%d.txt' % (level, weight, only_orbit)) if instances_filename is None: instances_filename = os.path.join( base_export, 'CMF_instances_%d_%d_%d.txt' % (level, weight, only_orbit)) if hecke_filename is None: hecke_filename = os.path.join( base_export, 'CMF_hecke_cc_%d_%d_%d.txt' % (level, weight, only_orbit)) if traces_filename is None: traces_filename = os.path.join( base_export, 'CMF_traces_%d_%d_%d.txt' % (level, weight, only_orbit)) if lfun_filename is None: lfun_filename = os.path.join( base_export, 'CMF_Lfunctions_%d.txt' % (level * weight**2)) if instances_filename is None: instances_filename = os.path.join( base_export, 'CMF_instances_%d.txt' % (level * weight**2)) if hecke_filename is None: hecke_filename = os.path.join( base_export, 'CMF_hecke_cc_%d.txt' % (level * weight**2)) if traces_filename is None: traces_filename = os.path.join( base_export, 'CMF_traces_%d.txt' % (level * weight**2)) def write_traces(traces_filename): with open(traces_filename, 'a') as F: for ol in Set(orbit_labels.values()): if only_orbit is not None: if ol != only_orbit: continue F.write('{}:{}:{}:{}:{}\n'.format(level, weight, ol, degrees_sorted[ol], traces_sorted[ol]).replace( ' ', '')) #level_list = set() #level_weight_list = [] #for dirpath, dirnames, filenames in os.walk(inpath): # for filename in filenames: # if not filename.endswith('.polydb'): # continue # level, weight, _ = filename.split('.') # level = int(level) # weight = int(weight) # level_weight_list.append( (level, weight, os.path.join(dirpath, filename)) ) # level_list.add(level) # #level_list = sorted(level_list) orbit_labels = {} G = DirichletGroup_conrey(level) orbits = G._galois_orbits() for k, orbit in enumerate(orbits): for chi in orbit: # we are starting at 1 orbit_labels[chi] = k + 1 if level == 1: k = 0 orbit_labels = {1: 1} degrees_sorted = [[] for _ in range(k + 2)] traces_sorted = [[] for _ in range(k + 2)] dim = dimension_new_cusp_forms(Gamma1(level), weight) if notfound: assert dim == 0, "dim = %s" % dim write_traces(traces_filename) return 1 degree_lists = {} traces_lists = {} db = sqlite3.connect(polyinfile) db.row_factory = sqlite3.Row ''' expected schema: CREATE TABLE heckepolys (level INTEGER, weight INTEGER, chi INTEGER, whatevernumber INTEGER, labelnumber INTEGER, operator BLOB, degree INTEGER, mforbit BLOB, polynomial BLOB); ''' mfdb = sqlite3.connect(os.path.join(mfdbinfile)) mfdb.row_factory = sqlite3.Row ''' expected schema: CREATE TABLE modforms (level INTEGER, weight INTEGER, chi INTEGER, orbit INTEGER, j INTEGER, prec INTEGER, exponent INTEGER, ncoeffs INTEGER, coefficients BLOB) ''' coeffs = {} for result in mfdb.execute( 'SELECT prec, exponent, ncoeffs, coefficients, chi, j FROM modforms WHERE level={} AND weight={};' .format(level, weight)): chi = result['chi'] chibar = inverse_mod(chi, level) if only_orbit is not None and only_orbit not in [ orbit_labels[chi], orbit_labels[chibar] ]: continue is_trivial = False #is_quadratic = False if chi == 1: is_trivial = True #elif (chi*chi) % level == 1: # is_quadratic = True j = result['j'] offset = 0 coeffblob = result['coefficients'] exponent = QQ(result['exponent']) prec = QQ(result['prec']) # print prec, exponent _coeffs = [CCC(0)] * (to_compute + 1) #for k in range(35): # number of prime powers < 100 for pp in prime_powers(to_compute): z, bytes_read = read_gmp_int(coeffblob, offset) #print z offset = offset + bytes_read real_part = CCC(z) * 2**exponent if prec != MF_PREC_EXACT: real_part = real_part.add_error(2**prec) imag_part = 0 if not is_trivial: z, bytes_read = read_gmp_int(coeffblob, offset) offset = offset + bytes_read imag_part = CCC.gens()[0] * CCC(z) * 2**exponent if prec != MF_PREC_EXACT: imag_part = imag_part.add_error(2**prec) #print real_part + imag_part _coeffs[pp] = real_part + imag_part #print coeffs _coeffs[1] = CCC(1) extend_multiplicatively(_coeffs) coeffs[(chi, j)] = _coeffs if chibar > chi: coeffs[(chibar, j)] = [elt.conjugate() for elt in _coeffs] if only_orbit is None: assert len(coeffs) == dim, "%s != %s, keys = %s" % (len(coeffs), dim, coeffs.keys()) if not only_traces: bad_euler_factors = {} euler_factors = {} angles = {} coeffs_f = {} for key, coeff in coeffs.iteritems(): chi, j = key coeffs_f[key], angles[key], euler_factors[key], bad_euler_factors[ key] = angles_euler_factors(coeff, level, weight, chi) #mforbits = {} for result in db.execute( 'SELECT level, weight, chi, whatevernumber, labelnumber, degree, mforbit from heckepolys;' ): level = result['level'] weight = result['weight'] chi = result['chi'] original_chi = chi if only_orbit is not None and only_orbit != orbit_labels[original_chi]: continue if (level, weight, chi) not in degree_lists: degree_lists[(level, weight, chi)] = [] traces_lists[(level, weight, chi)] = [] degree_lists[(level, weight, chi)].append(result['degree']) #whatever = result['whatevernumber'] label = result['labelnumber'] #degree = result['degree'] mforbit = read_orbit(result['mforbit']) #mforbits[original_chi] = mforbit #print level, weight, chi, whatever, label, degree, mforbit #is_trivial = False #is_quadratic = False #if chi == 1: # is_trivial = True #elif (chi*chi) % level == 1: # is_quadratic = True traces_bound = to_compute + 1 traces = [RRR(0)] * traces_bound for chi, j in mforbit: #if inverse_mod(chi, level) < chi: # continue for k, z in enumerate(coeffs[(chi, j)][:traces_bound]): traces[k] += RRR(z.real()) for i, z in enumerate(traces): try: traces[i] = z.unique_integer() except ValueError: traces = traces[:i] #print (level, weight, original_chi, orbit_labels[original_chi]) #print degree_lists[(level, weight, original_chi)] #print i, z #print traces[:i] break traces_lists[(level, weight, original_chi)].append( (traces[1:], mforbit)) Ldb = sqlite3.connect(os.path.join(Ldbinfile)) Ldb.row_factory = sqlite3.Row ''' expected schema: CREATE TABLE modformLfunctions (level INTEGER, weight INTEGER, chi INTEGER, orbit INTEGER, j INTEGER, rank INTEGER, rankverified INTEGER, signarg REAL gamma1 REAL, gamma2 REAL, gamma3 REAL, zeroprec INTEGER, nzeros INTEGER, zeros BLOB, valuesdelta REAL, nvalues INTEGER, Lvalues BLOB); ''' zeros = {} Ldbresults = {} if only_traces: cur = [] else: cur = Ldb.execute( 'SELECT level, weight, chi, j, rank, zeroprec, nzeros, zeros, valuesdelta, nvalues, Lvalues, signarg from modformLfunctions' ) for result in cur: nzeros = result['nzeros'] prec = result['zeroprec'] chi = result['chi'] if only_orbit is not None and only_orbit != orbit_labels[chi]: continue j = result['j'] #print result['level'], result['weight'], chi, j _zeros = [] offset = 0 for k in range(nzeros): nlimbs = struct.unpack_from(">I", result['zeros'], offset)[0] offset = offset + 4 zdata = struct.unpack_from("B" * nlimbs, result['zeros'], offset) offset = offset + nlimbs z = sum([x * 2**(8 * k) for (k, x) in enumerate(reversed(zdata))]) _zeros.append(z) zeros[(chi, j)] = map(ZZ, _zeros) Ldbresults[(chi, j)] = result ''' for level, weight, chi in sorted(degree_lists.keys()): toprint = '{}:{}:{}:[{}]:[{}]'.format(level, weight, orbit_labels[chi], sorted(degree_lists[(level, weight, chi)]), sorted(traces_lists[(level, weight, chi)])) print ''.join(toprint.split()) for chi2, j in mforbits[chi]: print chi2, j, zeros[(chi2, j)] ''' labels = {} original_pair = {} conjugates = {} selfduals = {} hecke_orbit_code = {} all_the_labels = {} embedding_m = {} for level, weight, originalchi in sorted(degree_lists.keys()): #toprint = '{}:{}:{}:{}'.format(level, weight, orbit_labels[originalchi], sorted(degree_lists[(level, weight, originalchi)])) #print ''.join(toprint.split()) degrees_sorted[orbit_labels[originalchi]] = sorted( degree_lists[(level, weight, originalchi)]) for mforbitlabel, (traces, mforbit) in enumerate( sorted(traces_lists[(level, weight, originalchi)])): selfdual = False if originalchi == 1: selfdual = True if (originalchi * originalchi) % level == 1: Z = coeffs[mforbit[0]] selfdual = True for z in Z: if not z.imag().contains_zero(): selfdual = False break #if selfdual: # print '*', #print mforbit, traces traces_sorted[orbit_labels[originalchi]].append(traces[:to_store]) if only_traces: continue chi_list = sorted(set(chi for (chi, j) in mforbit)) coeffs_list = {} for chi in chi_list: j_list = [elt for (_, elt) in mforbit if _ == chi] coeffs_list[chi] = [(chi, elt, coeffs[(chi, elt)]) for elt in j_list] coeffs_list[chi].sort(cmp=CBFlistcmp, key=lambda z: z[-1]) d = len(j_list) m = 1 for chi in chi_list: chibar = inverse_mod(chi, level) for k, _coeffs in enumerate(coeffs_list[chi]): j = _coeffs[1] assert chi == _coeffs[0] sa, sn = cremona_letter_code(mforbitlabel), k + 1 ol = cremona_letter_code(orbit_labels[chi] - 1) an_conjugate = [elt.conjugate() for elt in _coeffs[2]] if selfdual: chibar = chi ca, cn = sa, sn else: ca = sa # first try the obvious for elt in [k] + list(range(0, k)) + list( range(k + 1, d)): if CBFlisteq(coeffs_list[chibar][elt][2], an_conjugate): cn = elt + 1 break else: assert False assert CBFlisteq(coeffs_list[chibar][cn - 1][2], an_conjugate) # orbit_labels[chi] start at 1 # mforbitlabel starts at 0 hecke_orbit_code[(chi, j)] = int(level + (weight << 24) + ( (orbit_labels[chi] - 1) << 36) + (mforbitlabel << 52)) all_the_labels[(chi, j)] = (level, weight, ol, sa, chi, sn) converted_label = (chi, sa, sn) labels[(chi, j)] = converted_label original_pair[converted_label] = (chi, j) selfduals[converted_label] = selfdual conjugates[converted_label] = (chibar, ca, cn) embedding_m[(chi, j)] = m m += 1 if only_traces: write_traces(traces_filename) return 0 #for key, val in labels.iteritems(): # print key," \t-new->\t", val #for key, val in conjugates.iteritems(): # print key,"\t--c-->\t", val #for key, val in all_the_labels.iteritems(): # print key," \t--->\t" + "\t".join( map(str, [val,hecke_orbit_code[key]])) def origin(chi, a, n): return "ModularForm/GL2/Q/holomorphic/%d/%d/%s/%s/%d/%d" % ( level, weight, cremona_letter_code(orbit_labels[chi] - 1), a, chi, n) def rational_origin(chi, a): return "ModularForm/GL2/Q/holomorphic/%d/%d/%s/%s" % ( level, weight, cremona_letter_code(orbit_labels[chi] - 1), a) def label(chi, j): return labels[(chi, j)] def self_dual(chi, a, n): return selfduals[(chi, a, n)] Lhashes = {} instances = {} # the function below assumes this order assert schema_instances == ['url', 'Lhash', 'type'] def tuple_instance(row): return (row['origin'], row['Lhash'], default_type) real_zeros = {} rows = {} def populate_complex_row(Ldbrow): row = dict(constant_lf(level, weight, 2)) chi = int(Ldbrow['chi']) j = int(Ldbrow['j']) chil, a, n = label(chi, j) assert chil == chi row['order_of_vanishing'] = int(Ldbrow['rank']) zeros_as_int = zeros[(chi, j)][row['order_of_vanishing']:] prec = row['accuracy'] = Ldbrow['zeroprec'] two_power = 2**prec double_zeros = [float(z / two_power) for z in zeros_as_int] zeros_as_real = [ RealNumber(z.str() + ".") / two_power for z in zeros_as_int ] real_zeros[(chi, a, n)] = zeros_as_real zeros_as_str = [z.str(truncate=False) for z in zeros_as_real] for i, z in enumerate(zeros_as_str): assert float(z) == double_zeros[i] assert (RealNumber(z) * two_power).round() == zeros_as_int[i] row['positive_zeros'] = str(zeros_as_str).replace("'", "\"") row['origin'] = origin(chi, a, n) row['central_character'] = "%s.%s" % (level, chi) row['self_dual'] = self_dual(chi, a, n) row['conjugate'] = None row['Lhash'] = str((zeros_as_int[0] * 2**(100 - prec)).round()) if prec < 100: row['Lhash'] = '_' + row['Lhash'] Lhashes[(chi, a, n)] = row['Lhash'] row['sign_arg'] = float(Ldbrow['signarg'] / (2 * pi)) for i in range(0, 3): row['z' + str(i + 1)] = (RealNumber(str(zeros_as_int[i]) + ".") / 2**prec).str() row['plot_delta'] = Ldbrow['valuesdelta'] row['plot_values'] = [ float(CDF(elt).real_part()) for elt in struct.unpack('{}d'.format(len(Ldbrow['Lvalues']) / 8), Ldbrow['Lvalues']) ] row['leading_term'] = '\N' if row['self_dual']: row['root_number'] = str( RRR(CDF(exp(2 * pi * I * row['sign_arg'])).real()).unique_integer()) if row['root_number'] == str(1): row['sign_arg'] = 0 elif row['root_number'] == str(-1): row['sign_arg'] = 0.5 else: row['root_number'] = str(CDF(exp(2 * pi * I * row['sign_arg']))) #row['dirichlet_coefficients'] = [None] * 10 #print label(chi,j) for i, ai in enumerate(coeffs[(chi, j)][2:12]): if i + 2 <= 10: row['a' + str(i + 2)] = CBF_to_pair(ai) # print 'a' + str(i+2), ai_jsonb #row['dirichlet_coefficients'][i] = ai_jsonb row['coefficient_field'] = 'CDF' # only 30 row['euler_factors'] = map(lambda x: map(CBF_to_pair, x), euler_factors[(chi, j)][:30]) row['bad_lfactors'] = map( lambda x: [int(x[0]), map(CBF_to_pair, x[1])], bad_euler_factors[(chi, j)]) for key in schema_lf: assert key in row, "%s not in row = %s" % (key, row) assert len(row) == len(schema_lf), "%s != %s" % (len(row), len(schema_lf)) #rewrite row as a list rows[(chi, a, n)] = [row[key] for key in schema_lf] instances[(chi, a, n)] = tuple_instance(row) def populate_complex_rows(): for key, row in Ldbresults.iteritems(): populate_complex_row(row) def populate_conjugates(): # print Lhashes.keys() for key, row in rows.iteritems(): # print "key = %s" % (key,) row[schema_lf_dict['conjugate']] = Lhashes[conjugates[key]] row_conj = rows[conjugates[key]] zero_val_conj = row_conj[schema_lf_dict['plot_values']][0] assert (row[schema_lf_dict['plot_values']][0] - zero_val_conj) < 1e-10, "%s, %s: %s - %s = %s" % ( key, conjugates[key], row[schema_lf_dict['plot_values']][0], zero_val_conj, row[schema_lf_dict['plot_values']][0] - zero_val_conj) diff = (row[schema_lf_dict['sign_arg']] + row_conj[schema_lf_dict['sign_arg']]) % 1 assert min(diff, 1 - diff) < 1e-10, "%s + %s = %s" % ( row[schema_lf_dict['sign_arg']], row_conj[schema_lf_dict['sign_arg']], diff) rational_rows = {} def populate_rational_rows(): order_of_vanishing = schema_lf_dict['order_of_vanishing'] accuracy = schema_lf_dict['accuracy'] sign_arg = schema_lf_dict['sign_arg'] Lhash = schema_lf_dict['Lhash'] plot_delta = schema_lf_dict['plot_delta'] plot_values = schema_lf_dict['plot_values'] central_character = schema_lf_dict['central_character'] # reverse euler factors from the table for p^d < 1000 rational_keys = {} for chi, a, n in rows.keys(): orbit_label = orbit_labels[chi] if (orbit_label, a) not in rational_keys: rational_keys[(orbit_label, a)] = [] rational_keys[(orbit_label, a)].append((chi, a, n)) for (orbit_label, a), triples in rational_keys.iteritems(): # for now skip degree >= 100 if len(triples) > 80: # the real limit is 87 continue pairs = [original_pair[elt] for elt in triples] #print a, pairs, triples chi = triples[0][0] degree = 2 * len(triples) row = constant_lf(level, weight, degree) row['origin'] = rational_origin(chi, a) print row['origin'] row['self_dual'] = 't' row['conjugate'] = '\N' row['order_of_vanishing'] = sum( [rows[elt][order_of_vanishing] for elt in triples]) row['accuracy'] = min([rows[elt][accuracy] for elt in triples]) ### zeros_as_real = [] for elt in triples: zeros_as_real.extend(real_zeros[elt]) zeros_as_real.sort() zeros_as_str = [z.str(truncate=False) for z in zeros_as_real] row['positive_zeros'] = str(zeros_as_str).replace("'", "\"") zeros_hash = sorted([(rows[elt][Lhash], real_zeros[elt][0]) for elt in triples], key=lambda x: x[1]) row['Lhash'] = ",".join([elt[0] for elt in zeros_hash]) # character if degree == 2: row['central_character'] = rows[triples[0]][central_character] else: G = DirichletGroup_conrey(level) chiprod = prod([ G[int(rows[elt][central_character].split(".")[-1])] for elt in triples ]) chiprod_index = chiprod.number() row['central_character'] = "%s.%s" % (level, chiprod_index) row['sign_arg'] = sum([rows[elt][sign_arg] for elt in triples]) while row['sign_arg'] > 0.5: row['sign_arg'] -= 1 while row['sign_arg'] <= -0.5: row['sign_arg'] += 1 zeros_zi = [] for i in range(0, 3): for elt in triples: zeros_zi.append(rows[elt][schema_lf_dict['z' + str(i + 1)]]) zeros_zi.sort(key=lambda x: RealNumber(x)) for i in range(0, 3): row['z' + str(i + 1)] = zeros_zi[i] deltas = [rows[elt][plot_delta] for elt in triples] values = [rows[elt][plot_values] for elt in triples] row['plot_delta'], row['plot_values'] = prod_plot_values( deltas, values) row['leading_term'] = '\N' row['root_number'] = str( RRR(CDF(exp(2 * pi * I * row['sign_arg'])).real()).unique_integer()) if row['root_number'] == str(1): row['sign_arg'] = 0 elif row['root_number'] == str(-1): row['sign_arg'] = 0.5 row['coefficient_field'] = '1.1.1.1' for chi, _, _ in triples: if (level, weight, chi) in traces_lists: for elt in traces_lists[(level, weight, chi)]: if set(elt[1]) <= set(pairs): traces = elt[0] break else: print pairs print traces_lists[(level, weight, chi)] assert False break else: print pairs print traces_lists assert False euler_factors_cc = [euler_factors[elt] for elt in pairs] row['euler_factors'], row[ 'bad_lfactors'], dirichlet = rational_euler_factors( traces, euler_factors_cc, level, weight) #handling Nones row['euler_factors'] = json.dumps(row['euler_factors']) row['bad_lfactors'] = json.dumps(row['bad_lfactors']) # fill in ai for i, ai in enumerate(dirichlet): if i > 1: row['a' + str(i)] = int(dirichlet[i]) #print 'a' + str(i), dirichlet[i] for key in schema_lf: assert key in row, "%s not in row = %s" % (key, row.keys()) for key in row.keys(): assert key in schema_lf, "%s unexpected" % key assert len(row) == len(schema_lf), "%s != %s" % (len(row), len(schema_lf)) #rewrite row as a list rational_rows[(orbit_label, a)] = [row[key] for key in schema_lf] instances[(orbit_label, a)] = tuple_instance(row) # if dim == 1, drop row if len(triples) == 1: rows.pop(triples[0]) instances.pop(triples[0]) def get_hecke_cc(): # if field_poly exists then compute the corresponding embedding of the root # add the conrey label hecke_cc = {} for key, label in labels.iteritems(): # key = (chi,j) # label = (chi, a, n) chi, a, n = label ol = cremona_letter_code(orbit_labels[chi] - 1) lfuntion_label = ".".join( map(str, [level, weight] + [ol, a, chi, n])) hecke_cc[key] = [ int(hecke_orbit_code[key]), lfuntion_label, # N.k.c.x.n int(label[0]), # conrey_label int(label[2]), # embedding_index int(embedding_m[key]), '\N', # embedding_root_real '\N', # embedding_root_imag coeffs_f[key][1:], angles[key], ] return hecke_cc def json_hack(elt): if isinstance(elt, str): return elt else: return json.dumps(elt) def write_hecke_cc(hecke_filename): write_header_hecke_file(hecke_filename) with open(hecke_filename, 'a') as HF: for v in get_hecke_cc().values(): try: HF.write("\t".join(map(json_hack, v)).replace( '[', '{').replace(']', '}') + "\n") except TypeError: for elt in v: print elt print json_hack(elt) raise def export_complex_rows(lfunctions_filename, instances_filename): write_header(lfunctions_filename, instances_filename) #str_parsing_lf = '\t'.join(['%r'] * len(schema_lf)) + '\n' #str_parsing_instances = '\t'.join(['%r'] * len(schema_instances)) + '\n' with open(lfunctions_filename, 'a') as LF: for key, row in rows.iteritems(): try: LF.write("\t".join(map(json_hack, row)) + "\n") except TypeError: for i, elt in enumerate(row): print schema_lf[i] print elt print json_hack(elt) raise for key, row in rational_rows.iteritems(): try: LF.write("\t".join(map(json_hack, row)) + "\n") except TypeError: for elt in row: print elt print json_hack(elt) raise with open(instances_filename, 'a') as IF: for key, row in instances.iteritems(): IF.write("\t".join(map(json_hack, row)) + "\n") populate_complex_rows() #populate_conjugates() #populate_rational_rows() #export_complex_rows(lfun_filename, instances_filename) write_hecke_cc(hecke_filename) #write_traces(traces_filename) return 0