def field_label(F, pretty=True, check=False): r""" Returns the LMFDB label of the field F. """ if F.absolute_degree() == 1: p = 'x' else: pp = F.absolute_polynomial() x = pp.parent().gen() p = str(pp).replace(str(x), 'x') l = poly_to_field_label(p) if l is None: if check: return False else: if pretty: return web_latex_split_on_pm(pp) else: return pp else: if check: return True if pretty: return field_pretty(l) else: return l
def find_field(pol, verbose=False): """ pol is a string holding a list of coefficients, constant first, 1 last, e.g. '-2,0,1' Looks up this defining polynomial kn LMFDB and returns its label, or None """ coeffs = str_to_list(pol) deg = len(coeffs)-1 if deg==2: c, b, a = coeffs d = ZZ(b*b-4*a*c).squarefree_part() D = d if (d-1)%4==0 else 4*d absD = D.abs() s = 0 if d<0 else 2 return '2.{}.{}.1'.format(s,absD) from lmfdb.number_fields.number_field import poly_to_field_label poly = Qx(coeffs) Flabel = poly_to_field_label(poly) if Flabel==None: print("********* field with polynomial {} is not in the database!".format(poly)) K = NumberField(poly, 'a') poly = K.optimized_representation()[0].defining_polynomial() print("********* using optimised polynomial {}".format(poly)) return poly_to_str(poly) else: if verbose: print("{} has label {}".format(pol,Flabel)) return Flabel
def field_label(F, pretty = True, check=False): r""" Returns the LMFDB label of the field F. """ if F.absolute_degree() == 1: p = 'x' else: pp = F.absolute_polynomial() x = pp.parent().gen() p = str(pp).replace(str(x), 'x') l = poly_to_field_label(p) if l is None: if check: return False else: if pretty: return web_latex_split_on_pm(pp) else: return pp else: if check: return True if pretty: return field_pretty(l) else: return l
def find_field(pol, verbose=False): """ pol is a string holding a list of coefficients, constant first, 1 last, e.g. '-2,0,1' Looks up this defining polynomial kn LMFDB and returns its label, or None """ coeffs = str_to_list(pol) deg = len(coeffs) - 1 if deg == 2: c, b, a = coeffs d = ZZ(b * b - 4 * a * c).squarefree_part() D = d if (d - 1) % 4 == 0 else 4 * d absD = D.abs() s = 0 if d < 0 else 2 return '2.{}.{}.1'.format(s, absD) from lmfdb.number_fields.number_field import poly_to_field_label poly = Qx(coeffs) Flabel = poly_to_field_label(poly) if Flabel is None: print("********* field with polynomial {} is not in the database!". format(poly)) K = NumberField(poly, 'a') poly = K.optimized_representation()[0].defining_polynomial() print("********* using optimised polynomial {}".format(poly)) return poly_to_str(poly) else: if verbose: print("{} has label {}".format(pol, Flabel)) return Flabel
def to_db(self): r""" We store the LMFDB label of the absolute field in the db. """ K = self._value if K.absolute_degree() == 1: p = 'x' else: p = K.absolute_polynomial() l = poly_to_field_label(p) return l
def add_lattice_nf(ll): n_field, gram_input = ll gram_input = [[int(i) for i in l] for l in gram_input] R = PolynomialRing(QQ, 'x') nf_label = poly_to_field_label(R(n_field)) lattice = l1.find_one({'gram': gram_input}) if lattice is None: n = len(gram_input[0]) d = matrix(gram_input).determinant() result = [ B for B in l1.find({ 'dim': int(n), 'det': int(d) }) if isom(gram_input, B['gram']) ] if len(result) == 1: lat_label = result[0]['label'] is_lat_in = "yes" elif len(result) > 1: print "... need to be checked ..." print "***********" else: lat_label = "new" is_lat_in = gram_input else: lat_label = lattice['label'] is_lat_in = "yes" try: lab = nf_label + lat_label except: print nf_label, lat_label print "fail" res = l2.find_one({'label': lab}) if res is None: print "new data" if saving: l2.insert_one({ 'nf_label': nf_label, 'lat_label': lat_label, 'is_lat_in': is_lat_in, 'label': lab }) else: print "data already in the database"
def to_db(self): r""" We store the LMFDB label of the absolute field in the db. """ if self._db_value_has_been_set and not self._db_value is None: return self._db_value K = self._value if hasattr(K, "lmfdb_label"): return K.lmfdb_label if K.absolute_degree() == 1: p = 'x' else: p = K.absolute_polynomial() l = poly_to_field_label(p) return l
def add_lattice_nf(ll): n_field,gram_input = ll gram_input=[[int(i) for i in l] for l in gram_input] R = PolynomialRing(QQ, 'x'); nf_label = poly_to_field_label(R(n_field)) lattice = l1.find_one({'gram': gram_input }) if lattice is None: n=len(gram_input[0]) d=matrix(gram_input).determinant() result=[B for B in l1.find({'dim': int(n), 'det' : int(d)}) if isom(gram_input, B['gram'])] if len(result)==1: lat_label =result[0]['label'] is_lat_in = "yes" elif len(result)>1: print "... need to be checked ..." print "***********" else : lat_label = "new" is_lat_in = gram_input else: lat_label=lattice['label'] is_lat_in = "yes" try: lab=nf_label+lat_label except: print nf_label, lat_label print "fail" res=l2.find_one({'label': lab }) if res is None: print "new data" if saving: l2.insert_one({'nf_label': nf_label, 'lat_label': lat_label, 'is_lat_in' : is_lat_in, 'label': lab}) else: print "data already in the database"
def render_sample_page(family, sam, args, bread): info = { 'args': to_dict(args), 'sam': sam, 'latex': latex, 'type': sam.type(), 'name': sam.name(), 'full_name': sam.full_name(), 'weight': sam.weight(), 'fdeg': sam.degree_of_field(), 'is_eigenform': sam.is_eigenform(), 'field_poly': sam.field_poly() } if sam.is_integral() != None: info['is_integral'] = sam.is_integral() if 'Sp4Z' in sam.collection(): info['space_url'] = url_for('.Sp4Z_j_space', k=info['weight'], j=0) if 'Sp4Z_2' in sam.collection(): info['space_url'] = url_for('.Sp4Z_j_space', k=info['weight'], j=2) info['space'] = '$' + family.latex_name.replace( 'k', '{' + str(sam.weight()) + '}') + '$' if 'space_url' in info: bread.append((info['space'], info['space_url'])) info['space_href'] = '<a href="%s">%s</d>' % ( info['space_url'], info['space']) if 'space_url' in info else info['space'] if info['field_poly'].disc() < 10**10: label = poly_to_field_label(info['field_poly']) if label: info['field_label'] = label info['field_url'] = url_for('number_fields.by_label', label=label) info['field_href'] = '<a href="%s">%s</a>' % (info['field_url'], field_pretty(label)) bread.append((info['name'], '')) title = 'Siegel modular forms sample ' + info['full_name'] properties = [('Space', info['space_href']), ('Name', info['name']), ('Type', '<br>'.join(info['type'].split(','))), ('Weight', str(info['weight'])), ('Hecke eigenform', str(info['is_eigenform'])), ('Field degree', str(info['fdeg']))] try: evs_to_show = parse_ints_to_list_flash(args.get('ev_index'), 'list of $l$') fcs_to_show = parse_ints_to_list_flash(args.get('fc_det'), 'list of $\\det(F)$') except ValueError: evs_to_show = [] fcs_to_show = [] info['evs_to_show'] = sorted([ n for n in (evs_to_show if len(evs_to_show) else sam.available_eigenvalues()[:10]) ]) info['fcs_to_show'] = sorted([ n for n in (fcs_to_show if len(fcs_to_show) else sam. available_Fourier_coefficients()[1:6]) ]) info['evs_avail'] = [n for n in sam.available_eigenvalues()] info['fcs_avail'] = [n for n in sam.available_Fourier_coefficients()] # Do not attempt to constuct a modulus ideal unless the field has a reasonably small discriminant # otherwise sage may not even be able to factor the discriminant info['field'] = sam.field() if info['field_poly'].disc() < 10**80: null_ideal = sam.field().ring_of_integers().ideal(0) info['modulus'] = null_ideal modulus = args.get('modulus', '').strip() m = 0 if modulus: try: O = sam.field().ring_of_integers() m = O.ideal([O(str(b)) for b in modulus.split(',')]) except Exception: info['error'] = True flash_error( "Unable to construct modulus ideal from specified generators %s.", modulus) if m == 1: info['error'] = True flash_error( "The ideal %s is the unit ideal, please specify a different modulus.", '(' + modulus + ')') m = 0 info['modulus'] = m # Hack to reduce polynomials and to handle non integral stuff def redc(c): return m.reduce(c * c.denominator()) / m.reduce(c.denominator()) def redp(f): c = f.dict() return f.parent()(dict((e, redc(c[e])) for e in c)) def safe_reduce(f): if not m: return latex(f) try: if f in sam.field(): return latex(redc(f)) else: return latex(redp(f)) except ZeroDivisionError: return '\\textrm{Unable to reduce} \\bmod\\mathfrak{m}' info['reduce'] = safe_reduce else: info['reduce'] = latex # check that explicit formula is not ridiculously big if sam.explicit_formula(): info['explicit_formula_bytes'] = len(sam.explicit_formula()) if len(sam.explicit_formula()) < 100000: info['explicit_formula'] = sam.explicit_formula() return render_template("ModularForm_GSp4_Q_sample.html", title=title, bread=bread, properties2=properties, info=info)
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 nf_string_to_label(FF): # parse Q, Qsqrt2, Qsqrt-4, Qzeta5, etc if FF in ['q', 'Q']: return '1.1.1.1' if FF.lower() in ['qi', 'q(i)']: return '2.0.4.1' # Change unicode dash with minus sign FF = FF.replace(u'\u2212', '-') # remove non-ascii characters from F # we need to encode and decode for Python 3, as 'str' object has no attribute 'decode' FF = FF.encode('utf8').decode('utf8').encode('ascii', 'ignore') F = FF.lower() # keep original if needed if len(F) == 0: raise SearchParsingError( "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 SearchParsingError( "After {0}, the remainder must be a nonzero integer. Use {0}5 or {0}-11 for example." .format(FF[: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[0:5] == 'qzeta': if '_' in F: F = F.replace('_', '') match_obj = re.match(r'^qzeta(\d+)(\+|plus)?$', F) if not match_obj: raise SearchParsingError( "After {0}, the remainder must be a positive integer or a positive integer followed by '+'. Use {0}5 or {0}19+, for example." .format(F[:5])) d = ZZ(str(match_obj.group(1))) if d % 4 == 2: d /= 2 # Q(zeta_6)=Q(zeta_3), etc) if match_obj.group(2): # asking for the totally real field from lmfdb.number_fields.web_number_field import rcyclolookup if d in rcyclolookup: return rcyclolookup[d] else: raise SearchParsingError('%s is not in the database.' % F) # Now not the totally real subfield from lmfdb.number_fields.web_number_field import cyclolookup if d in cyclolookup: return cyclolookup[d] else: raise SearchParsingError('%s is not in the database.' % F) raise SearchParsingError( '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 SearchParsingError( '%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 SearchParsingError( "A number field label 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 SearchParsingError( "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 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 render_sample_page(family, sam, args, bread): info = { 'args': to_dict(args), 'sam': sam, 'latex': latex, 'type':sam.type(), 'name':sam.name(), 'full_name': sam.full_name(), 'weight':sam.weight(), 'fdeg':sam.degree_of_field(), 'is_eigenform':sam.is_eigenform(), 'field_poly': sam.field_poly()} if sam.is_integral() != None: info['is_integral'] = sam.is_integral() if 'Sp4Z' in sam.collection(): info['space_url'] = url_for('.Sp4Z_j_space', k=info['weight'], j=0) if 'Sp4Z_2' in sam.collection(): info['space_url'] = url_for('.Sp4Z_j_space', k=info['weight'], j=2) info['space'] = '$'+family.latex_name.replace('k', '{' + str(sam.weight()) + '}')+'$' if 'space_url' in info: bread.append((info['space'], info['space_url'])) info['space_href'] = '<a href="%s">%s</d>'%(info['space_url'],info['space']) if 'space_url' in info else info['space'] if info['field_poly'].disc() < 10**10: label = poly_to_field_label(info['field_poly']) if label: info['field_label'] = label info['field_url'] = url_for('number_fields.by_label', label=label) info['field_href'] = '<a href="%s">%s</a>'%(info['field_url'], field_pretty(label)) bread.append((info['name'], '')) title='Siegel modular forms sample ' + info['full_name'] properties = [('Space', info['space_href']), ('Name', info['name']), ('Type', '<br>'.join(info['type'].split(','))), ('Weight', str(info['weight'])), ('Hecke eigenform', str(info['is_eigenform'])), ('Field degree', str(info['fdeg']))] try: evs_to_show = parse_ints_to_list_flash(args.get('ev_index'), 'list of $l$') fcs_to_show = parse_ints_to_list_flash(args.get('fc_det'), 'list of $\\det(F)$') except ValueError: evs_to_show = [] fcs_to_show = [] info['evs_to_show'] = sorted([n for n in (evs_to_show if len(evs_to_show) else sam.available_eigenvalues()[:10])]) info['fcs_to_show'] = sorted([n for n in (fcs_to_show if len(fcs_to_show) else sam.available_Fourier_coefficients()[1:6])]) info['evs_avail'] = [n for n in sam.available_eigenvalues()] info['fcs_avail'] = [n for n in sam.available_Fourier_coefficients()] # Do not attempt to constuct a modulus ideal unless the field has a reasonably small discriminant # otherwise sage may not even be able to factor the discriminant info['field'] = sam.field() if info['field_poly'].disc() < 10**80: null_ideal = sam.field().ring_of_integers().ideal(0) info['modulus'] = null_ideal modulus = args.get('modulus','').strip() m = 0 if modulus: try: O = sam.field().ring_of_integers() m = O.ideal([O(str(b)) for b in modulus.split(',')]) except Exception: info['error'] = True flash_error("Unable to construct modulus ideal from specified generators %s.", modulus) if m == 1: info['error'] = True flash_error("The ideal %s is the unit ideal, please specify a different modulus.", '('+modulus+')') m = 0 info['modulus'] = m # Hack to reduce polynomials and to handle non integral stuff def redc(c): return m.reduce(c*c.denominator())/m.reduce(c.denominator()) def redp(f): c = f.dict() return f.parent()(dict((e,redc(c[e])) for e in c)) def safe_reduce(f): if not m: return latex(f) try: if f in sam.field(): return latex(redc(f)) else: return latex(redp(f)) except ZeroDivisionError: return '\\textrm{Unable to reduce} \\bmod\\mathfrak{m}' info['reduce'] = safe_reduce else: info['reduce'] = latex # check that explicit formula is not ridiculously big if sam.explicit_formula(): info['explicit_formula_bytes'] = len(sam.explicit_formula()) if len(sam.explicit_formula()) < 100000: info['explicit_formula'] = sam.explicit_formula() return render_template("ModularForm_GSp4_Q_sample.html", title=title, bread=bread, properties2=properties, info=info)
def nf_string_to_label(F): # parse Q, Qsqrt2, Qsqrt-4, Qzeta5, etc if F == "Q": return "1.1.1.1" if F == "Qi": 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") fail_string = str(F + " is not a valid field label or name or polynomial, or is not ") 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 F[1:5] in ["sqrt", "root"]: try: d = ZZ(str(F[5:])).squarefree_part() except 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 % 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": 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) return fail_string # 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 is not in the database." % F) # Expand out factored labels, like 11.11.11e20.1 parts = F.split(".") if len(parts) != 4: raise ValueError("It must be of the form <deg>.<real_emb>.<absdisc>.<number>, such as 2.2.5.1.") 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)