def string2number(s): # a start to replace p2sage (used for the paramters in the FE) strs = str(s).replace(' ','') try: if 'e' in strs: # check for e(m/n) := exp(2*pi*i*m/n), used by Dirichlet characters, for example r = re.match(r'^\$?e\\left\(\\frac\{(?P<num>\d+)\}\{(?P<den>\d+)\}\\right\)\$?$',strs) if not r: r = re.match(r'^e\((?P<num>\d+)/(?P<den>\d+)\)$',strs) if r: q = Rational(r.groupdict()['num'])/Rational(r.groupdict()['den']) return CDF(exp(2*pi*I*q)) if 'I' in strs: return CDF(strs) elif (type(s) is list or type(s) is tuple) and len(s) == 2: return CDF(tuple(s)) elif '/' in strs: return Rational(strs) elif strs=='0.5': # Temporary fix because 0.5 in db for EC return Rational('1/2') elif '.' in strs: return float(strs) else: return Integer(strs) except: return s
def specialValueTriple(L, s, sLatex_analytic, sLatex_arithmetic): ''' Returns [L_arithmetic, L_analytic, L_val] Currently only used for genus 2 curves and Dirichlet characters. Eventually want to use for all L-functions. ''' number_of_decimals = 10 val = None if L.fromDB: #getattr(L, 'fromDB', False): s_alg = s + L.analytic_normalization for x in L.values: # the numbers here are always half integers # so this comparison is exact if x[0] == s_alg: val = x[1] break if val is None: if L.fromDB: val = "not computed" else: val = L.sageLfunction.value(s) logger.warning( "a value of an L-function has been computed on the fly") if sLatex_arithmetic: lfunction_value_tex_arithmetic = L.texname_arithmetic.replace( 's)', sLatex_arithmetic + ')') else: lfunction_value_tex_arithmetic = '' if sLatex_analytic: lfunction_value_tex_analytic = L.texname.replace( '(s', '(' + sLatex_analytic) else: lfunction_value_tex_analytic = '' if isinstance(val, string_types): Lval = val else: ccval = CDF(val) # We must test for NaN first, since it would show as zero otherwise # Try "RR(NaN) < float(1e-10)" in sage -- GT if ccval.real().is_NaN(): Lval = r"$\infty$" else: Lval = display_complex(ccval.real(), ccval.imag(), number_of_decimals) return [lfunction_value_tex_analytic, lfunction_value_tex_arithmetic, Lval]
def verify_embeddings(nf): if nf['dim'] <= 20 and nf['dim'] > 1: hoc = nf['hecke_orbit_code'] embeddings = list(db.mf_hecke_cc.search({'hecke_orbit_code':hoc}, projection = ['embedding_root_imag','embedding_root_real'])) # we have the right number of embeddings assert len(embeddings) == nf['dim'], str(hoc) # they are all distinct assert len(set([ CDF(elt['embedding_root_real'], elt['embedding_root_imag']) for elt in embeddings ])) == nf['dim'], str(hoc)
def specialValueTriple(L, s, sLatex_analytic, sLatex_arithmetic): ''' Returns [L_arithmetic, L_analytic, L_val] Currently only used for genus 2 curves and Dirichlet characters. Eventually want to use for all L-functions. ''' number_of_decimals = 10 val = None if L.fromDB: #getattr(L, 'fromDB', False): s_alg = s + L.analytic_normalization for x in L.values: # the numbers here are always half integers # so this comparison is exact if x[0] == s_alg: val = x[1] break if val is None: if L.fromDB: val = "not computed" else: val = L.sageLfunction.value(s) logger.warning("a value of an L-function has been computed on the fly") if sLatex_arithmetic: lfunction_value_tex_arithmetic = L.texname_arithmetic.replace('s)', sLatex_arithmetic + ')') else: lfunction_value_tex_arithmetic = '' if sLatex_analytic: lfunction_value_tex_analytic = L.texname.replace('(s', '(' + sLatex_analytic) else: lfunction_value_tex_analytic = '' if isinstance(val, basestring): Lval = val else: ccval = CDF(val) # We must test for NaN first, since it would show as zero otherwise # Try "RR(NaN) < float(1e-10)" in sage -- GT if ccval.real().is_NaN(): Lval = "$\\infty$" else: Lval = display_complex(ccval.real(), ccval.imag(), number_of_decimals) return [lfunction_value_tex_analytic, lfunction_value_tex_arithmetic, Lval]
def lfuncFEtex(L, fmt): """ Returns the LaTex for displaying the Functional equation of the L-function L. fmt could be any of the values: "analytic", "selberg" """ if fmt == "arithmetic": mu_list = [mu - L.motivic_weight/2 for mu in L.mu_fe] nu_list = [nu - L.motivic_weight/2 for nu in L.nu_fe] mu_list.sort() nu_list.sort() texname = L.texname_arithmetic try: tex_name_s = L.texnamecompleteds_arithmetic tex_name_1ms = L.texnamecompleted1ms_arithmetic except AttributeError: tex_name_s = L.texnamecompleteds tex_name_1ms = L.texnamecompleted1ms else: mu_list = L.mu_fe[:] nu_list = L.nu_fe[:] texname = L.texname tex_name_s = L.texnamecompleteds tex_name_1ms = L.texnamecompleted1ms ans = "" if fmt == "arithmetic" or fmt == "analytic": ans = r"\begin{aligned}" + "\n" + tex_name_s + r"=\mathstrut &" if L.level > 1: if L.level >= 10**8 and not is_prime(int(L.level)): ans += r"\left(%s\right)^{s/2}" % latex(L.level_factored) else: ans += latex(L.level) + "^{s/2}" ans += r" \, " def munu_str(factors_list, field): assert field in [r'\R',r'\C'] # set up to accommodate multiplicity of Gamma factors old = "" res = "" curr_exp = 0 for elt in factors_list: if elt == old: curr_exp += 1 else: old = elt if curr_exp > 1: res += "^{" + str(curr_exp) + "}" if curr_exp > 0: res += r" \, " curr_exp = 1 res += r"\Gamma_{" + field + "}(s" + seriescoeff(elt, 0, "signed", "", 3) + ")" if curr_exp > 1: res += "^{" + str(curr_exp) + "}" if res != "": res += r" \, " return res ans += munu_str(mu_list, r'\R') ans += munu_str(nu_list, r'\C') ans += texname + r"\cr" + "\n" ans += r"=\mathstrut & " if L.sign == 0: ans += r"\epsilon \cdot " else: ans += seriescoeff(L.sign, 0, "factor", "", 3) + r"\," ans += tex_name_1ms if L.sign == 0 and L.degree == 1: ans += r"\quad (\text{with }\epsilon \text{ not computed})" if L.sign == 0 and L.degree > 1: ans += r"\quad (\text{with }\epsilon \text{ unknown})" ans += "\n" + r"\end{aligned}\n" elif fmt == "selberg": ans += "(" + str(int(L.degree)) + r",\ " if L.level >= 10**8 and not is_prime(int(L.level)): ans += latex(L.level_factored) else: ans += str(int(L.level)) ans += r",\ " ans += "(" # this is mostly a hack for GL2 Maass forms def real_digits(x): return len(str(x).replace('.','').lstrip('-').lstrip('0')) def mu_fe_prec(x): if L._Ltype == 'maass': return real_digits(imag_part(x)) else: return 3 if L.mu_fe != []: mus = [ display_complex(CDF(mu).real(), CDF(mu).imag(), mu_fe_prec(mu), method="round" ) for mu in L.mu_fe ] if len(mus) >= 6 and mus == [mus[0]]*len(mus): ans += '[%s]^{%d}' % (mus[0], len(mus)) else: ans += ", ".join(mus) else: ans += r"\ " ans += ":" if L.nu_fe != []: if len(L.nu_fe) >= 6 and L.nu_fe == [L.nu_fe[0]]*len(L.nu_fe): ans += '[%s]^{%d}' % (L.nu_fe[0], len(L.nu_fe)) else: ans += ", ".join(map(str, L.nu_fe)) else: ans += r"\ " ans += r"),\ " ans += seriescoeff(L.sign, 0, "literal", "", 3) ans += ")" return(ans)
def setup_cc_data(self, info): """ INPUT: - ``info`` -- a dictionary with keys - ``m`` -- a string describing the embedding indexes desired - ``n`` -- a string describing the a_n desired - ``CC_m`` -- a list of embedding indexes - ``CC_n`` -- a list of desired a_n - ``format`` -- one of 'embed', 'analytic_embed', 'satake', or 'satake_angle' """ an_formats = ['embed','analytic_embed', None] angles_formats = ['satake','satake_angle', None] analytic_shift_formats = ['embed', None] cc_proj = ['conrey_index','embedding_index','embedding_m','embedding_root_real','embedding_root_imag'] format = info.get('format') query = {'hecke_orbit_code':self.hecke_orbit_code} # deal with m if self.embedding_label is None: m = info.get('m','1-%s'%(min(self.dim,20))) if '.' in m: m = re.sub(r'\d+\.\d+', self.embedding_from_embedding_label, m) CC_m = info['CC_m'] if 'CC_m' in info else integer_options(m) CC_m = sorted(set(CC_m)) # if it is a range if len(CC_m) - 1 == CC_m[-1] - CC_m[0]: query['embedding_m'] = {'$gte':CC_m[0], '$lte':CC_m[-1]} else: query['embedding_m'] = {'$in': CC_m} self.embedding_m = None else: self.embedding_m = int(info['CC_m'][0]) cc_proj.extend(['dual_conrey_index', 'dual_embedding_index']) query = {'label' : self.label + '.' + self.embedding_label} if format is None and 'CC_n' not in info: # for download CC_n = (1, self.an_cc_bound) else: n = info.get('n','1-10') CC_n = info['CC_n'] if 'CC_n' in info else integer_options(n) # convert CC_n to an interval in [1,an_bound] CC_n = ( max(1, min(CC_n)), min(self.an_cc_bound, max(CC_n)) ) an_keys = (CC_n[0]-1, CC_n[1]) # extra 5 primes in case we hit too many bad primes angles_keys = ( bisect.bisect_left(primes_for_angles, CC_n[0]), min(bisect.bisect_right(primes_for_angles, CC_n[1]) + 5, self.primes_cc_bound) ) an_projection = 'an_normalized[%d:%d]' % an_keys angles_projection = 'angles[%d:%d]' % angles_keys if format in an_formats: cc_proj.append(an_projection) if format in angles_formats: cc_proj.append(angles_projection) cc_data= list(db.mf_hecke_cc.search(query, projection = cc_proj)) if not cc_data: self.has_complex_qexp = False else: self.has_complex_qexp = True self.cc_data = {} for embedded_mf in cc_data: if format in an_formats: an_normalized = embedded_mf.pop(an_projection) # we don't store a_0, thus the +1 embedded_mf['an_normalized'] = {i: [float(x), float(y)] for i, (x, y) in enumerate(an_normalized, an_keys[0] + 1)} if format in angles_formats: embedded_mf['angles'] = {primes_for_angles[i]: theta for i, theta in enumerate(embedded_mf.pop(angles_projection), angles_keys[0])} self.cc_data[embedded_mf.pop('embedding_m')] = embedded_mf if format in analytic_shift_formats: self.analytic_shift = {i : RR(i)**((ZZ(self.weight)-1)/2) for i in self.cc_data.values()[0]['an_normalized'].keys()} if format in angles_formats: self.character_values = defaultdict(list) G = DirichletGroup_conrey(self.level) chars = [DirichletCharacter_conrey(G, char) for char in self.conrey_indexes] for p in self.cc_data.values()[0]['angles'].keys(): if p.divides(self.level): self.character_values[p] = None continue for chi in chars: c = chi.logvalue(p) * self.char_order angle = float(c / self.char_order) value = CDF(0,2*CDF.pi()*angle).exp() self.character_values[p].append((angle, value)) if self.embedding_m is not None: m = self.embedding_m dci = self.cc_data[m].get('dual_conrey_index') dei = self.cc_data[m].get('dual_embedding_index') self.dual_label = "%s.%s" % (dci, dei) x = self.cc_data[m].get('embedding_root_real') y = self.cc_data[m].get('embedding_root_imag') if x is None or y is None: self.embedding_root = None else: self.embedding_root = display_complex(x, y, 6, method='round', try_halfinteger=False)
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 angles_euler_factors(coeffs, level, weight, chi): """ - ``coeffs`` -- a list of Dirichlet coefficients, as elements of CCC - ``level`` -- the level N - ``weight`` -- the weight k - ``chi`` -- the index of the Dirichlet character in the Conrey labeling returns a triple: (angles, euler_factos, bad_euler_factors) """ G = DirichletGroup_conrey(level, CCC) char = DirichletCharacter_conrey(G, chi) euler = [] bad_euler = [] angles = [] for p in prime_range(to_store): b = -coeffs[p] c = 1 if p.divides(level): bad_euler.append([p, [c, b]]) euler.append([c, b]) a = 0 angles.append(None) else: charval = CCC(2 * char.logvalue(int(p))).exppii() if charval.contains_exact(ZZ(1)): charval = 1 elif charval.contains_exact(ZZ(-1)): charval = -1 a = (p**QQ(weight - 1)) * charval euler.append([c, b, a]) # alpha solves T^2 - a_p T + chi(p)*p^(k-1) sqrt_disc = sqrt_hack(b**2 - 4 * a * c) thetas = [] for sign in [1, -1]: alpha = (-b + sign * sqrt_disc) / (2 * c) theta = (arg_hack(alpha) / (2 * CCC.pi().real())).mid() if theta > 0.5: theta -= 1 elif theta <= -0.5: theta += 1 assert theta <= 0.5 and theta > -0.5, "%s %s %s" % ( theta, arg_hack(alpha), alpha) thetas.append(theta) angles.append(float(min(thetas))) if len(coeffs) > p**2: if coeffs[p**2].abs().contains_zero(): match = (coeffs[p**2] - (b**2 - a)).abs().mid() < 1e-5 else: match = ((coeffs[p**2] - (b**2 - a)).abs() / coeffs[p**2].abs()).mid() < 1e-5 if not match: print "coeffs[p**2] doesn't match euler recursion" print zip(range(len(coeffs)), map(CDF, coeffs)) print "(level, weight, chi, p) = %s\n%s != %s\na_p2**2 - (b**2 - a)= %s\n b**2 - a = %s\na_p2 = %s\na=%s\nb = %s\nap = %s" % ( (level, weight, chi, p), CDF(coeffs[p**2]), CDF(b**2 - a), coeffs[p**2] - (b**2 - a), b**2 - a, coeffs[p**2], CDF(a), CDF(b), CDF(coeffs[p])) assert False an_f = [ CBF_to_pair(RRR(n)**(QQ(-(weight - 1)) / 2) * c) for n, c in enumerate(coeffs[:to_store + 1]) ] return an_f, angles, euler, bad_euler
def populate_rational_rows(orbits, euler_factors_cc, rows, instances): rational_rows = {} order_of_vanishing = schema_lf_dict['order_of_vanishing'] accuracy = schema_lf_dict['accuracy'] positive_zeros = schema_lf_dict['positive_zeros'] 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'] positive_zeros = schema_lf_dict['positive_zeros'] leading_term = schema_lf_dict['leading_term'] root_number = schema_lf_dict['root_number'] k = 0 for mf_orbit_label, labels in orbits.iteritems(): try: level, weight, char_orbit, hecke_orbit = mf_orbit_label.split(".") level, weight = map(int, [level, weight]) # read and convert zeros to str # is important to do this before converting them zeros_as_real = [] root_numbers = [] for elt in labels: zeros_factor = rows[elt][positive_zeros] zeros_as_real.extend( zeros_factor ) # and now convert them to strings zeros_factor = [ z.str(truncate=False) for z in zeros_factor] rows[elt][positive_zeros] = str(zeros_factor).replace("'","\"") # same for root numbers root_numbers.append(rows[elt][root_number]) rows[elt][root_number] = rows[elt][root_number].str(style="question").replace('?', '') # for now skip degree > 80 # no more, now the limit is 40 if len(labels) > 20: # the real limit is 87 continue degree = 2*len(labels) row = constant_lf(level, weight, degree) row['origin'] = "ModularForm/GL2/Q/holomorphic/%d/%d/%s/%s" % (level, weight, char_orbit, hecke_orbit) row['self_dual'] = True row['conjugate'] = '\N' row['order_of_vanishing'] = sum([rows[elt][order_of_vanishing] for elt in labels]) row['accuracy'] = min([rows[elt][accuracy] for elt in labels]) 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("'","\"") row['Lhash'] = ",".join(map(str, sorted([int(rows[elt][Lhash]) for elt in labels]))) for i in range(0,3): row['z' + str(i + 1)] = str(zeros_as_real[i]) # character if degree == 2: row['central_character'] = rows[labels[0]][central_character] else: G = DirichletGroup_conrey(level) chiprod = prod([G[ int(rows[elt][central_character].split(".")[-1]) ] for elt in labels]) chiprod_index = chiprod.number() row['central_character'] = "%s.%s" % (level, chiprod_index) row['sign_arg'] = sum([rows[elt][sign_arg] for elt in labels]) while row['sign_arg'] > 0.5: row['sign_arg'] -= 1 while row['sign_arg'] <= -0.5: row['sign_arg'] += 1 deltas = [rows[elt][plot_delta] for elt in labels] values = [rows[elt][plot_values] for elt in labels] row['plot_delta'], row['plot_values'] = prod_plot_values(deltas, values) row['leading_term'] = (prod(toRRR(rows[elt][leading_term], drop=False) for elt in labels)).str(style="question").replace('?', '') try: row['root_number'] = str(RRR(prod(root_numbers).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: assert row['root_number'] in map(str, [1, -1]), "%s" % row['root_number'] except ValueError: # couldn't pin down the unique integer through root_numbers row['root_number'] = str(RRR(CDF(exp(2*pi*I*row['sign_arg'])).real()).unique_integer()) row['coefficient_field'] = '1.1.1.1' euler_factors = [euler_factors_cc[elt] for elt in labels] row['euler_factors'], row['bad_lfactors'], dirichlet = rational_euler_factors(euler_factors, level, weight) # 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[mf_orbit_label] = [row[key] for key in schema_lf] instances[mf_orbit_label] = (row['origin'], row['Lhash'], 'CMF') # if dim == 1, drop row if len(labels) == 1: rows.pop(labels[0]) instances.pop(labels[0]) except Exception: print mf_orbit_label, labels raise k += 1 if len(orbits) > 10: if (k % (len(orbits)//10)) == 0: print "populate_rational_rows %.2f%% done" % (k*100./len(orbits)) print "populate_rational_rows done" return rational_rows
def __repr__(self): return '<ApproxAN: %s>' % CDF(self(100))
def __repr__(self): return '<SetOfAAN: %s>' % [CDF(z) for z in self.f(100)]
def setup_cc_data(self, info): """ INPUT: - ``info`` -- a dictionary with keys - ``m`` -- a string describing the embedding indexes desired - ``n`` -- a string describing the a_n desired - ``CC_m`` -- a list of embedding indexes - ``CC_n`` -- a list of desired a_n - ``format`` -- one of 'embed', 'analytic_embed', 'satake', or 'satake_angle' """ an_formats = ['embed','analytic_embed',None] angles_formats = ['satake','satake_angle',None] m = info.get('m','1-%s'%(min(self.dim,20))) n = info.get('n','1-10') CC_m = info.get('CC_m', integer_options(m)) CC_n = info.get('CC_n', integer_options(n)) # convert CC_n to an interval in [1,an_storage_bound] CC_n = ( max(1, min(CC_n)), min(an_storage_bound, max(CC_n)) ) an_keys = (CC_n[0]-1, CC_n[1]) # extra 5 primes in case we hit too many bad primes angles_keys = (bisect.bisect_left(primes_for_angles, CC_n[0]), bisect.bisect_right(primes_for_angles, CC_n[1]) + 5) format = info.get('format') cc_proj = ['conrey_label','embedding_index','embedding_m','embedding_root_real','embedding_root_imag'] an_projection = 'an[%d:%d]' % an_keys angles_projection = 'angles[%d:%d]' % angles_keys if format in an_formats: cc_proj.append(an_projection) if format in angles_formats: cc_proj.append(angles_projection) query = {'hecke_orbit_code':self.hecke_orbit_code} range_match = INTEGER_RANGE_RE.match(m) if range_match: low, high = int(range_match.group(1)), int(range_match.group(2)) query['embedding_m'] = {'$gte':low, '$lte':high} else: query['embedding_m'] = {'$in': CC_m} cc_data= list(db.mf_hecke_cc.search(query, projection = cc_proj)) if not cc_data: self.has_complex_qexp = False self.cqexp_prec = 0 else: self.has_complex_qexp = True self.cqexp_prec = an_keys[1] + 1 self.cc_data = {} for embedded_mf in cc_data: #as they are stored as a jsonb, large enough elements might be recognized as an integer if format in an_formats: # we don't store a_0, thus the +1 embedded_mf['an'] = {i: [float(x), float(y)] for i, (x, y) in enumerate(embedded_mf.pop(an_projection), an_keys[0] + 1)} if format in angles_formats: embedded_mf['angles'] = {primes_for_angles[i]: theta for i, theta in enumerate(embedded_mf.pop(angles_projection), angles_keys[0])} self.cc_data[embedded_mf.pop('embedding_m')] = embedded_mf if format in ['analytic_embed',None]: self.analytic_shift = {i : float(i)**((1-ZZ(self.weight))/2) for i in self.cc_data.values()[0]['an'].keys()} if format in angles_formats: self.character_values = defaultdict(list) G = DirichletGroup_conrey(self.level) chars = [DirichletCharacter_conrey(G, char) for char in self.char_labels] for p in self.cc_data.values()[0]['angles'].keys(): if p.divides(self.level): continue for chi in chars: c = chi.logvalue(p) * self.char_order angle = float(c / self.char_order) value = CDF(0,2*CDF.pi()*angle).exp() self.character_values[p].append((angle, value))
def analytically_continue(f, gamma, y0): r""" Analytically continues a y-fibre `y0` along the path `gamma`. Parameters ---------- f : complex algebraic curve gamma : parameterized complex path y0 : y-fibre Returns ------- y1 : orded y-fibre above end of gamma """ # first verify that y0 is a y-fibre above x0 x, y = f.parent().gens() x0 = gamma(0) f_x0 = f(x0, y).univariate_polynomial() y0_test = f_x0.roots(ring=CDF, multiplicities=False) phi = matching_permutation(y0, y0_test) # asserts the permutation exists # obtain necessary tools from the curve fx = f.derivative(x) fy = f.derivative(y) ratio = fx / fy a = f.polynomial(y).coefficients(sparse=False) disc = f.discriminant(y).univariate_polynomial() p = a[0] * disc rts = p.roots(CDF, multiplicities=False) # loop T = 0.0 x1 = x0 y1 = y0 while (T < 1.0): epsilon = compute_epsilon(y1) # determine a sufficient value of rho rho = min(abs(x1 - rt) for rt in rts) - 1e-8 # obtain the parameter Y Y = max(ratio(x1, y1j) for y1j in y1) # obtian the parameter M bounds = [ max( abs(coeff) * (abs(x1) + rho)**expon for expon, coeff in ak.dict().iteritems()) for ak in a if ak ] M = max(bounds) # compute the x-step size, delta delta = rho * (sqrt((rho * Y - epsilon)**2 + 4 * epsilon * M) - (rho * Y + epsilon)) delta /= (2 * (M - rho * Y)) delta = abs(delta) # maximize Ts such that |x(T) - X(Ts)| < delta g = lambda Ts: abs(gamma(T) - gamma(Ts)) - delta if (T < 1.0): T = CDF(scipy.optimize.bisect(g, T + 1e-14, 1)) # update # # TODO: this part is still pretty broken x1 = gamma(T) f_x1 = f(x1, y).univariate_polynomial() y1_next = f_x1.roots(ring=CDF, multiplicities=False) phi = matching_permutation(y1, y1_next) y1 = phi.action(y1_next) return y1
g = lambda Ts: abs(gamma(T) - gamma(Ts)) - delta if (T < 1.0): T = CDF(scipy.optimize.bisect(g, T + 1e-14, 1)) # update # # TODO: this part is still pretty broken x1 = gamma(T) f_x1 = f(x1, y).univariate_polynomial() y1_next = f_x1.roots(ring=CDF, multiplicities=False) phi = matching_permutation(y1, y1_next) y1 = phi.action(y1_next) return y1 if __name__ == '__main__': R = QQ['x,y'] x, y = R.gens() f = y**3 - 2 * x**3 * y + x**7 start = CDF(-1) end = CDF(-0.5) gamma = lambda s: start * (1 - s) + end * s y0 = f(start, y).univariate_polynomial().roots(ring=CDF, multiplicities=False) y1 = analytically_continue(f, gamma, y0) print y1
def seriescoeff(coeff, index, seriescoefftype, seriestype, digits): # seriescoefftype can be: series, serieshtml, signed, literal, factor try: if isinstance(coeff, string_types): if coeff == "I": rp = 0 ip = 1 coeff = CDF(I) elif coeff == "-I": rp = 0 ip = -1 coeff = CDF(-I) else: coeff = string2number(coeff) if type(coeff) == complex: rp = coeff.real ip = coeff.imag else: rp = real_part(coeff) ip = imag_part(coeff) except TypeError: # mostly a hack for Dirichlet L-functions if seriescoefftype == "serieshtml": return " +" + coeff + "·" + seriesvar(index, seriestype) else: return coeff ans = "" if seriescoefftype in ["series", "serieshtml", "signed", "factor"]: parenthesis = True else: parenthesis = False coeff_display = display_complex(rp, ip, digits, method="truncate", parenthesis=parenthesis) # deal with the zero case if coeff_display == "0": if seriescoefftype=="literal": return "0" else: return "" if seriescoefftype=="literal": return coeff_display if seriescoefftype == "factor": if coeff_display == "1": return "" elif coeff_display == "-1": return "-" #add signs and fix spacing if seriescoefftype in ["series", "serieshtml"]: if coeff_display == "1": coeff_display = " + " elif coeff_display == "-1": coeff_display = " - " # purely real or complex number that starts with - elif coeff_display[0] == '-': # add spacings around the minus coeff_display = coeff_display.replace('-',' - ') else: ans += " + " elif seriescoefftype == 'signed' and coeff_display[0] != '-': # add the plus without the spaces ans += "+" ans += coeff_display if seriescoefftype == "serieshtml": ans = ans.replace('i',"<em>i</em>").replace('-',"−") if coeff_display[-1] not in [')', ' ']: ans += "·" if seriescoefftype in ["series", "serieshtml", "signed"]: ans += seriesvar(index, seriestype) return ans
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 round_CBF_to_half_int(x): return CDF(tuple(map(round_RBF_to_half_int, [x.real(), x.imag()])))
def make_label(L, normalized=False): GR, GC = L['gamma_factors'] analytic_normalization = 0 if normalized else L['motivic_weight']/2 GR = [CDF(elt) + analytic_normalization for elt in GR] GC = [CDF(elt) + analytic_normalization for elt in GC] b, e = L['conductor'].perfect_power() if e == 1: conductor = b else: conductor = "{}e{}".format(b, e) beginning = "-".join(map(str, [L['degree'], conductor, L['central_character']])) GRcount = Counter(GR) GCcount = Counter(GC) # convert gamma_R to gamma_C zero = LmfdbRealLiteral(RR, '0') one = LmfdbRealLiteral(RR, '1') while GRcount[zero] > 0 and GRcount[one] > 0: GCcount[zero] += 1 GRcount[zero] -= 1 GRcount[one] -= 1 GR = sum([[m]*c for m, c in GRcount.items()], []) GC = sum([[m]*c for m, c in GCcount.items()], []) assert L['degree'] == len(GR) + 2*len(GC) GR.sort(key=CCtuple) GC.sort(key=CCtuple) L["mu_imag"] = [elt.imag() for elt in GR] L["nu_imag"] = [elt.imag() for elt in GC] # deal with real parts GR_real = [elt.real() for elt in GR] GC_real = [elt.real() for elt in GC] L["mu_real"] = [x.round() for x in GR_real] assert set(L["mu_real"]).issubset(set([0,1])) L["nu_real_doubled"] = [(2*x).round() for x in GC_real] GRcount = Counter(GR_real) GCcount = Counter(GC_real) ge = GCD(GCD(list(GRcount.values())), GCD(list(GCcount.values()))) if ge > 1: GR_real = sum(([k]*(v//ge) for k, v in GRcount.items()), []) GC_real = sum(([k]*(v//ge) for k, v in GCcount.items()), []) rs = ''.join(['r%d' % elt.real().round() for elt in GR_real]) cs = ''.join(['c%d' % (elt.real()*2).round() for elt in GC_real]) gammas = "-" + rs + cs if ge > 1: gammas += "e%d" % ge if L['algebraic']: end = "-0" else: end = "-" for G in [GR, GC]: for i, elt in enumerate(G): conjugate = False if elt.imag() <= 0 and i < len(G) - 1 and elt.conjugate() == G[i + 1]: conjugate = True elif elt.imag() >= 0 and i > 0 and elt.conjugate() == G[i - 1]: # we already listed this one as a conjugate continue end += spectral_str(elt.imag(), conjugate=conjugate) L["prelabel"] = beginning + gammas + end return tuple(GR), tuple(GC)