def finite_field(): """ Create a random finite field with degree at most 20 and prime at most 10^6. OUTPUT: a finite field EXAMPLES: sage: sage.rings.tests.finite_field() Finite Field in a of size 161123^4 """ from sage.all import ZZ, GF p = ZZ.random_element(x=2, y=10**6-18).next_prime() d = ZZ.random_element(x=1, y=20) return GF(p**d,'a')
def su2_mu_info(w,n): """ return data for ST group SU(2) x mu(n) (of any wt > 0); these groups are not stored in the database """ assert w > 0 and n > 0 n = ZZ(n) rec = {} rec['label'] = "%d.2.3.c%d"%(w,n) rec['weight'] = w rec['degree'] = 2 rec['rational'] = boolean_name(True if n <= 2 else False) rec['name'] = 'SU(2)[C%d]'%n if n > 1 else 'SU(2)' rec['pretty'] = r'\mathrm{SU}(2)[C_{%d}]'%n if n > 1 else r'\mathrm{SU}(2)' rec['real_dimension'] = 3 rec['components'] = int(n) rec['ambient'] = '\mathrm{U}(2)' rec['connected'] = boolean_name(rec['components'] == 1) rec['st0_name'] = 'SU(2)' rec['identity_component'] = st0_pretty(rec['st0_name']) rec['st0_description'] = r'\left\{\begin{bmatrix}\alpha&\beta\\-\bar\beta&\bar\alpha\end{bmatrix}:\alpha\bar\alpha+\beta\bar\beta = 1,\ \alpha,\beta\in\mathbb{C}\right\}' rec['component_group'] = 'C_{%d}'%n rec['abelian'] = boolean_name(True) rec['cyclic'] = boolean_name(True) rec['solvable'] = boolean_name(True) rec['trace_zero_density']='0' rec['gens'] = r'\begin{bmatrix} 1 & 0 \\ 0 & \zeta_{%d}\end{bmatrix}'%n rec['numgens'] = 1 rec['subgroups'] = comma_separated_list([st_link("%d.2.3.c%d"%(w,n/p)) for p in n.prime_factors()]) rec['supgroups'] = comma_separated_list([st_link("%d.2.3.c%d"%(w,p*n)) for p in [2,3,5]] + ["$\ldots$"]) rec['moments'] = [['x'] + [ '\\mathrm{E}[x^{%d}]'%m for m in range(13)]] su2moments = ['1','0','1','0','2','0','5','0','14','0','42','0','132'] rec['moments'] += [['a_1'] + [su2moments[m] if m % n == 0 else '0' for m in range(13)]] rec['trace_moments'] = trace_moments(rec['moments']) rec['counts'] = [] return rec
def niceideals(F, ideals): #HNF + sage ideal + label """Convert a list of ideas from strongs to actual NumberField ideals F is a Sage NumberField ideals is a list of strings representing ideals I in the field, of the form [N,a,alpha] where N is the norm of I, a the least positive integer in I, and alpha a field element such that I is generated by a and alpha. The output is a list """ nideals = [] ilabel = 1 norm = ZZ(0) for i in range(len(ideals)): N,n,idl,_ = str2ideal(F,ideals[i]) assert idl.norm() == N and idl.smallest_integer() == n if N != norm: ilabel = ZZ(1) norm = N label = N.str() + '.' + ilabel.str() hnf = idl.pari_hnf().python() nideals.append([hnf, idl, label]) ilabel += 1 return nideals
def nu1_mu_info(w,n): """ return data for ST group N(U(1)) x mu(n) (of any wt > 0); these groups are not stored in the database """ assert w > 0 and n > 0 n = ZZ(n) rec = {} rec['label'] = "%d.2.1.d%d"%(w,n) rec['weight'] = w rec['degree'] = 2 rec['rational'] = boolean_name(True if n <= 2 else False) rec['name'] = 'U(1)[D%d]'%n if n > 1 else 'N(U(1))' rec['pretty'] = r'\mathrm{U}(1)[D_{%d}]'%n if n > 1 else r'N(\mathrm{U}(1))' rec['real_dimension'] = 1 rec['components'] = int(2*n) rec['ambient'] = '\mathrm{U}(2)' rec['connected'] = boolean_name(rec['components'] == 1) rec['st0_name'] = 'U(1)' rec['identity_component'] = st0_pretty(rec['st0_name']) rec['st0_description'] = '\\left\\{\\begin{bmatrix}\\alpha&0\\\\0&\\bar\\alpha\\end{bmatrix}:\\alpha\\bar\\alpha = 1,\\ \\alpha\\in\\mathbb{C}\\right\\}' rec['component_group'] = 'D_{%d}'%n rec['abelian'] = boolean_name(n <= 2) rec['cyclic'] = boolean_name(n <= 1) rec['solvable'] = boolean_name(True) rec['trace_zero_density']='1/2' rec['gens'] = r'\left\{\begin{bmatrix} 0 & 1\\ -1 & 0\end{bmatrix}, \begin{bmatrix} 1 & 0 \\ 0 & \zeta_{%d}\end{bmatrix}\right\}'%n rec['numgens'] = 2 rec['subgroups'] = comma_separated_list([st_link("%d.2.1.d%d"%(w,n/p)) for p in n.prime_factors()]) rec['supgroups'] = comma_separated_list([st_link("%d.2.1.d%d"%(w,p*n)) for p in [2,3,5]] + ["$\ldots$"]) rec['moments'] = [['x'] + [ '\\mathrm{E}[x^{%d}]'%m for m in range(13)]] nu1moments = ['1','0','1','0','3','0','10','0','35','0','126','0','462'] rec['moments'] += [['a_1'] + [nu1moments[m] if m % n == 0 else '0' for m in range(13)]] rec['trace_moments'] = trace_moments(rec['moments']) rec['counts'] = [['a_1', [[0,n]]]] return rec
def aplist(E, B=100): """ Compute aplist for an elliptic curve E over Q(sqrt(5)), as a string->number dictionary. INPUT: - E -- an elliptic curve - B -- a positive integer (default: 100) OUTPUT: - dictionary mapping strings (labeled primes) to Python ints, with keys the primes of P with norm up to B such that the norm of the conductor is coprime to the characteristic of P. """ from psage.modform.hilbert.sqrt5.tables import canonical_gen v = {} from psage.modform.hilbert.sqrt5.sqrt5 import F labels, primes = labeled_primes_of_bounded_norm(F, B) from sage.all import ZZ N = E.conductor() try: N = ZZ(N.norm()) except: N = ZZ(N) for i in range(len(primes)): p = primes[i] k = p.residue_field() if N.gcd(k.cardinality()) == 1: v[labels[i]] = int(k.cardinality() + 1 - E.change_ring(k).cardinality()) return v
def randomize(self, prime): assert not self.randomized prev = None for i in xrange(0, len(self.bp)): d_i_minus_one = self.bp[i].zero.nrows() d_i = self.bp[i].zero.ncols() MSZp = MatrixSpace(ZZ.residue_field(ZZ.ideal(prime)), d_i_minus_one, d_i) MSZp_square = MatrixSpace(ZZ.residue_field(ZZ.ideal(prime)), d_i, d_i) if i != 0: MSZp = MatrixSpace(ZZ.residue_field(ZZ.ideal(prime)), d_i_minus_one, d_i) self.bp[i] = self.bp[i].group(MSZp, prime).mult_left(prev.adjoint()) if i != len(self.bp) - 1: cur = MSZp_square.random_element() self.bp[i] = self.bp[i].group(MSZp, prime).mult_right(cur) prev = cur # compute S * B_0 d_0 = self.bp[0].zero.nrows() d_1 = self.bp[0].zero.ncols() S = matrix.identity(d_0) for i in xrange(d_0): S[i, i] = random.randint(0, prime - 1) MSZp = MatrixSpace(ZZ.residue_field(ZZ.ideal(prime)), d_0, d_1) self.bp[0] = self.bp[0].group(MSZp, prime).mult_left(S) # compute B_ell * T r = self.bp[-1].zero.nrows() c = self.bp[-1].zero.ncols() T = matrix.identity(c) for i in xrange(c): T[i, i] = random.randint(0, prime - 1) MSZp = MatrixSpace(ZZ.residue_field(ZZ.ideal(prime)), r, c) self.bp[-1] = self.bp[-1].group(MSZp, prime).mult_right(T) self.randomized = True
def factor_out_p(val, p): val = ZZ(val) if val == 0 or val == -1: return str(val) if val==1: return '+1' s = 1 if val<0: s = -1 val = -val ord = val.valuation(p) val = val/p**ord out = '' if s == -1: out += '-' else: out += '+' if ord==1: out += str(p) elif ord>1: out += '%d^{%d}' % (p, ord) if val>1: if ord ==1: out += r'\cdot ' out += str(val) return out
def nextchr(c): s = ord('a') - 1 # really 96 l = [ZZ(ord(j) - s) for j in list(c)] l.reverse() tot = ZZ(l, 27) + 1 newl = tot.digits(27) newl.reverse() newl = map(lambda x: x + 1 if x == 0 else x, newl) return ''.join([chr(j + s) for j in newl])
def render_hgm_webpage(args): data = None info = {} if 'label' in args: label = clean_input(args['label']) C = base.getDBConnection() data = C.hgm.motives.find_one({'label': label}) if data is None: bread = get_bread([("Search error", url_for('.search'))]) info['err'] = "Motive " + label + " was not found in the database." info['label'] = label return search_input_error(info, bread) title = 'Hypergeometric Motive:' + label A = data['A'] B = data['B'] tn,td = data['t'] t = latex(QQ(str(tn)+'/'+str(td))) primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71] locinfo = data['locinfo'] for j in range(len(locinfo)): locinfo[j] = [primes[j]] + locinfo[j] locinfo[j][2] = poly_with_factored_coeffs(locinfo[j][2], primes[j]) hodge = data['hodge'] prop2 = [ ('Degree', '\(%s\)' % data['degree']), ('Weight', '\(%s\)' % data['weight']), ('Conductor', '\(%s\)' % data['cond']), ] # Now add factorization of conductor Cond = ZZ(data['cond']) if not (Cond.abs().is_prime() or Cond == 1): data['cond'] = "%s=%s" % (str(Cond), factorint(data['cond'])) info.update({ 'A': A, 'B': B, 't': t, 'degree': data['degree'], 'weight': data['weight'], 'sign': data['sign'], 'sig': data['sig'], 'hodge': hodge, 'cond': data['cond'], 'req': data['req'], 'locinfo': locinfo }) AB_data, t_data = data["label"].split("_t") #AB_data = data["label"].split("_t")[0] friends = [("Motive family "+AB_data.replace("_"," "), url_for(".by_family_label", label = AB_data))] friends.append(('L-function', url_for("l_functions.l_function_hgm_page", label=AB_data, t='t'+t_data))) # if rffriend != '': # friends.append(('Discriminant root field', rffriend)) bread = get_bread([(label, ' ')]) return render_template("hgm-show-motive.html", credit=HGM_credit, title=title, bread=bread, info=info, properties2=prop2, friends=friends)
def _i_func(q): '''Return i(B) in Katsurada's paper. ''' m = ZZ(2) * (q.matrix()) ** (-1) i = valuation(gcd(m.list()), ZZ(2)) m = ZZ(2) ** (-i) * m if all(m[a, a] % 2 == 0 for a in range(m.ncols())): return - i - 1 else: return - i
def read_line(line, debug=0): r""" Parses one line from input file. Returns and a dict containing fields with keys as above. Sample line: 11 a 1 0,-1,1,-10,-20 7 1,0 0,1,0 0,0 0,1 Fields: label (3 fields) a-invariants p0 For each bad prime: 'a' if additive lambda,mu if multiplicative (or 'o?' if unknown) For each good prime: lambda,mu if ordinary (or 'o?' if unknown) lambda+,lambda-,mu if supersingular (or 's?' if unknown) """ data = {} if debug: print("Parsing input line {}".format(line[:-1])) fields = line.split() label = fields[0]+fields[1]+fields[2] data['label'] = label N = ZZ(fields[0]) badp = N.support() nbadp = len(badp) p0 = int(fields[4]) data['iwp0'] = p0 if debug: print("p0={}".format(p0)) iwdata = {} # read data for bad primes for p,pdat in zip(badp,fields[5:5+nbadp]): p = str(p) if debug>1: print("p={}, pdat={}".format(p,pdat)) if pdat in ['o?','a']: iwdata[p]=pdat else: iwdata[p]=[int(x) for x in pdat.split(",")] # read data for all primes for p,pdat in zip(primes(1000),fields[5+nbadp:]): p = str(p) if debug>1: print("p={}, pdat={}".format(p,pdat)) if pdat in ['s?','o?','a']: iwdata[p]=pdat else: iwdata[p]=[int(x) for x in pdat.split(",")] data['iwdata'] = iwdata if debug: print("label {}, data {}".format(label,data)) return label, data
def includes_composite(s): s = s.replace(" ", "").replace("..", "-") for interval in s.split(","): if "-" in interval[1:]: ix = interval.index("-", 1) a, b = int(interval[:ix]), int(interval[ix + 1 :]) if b == a: if a != 1 and not a.is_prime(): return True if b > a and b > 3: return True else: a = ZZ(interval) if a != 1 and not a.is_prime(): return True
def rsa(bits): # only prove correctness up to 1024bits proof = (bits <= 1024) p = next_prime(ZZ.random_element(2**(bits // 2 + 1)), proof=proof) q = next_prime(ZZ.random_element(2**(bits // 2 + 1)), proof=proof) n = p * q phi_n = (p - 1) * (q - 1) while True: e = ZZ.random_element(1, phi_n) if gcd(e, phi_n) == 1: break d = lift(Mod(e, phi_n)**(-1)) return e, d, n
def includes_composite(s): s = s.replace(' ','').replace('..','-') for interval in s.split(','): if '-' in interval[1:]: ix = interval.index('-',1) a,b = int(interval[:ix]), int(interval[ix+1:]) if b == a: if a != 1 and not a.is_prime(): return True if b > a and b > 3: return True else: a = ZZ(interval) if a != 1 and not a.is_prime(): return True
def random_element(self, x=None, y=None, distribution=None): """ Return a random integer in Pari. NOTE: The given arguments are passed to ``ZZ.random_element(...)``. INPUT: - `x`, `y` -- optional integers, that are lower and upper bound for the result. If only `x` is provided, then the result is between 0 and `x-1`, inclusive. If both are provided, then the result is between `x` and `y-1`, inclusive. - `distribution` -- optional string, so that ``ZZ`` can make sense of it as a probability distribution. EXAMPLE:: sage: R = PariRing() sage: R.random_element() -8 sage: R.random_element(5,13) 12 sage: [R.random_element(distribution="1/n") for _ in range(10)] [0, 1, -1, 2, 1, -95, -1, -2, -12, 0] """ from sage.all import ZZ return self(ZZ.random_element(x,y,distribution))
def relative_number_field(n=2, maxdeg=2): """ Return a tower of at most n extensions each of degree at most maxdeg. EXAMPLES: sage: sage.rings.tests.relative_number_field(3) Number Field in aaa with defining polynomial x^2 - 15*x + 17 over its base field """ from sage.all import ZZ K = absolute_number_field(maxdeg) n -= 1 var = 'aa' R = ZZ['x'] while n >= 1: while True: f = R.random_element(degree=ZZ.random_element(x=1,y=maxdeg),x=-100,y=100) if f.degree() <= 0: continue f = f * f.denominator() # bug trac #4781 f = f + R.gen()**maxdeg # make monic if f.is_irreducible(): break K = K.extension(f,var) var += 'a' n -= 1 return K
def rings1(): """ Return an iterator over random rings. Return a list of pairs (f, desc), where f is a function that outputs a random ring that takes a ring and possibly some other data as constructor. RINGS:: - polynomial ring in one variable over a rings0() ring. - polynomial ring over a rings1() ring. - multivariate polynomials EXAMPLES:: sage: import sage.rings.tests sage: type(sage.rings.tests.rings0()) <type 'list'> """ v = rings0() X = random_rings(level=0) from sage.all import PolynomialRing, ZZ v = [(lambda : PolynomialRing(next(X), names='x'), 'univariate polynomial ring over level 0 ring'), (lambda : PolynomialRing(next(X), abs(ZZ.random_element(x=2,y=10)), names='x'), 'multivariate polynomial ring in between 2 and 10 variables over a level 0 ring')] return v
def allbsd(line): r""" Parses one line from an allbsd file. Returns the label and a dict containing fields with keys 'conductor', 'iso', 'number', 'ainvs', 'rank', 'torsion', 'torsion_primes', 'tamagawa_product', 'real_period', 'special_value', 'regulator', 'sha_an', 'sha', 'sha_primes', all values being strings or floats or ints or lists of ints. Input line fields: conductor iso number ainvs rank torsion tamagawa_product real_period special_value regulator sha_an Sample input line: 11 a 1 [0,-1,1,-10,-20] 0 5 5 1.2692093042795534217 0.25384186085591068434 1 1.00000000000000000000 """ data = split(line) label = data[0] + data[1] + data[2] ainvs = parse_ainvs(data[3]) torsion = ZZ(data[5]) sha_an = RR(data[10]) sha = sha_an.round() sha_primes = sha.prime_divisors() torsion_primes = torsion.prime_divisors() data = { 'conductor': int(data[0]), 'iso': data[0] + data[1], 'number': int(data[2]), 'ainvs': ainvs, 'rank': int(data[4]), 'tamagawa_product': int(data[6]), 'real_period': float(data[7]), 'special_value': float(data[8]), 'regulator': float(data[9]), 'sha_an': float(sha_an), 'sha': int(sha), 'sha_primes': [int(p) for p in sha_primes], 'torsion': int(torsion), 'torsion_primes': [int(p) for p in torsion_primes] } return label, data
def init_dir_char(self, chi): """ Initiate with a Web Dirichlet character. """ self.original_object = [chi] chi = chi.chi.primitive_character() self.object_type = "dirichletcharacter" self.dim = 1 self.motivic_weight = 0 self.conductor = ZZ(chi.conductor()) self.bad_semistable_primes = [] self.bad_pot_good = self.conductor.prime_factors() if chi.is_odd(): aa = 1 bb = I else: aa = 0 bb = 1 self.sign = chi.gauss_sum_numerical() / (bb * float(sqrt(chi.modulus())) ) # this has now type python complex. later we need a gp complex self.sign = ComplexField()(self.sign) self.mu_fe = [aa] self.nu_fe = [] self.gammaV = [aa] self.langlands = True self.selfdual = (chi.multiplicative_order() <= 2) # rather than all( abs(chi(m).imag) < 0.0001 for m in range(chi.modulus() ) ) self.primitive = True self.set_dokchitser_Lfunction() self.set_number_of_coefficients() self.dirichlet_coefficients = [ chi(m) for m in range(self.numcoeff + 1) ] if self.selfdual: self.coefficient_type = 2 else: self.coefficient_type = 3 self.coefficient_period = chi.modulus() self.besancon_bound = 10000 def eu(p): """ local euler factor """ if self.selfdual: K = QQ else: K = ComplexField() R = PolynomialRing(K, "T") T = R.gens()[0] if self.conductor % p != 0: return 1 - ComplexField()(chi(p)) * T else: return R(1) self.local_euler_factor = eu self.ld.gp().quit()
def twoadic(line): r""" Parses one line from a 2adic file. Returns the label and a dict containing fields with keys '2adic_index', '2adic_log_level', '2adic_gens' and '2adic_label'. Input line fields: conductor iso number ainvs index level gens label Sample input lines: 110005 a 2 [1,-1,1,-185793,29503856] 12 4 [[3,0,0,1],[3,2,2,3],[3,0,0,3]] X24 27 a 1 [0,0,1,0,-7] inf inf [] CM """ data = split(line) assert len(data)==8 label = data[0] + data[1] + data[2] model = data[7] if model == 'CM': return label, { '2adic_index': int(0), '2adic_log_level': None, '2adic_gens': None, '2adic_label': None, } index = int(data[4]) level = ZZ(data[5]) log_level = int(level.valuation(2)) assert 2**log_level==level if data[6]=='[]': gens=[] else: gens = data[6][1:-1].replace('],[','];[').split(';') gens = [[int(c) for c in g[1:-1].split(',')] for g in gens] return label, { '2adic_index': index, '2adic_log_level': log_level, '2adic_gens': gens, '2adic_label': model, }
def integer_mod_ring(): """ Return a random ring of integers modulo n with n at most 50000. EXAMPLES: sage: sage.rings.tests.integer_mod_ring() Ring of integers modulo 30029 """ from sage.all import ZZ, IntegerModRing n = ZZ.random_element(x=2,y=50000) return IntegerModRing(n)
def quadratic_number_field(): """ Return a quadratic extension of QQ. EXAMPLES: sage: sage.rings.tests.quadratic_number_field() Number Field in a with defining polynomial x^2 - 61099 """ from sage.all import ZZ, QuadraticField while True: d = ZZ.random_element(x=-10**5, y=10**5) if not d.is_square(): return QuadraticField(d,'a')
def randomize(self, prime): assert not self.randomized MSZp = MatrixSpace(ZZ.residue_field(ZZ.ideal(prime)), self.size) def random_matrix(): while True: m = MSZp.random_element() if not m.is_singular() and m.rank() == self.size: return m, m.inverse() m0, m0i = random_matrix() self.bp[0] = self.bp[0].group(MSZp, prime).mult_left(m0) for i in xrange(1, len(self.bp)): mi, mii = random_matrix() self.bp[i-1] = self.bp[i-1].group(MSZp, prime).mult_right(mii) self.bp[i] = self.bp[i].group(MSZp, prime).mult_left(mi) self.bp[-1] = self.bp[-1].group(MSZp, prime).mult_right(m0i) VSZp = VectorSpace(ZZ.residue_field(ZZ.ideal(prime)), self.size) self.s = copy(VSZp.zero()) self.s[0] = 1 self.t = copy(VSZp.zero()) self.t[len(self.t) - 1] = 1 self.m0, self.m0i = m0, m0i self.randomized = True
def get_cusp_expansions_of_newform(k, N=1, fi=0, prec=10): r""" Get and return Fourier coefficients of all cusps where there exist Atkin-Lehner involutions for these cusps. INPUT: - ''k'' -- positive integer : the weight - ''N'' -- positive integer (default 1) : level - ''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) OUTPUT: - ''s'' string giving the Atkin-Lehner eigenvalues corresponding to the Cusps (where possible) """ res = dict() (t, f) = _get_newform(k, N, 0, fi) if(not t): return s res[Infinity] = 1 for c in f.group().cusps(): if(c == Cusp(Infinity)): continue res[c] = list() cusp = QQ(c) q = cusp.denominator() p = cusp.numerator() d = ZZ(cusp * N) if(d == 0): ep = f.atkin_lehner_eigenvalue() if(d.divides(N) and gcd(ZZ(N / d), ZZ(d)) == 1): ep = f.atkin_lehner_eigenvalue(ZZ(d)) else: # this case is not known... res[c] = None continue res[c] = ep s = html.table([res.keys(), res.values()]) return s
def test_eigenvalues(prec=100,nmax=10,dimmax=10): r""" Test the eigenvalue computations for some random matrices. """ F = MPComplexField(prec) dim = ZZ.random_element(2,dimmax) M = MatrixSpace(F,dim) for n in range(nmax): A,U,l=random_matrix_eigenvalues(F,dim) ev = A.eigenvalues() ev.sort(); l.sort() test = max([abs(ev[j]-l[j]) for j in range(len(ev))]) assert test < A.eps()*100
def prime_finite_field(): """ Create a random prime finite field with cardinality at most 10^20. OUTPUT: a prime finite field EXAMPLES: sage: sage.rings.tests.prime_finite_field() Finite Field of size 64748301524082521489 """ from sage.all import ZZ, GF return GF(ZZ.random_element(x=2, y=10**20 - 12).next_prime())
def init_elliptic_modular_form(self, F, number): """ Initiate with an Elliptic Modular Form. """ self.number = number self.original_object = [[F,number]] self.object_type = "Elliptic Modular newform" self.dim = 2 self.weight = ZZ(F.weight) self.motivic_weight = ZZ(F.weight) - 1 self.conductor = ZZ(F.level) self.bad_semistable_primes = [fa[0] for fa in self.conductor.factor() if fa[1]==1 ] # should be including primes of bad red that are pot good # however I don't know how to recognise them self.bad_pot_good = [] self.langlands = True self.mu_fe = [] self.nu_fe = [ZZ(F.weight-1)/ZZ(2)] self.primitive = True self.selfdual = True self.coefficient_type = 2 self.coefficient_period = 0 self.sign = (-1) ** (self.weight / 2.) if self.conductor != 1: for p, ev in F.atkin_lehner_eigenvals: self.sign *= ev**(self.conductor.valuation(p)) self.gammaV = [0,1] self.set_dokchitser_Lfunction() self.set_number_of_coefficients() self.besancon_bound = 300 def eu(p): """ Local euler factor """ # There was no function q_expansion_embeddings before the transition to postgres # so I'm not sure what this is supposed to do. ans = F.q_expansion_embeddings(p + 1) K = ComplexField() R = PolynomialRing(K, "T") T = R.gens()[0] N = self.conductor if N % p != 0 : # good reduction return 1 - ans[p-1][self.number] * T + T**2 elif N % (p**2) != 0: # semistable reduction return 1 - ans[p-1][self.number] * T else: return R(1) self.local_euler_factor = eu self.ld.gp().quit()
def _iter_ideals(self, primes=False, number=None): """ Iterator through all ideals of self. Delivers dicts with keys 'label' and 'ideal'. """ count = 0 ilabel = 1 norm = ZZ(0) ideals = self.ideals if primes: ideals = self.primes for idlstr in ideals: N,n,idl,_ = str2ideal(self.K(),idlstr) assert idl.norm() == N and idl.smallest_integer() == n if N != norm: ilabel = ZZ(1) norm = N label = N.str() + '.' + ilabel.str() yield {'label':label, 'ideal':idl} ilabel += 1 count += 1 if count==number: raise StopIteration
def mu_info(n): """ return data for ST group mu(n); for n > 2 these groups are irrational and not stored in the database """ n = ZZ(n) rec = {} rec['label'] = "0.1.%d"%n rec['weight'] = 0 rec['degree'] = 1 rec['rational'] = boolean_name(True if n <= 2 else False) rec['name'] = 'mu(%d)'%n rec['pretty'] = '\mu(%d)'%n rec['real_dimension'] = 0 rec['components'] = int(n) rec['ambient'] = '\mathrm{O}(1)' if n <= 2 else '\mathrm{U}(1)' rec['connected'] = boolean_name(rec['components'] == 1) rec['st0_name'] = '\mathrm{SO}(1)' rec['identity_component'] = st0_pretty(rec['st0_name']) rec['st0_description'] = '\\mathrm{trivial}' rec['component_group'] = 'C_{%d}'%n rec['trace_zero_density']='0' rec['abelian'] = boolean_name(True) rec['cyclic'] = boolean_name(True) rec['solvable'] = boolean_name(True) rec['gens'] = r'\left[\zeta_{%d}\right]'%n rec['numgens'] = 1 rec['subgroups'] = comma_separated_list([st_link("0.1.%d"%(n/p)) for p in n.prime_factors()]) # only list supgroups with the same ambient (i.e.if mu(n) lies in O(1) don't list supgroups that are not) if n == 1: rec['supgroups'] = st_link("0.1.2") elif n > 2: rec['supgroups'] = comma_separated_list([st_link("0.1.%d"%(p*n)) for p in [2,3,5]] + ["$\ldots$"]) rec['moments'] = [['x'] + [ '\\mathrm{E}[x^{%d}]'%m for m in range(13)]] rec['moments'] += [['a_1'] + ['1' if m % n == 0 else '0' for m in range(13)]] rec['trace_moments'] = trace_moments(rec['moments']) rational_traces = [1] if n%2 else [1,-1] rec['counts'] = [['a_1', [[t,1] for t in rational_traces]]] rec['probabilities'] = [['\\mathrm{P}[a_1=%d]=\\frac{1}{%d}'%(m,n)] for m in rational_traces] return rec
def add_sha_tor_primes(N1,N2): """ Add the 'sha', 'sha_primes', 'torsion_primes' fields to every curve in the database whose conductor is between N1 and N2 inclusive. """ query = {} query['conductor'] = { '$gte': int(N1), '$lte': int(N2) } res = curves.find(query) res = res.sort([('conductor', pymongo.ASCENDING)]) n = 0 for C in res: label = C['lmfdb_label'] if n%1000==0: print label n += 1 torsion = ZZ(C['torsion']) sha = RR(C['sha_an']).round() sha_primes = sha.prime_divisors() torsion_primes = torsion.prime_divisors() data = {} data['sha'] = int(sha) data['sha_primes'] = [int(p) for p in sha_primes] data['torsion_primes'] = [int(p) for p in torsion_primes] curves.update({'lmfdb_label': label}, {"$set": data}, upsert=True)
except Exception as e: print(self.client_address[0], e) # logging self.wfile.write(str(e).encode() + b'\n') return # the signature is valid -> looks like the backdoor does exist! self.wfile.write(flag + b'\n') # logging print(self.client_address[0], "got FLAG!") if __name__ == "__main__": from yaecc_secret import a, A, flag assert ZZ(a) * G == A with open("public_key.txt", "w") as f: f.write(str(A)) HOST, PORT = "0.0.0.0", 5555 # maybe updated server = socketserver.ForkingTCPServer((HOST, PORT), Handler, False) server.allow_reuse_address = True server.server_bind() server.server_activate() def timeout_handler(_, __): raise TimeoutError("Timeout!") signal.signal(signal.SIGALRM, timeout_handler) print("Serving at", HOST, PORT)
def factorint(inp): return latex(ZZ(inp).factor())
def ideal_from_label(K, lab): r"""Returns the ideal with label lab in the quadratic field K. """ N, c, d = [ZZ(c) for c in lab.split(".")] a = N // d return K.ideal(a, K([c, d]))
def read_line(line): r""" Parses one line from input file. Returns the hash and a dict containing fields with keys as above. """ fields = line.split(":") assert len(fields) == 6 label = fields[ 1] # use this isogeny class label to get info about the curve E = curves.find_one({'iso': label}) data = constant_data() instances = {} # Set the fields in the Instances collection: cond = data['conductor'] = int(E['conductor']) iso = E['lmfdb_iso'].split('.')[1] instances['url'] = 'EllipticCurve/Q/%s/%s' % (cond, iso) instances['Lhash'] = Lhash = fields[0] instances['type'] = 'ECQ' # Set the fields in the Lfunctions collection: data['Lhash'] = Lhash data['root_number'] = int(fields[2]) data['order_of_vanishing'] = int(E['rank']) data['central_character'] = '%s.1' % cond data['st_group'] = 'N(U(1))' if E['cm'] else 'SU(2)' data['leading_term'] = float(E['special_value']) # Zeros zeros = fields[4][1:-1].split(",") # omit negative ones and 0, using only string tests: data['positive_zeros'] = [y for y in zeros if y != '0' and y[0] != '-'] data['z1'] = data['positive_zeros'][0] data['z2'] = data['positive_zeros'][1] data['z3'] = data['positive_zeros'][2] # plot data plot_xy = [[float(v) for v in vv.split(",")] for vv in fields[5][2:-3].split("],[")] # constant difference in x-coordinate sequence: data['plot_delta'] = plot_xy[1][0] - plot_xy[0][0] # list of y coordinates for x>0: data['plot_values'] = [y for x, y in plot_xy if x >= 0] # Euler factors: we need the ap which are currently not in the # database so we call Sage. It might be a good idea to store in # the ec database (1) all ap for p<100; (2) all ap for bad p. Esage = EllipticCurve([ZZ(a) for a in E['ainvs']]) data['bad_lfactors'] = make_bad_lfactors(Esage) data['euler_factors'] = make_euler_factors(Esage) # Dirichlet coefficients an = Esage.anlist(10) for n in range(2, 11): data['A%s' % n] = str(an[n]) data['a%s' % n] = [an[n] / sqrt(float(n)), 0] return Lhash, data, instances
def make_conductor(ecnfdata, hfield): N, c, d = [ZZ(c) for c in ecnfdata['conductor_ideal'][1:-1].split(',')] return hfield.K().ideal([N // d, c + d * hfield.K().gen()])
def render_group_webpage(args): data = {} if 'label' in args: label = clean_input(args['label']) label = label.replace('t', 'T') data = db.gps_transitive.lookup(label) if data is None: if re.match(r'^\d+T\d+$', label): flash_error("Group %s was not found in the database.", label) else: flash_error("%s is not a valid label for a Galois group.", label) return redirect(url_for(".index")) data['label_raw'] = label.lower() title = 'Galois Group: ' + label wgg = WebGaloisGroup.from_nt(data['n'], data['t']) data['wgg'] = wgg n = data['n'] t = data['t'] data['yesno'] = yesno order = data['order'] data['orderfac'] = latex(ZZ(order).factor()) orderfac = latex(ZZ(order).factor()) data['ordermsg'] = "$%s=%s$" % (order, latex(orderfac)) if order == 1: data['ordermsg'] = "$1$" if ZZ(order).is_prime(): data['ordermsg'] = "$%s$ (is prime)" % order pgroup = len(ZZ(order).prime_factors()) < 2 if wgg.num_conjclasses() < 50: data['cclasses'] = wgg.conjclasses() if ZZ(order) < ZZ(10000000) and wgg.num_conjclasses() < 21: data['chartable'] = chartable(n, t) data['gens'] = wgg.generator_string() if n == 1 and t == 1: data['gens'] = 'None needed' data['num_cc'] = comma(wgg.num_conjclasses()) data['parity'] = "$%s$" % data['parity'] data['subinfo'] = subfield_display(n, data['subfields']) data['resolve'] = resolve_display(data['quotients']) if data['gapid'] == 0: data['gapid'] = "Data not available" else: data['gapid'] = small_group_display_knowl( int(data['order']), int(data['gapid']), str([int(data['order']), int(data['gapid'])])) data['otherreps'] = wgg.otherrep_list() ae = data['arith_equiv'] if ae > 0: if ae > 1: data[ 'arith_equiv'] = r'A number field with this Galois group has %d <a knowl="nf.arithmetically_equivalent", title="arithmetically equivalent">arithmetically equivalent</a> fields.' % ae else: data[ 'arith_equiv'] = r'A number field with this Galois group has exactly one <a knowl="nf.arithmetically_equivalent", title="arithmetically equivalent">arithmetically equivalent</a> field.' elif ae > -1: data[ 'arith_equiv'] = r'A number field with this Galois group has no <a knowl="nf.arithmetically_equivalent", title="arithmetically equivalent">arithmetically equivalent</a> fields.' else: data[ 'arith_equiv'] = r'Data on whether or not a number field with this Galois group has <a knowl="nf.arithmetically_equivalent", title="arithmetically equivalent">arithmetically equivalent</a> fields has not been computed.' intreps = list(db.gps_gmodules.search({'n': n, 't': t})) if len(intreps) > 0: data['int_rep_classes'] = [str(z[0]) for z in intreps[0]['gens']] for onerep in intreps: onerep['gens'] = [ list_to_latex_matrix(z[1]) for z in onerep['gens'] ] data['int_reps'] = intreps data['int_reps_complete'] = int_reps_are_complete(intreps) dcq = data['moddecompuniq'] if dcq[0] == 0: data['decompunique'] = 0 else: data['decompunique'] = dcq[0] data['isoms'] = [[mult2mult(z[0]), mult2mult(z[1])] for z in dcq[1]] data['isoms'] = [[ modules2string(n, t, z[0]), modules2string(n, t, z[1]) ] for z in data['isoms']] #print dcq[1] #print data['isoms'] friends = [] if db.nf_fields.exists({'degree': n, 'galt': t}): friends.append( ('Number fields with this Galois group', url_for('number_fields.number_field_render_webpage') + "?galois_group=%dT%d" % (n, t))) prop2 = [ ('Label', label), ('Order', r'\(%s\)' % order), ('n', r'\(%s\)' % data['n']), ('Cyclic', yesno(data['cyc'])), ('Abelian', yesno(data['ab'])), ('Solvable', yesno(data['solv'])), ('Primitive', yesno(data['prim'])), ('$p$-group', yesno(pgroup)), ] pretty = group_display_short(n, t, emptyifnotpretty=True) if len(pretty) > 0: prop2.extend([('Group:', pretty)]) data['pretty_name'] = pretty data['name'] = re.sub(r'_(\d+)', r'_{\1}', data['name']) data['name'] = re.sub(r'\^(\d+)', r'^{\1}', data['name']) data['nilpotency'] = '$%s$' % data['nilpotency'] if data['nilpotency'] == '$-1$': data['nilpotency'] += ' (not nilpotent)' bread = get_bread([(label, ' ')]) return render_template("gg-show-group.html", credit=GG_credit, title=title, bread=bread, info=data, properties=prop2, friends=friends, KNOWL_ID="gg.%s" % data['label_raw'], learnmore=learnmore_list())
def make_order_key(order): order1 = int(ZZ(order).log(10)) return '%03d%s' % (order1, str(order))
def set_info_for_web_newform(level=None, weight=None, character=None, label=None, **kwds): r""" Set the info for on modular form. """ info = to_dict(kwds) info['level'] = level info['weight'] = weight info['character'] = character info['label'] = label if level is None or weight is None or character is None or label is None: s = "In set info for one form but do not have enough args!" s += "level={0},weight={1},character={2},label={3}".format( level, weight, character, label) emf_logger.critical(s) emf_logger.debug("In set_info_for_one_mf: info={0}".format(info)) prec = my_get(info, 'prec', default_prec, int) bprec = my_get(info, 'bprec', default_display_bprec, int) emf_logger.debug("PREC: {0}".format(prec)) emf_logger.debug("BITPREC: {0}".format(bprec)) try: WNF = WebNewForm_cached(level=level, weight=weight, character=character, label=label) if not WNF.has_updated(): raise IndexError( "Unfortunately, we do not have this newform in the database.") info['character_order'] = WNF.character.order info['code'] = WNF.code emf_logger.debug("defined webnewform for rendering!") except IndexError as e: info['error'] = e.message url1 = url_for("emf.render_elliptic_modular_forms") url2 = url_for("emf.render_elliptic_modular_forms", level=level) url3 = url_for("emf.render_elliptic_modular_forms", level=level, weight=weight) url4 = url_for("emf.render_elliptic_modular_forms", level=level, weight=weight, character=character) bread = [(EMF_TOP, url1)] bread.append(("Level %s" % level, url2)) bread.append(("Weight %s" % weight, url3)) bread.append(("Character \( %s \)" % (WNF.character.latex_name), url4)) bread.append( ("Newform %d.%d.%d.%s" % (level, weight, int(character), label), '')) info['bread'] = bread properties2 = list() friends = list() space_url = url_for('emf.render_elliptic_modular_forms', level=level, weight=weight, character=character) friends.append( ('\( S_{%s}(%s, %s)\)' % (WNF.weight, WNF.level, WNF.character.latex_name), space_url)) if hasattr(WNF.base_ring, "lmfdb_url") and WNF.base_ring.lmfdb_url: friends.append(('Number field ' + WNF.base_ring.lmfdb_pretty, WNF.base_ring.lmfdb_url)) if hasattr(WNF.coefficient_field, "lmfdb_url") and WNF.coefficient_field.lmfdb_label: friends.append(('Number field ' + WNF.coefficient_field.lmfdb_pretty, WNF.coefficient_field.lmfdb_url)) friends = uniq(friends) friends.append(("Dirichlet character \(" + WNF.character.latex_name + "\)", WNF.character.url())) if WNF.dimension == 0 and not info.has_key('error'): info['error'] = "This space is empty!" info['title'] = 'Newform ' + WNF.hecke_orbit_label info['learnmore'] = [('History of Modular forms', url_for('holomorphic_mf_history'))] if 'error' in info: return info ## Until we have figured out how to do the embeddings correctly we don't display the Satake ## parameters for non-trivial characters.... ## Example to illustrate the different cases ## base = CyclotomicField(n) -- of degree phi(n) ## coefficient_field = NumberField( p(x)) for some p in base['x'] of degree m ## we would then have cdeg = m*phi(n) and bdeg = phi(n) ## and rdeg = m ## Unfortunately, for e.g. base = coefficient_field = CyclotomicField(6) ## we get coefficient_field.relative_degree() == 2 although it should be 1 cdeg = WNF.coefficient_field.absolute_degree() bdeg = WNF.base_ring.absolute_degree() if cdeg == 1: rdeg = 1 else: ## just setting rdeg = WNF.coefficient_field.relative_degree() does not give correct result... ## rdeg = QQ(cdeg) / QQ(bdeg) cf_is_QQ = (cdeg == 1) br_is_QQ = (bdeg == 1) if cf_is_QQ: info['satake'] = WNF.satake if WNF.complexity_of_first_nonvanishing_coefficients( ) > default_max_height: info['qexp'] = "" info['qexp_display'] = '' info['hide_qexp'] = True n, c = WNF.first_nonvanishing_coefficient() info['trace_nv'] = latex(WNF.first_nonvanishing_coefficient_trace()) info['norm_nv'] = '\\approx ' + latex( WNF.first_nonvanishing_coefficient_norm().n()) info['index_nv'] = n else: if WNF.prec < prec: #get WNF record at larger prec WNF.prec = prec WNF.update_from_db() info['qexp'] = WNF.q_expansion_latex(prec=10, name='\\alpha ') info['qexp_display'] = url_for(".get_qexp_latex", level=level, weight=weight, character=character, label=label) info["hide_qexp"] = False info['max_cn_qexp'] = WNF.q_expansion.prec() ## All combinations should be tested... ## 13/4/4/a -> base ring = coefficient_field = QQ(zeta_6) ## 13/3/8/a -> base_ring = QQ(zeta_4), coefficient_field has poly x^2+(2\zeta_4+2x-3\zeta_$ over base_ring ## 13/4/3/a -> base_ring = coefficient_field = QQ(zeta_3) ## 13/4/1/a -> all rational ## 13/6/1/a/ -> base_ring = QQ, coefficient_field = Q(sqrt(17)) ## These are variables which needs to be set properly below info['polvars'] = {'base_ring': 'x', 'coefficient_field': '\\alpha'} if not cf_is_QQ: if rdeg > 1: # not WNF.coefficient_field == WNF.base_ring: ## Here WNF.base_ring should be some cyclotomic field and we have an extension over this. p1 = WNF.coefficient_field.relative_polynomial() c_pol_ltx = web_latex_poly(p1, '\\alpha') # make the variable \alpha c_pol_ltx_x = web_latex_poly(p1, 'x') zeta = p1.base_ring().gens()[0] # p2 = zeta.minpoly() #this is not used anymore # b_pol_ltx = web_latex_poly(p2, latex(zeta)) #this is not used anymore z1 = zeta.multiplicative_order() info['coeff_field'] = [ WNF.coefficient_field.absolute_polynomial_latex('x'), c_pol_ltx_x, z1 ] if hasattr(WNF.coefficient_field, "lmfdb_url") and WNF.coefficient_field.lmfdb_url: info['coeff_field_pretty'] = [ WNF.coefficient_field.lmfdb_url, WNF.coefficient_field.lmfdb_pretty, WNF.coefficient_field.lmfdb_label ] if z1 == 4: info[ 'polynomial_st'] = '<div class="where">where</div> {0}\(\mathstrut=0\) and \(\zeta_4=i\).</div><br/>'.format( c_pol_ltx) info['polvars']['base_ring'] = 'i' elif z1 <= 2: info[ 'polynomial_st'] = '<div class="where">where</div> {0}\(\mathstrut=0\).</div><br/>'.format( c_pol_ltx) else: info[ 'polynomial_st'] = '<div class="where">where</div> %s\(\mathstrut=0\) and \(\zeta_{%s}=e^{\\frac{2\\pi i}{%s}}\) ' % ( c_pol_ltx, z1, z1) info['polvars']['base_ring'] = '\zeta_{{ {0} }}'.format(z1) if z1 == 3: info[ 'polynomial_st'] += 'is a primitive cube root of unity.' else: info[ 'polynomial_st'] += 'is a primitive {0}-th root of unity.'.format( z1) elif not br_is_QQ: ## Now we have base and coefficient field being equal, meaning that since the coefficient field is not QQ it is some cyclotomic field ## generated by some \zeta_n p1 = WNF.coefficient_field.absolute_polynomial() z1 = WNF.coefficient_field.gens()[0].multiplicative_order() c_pol_ltx = web_latex_poly(p1, '\\zeta_{{{0}}}'.format(z1)) c_pol_ltx_x = web_latex_poly(p1, 'x') info['coeff_field'] = [ WNF.coefficient_field.absolute_polynomial_latex('x'), c_pol_ltx_x ] if hasattr(WNF.coefficient_field, "lmfdb_url") and WNF.coefficient_field.lmfdb_url: info['coeff_field_pretty'] = [ WNF.coefficient_field.lmfdb_url, WNF.coefficient_field.lmfdb_pretty, WNF.coefficient_field.lmfdb_label ] if z1 == 4: info[ 'polynomial_st'] = '<div class="where">where \(\zeta_4=e^{{\\frac{{\\pi i}}{{ 2 }} }}=i \).</div>'.format( c_pol_ltx) info['polvars']['coefficient_field'] = 'i' elif z1 <= 2: info['polynomial_st'] = '' else: info[ 'polynomial_st'] = '<div class="where">where \(\zeta_{{{0}}}=e^{{\\frac{{2\\pi i}}{{ {0} }} }}\) '.format( z1) info['polvars']['coefficient_field'] = '\zeta_{{{0}}}'.format( z1) if z1 == 3: info[ 'polynomial_st'] += 'is a primitive cube root of unity.</div>' else: info[ 'polynomial_st'] += 'is a primitive {0}-th root of unity.</div>'.format( z1) else: info['polynomial_st'] = '' if info["hide_qexp"]: info['polynomial_st'] = '' info['degree'] = int(cdeg) if cdeg == 1: info['is_rational'] = 1 info['coeff_field_pretty'] = [ WNF.coefficient_field.lmfdb_url, WNF.coefficient_field.lmfdb_pretty ] else: info['is_rational'] = 0 emf_logger.debug("PREC2: {0}".format(prec)) info['embeddings'] = WNF._embeddings[ 'values'] #q_expansion_embeddings(prec, bprec,format='latex') info['embeddings_len'] = len(info['embeddings']) properties2 = [('Level', str(level)), ('Weight', str(weight)), ('Character', '$' + WNF.character.latex_name + '$'), ('Label', WNF.hecke_orbit_label), ('Dimension of Galois orbit', str(WNF.dimension))] if (ZZ(level)).is_squarefree(): info['twist_info'] = WNF.twist_info if isinstance(info['twist_info'], list) and len(info['twist_info']) > 0: info['is_minimal'] = info['twist_info'][0] if (info['twist_info'][0]): s = 'Is minimal<br>' else: s = 'Is a twist of lower level<br>' properties2 += [('Twist info', s)] else: info['twist_info'] = 'Twist info currently not available.' properties2 += [('Twist info', 'not available')] args = list() for x in range(5, 200, 10): args.append({'digits': x}) alev = None CM = WNF._cm_values if CM is not None: if CM.has_key('tau') and len(CM['tau']) != 0: info['CM_values'] = CM info['is_cm'] = WNF.is_cm if WNF.is_cm == 1: info['cm_field'] = "2.0.{0}.1".format(-WNF.cm_disc) info['cm_disc'] = WNF.cm_disc info['cm_field_knowl'] = nf_display_knowl( info['cm_field'], getDBConnection(), field_pretty(info['cm_field'])) info['cm_field_url'] = url_for("number_fields.by_label", label=info["cm_field"]) if WNF.is_cm is None or WNF.is_cm == -1: s = '- Unknown (insufficient data)<br>' elif WNF.is_cm == 1: s = 'Yes<br>' else: s = 'No<br>' properties2.append(('CM', s)) alev = WNF.atkin_lehner_eigenvalues() info['atkinlehner'] = None if isinstance(alev, dict) and len(alev.keys()) > 0 and level != 1: s1 = " Atkin-Lehner eigenvalues " s2 = "" for Q in alev.keys(): s2 += "\( \omega_{ %s } \) : %s <br>" % (Q, alev[Q]) properties2.append((s1, s2)) emf_logger.debug("properties={0}".format(properties2)) # alev = WNF.atkin_lehner_eigenvalues_for_all_cusps() # if isinstance(alev,dict) and len(alev.keys())>0: # emf_logger.debug("alev={0}".format(alev)) # info['atkinlehner'] = list() # for Q in alev.keys(): # s = "\(" + latex(c) + "\)" # Q = alev[c][0] # ev = alev[c][1] # info['atkinlehner'].append([Q, c, ev]) if (level == 1): poly = WNF.explicit_formulas.get('as_polynomial_in_E4_and_E6', '') if poly != '': d, monom, coeffs = poly emf_logger.critical("poly={0}".format(poly)) info['explicit_formulas'] = '\(' for i in range(len(coeffs)): c = QQ(coeffs[i]) s = "" if d > 1 and i > 0 and c > 0: s = "+" if c < 0: s = "-" if c.denominator() > 1: cc = "\\frac{{ {0} }}{{ {1} }}".format( abs(c.numerator()), c.denominator()) else: cc = str(abs(c)) s += "{0} \cdot ".format(cc) a = monom[i][0] b = monom[i][1] if a == 0 and b != 0: s += "E_6^{{ {0} }}".format(b) elif b == 0 and a != 0: s += "E_4^{{ {0} }}".format(a) else: s += "E_4^{{ {0} }}E_6^{{ {1} }}".format(a, b) info['explicit_formulas'] += s info['explicit_formulas'] += " \)" cur_url = '?&level=' + str(level) + '&weight=' + str(weight) + '&character=' + str(character) + \ '&label=' + str(label) if len(WNF.parent.hecke_orbits) > 1: for label_other in WNF.parent.hecke_orbits.keys(): if (label_other != label): s = 'Modular form ' if character: s += newform_label(level, weight, character, label_other) else: s += newform_label(level, weight, 1, label_other) url = url_for('emf.render_elliptic_modular_forms', level=level, weight=weight, character=character, label=label_other) friends.append((s, url)) s = 'L-Function ' if character: s += newform_label(level, weight, character, label) else: s += newform_label(level, weight, 1, label) # url = # "/L/ModularForm/GL2/Q/holomorphic?level=%s&weight=%s&character=%s&label=%s&number=%s" # %(level,weight,character,label,0) url = '/L' + url_for('emf.render_elliptic_modular_forms', level=level, weight=weight, character=character, label=label) if WNF.coefficient_field_degree > 1: for h in range(WNF.coefficient_field_degree): s0 = s + ".{0}".format(h) url0 = url + "{0}/".format(h) friends.append((s0, url0)) else: friends.append((s, url)) # if there is an elliptic curve over Q associated to self we also list that if WNF.weight == 2 and WNF.coefficient_field_degree == 1: llabel = str(level) + '.' + label s = 'Elliptic curve isogeny class ' + llabel url = '/EllipticCurve/Q/' + llabel friends.append((s, url)) info['properties2'] = properties2 info['friends'] = friends info['max_cn'] = WNF.max_available_prec() return info
def make_curve(self): # To start with the data fields of self are just those from # the database. We need to reformat these, construct the # actual elliptic curve E, and compute some further (easy) # data about it. # # Weierstrass equation data = self.data = {} data['ainvs'] = [int(ai) for ai in self.ainvs] self.E = EllipticCurve(data['ainvs']) data['equation'] = web_latex(self.E) # conductor, j-invariant and discriminant data['conductor'] = N = ZZ(self.conductor) bad_primes = N.prime_factors() try: data['j_invariant'] = QQ(str(self.jinv)) except KeyError: data['j_invariant'] = self.E.j_invariant() data['j_inv_factor'] = latex(0) if data['j_invariant']: data['j_inv_factor'] = latex(data['j_invariant'].factor()) data['j_inv_str'] = unicode(str(data['j_invariant'])) data['j_inv_latex'] = web_latex(data['j_invariant']) data['disc'] = D = self.E.discriminant() data['disc_latex'] = web_latex(data['disc']) data['disc_factor'] = latex(data['disc'].factor()) data['cond_factor'] = latex(N.factor()) data['cond_latex'] = web_latex(N) # CM and endomorphism ring data['CMD'] = self.cm data['CM'] = "no" data['EndE'] = "\(\Z\)" if self.cm: data['CM'] = "yes (\(D=%s\))" % data['CMD'] if data['CMD'] % 4 == 0: d4 = ZZ(data['CMD']) // 4 data['EndE'] = "\(\Z[\sqrt{%s}]\)" % d4 else: data['EndE'] = "\(\Z[(1+\sqrt{%s})/2]\)" % data['CMD'] # modular degree try: data['degree'] = self.degree except AttributeError: try: data['degree'] = self.E.modular_degree() except RuntimeError: data['degree'] # invalid, but will be displayed nicely # Minimal quadratic twist E_pari = self.E.pari_curve() from sage.libs.pari.all import PariError try: minq, minqD = self.E.minimal_quadratic_twist() except PariError: # this does occur with 164411a1 ec.debug( "PariError computing minimal quadratic twist of elliptic curve %s" % lmfdb_label) minq = self.E minqD = 1 data['minq_D'] = minqD if self.E == minq: data['minq_label'] = self.lmfdb_label data['minq_info'] = '(itself)' else: minq_ainvs = [str(c) for c in minq.ainvs()] data['minq_label'] = db_ec().find_one({'ainvs': minq_ainvs})['lmfdb_label'] data['minq_info'] = '(by %s)' % minqD minq_N, minq_iso, minq_number = split_lmfdb_label(data['minq_label']) # rational and integral points mw = self.mw = {} xintpoints_projective = [self.E.lift_x(x) for x in self.xintcoords] xintpoints = [P.xy() for P in xintpoints_projective] mw['int_points'] = ', '.join(web_latex(P) for P in xintpoints) # Generators of infinite order mw['rank'] = self.rank try: self.generators = [self.E(g) for g in parse_points(self.gens)] mw['generators'] = [web_latex(P.xy()) for P in self.generators] mw['heights'] = [P.height() for P in self.generators] except AttributeError: mw['generators'] = '' mw['heights'] = [] # Torsion subgroup: order, structure, generators mw['tor_order'] = self.torsion tor_struct = [int(c) for c in self.torsion_structure] if mw['tor_order'] == 1: mw['tor_struct'] = '\mathrm{Trivial}' mw['tor_gens'] = '' else: mw['tor_struct'] = ' \\times '.join( ['\Z/{%s}\Z' % n for n in tor_struct]) mw['tor_gens'] = ', '.join( web_latex(self.E(g).xy()) for g in parse_points(self.torsion_generators)) # Images of Galois representations try: data['galois_images'] = [ trim_galois_image_code(s) for s in self.galois_images ] data['non_surjective_primes'] = self.non_surjective_primes except AttributeError: #print "No Galois image data" data['galois_images'] = [] data['non_surjective_primes'] = [] data['galois_data'] = [{ 'p': p, 'image': im } for p, im in zip(data['non_surjective_primes'], data['galois_images'])] if self.twoadic_gens: from sage.matrix.all import Matrix data['twoadic_gen_matrices'] = ','.join( [latex(Matrix(2, 2, M)) for M in self.twoadic_gens]) data[ 'twoadic_rouse_url'] = ROUSE_URL_PREFIX + self.twoadic_label + ".html" # Leading term of L-function & BSD data bsd = self.bsd = {} r = self.rank if r >= 2: bsd['lder_name'] = "L^{(%s)}(E,1)/%s!" % (r, r) elif r: bsd['lder_name'] = "L'(E,1)" else: bsd['lder_name'] = "L(E,1)" bsd['reg'] = self.regulator bsd['omega'] = self.real_period bsd['sha'] = int(0.1 + self.sha_an) bsd['lder'] = self.special_value # Optimality (the optimal curve in the class is the curve # whose Cremona label ends in '1' except for '990h' which was # labelled wrongly long ago) if self.iso == '990h': data['Gamma0optimal'] = bool(self.number == 3) else: data['Gamma0optimal'] = bool(self.number == 1) data['p_adic_data_exists'] = False if data['Gamma0optimal']: data['p_adic_data_exists'] = (padic_db().find({ 'lmfdb_iso': self.lmfdb_iso }).count()) > 0 data['p_adic_primes'] = [ p for p in sage.all.prime_range(5, 100) if self.E.is_ordinary(p) and not p.divides(N) ] # Local data local_data = self.local_data = [] # if we use E.tamagawa_numbers() it calls E.local_data(p) which # used to crash on some curves e.g. 164411a1 tamagawa_numbers = [] for p in bad_primes: local_info = self.E.local_data(p, algorithm="generic") local_data_p = {} local_data_p['p'] = p local_data_p['tamagawa_number'] = local_info.tamagawa_number() tamagawa_numbers.append(ZZ(local_info.tamagawa_number())) local_data_p['kodaira_symbol'] = web_latex( local_info.kodaira_symbol()).replace('$', '') local_data_p['reduction_type'] = local_info.bad_reduction_type() local_data_p['ord_cond'] = local_info.conductor_valuation() local_data_p['ord_disc'] = local_info.discriminant_valuation() local_data_p['ord_den_j'] = max(0, -self.E.j_invariant().valuation(p)) local_data.append(local_data_p) cp_fac = [cp.factor() for cp in tamagawa_numbers] cp_fac = [ latex(cp) if len(cp) < 2 else '(' + latex(cp) + ')' for cp in cp_fac ] bsd['tamagawa_factors'] = r'\cdot'.join(cp_fac) bsd['tamagawa_product'] = sage.misc.all.prod(tamagawa_numbers) cond, iso, num = split_lmfdb_label(self.lmfdb_label) data['newform'] = web_latex(self.E.q_eigenform(10)) self.make_code_snippets() self.friends = [('Isogeny class ' + self.lmfdb_iso, url_for(".by_double_iso_label", conductor=N, iso_label=iso)), ('Minimal quadratic twist %s %s' % (data['minq_info'], data['minq_label']), url_for(".by_triple_label", conductor=minq_N, iso_label=minq_iso, number=minq_number)), ('All twists ', url_for(".rational_elliptic_curves", jinv=self.jinv)), ('L-function', url_for("l_functions.l_function_ec_page", label=self.lmfdb_label)), ('Symmetric square L-function', url_for("l_functions.l_function_ec_sym_page", power='2', label=self.lmfdb_iso)), ('Symmetric 4th power L-function', url_for("l_functions.l_function_ec_sym_page", power='4', label=self.lmfdb_iso)), ('Modular form ' + self.lmfdb_iso.replace('.', '.2'), url_for("emf.render_elliptic_modular_forms", level=int(N), weight=2, character=1, label=iso))] self.downloads = [('Download coefficients of q-expansion', url_for(".download_EC_qexp", label=self.lmfdb_label, limit=100)), ('Download all stored data', url_for(".download_EC_all", label=self.lmfdb_label))] self.plot = encode_plot(self.E.plot()) self.plot_link = '<img src="%s" width="200" height="150"/>' % self.plot self.properties = [('Label', self.lmfdb_label), (None, self.plot_link), ('Conductor', '\(%s\)' % data['conductor']), ('Discriminant', '\(%s\)' % data['disc']), ('j-invariant', '%s' % data['j_inv_latex']), ('CM', '%s' % data['CM']), ('Rank', '\(%s\)' % mw['rank']), ('Torsion Structure', '\(%s\)' % mw['tor_struct'])] self.title = "Elliptic Curve %s (Cremona label %s)" % ( self.lmfdb_label, self.label) self.bread = [('Elliptic Curves', url_for("ecnf.index")), ('$\Q$', url_for(".rational_elliptic_curves")), ('%s' % N, url_for(".by_conductor", conductor=N)), ('%s' % iso, url_for(".by_double_iso_label", conductor=N, iso_label=iso)), ('%s' % num, ' ')]
def render_hgm_family_webpage(label): data = None info = {} data = db.hgm_families.lookup(label) if data is None: abort(404, "Hypergeometric motive family " + label + " was not found in the database.") title = 'Hypergeometric Motive Family:' + label A = data['A'] B = data['B'] hodge = data['famhodge'] mydet = data['det'] detexp = QQ(data['weight']*data['degree']) detexp = -detexp/2 mydet = r'\Q(%s)\otimes\Q(\sqrt{'%str(detexp) if int(data['det'][0]) != 1: mydet += str(data['det'][0]) if len(data['det'][1])>0: mydet += data['det'][1] if int(data['det'][0]) == 1 and len(data['det'][1])==0: mydet += '1' mydet += '})' bezoutmat = matrix(data['bezout']) bezoutdet = bezoutmat.det() bezoutmat = latex(bezoutmat) snf = data['snf'] snf = list2Cnstring(snf) typee = 'Orthogonal' if (data['weight'] % 2) == 1 and (data['degree'] % 2) == 0: typee = 'Symplectic' ppart = [[2, [data['A2'],data['B2'],data['C2']]], [3, [data['A3'],data['B3'],data['C3']]], [5, [data['A5'],data['B5'],data['C5']]], [7, [data['A7'],data['B7'],data['C7']]]] prop2 = [ ('Degree', '\(%s\)' % data['degree']), ('Weight', '\(%s\)' % data['weight']) ] mono = [m for m in data['mono'] if m[1] != 0] mono = [[m[0], dogapthing(m[1]), getgroup(m[1],m[0]), latex(ZZ(m[1][0]).factor())] for m in mono] mono = [[m[0], m[1], m[2][0], splitint(m[1][0]/m[2][1],m[0]), m[3]] for m in mono] info.update({ 'A': A, 'B': B, 'degree': data['degree'], 'weight': data['weight'], 'hodge': hodge, 'det': mydet, 'snf': snf, 'bezoutmat': bezoutmat, 'bezoutdet': bezoutdet, 'mono': mono, 'imprim': data['imprim'], 'ppart': ppart, 'type': typee, 'junk': small_group_display_knowl(18,2), 'showlist': showlist }) friends = [('Motives in the family', url_for('hypergm.index')+"?A=%s&B=%s" % (str(A), str(B)))] # if unramfriend != '': # friends.append(('Unramified subfield', unramfriend)) # if rffriend != '': # friends.append(('Discriminant root field', rffriend)) info.update({"plotcircle": url_for(".hgm_family_circle_image", AB = "A"+".".join(map(str,A))+"_B"+".".join(map(str,B)))}) info.update({"plotlinear": url_for(".hgm_family_linear_image", AB = "A"+".".join(map(str,A))+"_B"+".".join(map(str,B)))}) info.update({"plotconstant": url_for(".hgm_family_constant_image", AB = "A"+".".join(map(str,A))+"_B"+".".join(map(str,B)))}) bread = get_bread([(label, ' ')]) return render_template("hgm-show-family.html", credit=HGM_credit, title=title, bread=bread, info=info, properties2=prop2, friends=friends, learnmore=learnmore_list())
def nice_coset_reps(G): r""" Compute a better/nicer list of right coset representatives [V_j] i.e. SL2Z = \cup G V_j Use this routine for known congruence subgroups. EXAMPLES:: sage: G=MySubgroup(Gamma0(5)) sage: G._get_coset_reps_from_G(Gamma0(5)) [[1 0] [0 1], [ 0 -1] [ 1 0], [ 0 -1] [ 1 1], [ 0 -1] [ 1 -1], [ 0 -1] [ 1 2], [ 0 -1] [ 1 -2]] """ cl = list() S, T = SL2Z.gens() lvl = G.generalised_level() # Start with identity rep. cl.append(SL2Z([1, 0, 0, 1])) if (not S in G): cl.append(S) # If the original group is given as a Gamma0 then # the reps are not the one we want # I.e. we like to have a fundamental domain in # -1/2 <=x <= 1/2 for Gamma0, Gamma1, Gamma for j in range(1, ZZ(ceil(RR(lvl / 2.0)) + 2)): for ep in [1, -1]: if (len(cl) >= G.index()): break # The ones about 0 are all of this form A = SL2Z([0, -1, 1, ep * j]) # just make sure they are inequivalent try: for V in cl: if ((A != V and A * V**-1 in G) or cl.count(A) > 0): raise StopIteration() cl.append(A) except StopIteration: pass # We now add the rest of the "flips" of these reps. # So that we end up with a connected domain i = 1 while (True): lold = len(cl) for V in cl: for A in [S, T, T**-1]: B = V * A try: for W in cl: if ((B * W**-1 in G) or cl.count(B) > 0): raise StopIteration() cl.append(B) except StopIteration: pass if (len(cl) >= G.index() or lold >= len(cl)): # If we either did not add anything or if we added enough # we exit break # If we missed something (which is unlikely) if len(cl) != G.index(): print("cl=", cl) raise ValueError("Problem getting coset reps! Need %s and got %s" % (G.index(), len(cl))) return cl
def make_E(self): #print("Creating ECNF object for {}".format(self.label)) #sys.stdout.flush() K = self.field.K() # a-invariants self.ainvs = parse_ainvs(K, self.ainvs) self.latex_ainvs = web_latex(self.ainvs) self.numb = str(self.number) # Conductor, discriminant, j-invariant if self.conductor_norm == 1: N = K.ideal(1) else: N = ideal_from_string(K, self.conductor_ideal) # The following can trigger expensive computations! #self.cond = web_latex(N) self.cond = pretty_ideal(N) self.cond_norm = web_latex(self.conductor_norm) local_data = self.local_data # NB badprimes is a list of primes which divide the # discriminant of this model. At most one of these might # actually be a prime of good reduction, if the curve has no # global minimal model. badprimes = [ideal_from_string(K, ld['p']) for ld in local_data] badnorms = [ZZ(ld['normp']) for ld in local_data] mindisc_ords = [ld['ord_disc'] for ld in local_data] # Assumption: the curve models stored in the database are # either global minimal models or minimal at all but one # prime, so the list here has length 0 or 1: self.non_min_primes = [ideal_from_string(K, P) for P in self.non_min_p] self.is_minimal = (len(self.non_min_primes) == 0) self.has_minimal_model = self.is_minimal disc_ords = [ld['ord_disc'] for ld in local_data] if not self.is_minimal: Pmin = self.non_min_primes[0] P_index = badprimes.index(Pmin) self.non_min_prime = pretty_ideal(Pmin) disc_ords[P_index] += 12 if self.conductor_norm == 1: # since the factorization of (1) displays as "1" self.fact_cond = self.cond self.fact_cond_norm = '1' else: Nfac = Factorization([(P, ld['ord_cond']) for P, ld in zip(badprimes, local_data)]) self.fact_cond = web_latex_ideal_fact(Nfac) Nnormfac = Factorization([(q, ld['ord_cond']) for q, ld in zip(badnorms, local_data)]) self.fact_cond_norm = web_latex(Nnormfac) # D is the discriminant ideal of the model D = prod([P**e for P, e in zip(badprimes, disc_ords)], K.ideal(1)) self.disc = pretty_ideal(D) Dnorm = D.norm() self.disc_norm = web_latex(Dnorm) if Dnorm == 1: # since the factorization of (1) displays as "1" self.fact_disc = self.disc self.fact_disc_norm = '1' else: Dfac = Factorization([(P, e) for P, e in zip(badprimes, disc_ords)]) self.fact_disc = web_latex_ideal_fact(Dfac) Dnormfac = Factorization([(q, e) for q, e in zip(badnorms, disc_ords)]) self.fact_disc_norm = web_latex(Dnormfac) if not self.is_minimal: Dmin = ideal_from_string(K, self.minD) self.mindisc = pretty_ideal(Dmin) Dmin_norm = Dmin.norm() self.mindisc_norm = web_latex(Dmin_norm) if Dmin_norm == 1: # since the factorization of (1) displays as "1" self.fact_mindisc = self.mindisc self.fact_mindisc_norm = self.mindisc else: Dminfac = Factorization([ (P, e) for P, edd in zip(badprimes, mindisc_ords) ]) self.fact_mindisc = web_latex_ideal_fact(Dminfac) Dminnormfac = Factorization([ (q, e) for q, e in zip(badnorms, mindisc_ords) ]) self.fact_mindisc_norm = web_latex(Dminnormfac) j = self.field.parse_NFelt(self.jinv) # if j: # d = j.denominator() # n = d * j # numerator exists for quadratic fields only! # g = GCD(list(n)) # n1 = n / g # self.j = web_latex(n1) # if d != 1: # if n1 > 1: # # self.j = "("+self.j+")\(/\)"+web_latex(d) # self.j = web_latex(r"\frac{%s}{%s}" % (self.j, d)) # else: # self.j = web_latex(d) # if g > 1: # if n1 > 1: # self.j = web_latex(g) + self.j # else: # self.j = web_latex(g) self.j = web_latex(j) self.fact_j = None # See issue 1258: some j factorizations work but take too long # (e.g. EllipticCurve/6.6.371293.1/1.1/a/1). Note that we do # store the factorization of the denominator of j and display # that, which is the most interesting part. # The equation is stored in the database as a latex string. # Some of these have extraneous double quotes at beginning and # end, shich we fix here. We also strip out initial \( and \) # (if present) which are added in the template. self.equation = self.equation.replace('"', '').replace('\\(', '').replace( '\\)', '') # Images of Galois representations if not hasattr(self, 'galois_images'): #print "No Galois image data" self.galois_images = "?" self.non_surjective_primes = "?" self.galois_data = [] else: self.galois_data = [{ 'p': p, 'image': im } for p, im in zip(self.non_surjective_primes, self.galois_images)] # CM and End(E) self.cm_bool = "no" self.End = "\(\Z\)" if self.cm: self.rational_cm = K(self.cm).is_square() self.cm_sqf = ZZ(self.cm).squarefree_part() self.cm_bool = "yes (\(%s\))" % self.cm if self.cm % 4 == 0: d4 = ZZ(self.cm) // 4 self.End = "\(\Z[\sqrt{%s}]\)" % (d4) else: self.End = "\(\Z[(1+\sqrt{%s})/2]\)" % self.cm # Galois images in CM case: if self.cm and self.galois_images != '?': self.cm_ramp = [ p for p in ZZ(self.cm).support() if not p in self.non_surjective_primes ] self.cm_nramp = len(self.cm_ramp) if self.cm_nramp == 1: self.cm_ramp = self.cm_ramp[0] else: self.cm_ramp = ", ".join([str(p) for p in self.cm_ramp]) # Sato-Tate: # The lines below will need to change once we have curves over non-quadratic fields # that contain the Hilbert class field of an imaginary quadratic field if self.cm: if self.signature == [0, 1] and ZZ( -self.abs_disc * self.cm).is_square(): self.ST = st_link_by_name(1, 2, 'U(1)') else: self.ST = st_link_by_name(1, 2, 'N(U(1))') else: self.ST = st_link_by_name(1, 2, 'SU(2)') # Q-curve / Base change try: qc = self.q_curve if qc == True: self.qc = "yes" elif qc == False: self.qc = "no" else: # just in case self.qc = "not determined" except AttributeError: self.qc = "not determined" # Torsion self.ntors = web_latex(self.torsion_order) self.tr = len(self.torsion_structure) if self.tr == 0: self.tor_struct_pretty = "Trivial" if self.tr == 1: self.tor_struct_pretty = "\(\Z/%s\Z\)" % self.torsion_structure[0] if self.tr == 2: self.tor_struct_pretty = r"\(\Z/%s\Z\times\Z/%s\Z\)" % tuple( self.torsion_structure) torsion_gens = [parse_point(K, P) for P in self.torsion_gens] self.torsion_gens = ",".join([web_point(P) for P in torsion_gens]) # Rank or bounds try: self.rk = web_latex(self.rank) except AttributeError: self.rk = "?" try: self.rk_bnds = "%s...%s" % tuple(self.rank_bounds) except AttributeError: self.rank_bounds = [0, Infinity] self.rk_bnds = "not available" # Generators try: gens = [parse_point(K, P) for P in self.gens] self.gens = ", ".join([web_point(P) for P in gens]) if self.rk == "?": self.reg = "not available" else: if gens: try: self.reg = self.reg except AttributeError: self.reg = "not available" pass # self.reg already set else: self.reg = 1 # otherwise we only get 1.00000... except AttributeError: self.gens = "not available" self.reg = "not available" try: if self.rank == 0: self.reg = 1 except AttributeError: pass # Local data # Fix for Kodaira symbols, which in the database start and end # with \( and \) and may have multiple backslashes. Note that # to put a single backslash into a python string you have to # use '\\' which will display as '\\' but only counts as one # character in the string. which are added in the template. def tidy_kod(kod): while '\\\\' in kod: kod = kod.replace('\\\\', '\\') kod = kod.replace('\\(', '').replace('\\)', '') return kod for P, ld in zip(badprimes, local_data): ld['p'] = web_latex(P) ld['norm'] = P.norm() ld['kod'] = tidy_kod(ld['kod']) # URLs of self and related objects: self.urls = {} # It's useful to be able to use this class out of context, when calling url_for will fail: try: self.urls['curve'] = url_for(".show_ecnf", nf=self.field_label, conductor_label=quote( self.conductor_label), class_label=self.iso_label, number=self.number) except RuntimeError: return self.urls['class'] = url_for(".show_ecnf_isoclass", nf=self.field_label, conductor_label=quote( self.conductor_label), class_label=self.iso_label) self.urls['conductor'] = url_for(".show_ecnf_conductor", nf=self.field_label, conductor_label=quote( self.conductor_label)) self.urls['field'] = url_for(".show_ecnf1", nf=self.field_label) # Isogeny information self.one_deg = ZZ(self.class_deg).is_prime() isodegs = [str(d) for d in self.isogeny_degrees if d > 1] if len(isodegs) < 3: self.isogeny_degrees = " and ".join(isodegs) else: self.isogeny_degrees = " and ".join( [", ".join(isodegs[:-1]), isodegs[-1]]) sig = self.signature totally_real = sig[1] == 0 imag_quadratic = sig == [0, 1] if totally_real: self.hmf_label = "-".join( [self.field.label, self.conductor_label, self.iso_label]) self.urls['hmf'] = url_for('hmf.render_hmf_webpage', field_label=self.field.label, label=self.hmf_label) lfun_url = url_for("l_functions.l_function_ecnf_page", field_label=self.field_label, conductor_label=self.conductor_label, isogeny_class_label=self.iso_label) origin_url = lfun_url.lstrip('/L/').rstrip('/') if sig[0] <= 2 and db.lfunc_instances.exists({'url': origin_url}): self.urls['Lfunction'] = lfun_url elif self.abs_disc**2 * self.conductor_norm < 70000: # we shouldn't trust the Lfun computed on the fly for large conductor self.urls['Lfunction'] = url_for( "l_functions.l_function_hmf_page", field=self.field_label, label=self.hmf_label, character='0', number='0') if imag_quadratic: self.bmf_label = "-".join( [self.field.label, self.conductor_label, self.iso_label]) self.bmf_url = url_for('bmf.render_bmf_webpage', field_label=self.field_label, level_label=self.conductor_label, label_suffix=self.iso_label) lfun_url = url_for("l_functions.l_function_ecnf_page", field_label=self.field_label, conductor_label=self.conductor_label, isogeny_class_label=self.iso_label) origin_url = lfun_url.lstrip('/L/').rstrip('/') if db.lfunc_instances.exists({'url': origin_url}): self.urls['Lfunction'] = lfun_url # most of this code is repeated in isog_class.py # and should be refactored self.friends = [] self.friends += [('Isogeny class ' + self.short_class_label, self.urls['class'])] self.friends += [('Twists', url_for('ecnf.index', field=self.field_label, jinv=rename_j(j)))] if totally_real and not 'Lfunction' in self.urls: self.friends += [('Hilbert modular Form ' + self.hmf_label, self.urls['hmf'])] if imag_quadratic: if "CM" in self.label: self.friends += [('Bianchi modular Form is not cuspidal', '')] elif not 'Lfunction' in self.urls: if db.bmf_forms.label_exists(self.bmf_label): self.friends += [ ('Bianchi modular Form %s' % self.bmf_label, self.bmf_url) ] else: self.friends += [ ('(Bianchi modular Form %s)' % self.bmf_label, '') ] self.properties = [('Base field', self.field.field_pretty()), ('Label', self.label)] # Plot if K.signature()[0]: self.plot = encode_plot( EC_nf_plot(K, self.ainvs, self.field.generator_name())) self.plot_link = '<a href="{0}"><img src="{0}" width="200" height="150"/></a>'.format( self.plot) self.properties += [(None, self.plot_link)] self.properties += [ ('Conductor', self.cond), ('Conductor norm', self.cond_norm), # See issue #796 for why this is hidden (can be very large) # ('j-invariant', self.j), ('CM', self.cm_bool) ] if self.base_change: self.properties += [ ('base-change', 'yes: %s' % ','.join([str(lab) for lab in self.base_change])) ] else: self.base_change = [] # in case it was False instead of [] self.properties += [('base-change', 'no')] self.properties += [('Q-curve', self.qc)] r = self.rk if r == "?": r = self.rk_bnds self.properties += [ ('Torsion order', self.ntors), ('Rank', r), ] for E0 in self.base_change: self.friends += [('Base-change of %s /\(\Q\)' % E0, url_for("ec.by_ec_label", label=E0))] self._code = None # will be set if needed by get_code() self.downloads = [('All stored data to text', url_for(".download_ECNF_all", nf=self.field_label, conductor_label=quote(self.conductor_label), class_label=self.iso_label, number=self.number))] for lang in [["Magma", "magma"], ["SageMath", "sage"], ["GP", "gp"]]: self.downloads.append( ('Code to {}'.format(lang[0]), url_for(".ecnf_code_download", nf=self.field_label, conductor_label=quote(self.conductor_label), class_label=self.iso_label, number=self.number, download_type=lang[1]))) if 'Lfunction' in self.urls: Lfun = get_lfunction_by_url( self.urls['Lfunction'].lstrip('/L').rstrip('/'), projection=['degree', 'trace_hash', 'Lhash']) if Lfun is None: self.friends += [('L-function not available', "")] else: instances = get_instances_by_Lhash_and_trace_hash( Lfun['Lhash'], Lfun['degree'], Lfun.get('trace_hash')) exclude = { elt[1].rstrip('/').lstrip('/') for elt in self.friends if elt[1] } self.friends += names_and_urls(instances, exclude=exclude) self.friends += [('L-function', self.urls['Lfunction'])] else: self.friends += [('L-function not available', "")]
def render_hgm_webpage(args): data = None info = {} if 'label' in args: label = clean_input(args['label']) data = motivedb().find_one({'label': label}) if data is None: bread = get_bread([("Search error", url_for('.search'))]) info['err'] = "Motive " + label + " was not found in the database." info['label'] = label return search_input_error(info, bread) title = 'Hypergeometric Motive:' + label A = data['A'] B = data['B'] myfam = familydb().find_one({'A': A, 'B': B}) if myfam is None: det = 'data not computed' else: det = myfam['det'] det = [det[0],str(det[1])] d1 = det[1] d1 = re.sub(r'\s','', d1) d1 = re.sub(r'(.)\(', r'\1*(', d1) R = PolynomialRing(ZZ, 't') if det[1]=='': d2 = R(1) else: d2 = R(d1) det = d2(QQ(data['t']))*det[0] t = latex(QQ(data['t'])) typee = 'Orthogonal' if (data['weight'] % 2) == 1 and (data['degree'] % 2) == 0: typee = 'Symplectic' primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71] locinfo = data['locinfo'] for j in range(len(locinfo)): locinfo[j] = [primes[j]] + locinfo[j] #locinfo[j][2] = poly_with_factored_coeffs(locinfo[j][2], primes[j]) locinfo[j][2] = list_to_factored_poly_otherorder(locinfo[j][2], vari='x') hodge = string2list(data['hodge']) famhodge = string2list(data['famhodge']) prop2 = [ ('Degree', '\(%s\)' % data['degree']), ('Weight', '\(%s\)' % data['weight']), ('Hodge vector', '\(%s\)' % hodge), ('Conductor', '\(%s\)' % data['cond']), ] # Now add factorization of conductor Cond = ZZ(data['cond']) if not (Cond.abs().is_prime() or Cond == 1): data['cond'] = "%s=%s" % (str(Cond), factorint(data['cond'])) info.update({ 'A': A, 'B': B, 't': t, 'degree': data['degree'], 'weight': data['weight'], 'sign': data['sign'], 'sig': data['sig'], 'hodge': hodge, 'famhodge': famhodge, 'cond': data['cond'], 'req': data['req'], 'lcms': data['lcms'], 'type': typee, 'det': det, 'locinfo': locinfo }) AB_data, t_data = data["label"].split("_t") friends = [("Motive family "+AB_data.replace("_"," "), url_for(".by_family_label", label = AB_data))] friends.append(('L-function', url_for("l_functions.l_function_hgm_page", label=AB_data, t='t'+t_data))) # if rffriend != '': # friends.append(('Discriminant root field', rffriend)) bread = get_bread([(label, ' ')]) return render_template("hgm-show-motive.html", credit=HGM_credit, title=title, bread=bread, info=info, properties2=prop2, friends=friends, learnmore=learnmore_list())
def fundamental_discriminants(A, B): """Return the fundamental discriminants between A and B (inclusive), as Sage integers, ordered by absolute value, with negatives first when abs same.""" v = [ZZ(D) for D in range(A, B + 1) if is_fundamental_discriminant(D)] v.sort(lambda x, y: cmp((abs(x), sgn(x)), (abs(y), sgn(y)))) return v
def make_cond_key(D): D1 = ZZ(D) if D1 < 1: D1 = ZZ.one() D1 = int(D1.log(10)) return '%04d%s' % (D1, str(D))
def rational_euler_factors(traces, euler_factors_cc, level, weight): dirichlet = [1] * 11 dirichlet[0] = 0 euler_factors = [] bad_lfactors = [] halfdegree = len(euler_factors_cc) PS = PowerSeriesRing(ZZ, "X") CCCx = PolynomialRing(CCC, "x") todo = list(enumerate(primes_first_n(30))) for p in sorted(ZZ(level).prime_divisors()): p_index = prime_pi(p) - 1 if p_index >= 30: todo.append((p_index, p)) for p_index, p in todo: if p_index > len(euler_factors_cc[0]): assert level % p == 0 bad_lfactors.append([int(p), [int(1)] + [None] * halfdegree]) continue #try to guess the rest by multiplying them roots = [] for lf in euler_factors_cc: roots += reciprocal_roots(lf[p_index]) root_powers = [None] * (halfdegree + 1) for j in range(1, halfdegree + 1): try: root_powers[j] = RRR(sum(map(lambda z: (z**j).real(), roots))).unique_integer() except ValueError: root_powers = root_powers[:j] break partial_efzz = from_power_sums(root_powers) efzz = map( int, partial_efzz) + [None] * (halfdegree + 1 - len(partial_efzz)) if len(traces) > p: if efzz[1] is None: efzz[1] = int(-traces[p - 1]) else: assert efzz[1] == -traces[p - 1] # to check that from_power_sums is correct ef = prod([CCCx(lf[p_index]) for lf in euler_factors_cc]) for j, elt in enumerate(ef.list()[:len(partial_efzz)]): try: efj = RRR(elt.real()).unique_integer() except ValueError: break assert efj == efzz[j] if level % p != 0: sign = RRR(ef.list()[-1].real() / p**((halfdegree) * (weight - 1))).unique_integer() assert sign in [1, -1], "%s\n%s" % (RRR( prod(lf[p_index][2] for lf in euler_factors_cc).real()).unique_integer(), p**( (halfdegree) * (weight - 1))) efzz2 = [None] * halfdegree for i, elt in enumerate(reversed(efzz[:-1])): if elt is None: efzz2[i] = None else: efzz2[i] = int(sign * p**((i + 1) * (weight - 1)) * elt) efzz += efzz2 euler_factors.append(efzz) else: if None not in efzz: k = len(efzz) while efzz[k - 1] == 0 and k >= 1: k -= 1 efzz = efzz[:k] bad_lfactors.append([int(p), efzz]) if p_index < 30: euler_factors.append(efzz) if p < 11: if p == 2: foo = (1 / PS(efzz[:4])).padded_list(4) for i in range(1, 4): dirichlet[p**i] = foo[i] elif p == 3: foo = (1 / PS(efzz[:3])).padded_list(4) for i in range(1, 3): dirichlet[p**i] = foo[i] else: dirichlet[p] = -efzz[1] if len(efzz) > 1 else 0 assert dirichlet[p] == traces[ p - 1], "p = %s, ap = %s, tp = %s, efzz = %s" % ( p, dirichlet[p], traces[p - 1], efzz) extend_multiplicatively(dirichlet) assert len(euler_factors) == 30 return euler_factors, bad_lfactors, dirichlet
def __init__(self, seed): self.s = ZZ(bytes_to_long(seed))
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 rational_euler_factors(euler_factors_cc, level, weight, an_list_bound = 11): dirichlet = [1]*an_list_bound dirichlet[0] = 0 euler_factors = [] bad_lfactors = [] halfdegree = len(euler_factors_cc) PS = PowerSeriesRing(ZZ, "X") CCCx = PolynomialRing(CCC, "x") todo = list(enumerate(primes_first_n(30))) for p in sorted(ZZ(level).prime_divisors()): p_index = prime_pi(p) - 1 if p_index >= 30: todo.append((p_index, p)) for p_index, p in todo: if p_index >= len(euler_factors_cc[0]): assert level % p == 0, "%s, %s, %s" % (level, weight, len(euler_factors_cc)) bad_lfactors.append([int(p), [int(1)] + [None]*halfdegree]) continue #try to guess the rest by multiplying them roots = [] for lf in euler_factors_cc: roots += reciprocal_roots(lf[p_index]) root_powers = [None] * (halfdegree + 1) for j in range(1,halfdegree + 1): try: root_powers[j] = RRR(sum( map(lambda z: (z**j).real(), roots) )).unique_integer() except ValueError: root_powers = root_powers[:j] break partial_efzz = from_power_sums(root_powers) efzz = map(int, partial_efzz) + [None]*(halfdegree +1 - len(partial_efzz)) # to check that from_power_sums is correct ef = prod([CCCx(lf[p_index]) for lf in euler_factors_cc]) for j, elt in enumerate(ef.list()[:len(partial_efzz)]): try: efj = int(RRR(elt.real()).unique_integer()) except ValueError: #print j #print RRR(elt.real()) #print p #print "[%s]" % (", ".join(["[%s]" % (", ".join(map(print_CCC, lf[p_index]))) for ef in euler_factors_cc])) #assert False break; assert efj == efzz[j], "%s, %s, %s, %s != %s" % (level, weight, len(euler_factors_cc), efj, efzz[j]) if (level % p) != 0: sign = RRR(ef.list()[-1].real()/p**((halfdegree)*(weight - 1))).unique_integer() assert sign in [1,-1], "%s\n%s" % (RRR(prod( lf[p_index][2] for lf in euler_factors_cc).real()).unique_integer(),p**((halfdegree)*(weight - 1))) efzz2 = [None] * halfdegree for i, elt in enumerate(reversed(efzz[:-1])): if elt is None: efzz2[i] = None else: efzz2[i] = int(sign*p**((i+1)*(weight - 1)) * elt) efzz += efzz2 euler_factors.append(efzz) else: if None not in efzz: k = len(efzz) while efzz[k - 1] == 0 and k >= 1: k -= 1 efzz = efzz[:k] bad_lfactors.append([int(p), efzz]) if p_index < 30: euler_factors.append(efzz) if p < an_list_bound: k = RR(an_list_bound).log(p).floor()+1 foo = (1/PS(efzz)).padded_list(k) for i in range(1, k): dirichlet[p**i] = foo[i] extend_multiplicatively(dirichlet) assert len(euler_factors) == 30, "%s, %s, %s, %s != 30" % (level, weight, len(euler_factors_cc), len(euler_factors)) return euler_factors, bad_lfactors, dirichlet
def nf_string_to_label(F): # parse Q, Qsqrt2, Qsqrt-4, Qzeta5, etc if F == 'Q': return '1.1.1.1' if F == 'Qi' or F == 'Q(i)': return '2.0.4.1' # Change unicode dash with minus sign F = F.replace(u'\u2212', '-') # remove non-ascii characters from F F = F.decode('utf8').encode('ascii', 'ignore') if len(F) == 0: raise ValueError( "Entry for the field was left blank. You need to enter a field label, field name, or a polynomial." ) if F[0] == 'Q': if '(' in F and ')' in F: F = F.replace('(', '').replace(')', '') if F[1:5] in ['sqrt', 'root']: try: d = ZZ(str(F[5:])).squarefree_part() except (TypeError, ValueError): d = 0 if d == 0: raise ValueError( "After {0}, the remainder must be a nonzero integer. Use {0}5 or {0}-11 for example." .format(F[:5])) if d == 1: return '1.1.1.1' if d % 4 in [2, 3]: D = 4 * d else: D = d absD = D.abs() s = 0 if D < 0 else 2 return '2.%s.%s.1' % (s, str(absD)) if F[1:5] == 'zeta': if '_' in F: F = F.replace('_', '') try: d = ZZ(str(F[5:])) except ValueError: d = 0 if d < 1: raise ValueError( "After {0}, the remainder must be a positive integer. Use {0}5 for example." .format(F[:5])) if d % 4 == 2: d /= 2 # Q(zeta_6)=Q(zeta_3), etc) if d == 1: return '1.1.1.1' deg = euler_phi(d) if deg > 23: raise ValueError('%s is not in the database.' % F) adisc = CyclotomicField(d).discriminant().abs() # uses formula! return '%s.0.%s.1' % (deg, adisc) raise ValueError( 'It is not a valid field name or label, or a defining polynomial.') # check if a polynomial was entered F = F.replace('X', 'x') if 'x' in F: F1 = F.replace('^', '**') # print F from lmfdb.number_fields.number_field import poly_to_field_label F1 = poly_to_field_label(F1) if F1: return F1 raise ValueError('%s does not define a number field in the database.' % F) # Expand out factored labels, like 11.11.11e20.1 if not re.match(r'\d+\.\d+\.[0-9e_]+\.\d+', F): raise ValueError("It must be of the form d.r.D.n, such as 2.2.5.1.") parts = F.split(".") def raise_power(ab): if ab.count("e") == 0: return ZZ(ab) elif ab.count("e") == 1: a, b = ab.split("e") return ZZ(a)**ZZ(b) else: raise ValueError( "Malformed absolute discriminant. It must be a sequence of strings AeB for A and B integers, joined by _s. For example, 2e7_3e5_11." ) parts[2] = str(prod(raise_power(c) for c in parts[2].split("_"))) return ".".join(parts)
def lattice_search(**args): info = to_dict(args) # what has been entered in the search boxes if 'download' in info: return download_search(info) if 'label' in info and info.get('label'): return lattice_by_label_or_name(info.get('label')) query = {} try: for field, name in (('dim', 'Dimension'), ('det', 'Determinant'), ('level', None), ('minimum', 'Minimal vector length'), ('class_number', None), ('aut', 'Group order')): parse_ints(info, query, field, name) # Check if length of gram is triangular gram = info.get('gram') if gram and not (9 + 8 * ZZ(gram.count(','))).is_square(): flash( Markup( "Error: <span style='color:black'>%s</span> is not a valid input for Gram matrix. It must be a list of integer vectors of triangular length, such as [1,2,3]." % (gram)), "error") raise ValueError parse_list(info, query, 'gram', process=vect_to_sym) except ValueError as err: info['err'] = str(err) return search_input_error(info) count = parse_count(info, 50) start = parse_start(info) info['query'] = dict(query) res = lattice_db().find(query).sort([('dim', ASC), ('det', ASC), ('level', ASC), ('class_number', ASC), ('label', ASC), ('minimum', ASC), ('aut', ASC) ]).skip(start).limit(count) nres = res.count() # here we are checking for isometric lattices if the user enters a valid gram matrix but not one stored in the database_names, this may become slow in the future: at the moment we compare against list of stored matrices with same dimension and determinant (just compare with respect to dimension is slow) if nres == 0 and info.get('gram'): A = query['gram'] n = len(A[0]) d = matrix(A).determinant() result = [ B for B in lattice_db().find({ 'dim': int(n), 'det': int(d) }) if isom(A, B['gram']) ] if len(result) > 0: result = result[0]['gram'] query_gram = {'gram': result} query.update(query_gram) res = lattice_db().find(query) nres = res.count() if (start >= nres): start -= (1 + (start - nres) / count) * count if (start < 0): start = 0 info['number'] = nres info['start'] = int(start) info['more'] = int(start + count < nres) if nres == 1: info['report'] = 'unique match' else: if nres == 0: info['report'] = 'no matches' else: if nres > count or start != 0: info['report'] = 'displaying matches %s-%s of %s' % ( start + 1, min(nres, start + count), nres) else: info['report'] = 'displaying all %s matches' % nres res_clean = [] for v in res: v_clean = {} v_clean['label'] = v['label'] v_clean['dim'] = v['dim'] v_clean['det'] = v['det'] v_clean['level'] = v['level'] v_clean['class_number'] = v['class_number'] v_clean['min'] = v['minimum'] v_clean['aut'] = v['aut'] res_clean.append(v_clean) info['lattices'] = res_clean t = 'Integral Lattices Search Results' bread = [('Lattices', url_for(".lattice_render_webpage")), ('Search Results', ' ')] properties = [] return render_template("lattice-search.html", info=info, title=t, properties=properties, bread=bread, learnmore=learnmore_list())
def get_satake_parameters(k, N=1, chi=0, fi=0, prec=10, bits=53, angles=False): r""" Compute the Satake parameters and return an html-table. 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'' -- compute parameters for p <=prec -''bits'' -- do real embedings intoi field of bits precision -''angles''-- return the angles t_p instead of the alpha_p here alpha_p=p^((k-1)/2)exp(i*t_p) """ (t, f) = _get_newform(k, N, chi, fi) if(not t): return f K = f.base_ring() RF = RealField(bits) CF = ComplexField(bits) if(K != QQ): M = len(K.complex_embeddings()) ems = dict() for j in range(M): ems[j] = list() ps = prime_range(prec) alphas = list() for p in ps: ap = f.coefficients(ZZ(prec))[p] if(K == QQ): f1 = QQ(4 * p ** (k - 1) - ap ** 2) alpha_p = (QQ(ap) + I * f1.sqrt()) / QQ(2) # beta_p=(QQ(ap)-I*f1.sqrt())/QQ(2) # satake[p]=(alpha_p,beta_p) ab = RF(p ** ((k - 1) / 2)) norm_alpha = alpha_p / ab t_p = CF(norm_alpha).argument() if(angles): alphas.append(t_p) else: alphas.append(alpha_p) else: for j in range(M): app = ap.complex_embeddings(bits)[j] f1 = (4 * p ** (k - 1) - app ** 2) alpha_p = (app + I * f1.sqrt()) / RealField(bits)(2) ab = RF(p ** ((k - 1) / 2)) norm_alpha = alpha_p / ab t_p = CF(norm_alpha).argument() if(angles): ems[j].append(t_p) else: ems[j].append(alpha_p) tbl = dict() tbl['headersh'] = ps if(K == QQ): tbl['headersv'] = [""] tbl['data'] = [alphas] tbl['corner_label'] = "$p$" else: tbl['data'] = list() tbl['headersv'] = list() tbl['corner_label'] = "Embedding \ $p$" for j in ems.keys(): tbl['headersv'].append(j) tbl['data'].append(ems[j]) # logger.debug(tbl) s = html_table(tbl) return s
def make_object(self, curve, endo, tama, ratpts, is_curve): from lmfdb.genus2_curves.main import url_for_curve_label # all information about the curve, its Jacobian, isogeny class, and endomorphisms goes in the data dictionary # most of the data from the database gets polished/formatted before we put it in the data dictionary data = self.data = {} data['label'] = curve['label'] if is_curve else curve['class'] data['slabel'] = data['label'].split('.') # set attributes common to curves and isogeny classes here data['Lhash'] = str(curve['Lhash']) data['cond'] = ZZ(curve['cond']) data['cond_factor_latex'] = web_latex(factor(int(data['cond']))) data['analytic_rank'] = ZZ(curve['analytic_rank']) data['st_group'] = curve['st_group'] data['st_group_link'] = st_link_by_name(1, 4, data['st_group']) data['st0_group_name'] = st0_group_name(curve['real_geom_end_alg']) data['is_gl2_type'] = curve['is_gl2_type'] data['root_number'] = ZZ(curve['root_number']) data['lfunc_url'] = url_for("l_functions.l_function_genus2_page", cond=data['slabel'][0], x=data['slabel'][1]) data['bad_lfactors'] = literal_eval(curve['bad_lfactors']) data['bad_lfactors_pretty'] = [(c[0], list_to_factored_poly_otherorder(c[1])) for c in data['bad_lfactors']] if is_curve: # invariants specific to curve data['class'] = curve['class'] data['abs_disc'] = ZZ(curve['abs_disc']) data['disc'] = curve['disc_sign'] * data['abs_disc'] data['min_eqn'] = literal_eval(curve['eqn']) data['min_eqn_display'] = list_to_min_eqn(data['min_eqn']) data['disc_factor_latex'] = web_latex(factor(data['disc'])) data['igusa_clebsch'] = [ ZZ(a) for a in literal_eval(curve['igusa_clebsch_inv']) ] data['igusa'] = [ZZ(a) for a in literal_eval(curve['igusa_inv'])] data['g2'] = [QQ(a) for a in literal_eval(curve['g2_inv'])] data['igusa_clebsch_factor_latex'] = [ web_latex(zfactor(i)) for i in data['igusa_clebsch'] ] data['igusa_factor_latex'] = [ web_latex(zfactor(j)) for j in data['igusa'] ] data['aut_grp_id'] = curve['aut_grp_id'] data['geom_aut_grp_id'] = curve['geom_aut_grp_id'] data['num_rat_wpts'] = ZZ(curve['num_rat_wpts']) data['two_selmer_rank'] = ZZ(curve['two_selmer_rank']) data['has_square_sha'] = "square" if curve[ 'has_square_sha'] else "twice a square" P = curve['non_solvable_places'] if len(P): sz = "except over " sz += ", ".join([QpName(p) for p in P]) last = " and" if len(P) > 2: last = ", and" sz = last.join(sz.rsplit(",", 1)) else: sz = "everywhere" data['non_solvable_places'] = sz data['torsion_order'] = curve['torsion_order'] data['torsion_factors'] = [ ZZ(a) for a in literal_eval(curve['torsion_subgroup']) ] if len(data['torsion_factors']) == 0: data['torsion_subgroup'] = '\mathrm{trivial}' else: data['torsion_subgroup'] = ' \\times '.join( ['\Z/{%s}\Z' % n for n in data['torsion_factors']]) data['end_ring_base'] = endo['ring_base'] data['end_ring_geom'] = endo['ring_geom'] data['tama'] = '' for item in tama: if item['tamagawa_number'] > 0: tamgwnr = str(item['tamagawa_number']) else: tamgwnr = 'N/A' data['tama'] += tamgwnr + ' (p = ' + str(item['p']) + '), ' data['tama'] = data['tama'][:-2] # trim last ", " if ratpts: if len(ratpts['rat_pts']): data['rat_pts'] = ', '.join( web_latex('(' + ' : '.join(map(str, P)) + ')') for P in ratpts['rat_pts']) data['rat_pts_v'] = 2 if ratpts['rat_pts_v'] else 1 # data['mw_rank'] = ratpts['mw_rank'] # data['mw_rank_v'] = ratpts['mw_rank_v'] else: data['rat_pts_v'] = 0 if curve['two_torsion_field'][0]: data['two_torsion_field_knowl'] = nf_display_knowl( curve['two_torsion_field'][0], field_pretty(curve['two_torsion_field'][0])) else: t = curve['two_torsion_field'] data[ 'two_torsion_field_knowl'] = """splitting field of \(%s\) with Galois group %s""" % ( intlist_to_poly( t[1]), group_display_knowl(t[2][0], t[2][1])) else: # invariants specific to isogeny class curves_data = list( db.g2c_curves.search({"class": curve['class']}, ['label', 'eqn'])) if not curves_data: raise KeyError( "No curves found in database for isogeny class %s of genus 2 curve %s." % (curve['class'], curve['label'])) data['curves'] = [{ "label": c['label'], "equation_formatted": list_to_min_eqn(literal_eval(c['eqn'])), "url": url_for_curve_label(c['label']) } for c in curves_data] lfunc_data = db.lfunc_lfunctions.lucky( {'Lhash': str(curve['Lhash'])}) if not lfunc_data: raise KeyError( "No Lfunction found in database for isogeny class of genus 2 curve %s." % curve['label']) if lfunc_data and lfunc_data.get('euler_factors'): data['good_lfactors'] = [ [nth_prime(n + 1), lfunc_data['euler_factors'][n]] for n in range(len(lfunc_data['euler_factors'])) if nth_prime(n + 1) < 30 and (data['cond'] % nth_prime(n + 1)) ] data['good_lfactors_pretty'] = [ (c[0], list_to_factored_poly_otherorder(c[1])) for c in data['good_lfactors'] ] # Endomorphism data over QQ: data['gl2_statement_base'] = gl2_statement_base( endo['factorsRR_base'], r'\(\Q\)') data['factorsQQ_base'] = endo['factorsQQ_base'] data['factorsRR_base'] = endo['factorsRR_base'] data['end_statement_base'] = """Endomorphism %s over \(\Q\):<br>""" %("ring" if is_curve else "algebra") + \ end_statement(data['factorsQQ_base'], endo['factorsRR_base'], ring=data['end_ring_base'] if is_curve else None) # Field over which all endomorphisms are defined data['end_field_label'] = endo['fod_label'] data['end_field_poly'] = intlist_to_poly(endo['fod_coeffs']) data['end_field_statement'] = end_field_statement( data['end_field_label'], data['end_field_poly']) # Endomorphism data over QQbar: data['factorsQQ_geom'] = endo['factorsQQ_geom'] data['factorsRR_geom'] = endo['factorsRR_geom'] if data['end_field_label'] != '1.1.1.1': data['gl2_statement_geom'] = gl2_statement_base( data['factorsRR_geom'], r'\(\overline{\Q}\)') data['end_statement_geom'] = """Endomorphism %s over \(\overline{\Q}\):""" %("ring" if is_curve else "algebra") + \ end_statement(data['factorsQQ_geom'], data['factorsRR_geom'], field=r'\overline{\Q}', ring=data['end_ring_geom'] if is_curve else None) data['real_geom_end_alg_name'] = real_geom_end_alg_name( curve['real_geom_end_alg']) data['geom_end_alg_name'] = geom_end_alg_name(curve['geom_end_alg']) # Endomorphism data over intermediate fields not already treated (only for curves, not necessarily isogeny invariant): if is_curve: data['end_lattice'] = (endo['lattice'])[1:-1] if data['end_lattice']: data['end_lattice_statement'] = end_lattice_statement( data['end_lattice']) # Field over which the Jacobian decomposes (base field if Jacobian is geometrically simple) data['is_simple_geom'] = endo['is_simple_geom'] data['split_field_label'] = endo['spl_fod_label'] data['split_field_poly'] = intlist_to_poly(endo['spl_fod_coeffs']) data['split_field_statement'] = split_field_statement( data['is_simple_geom'], data['split_field_label'], data['split_field_poly']) # Elliptic curve factors for non-simple Jacobians if not data['is_simple_geom']: data['split_coeffs'] = endo['spl_facs_coeffs'] if 'spl_facs_labels' in endo and len( endo['spl_facs_labels']) == len(endo['spl_facs_coeffs']): data['split_labels'] = endo['spl_facs_labels'] data['split_condnorms'] = endo['spl_facs_condnorms'] data['split_statement'] = split_statement(data['split_coeffs'], data.get('split_labels'), data['split_condnorms']) # Properties self.properties = properties = [('Label', data['label'])] if is_curve: self.plot = encode_plot( eqn_list_to_curve_plot( data['min_eqn'], data['rat_pts'].split(',') if 'rat_pts' in data else [])) plot_link = '<a href="{0}"><img src="{0}" width="200" height="150"/></a>'.format( self.plot) properties += [ (None, plot_link), ('Conductor', str(data['cond'])), ('Discriminant', str(data['disc'])), ] properties += [ ('Sato-Tate group', data['st_group_link']), ('\(\\End(J_{\\overline{\\Q}}) \\otimes \\R\)', '\(%s\)' % data['real_geom_end_alg_name']), ('\(\\End(J_{\\overline{\\Q}}) \\otimes \\Q\)', '\(%s\)' % data['geom_end_alg_name']), ('\(\\overline{\\Q}\)-simple', bool_pretty(data['is_simple_geom'])), ('\(\mathrm{GL}_2\)-type', bool_pretty(data['is_gl2_type'])), ] # Friends self.friends = friends = [] if is_curve: friends.append(('Isogeny class %s.%s' % (data['slabel'][0], data['slabel'][1]), url_for(".by_url_isogeny_class_label", cond=data['slabel'][0], alpha=data['slabel'][1]))) # first deal with EC ecs = [] if 'split_labels' in data: for friend_label in data['split_labels']: if is_curve: ecs.append(("Elliptic curve " + friend_label, url_for_ec(friend_label))) else: ecs.append( ("Isogeny class " + ec_label_class(friend_label), url_for_ec_class(friend_label))) ecs.sort(key=lambda x: key_for_numerically_sort(x[0])) # then again EC from lfun instances = [] for elt in db.lfunc_instances.search( { 'Lhash': data['Lhash'], 'type': 'ECQP' }, 'url'): instances.extend(elt.split('|')) # and then the other isogeny friends instances.extend([ elt['url'] for elt in get_instances_by_Lhash_and_trace_hash( data["Lhash"], 4, int(data["Lhash"])) ]) exclude = { elt[1].rstrip('/').lstrip('/') for elt in self.friends if elt[1] } exclude.add(data['lfunc_url'].lstrip('/L/').rstrip('/')) for elt in ecs + names_and_urls(instances, exclude=exclude): # because of the splitting we must use G2C specific code add_friend(friends, elt) if is_curve: friends.append(('Twists', url_for(".index_Q", g20=str(data['g2'][0]), g21=str(data['g2'][1]), g22=str(data['g2'][2])))) friends.append(('L-function', data['lfunc_url'])) # Breadcrumbs self.bread = bread = [('Genus 2 Curves', url_for(".index")), ('$\Q$', url_for(".index_Q")), ('%s' % data['slabel'][0], url_for(".by_conductor", cond=data['slabel'][0])), ('%s' % data['slabel'][1], url_for(".by_url_isogeny_class_label", cond=data['slabel'][0], alpha=data['slabel'][1]))] if is_curve: bread += [('%s' % data['slabel'][2], url_for(".by_url_isogeny_class_discriminant", cond=data['slabel'][0], alpha=data['slabel'][1], disc=data['slabel'][2])), ('%s' % data['slabel'][3], url_for(".by_url_curve_label", cond=data['slabel'][0], alpha=data['slabel'][1], disc=data['slabel'][2], num=data['slabel'][3]))] # Title self.title = "Genus 2 " + ("Curve " if is_curve else "Isogeny Class ") + data['label'] # Code snippets (only for curves) if not is_curve: return self.code = code = {} code['show'] = {'sage': '', 'magma': ''} # use default show names code['curve'] = { 'sage': 'R.<x> = PolynomialRing(QQ); C = HyperellipticCurve(R(%s), R(%s))' % (data['min_eqn'][0], data['min_eqn'][1]), 'magma': 'R<x> := PolynomialRing(Rationals()); C := HyperellipticCurve(R!%s, R!%s);' % (data['min_eqn'][0], data['min_eqn'][1]) } if data['abs_disc'] % 4096 == 0: ind2 = [a[0] for a in data['bad_lfactors']].index(2) bad2 = data['bad_lfactors'][ind2][1] magma_cond_option = ': ExcFactors:=[*<2,Valuation(' + str( data['cond']) + ',2),R!' + str(bad2) + '>*]' else: magma_cond_option = '' code['cond'] = { 'magma': 'Conductor(LSeries(C%s)); Factorization($1);' % magma_cond_option } code['disc'] = { 'magma': 'Discriminant(C); Factorization(Integers()!$1);' } code['igusa_clebsch'] = { 'sage': 'C.igusa_clebsch_invariants(); [factor(a) for a in _]', 'magma': 'IgusaClebschInvariants(C); [Factorization(Integers()!a): a in $1];' } code['igusa'] = { 'magma': 'IgusaInvariants(C); [Factorization(Integers()!a): a in $1];' } code['g2'] = {'magma': 'G2Invariants(C);'} code['aut'] = {'magma': 'AutomorphismGroup(C); IdentifyGroup($1);'} code['autQbar'] = { 'magma': 'AutomorphismGroup(ChangeRing(C,AlgebraicClosure(Rationals()))); IdentifyGroup($1);' } code['num_rat_wpts'] = { 'magma': '#Roots(HyperellipticPolynomials(SimplifiedModel(C)));' } if ratpts: code['rat_pts'] = { 'magma': '[' + ','.join([ "C![%s,%s,%s]" % (p[0], p[1], p[2]) for p in ratpts['rat_pts'] ]) + '];' } code['two_selmer'] = { 'magma': 'TwoSelmerGroup(Jacobian(C)); NumberOfGenerators($1);' } code['has_square_sha'] = {'magma': 'HasSquareSha(Jacobian(C));'} code['locally_solvable'] = { 'magma': 'f,h:=HyperellipticPolynomials(C); g:=4*f+h^2; HasPointsEverywhereLocally(g,2) and (#Roots(ChangeRing(g,RealField())) gt 0 or LeadingCoefficient(g) gt 0);' } code['torsion_subgroup'] = { 'magma': 'TorsionSubgroup(Jacobian(SimplifiedModel(C))); AbelianInvariants($1);' }
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 rep_galois_modl_search(**args): C = getDBConnection() info = to_dict(args) # what has been entered in the search boxes if 'download' in info: return download_search(info) if 'label' in info and info.get('label'): return rep_galois_modl_by_label_or_name(info.get('label'), C) query = {} try: for field, name in (('dim', 'Dimension'), ('det', 'Determinant'), ('level', None), ('minimum', 'Minimal vector length'), ('class_number', None), ('aut', 'Group order')): parse_ints(info, query, field, name) # Check if length of gram is triangular gram = info.get('gram') if gram and not (9 + 8 * ZZ(gram.count(','))).is_square(): flash( Markup( "Error: <span style='color:black'>%s</span> is not a valid input for Gram matrix. It must be a list of integer vectors of triangular length, such as [1,2,3]." % (gram)), "error") raise ValueError parse_list(info, query, 'gram', process=vect_to_sym) except ValueError as err: info['err'] = str(err) return search_input_error(info) count = parse_count(info, 50) start = parse_start(info) info['query'] = dict(query) res = C.mod_l_galois.reps.find(query).sort([('dim', ASC), ('det', ASC), ('level', ASC), ('class_number', ASC), ('label', ASC) ]).skip(start).limit(count) nres = res.count() if (start >= nres): start -= (1 + (start - nres) / count) * count if (start < 0): start = 0 info['number'] = nres info['start'] = int(start) info['more'] = int(start + count < nres) if nres == 1: info['report'] = 'unique match' else: if nres == 0: info['report'] = 'no matches' else: if nres > count or start != 0: info['report'] = 'displaying matches %s-%s of %s' % ( start + 1, min(nres, start + count), nres) else: info['report'] = 'displaying all %s matches' % nres res_clean = [] for v in res: v_clean = {} v_clean['label'] = v['label'] v_clean['dim'] = v['dim'] v_clean['det'] = v['det'] v_clean['level'] = v['level'] v_clean['gram'] = vect_to_matrix(v['gram']) res_clean.append(v_clean) info['rep_galois_modls'] = res_clean t = 'Mod ℓ Galois representations Search Results' bread = [('Representations', "/Representation"), ("mod ℓ", url_for(".index")), ('Search Results', ' ')] properties = [] return render_template("rep_galois_modl-search.html", info=info, title=t, properties=properties, bread=bread, learnmore=learnmore_list())
def render_hgm_webpage(label): data = None info = {} data = db.hgm_motives.lookup(label) if data is None: abort( 404, "Hypergeometric motive " + label + " was not found in the database.") title = 'Hypergeometric Motive:' + label A = data['A'] B = data['B'] alpha = cyc_to_QZ(A) beta = cyc_to_QZ(B) gammas = ab2gammas(A, B) det = db.hgm_families.lucky({'A': A, 'B': B}, 'det') if det is None: det = 'data not computed' else: det = [det[0], str(det[1])] d1 = det[1] d1 = re.sub(r'\s', '', d1) d1 = re.sub(r'(.)\(', r'\1*(', d1) R = PolynomialRing(ZZ, 't') if det[1] == '': d2 = R(1) else: d2 = R(d1) det = d2(QQ(data['t'])) * det[0] t = latex(QQ(data['t'])) typee = 'Orthogonal' if (data['weight'] % 2) == 1 and (data['degree'] % 2) == 0: typee = 'Symplectic' primes = [ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71 ] locinfo = data['locinfo'] for j in range(len(locinfo)): locinfo[j] = [primes[j]] + locinfo[j] #locinfo[j][2] = poly_with_factored_coeffs(locinfo[j][2], primes[j]) locinfo[j][2] = list_to_factored_poly_otherorder(locinfo[j][2], vari='x') hodge = data['hodge'] famhodge = data['famhodge'] prop2 = [ ('Label', '%s' % data['label']), ('A', r'\(%s\)' % A), ('B', r'\(%s\)' % B), ('Degree', r'\(%s\)' % data['degree']), ('Weight', r'\(%s\)' % data['weight']), ('Hodge vector', r'\(%s\)' % hodge), ('Conductor', r'\(%s\)' % data['cond']), ] # Now add factorization of conductor Cond = ZZ(data['cond']) if not (Cond.abs().is_prime() or Cond == 1): data['cond'] = "%s=%s" % (str(Cond), factorint(data['cond'])) info.update({ 'A': A, 'B': B, 'alpha': web_latex(alpha), 'beta': web_latex(beta), 'gammas': gammas, 't': t, 'degree': data['degree'], 'weight': data['weight'], 'sign': data['sign'], 'sig': data['sig'], 'hodge': hodge, 'famhodge': famhodge, 'cond': data['cond'], 'req': data['req'], 'lcms': data['lcms'], 'type': typee, 'det': det, 'locinfo': locinfo }) AB_data, t_data = data["label"].split("_t") friends = [("Motive family " + AB_data.replace("_", " "), url_for(".by_family_label", label=AB_data))] friends.append(('L-function', url_for("l_functions.l_function_hgm_page", label=AB_data, t='t' + t_data))) # if rffriend != '': # friends.append(('Discriminant root field', rffriend)) AB = 'A = ' + str(A) + ', B = ' + str(B) t_data = str(QQ(data['t'])) bread = get_bread([('family ' + str(AB), url_for(".by_family_label", label=AB_data)), ('t = ' + t_data, ' ')]) return render_template("hgm-show-motive.html", credit=HGM_credit, title=title, bread=bread, info=info, properties=prop2, friends=friends, learnmore=learnmore_list())
def monodromy(self): def dogapthing(m1): mnew = str(m1[2]) mnew = mnew.replace(' ', '') if GAP_ID_RE.match(mnew): mnew = mnew[1:-1] two = mnew.split(',') two = [int(j) for j in two] try: m1[2] = small_group_display_knowl(two[0], two[1]) except TypeError: m1[2] = 'Gap[%d,%d]' % (two[0], two[1]) else: # Fix multiple backslashes m1[2] = re.sub(r'\\+', r'\\', m1[2]) m1[2] = '$%s$' % m1[2] return m1 def getgroup(m1, ell): pind = {2: 0, 3: 1, 5: 2, 7: 3, 11: 4, 13: 5} if not m1[3][2]: return [m1[2], m1[0]] myA = m1[3][0] myB = m1[3][1] if not myA and not myB: # myA = myB = [] return [small_group_display_knowl(1, 1), 1] mono = db.hgm_families.lucky({ 'A': myA, 'B': myB }, projection="mono") if mono is None: return ['??', 1] newthing = mono[pind[ell]] newthing = dogapthing(newthing[1]) return [newthing[2], newthing[0]] def splitint(a, p): if a == 1: return ' ' j = valuation(a, p) if j == 0: return str(a) a = a / p**j if a == 1: return latex(ZZ(p**j).factor()) return str(a) + r'\cdot' + latex(ZZ(p**j).factor()) # # this will have a new data format in the future # converted = [[ell, # dogapthing(m1), # getgroup(m1, ell), # latex(ZZ(m1[0]).factor())] for ell, m1 in self.mono if m1 != 0] # return [[m[0], m[1], m[2][0], # splitint(m[1][0]/m[2][1], m[0]), m[3]] for m in converted] mono = [m for m in self.mono if m[1] != 0] mono = [[ m[0], dogapthing(m[1]), getgroup(m[1], m[0]), latex(ZZ(m[1][0]).factor()) ] for m in mono] mono = [[ m[0], m[1], m[2][0], splitint(ZZ(m[1][0]) / m[2][1], m[0]), m[3] ] for m in mono] return mono
def make_E(self): coeffs = self.ainvs # list of 5 lists of d strings self.ainvs = [self.field.parse_NFelt(x) for x in coeffs] self.latex_ainvs = web_latex(self.ainvs) from sage.schemes.elliptic_curves.all import EllipticCurve self.E = E = EllipticCurve(self.ainvs) self.equn = web_latex(E) self.numb = str(self.number) # Conductor, discriminant, j-invariant N = E.conductor() self.cond = web_latex(N) self.cond_norm = web_latex(N.norm()) if N.norm() == 1: # since the factorization of (1) displays as "1" self.fact_cond = self.cond else: self.fact_cond = web_latex_ideal_fact(N.factor()) self.fact_cond_norm = web_latex(N.norm().factor()) D = self.field.K().ideal(E.discriminant()) self.disc = web_latex(D) self.disc_norm = web_latex(D.norm()) if D.norm() == 1: # since the factorization of (1) displays as "1" self.fact_disc = self.disc else: self.fact_disc = web_latex_ideal_fact(D.factor()) self.fact_disc_norm = web_latex(D.norm().factor()) # Minimal model? # # All curves in the database should be given # by models which are globally minimal if possible, else # minimal at all but one prime. But we do not rely on this # here, and the display should be correct if either (1) there # exists a global minimal model but this model is not; or (2) # this model is non-minimal at more than one prime. # self.non_min_primes = non_minimal_primes(E) self.is_minimal = (len(self.non_min_primes) == 0) self.has_minimal_model = True if not self.is_minimal: self.non_min_prime = ','.join([web_latex(P) for P in self.non_min_primes]) self.has_minimal_model = has_global_minimal_model(E) if not self.is_minimal: Dmin = minimal_discriminant_ideal(E) self.mindisc = web_latex(Dmin) self.mindisc_norm = web_latex(Dmin.norm()) if Dmin.norm() == 1: # since the factorization of (1) displays as "1" self.fact_mindisc = self.mindisc else: self.fact_mindisc = web_latex_ideal_fact(Dmin.factor()) self.fact_mindisc_norm = web_latex(Dmin.norm().factor()) j = E.j_invariant() if j: d = j.denominator() n = d * j # numerator exists for quadratic fields only! g = GCD(list(n)) n1 = n / g self.j = web_latex(n1) if d != 1: if n1 > 1: # self.j = "("+self.j+")\(/\)"+web_latex(d) self.j = web_latex(r"\frac{%s}{%s}" % (self.j, d)) else: self.j = web_latex(d) if g > 1: if n1 > 1: self.j = web_latex(g) + self.j else: self.j = web_latex(g) self.j = web_latex(j) self.fact_j = None if j.is_zero(): self.fact_j = web_latex(j) else: try: self.fact_j = web_latex(j.factor()) except (ArithmeticError, ValueError): # if not all prime ideal factors principal pass # CM and End(E) self.cm_bool = "no" self.End = "\(\Z\)" if self.cm: self.cm_bool = "yes (\(%s\))" % self.cm if self.cm % 4 == 0: d4 = ZZ(self.cm) // 4 self.End = "\(\Z[\sqrt{%s}]\)" % (d4) else: self.End = "\(\Z[(1+\sqrt{%s})/2]\)" % self.cm # Q-curve / Base change self.qc = "no" try: if self.q_curve: self.qc = "yes" except AttributeError: # in case the db entry does not have this field set pass # Torsion self.ntors = web_latex(self.torsion_order) self.tr = len(self.torsion_structure) if self.tr == 0: self.tor_struct_pretty = "Trivial" if self.tr == 1: self.tor_struct_pretty = "\(\Z/%s\Z\)" % self.torsion_structure[0] if self.tr == 2: self.tor_struct_pretty = r"\(\Z/%s\Z\times\Z/%s\Z\)" % tuple(self.torsion_structure) torsion_gens = [E([self.field.parse_NFelt(x) for x in P]) for P in self.torsion_gens] self.torsion_gens = ",".join([web_latex(P) for P in torsion_gens]) # Rank or bounds try: self.rk = web_latex(self.rank) except AttributeError: self.rk = "?" try: self.rk_bnds = "%s...%s" % tuple(self.rank_bounds) except AttributeError: self.rank_bounds = [0, Infinity] self.rk_bnds = "not recorded" # Generators try: gens = [E([self.field.parse_NFelt(x) for x in P]) for P in self.gens] self.gens = ", ".join([web_latex(P) for P in gens]) if self.rk == "?": self.reg = "unknown" else: if gens: self.reg = E.regulator_of_points(gens) else: self.reg = 1 # otherwise we only get 1.00000... except AttributeError: self.gens = "not recorded" self.reg = "unknown" try: if self.rank == 0: self.reg = 1 except AttributeError: pass # Local data self.local_data = [] for p in N.prime_factors(): self.local_info = E.local_data(p, algorithm="generic") self.local_data.append({'p': web_latex(p), 'norm': web_latex(p.norm().factor()), 'tamagawa_number': self.local_info.tamagawa_number(), 'kodaira_symbol': web_latex(self.local_info.kodaira_symbol()).replace('$', ''), 'reduction_type': self.local_info.bad_reduction_type(), 'ord_den_j': max(0, -E.j_invariant().valuation(p)), 'ord_mindisc': self.local_info.discriminant_valuation(), 'ord_cond': self.local_info.conductor_valuation() }) # URLs of self and related objects: self.urls = {} # It's useful to be able to use this class out of context, when calling url_for will fail: try: self.urls['curve'] = url_for(".show_ecnf", nf=self.field_label, conductor_label=self.conductor_label, class_label=self.iso_label, number=self.number) except RuntimeError: return self.urls['class'] = url_for(".show_ecnf_isoclass", nf=self.field_label, conductor_label=self.conductor_label, class_label=self.iso_label) self.urls['conductor'] = url_for(".show_ecnf_conductor", nf=self.field_label, conductor_label=self.conductor_label) self.urls['field'] = url_for(".show_ecnf1", nf=self.field_label) if self.field.is_real_quadratic(): self.hmf_label = "-".join([self.field.label, self.conductor_label, self.iso_label]) self.urls['hmf'] = url_for('hmf.render_hmf_webpage', field_label=self.field.label, label=self.hmf_label) if self.field.is_imag_quadratic(): self.bmf_label = "-".join([self.field.label, self.conductor_label, self.iso_label]) self.friends = [] self.friends += [('Isogeny class ' + self.short_class_label, self.urls['class'])] self.friends += [('Twists', url_for('ecnf.index', field_label=self.field_label, jinv=self.jinv))] if self.field.is_real_quadratic(): self.friends += [('Hilbert Modular Form ' + self.hmf_label, self.urls['hmf'])] if self.field.is_imag_quadratic(): self.friends += [('Bianchi Modular Form %s not yet available' % self.bmf_label, '')] self.properties = [ ('Base field', self.field.field_pretty()), ('Label', self.label)] # Plot if E.base_field().signature()[0]: self.plot = encode_plot(EC_nf_plot(E, self.field.generator_name())) self.plot_link = '<img src="%s" width="200" height="150"/>' % self.plot self.properties += [(None, self.plot_link)] self.properties += [ ('Conductor', self.cond), ('Conductor norm', self.cond_norm), ('j-invariant', self.j), ('CM', self.cm_bool)] if self.base_change: self.properties += [('base-change', 'yes: %s' % ','.join([str(lab) for lab in self.base_change]))] else: self.base_change = [] # in case it was False instead of [] self.properties += [('Q-curve', self.qc)] r = self.rk if r == "?": r = self.rk_bnds self.properties += [ ('Torsion order', self.ntors), ('Rank', r), ] for E0 in self.base_change: self.friends += [('Base-change of %s /\(\Q\)' % E0, url_for("ec.by_ec_label", label=E0))]
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 dim_error_tradeoff(A, c, u, beta, h, k, alpha=None, tau=None, float_type="mpfr", use_lll=True): """ :param A: LWE matrix :param c: LWE vector :param u: Uniform vector :param beta: BKW block size :param h: Hamming weight of secret :param k: LWE dim after tradeoff :param tau: number of new samples to generate :param use_lll: If True, run BKZ only once and then run LLL If False, run BKZ iteratively * secret vector s is used to see the error term of new LWE(-like) samples. """ from fpylll import BKZ, IntegerMatrix, LLL, GSO from fpylll.algorithms.bkz2 import BKZReduction as BKZ2 n = A.ncols() q = A.base_ring().order() K = GF(q, proof=False) if alpha is None: alpha = 8 / q if tau is None: tau = 30 m = A.nrows() / n scale = round(alpha * q * sqrt(m) / sqrt(2 * pi * h)) scale = ZZ(scale) count = 0 A_k = matrix(ZZ, 1, k) c_k = [] u_k = [] length = 0 while count < tau: r = count * m T = A.matrix_from_rows([i + r for i in range(m)]) ct = c[r:r + m] ut = u[r:r + m] T1 = T.matrix_from_columns([i for i in range(n - k)]) L = dual_instance1(T1, scale=scale) L = IntegerMatrix.from_matrix(L) L = LLL.reduction(L) M = GSO.Mat(L, float_type=float_type) bkz = BKZ2(M) param = BKZ.Param(block_size=beta, strategies=BKZ.DEFAULT_STRATEGY, auto_abort=True, max_loops=16, flags=BKZ.AUTO_ABORT | BKZ.MAX_LOOPS) bkz(param) H = copy(L) y = vector(ZZ, tuple(L[0])) length += y.norm() T2 = T.matrix_from_columns([n - k + i for i in range(k)]) A_kt, c_kt, u_kt = apply_short1(y, T2, ct, ut, scale=scale) if r == 0: A_k[0] = A_kt else: A_k = A_k.stack(A_kt) c_k.append(c_kt) u_k.append(u_kt) count += 1 length = float(length / tau) A_k = A_k.change_ring(K) c_k = vector(K, c_k) u_k = vector(K, u_k) B = float(2 + 1 / sqrt(2 * pi)) * (alpha * q) B = B * B * m / (m + n) B = sqrt(B) * length / scale print '(A_k, c_k) is k-dim LWE samples (with secret s[-k:]) / (A_k, u_k) is uniform samples. ' return A_k, c_k, u_k, B