def add_isogeny_matrices(N1, N2): """ Add the 'isogeny_matrix' field to every curve in the database whose conductor is between N1 and N2 inclusive. The matrix is stored as a list of n lists of n ints, where n is the size of the class and the (i,j) entry is the degree of a cyclic isogeny from curve i to curve j in the class, using the lmfdb numbering within each class. Hence this matrix is exactly the same for all curves in the class. This was added in July 2014 to save recomputing the complete isogeny class every time despite the fact that the curves in the class were already in the database. """ query = {} query['conductor'] = {'$gt': int(N1) - 1, '$lt': int(N2) + 1} query['number'] = int(1) res = curves.find(query) res = res.sort([('conductor', pymongo.ASCENDING), ('lmfdb_iso', pymongo.ASCENDING)]) for C in res: if 'isogeny_matrix' in C: print("class {} has isogeny matrix already, skipping".format( C['label'])) continue lmfdb_iso = C['lmfdb_iso'] E = EllipticCurve([int(a) for a in C['ainvs']]) M = E.isogeny_class(order="lmfdb").matrix() mat = [list([int(c) for c in r]) for r in M.rows()] n = len(mat) print("{} curves in class {}".format(n, lmfdb_iso)) for label_i in [lmfdb_iso + str(i + 1) for i in range(n)]: data = {} data['lmfdb_label'] = label_i data['isogeny_matrix'] = mat curves.update({'lmfdb_label': label_i}, {"$set": data}, upsert=True)
def add_isogeny_matrices(N1,N2): """ Add the 'isogeny_matrix' field to every curve in the database whose conductor is between N1 and N2 inclusive. The matrix is stored as a list of n lists of n ints, where n is the size of the class and the (i,j) entry is the degree of a cyclic isogeny from curve i to curve j in the class, using the lmfdb numbering within each class. Hence this matrix is exactly the same for all curves in the class. This was added in July 2014 to save recomputing the complete isogeny class every time despite the fact that the curves in the class were already in the database. """ query = {} query['conductor'] = { '$gt': int(N1)-1, '$lt': int(N2)+1 } query['number'] = int(1) res = curves.find(query) res = res.sort([('conductor', pymongo.ASCENDING), ('lmfdb_iso', pymongo.ASCENDING)]) for C in res: if 'isogeny_matrix' in C: print("class {} has isogeny matrix already, skipping".format(C['label'])) continue lmfdb_iso = C['lmfdb_iso'] E = EllipticCurve([int(a) for a in C['ainvs']]) M = E.isogeny_class(order="lmfdb").matrix() mat = [list([int(c) for c in r]) for r in M.rows()] n = len(mat) print("{} curves in class {}".format(n,lmfdb_iso)) for label_i in [lmfdb_iso+str(i+1) for i in range(n)]: data = {} data['lmfdb_label'] = label_i data['isogeny_matrix'] = mat curves.update({'lmfdb_label': label_i}, {"$set": data}, upsert=True)
def render_isogeny_class(iso_class): info = {} credit = 'John Cremona' lmfdb_iso = iso_class # e.g. '11.a' N, iso, number = lmfdb_label_regex.match(lmfdb_iso).groups() CDB = lmfdb.base.getDBConnection().elliptic_curves.curves E1data = CDB.find_one({'lmfdb_label': lmfdb_iso + '1'}) if E1data is None: return elliptic_curve_jump_error(lmfdb_iso, {}) cremona_iso = E1data['iso'] ainvs = [int(a) for a in E1data['ainvs']] E1 = EllipticCurve(ainvs) ver = sage.version.version.split('.') # e.g. "6.1.beta2" ma = int(ver[0]) mi = int(ver[1]) if ma > 6 or ma == 6 and mi > 1: # Code for Sage 6.2 and later: isogeny_class = E1.isogeny_class() curves = isogeny_class.curves mat = isogeny_class.matrix() else: # Code for Sage 6.1 and before: curves, mat = E1.isogeny_class() size = len(curves) # Create a list of the curves in the class from the database, so # they are in the correct order! db_curves = [E1] optimal_flags = [False] * size degrees = [0] * size if 'degree' in E1data: degrees[0] = E1data['degree'] else: try: degrees[0] = E1.modular_degree() except RuntimeError: pass cremona_labels = [E1data['label']] + [0] * (size - 1) if E1data['number'] == 1: optimal_flags[0] = True for i in range(2, size + 1): Edata = CDB.find_one({'lmfdb_label': lmfdb_iso + str(i)}) E = EllipticCurve([int(a) for a in Edata['ainvs']]) cremona_labels[i - 1] = Edata['label'] if Edata['number'] == 1: optimal_flags[i - 1] = True if 'degree' in Edata: degrees[i - 1] = Edata['degree'] else: try: degrees[i - 1] = E.modular_degree() except RuntimeError: pass db_curves.append(E) if cremona_iso == '990h': # this isogeny class is labeled wrong in Cremona's tables optimal_flags = [False, False, True, False] # Now work out the permutation needed to match the two lists of curves: perm = [db_curves.index(E) for E in curves] # Apply the same permutation to the isogeny matrix: mat = [[mat[perm[i], perm[j]] for j in range(size)] for i in range(size)] info = {'label': lmfdb_iso} info['optimal_ainvs'] = ainvs info['rank'] = E1data['rank'] info['isogeny_matrix'] = latex(matrix(mat)) # info['f'] = ajax_more(E.q_eigenform, 10, 20, 50, 100, 250) info['f'] = web_latex(E.q_eigenform(10)) info['graph_img'] = url_for('.plot_iso_graph', label=lmfdb_iso) info['curves'] = [[ lmfdb_iso + str(i + 1), cremona_labels[i], str(list(c.ainvs())), c.torsion_order(), degrees[i], optimal_flags[i] ] for i, c in enumerate(db_curves)] friends = [] # friends.append(('Quadratic Twist', "/quadratic_twists/%s" % (lmfdb_iso))) friends.append(('L-function', url_for("l_functions.l_function_ec_page", label=lmfdb_iso))) friends.append(('Symmetric square L-function', url_for("l_functions.l_function_ec_sym_page", power='2', label=lmfdb_iso))) friends.append(('Symmetric 4th power L-function', url_for("l_functions.l_function_ec_sym_page", power='4', label=lmfdb_iso))) # render_one_elliptic_modular_form(level,weight,character,label,**kwds) friends.append(('Modular form ' + lmfdb_iso.replace('.', '.2'), url_for("emf.render_elliptic_modular_forms", level=N, weight=2, character=0, label=iso))) info['friends'] = friends info['downloads'] = [('Download coeffients of q-expansion', url_for(".download_EC_qexp", label=lmfdb_iso, limit=100)), ('Download stored data for curves in this class', url_for(".download_EC_all", label=lmfdb_iso))] if lmfdb_iso == cremona_iso: t = "Elliptic Curve Isogeny Class %s" % lmfdb_iso else: t = "Elliptic Curve Isogeny Class %s (Cremona label %s)" % ( lmfdb_iso, cremona_iso) bread = [('Elliptic Curves ', url_for(".rational_elliptic_curves")), ('isogeny class %s' % lmfdb_iso, ' ')] return render_template("iso_class.html", info=info, bread=bread, credit=credit, title=t, friends=info['friends'], downloads=info['downloads'])
class ECisog_class(object): """ Class for an isogeny class of elliptic curves over Q """ def __init__(self, dbdata): """ Arguments: - dbdata: the data from the database """ logger.debug("Constructing an instance of ECisog_class") self.__dict__.update(dbdata) self.make_class() @staticmethod def by_label(label): """ Searches for a specific elliptic curve isogeny class in the curves collection by its label, which can be either a curve label (e.g. "11.a1") or a class label (e.g. "11.a") in either LMFDB or Cremona format. """ #print "label = %s" % label try: N, iso, number = split_lmfdb_label(label) if number: data = db_ec().find_one({"lmfdb_label": label}) else: data = db_ec().find_one({"lmfdb_label": label + "1"}) except AttributeError: try: N, iso, number = split_cremona_label(label) if number: data = db_ec().find_one({"label": label}) else: data = db_ec().find_one({"label": label + "1"}) except AttributeError: return "Invalid label" # caller must catch this and raise an error if data: return ECisog_class(data) return "Class not found" # caller must catch this and raise an error def make_class(self): self.ainvs_str = self.ainvs self.ainvs = [int(a) for a in self.ainvs_str] self.E = EllipticCurve(self.ainvs) self.CM = self.E.has_cm() try: # Extract the isogeny degree matrix from the database size = len(self.isogeny_matrix) from sage.matrix.all import Matrix self.isogeny_matrix = Matrix(self.isogeny_matrix) except AttributeError: # Failsafe: construct it from scratch self.isogeny_matrix = self.E.isogeny_class(order="lmfdb").matrix() size = self.isogeny_matrix.nrows() self.ncurves = size # Create isogeny graph: self.graph = make_graph(self.isogeny_matrix) P = self.graph.plot(edge_labels=True) self.graph_img = encode_plot(P) self.graph_link = '<img src="%s" width="200" height="150"/>' % self.graph_img # Create a list of the curves in the class from the database self.db_curves = [self.E] self.optimal_flags = [False] * size self.degrees = [0] * size if self.degree: self.degrees[0] = self.degree else: try: self.degrees[0] = self.E.modular_degree() except RuntimeError: pass # Fill in the curves in the class by looking each one up in the db: self.cremona_labels = [self.label] + [0] * (size - 1) if self.number == 1: self.optimal_flags[0] = True for i in range(2, size + 1): Edata = db_ec().find_one({'lmfdb_label': self.lmfdb_iso + str(i)}) Ei = EllipticCurve([int(a) for a in Edata['ainvs']]) self.cremona_labels[i - 1] = Edata['label'] if Edata['number'] == 1: self.optimal_flags[i - 1] = True if 'degree' in Edata: self.degrees[i - 1] = Edata['degree'] else: try: self.degrees[i - 1] = Ei.modular_degree() except RuntimeError: pass self.db_curves.append(Ei) if self.iso == '990h': # this isogeny class is labeled wrong in Cremona's tables self.optimal_flags = [False, False, True, False] self.isogeny_matrix_str = latex(matrix(self.isogeny_matrix)) N, iso, number = split_lmfdb_label(self.lmfdb_iso) self.newform = web_latex(self.E.q_eigenform(10)) self.newform_label = newform_label(N, 2, 1, iso) self.newform_link = url_for("emf.render_elliptic_modular_forms", level=N, weight=2, character=1, label=iso) newform_exists_in_db = is_newform_in_db(self.newform_label) self.lfunction_link = url_for("l_functions.l_function_ec_page", label=self.lmfdb_iso) self.curves = [ dict([('label', self.lmfdb_iso + str(i + 1)), ('url', url_for(".by_triple_label", conductor=N, iso_label=iso, number=i + 1)), ('cremona_label', self.cremona_labels[i]), ('ainvs', str(list(c.ainvs()))), ('torsion', c.torsion_order()), ('degree', self.degrees[i]), ('optimal', self.optimal_flags[i])]) for i, c in enumerate(self.db_curves) ] self.friends = [('L-function', self.lfunction_link)] if not self.CM: if int(N) <= 300: self.friends += [('Symmetric square L-function', url_for("l_functions.l_function_ec_sym_page", power='2', label=self.lmfdb_iso))] if int(N) <= 50: self.friends += [('Symmetric cube L-function', url_for("l_functions.l_function_ec_sym_page", power='3', label=self.lmfdb_iso))] if newform_exists_in_db: self.friends += [('Modular form ' + self.newform_label, self.newform_link)] self.properties = [('Label', self.lmfdb_iso), ('Number of curves', str(self.ncurves)), ('Conductor', '\(%s\)' % N), ('CM', '%s' % self.CM), ('Rank', '\(%s\)' % self.rank), ('Graph', ''), (None, self.graph_link)] self.downloads = [('Download coefficients of newform', url_for(".download_EC_qexp", label=self.lmfdb_iso, limit=100)), ('Download stored data for all curves', url_for(".download_EC_all", label=self.lmfdb_iso))] if self.lmfdb_iso == self.iso: self.title = "Elliptic Curve Isogeny Class %s" % self.lmfdb_iso else: self.title = "Elliptic Curve Isogeny Class %s (Cremona label %s)" % ( self.lmfdb_iso, self.iso) self.bread = [('Elliptic Curves', url_for("ecnf.index")), ('$\Q$', url_for(".rational_elliptic_curves")), ('%s' % N, url_for(".by_conductor", conductor=N)), ('%s' % iso, ' ')]
class ECisog_class(object): """ Class for an isogeny class of elliptic curves over Q """ def __init__(self, dbdata): """ Arguments: - dbdata: the data from the database """ logger.debug("Constructing an instance of ECisog_class") self.__dict__.update(dbdata) self.make_class() @staticmethod def by_label(label): """ Searches for a specific elliptic curve isogeny class in the curves collection by its label, which can be either a curve label (e.g. "11.a1") or a class label (e.g. "11.a") in either LMFDB or Cremona format. """ #print "label = %s" % label try: N, iso, number = split_lmfdb_label(label) if number: data = db_ec().find_one({"lmfdb_label" : label}) else: data = db_ec().find_one({"lmfdb_label" : label+"1"}) except AttributeError: try: N, iso, number = split_cremona_label(label) if number: data = db_ec().find_one({"label" : label}) else: data = db_ec().find_one({"label" : label+"1"}) except AttributeError: return "Invalid label" # caller must catch this and raise an error if data: return ECisog_class(data) return "Class not found" # caller must catch this and raise an error def make_class(self): self.ainvs_str = self.ainvs self.ainvs = [int(a) for a in self.ainvs_str] self.E = EllipticCurve(self.ainvs) self.CM = self.E.has_cm() try: # Extract the isogeny degree matrix from the database size = len(self.isogeny_matrix) from sage.matrix.all import Matrix self.isogeny_matrix = Matrix(self.isogeny_matrix) except AttributeError: # Failsafe: construct it from scratch self.isogeny_matrix = self.E.isogeny_class(order="lmfdb").matrix() size = self.isogeny_matrix.nrows() self.ncurves = size # Create isogeny graph: self.graph = make_graph(self.isogeny_matrix) P = self.graph.plot(edge_labels=True) self.graph_img = encode_plot(P) self.graph_link = '<img src="%s" width="200" height="150"/>' % self.graph_img # Create a list of the curves in the class from the database self.db_curves = [self.E] self.optimal_flags = [False] * size self.degrees = [0] * size if self.degree: self.degrees[0] = self.degree else: try: self.degrees[0] = self.E.modular_degree() except RuntimeError: pass # Fill in the curves in the class by looking each one up in the db: self.cremona_labels = [self.label] + [0] * (size - 1) if self.number == 1: self.optimal_flags[0] = True for i in range(2, size + 1): Edata = db_ec().find_one({'lmfdb_label': self.lmfdb_iso + str(i)}) Ei = EllipticCurve([int(a) for a in Edata['ainvs']]) self.cremona_labels[i - 1] = Edata['label'] if Edata['number'] == 1: self.optimal_flags[i - 1] = True if 'degree' in Edata: self.degrees[i - 1] = Edata['degree'] else: try: self.degrees[i - 1] = Ei.modular_degree() except RuntimeError: pass self.db_curves.append(Ei) if self.iso == '990h': # this isogeny class is labeled wrong in Cremona's tables self.optimal_flags = [False, False, True, False] self.isogeny_matrix_str = latex(matrix(self.isogeny_matrix)) N, iso, number = split_lmfdb_label(self.lmfdb_iso) self.newform = web_latex(self.E.q_eigenform(10)) self.newform_label = newform_label(N,2,1,iso) self.newform_link = url_for("emf.render_elliptic_modular_forms", level=N, weight=2, character=1, label=iso) self.newform_exists_in_db = is_newform_in_db(self.newform_label) self.lfunction_link = url_for("l_functions.l_function_ec_page", label=self.lmfdb_iso) self.curves = [dict([('label',self.lmfdb_iso + str(i + 1)), ('url',url_for(".by_triple_label", conductor=N, iso_label=iso, number=i+1)), ('cremona_label',self.cremona_labels[i]), ('ainvs',str(list(c.ainvs()))), ('torsion',c.torsion_order()), ('degree',self.degrees[i]), ('optimal',self.optimal_flags[i])]) for i, c in enumerate(self.db_curves)] self.friends = [('L-function', self.lfunction_link)] if not self.CM: if int(N)<=300: self.friends += [('Symmetric square L-function', url_for("l_functions.l_function_ec_sym_page", power='2', label=self.lmfdb_iso))] if int(N)<=50: self.friends += [('Symmetric cube L-function', url_for("l_functions.l_function_ec_sym_page", power='3', label=self.lmfdb_iso))] if self.newform_exists_in_db: self.friends += [('Modular form ' + self.newform_label, self.newform_link)] self.properties = [('Label', self.lmfdb_iso), ('Number of curves', str(self.ncurves)), ('Conductor', '\(%s\)' % N), ('CM', '%s' % self.CM), ('Rank', '\(%s\)' % self.rank), ('Graph', ''),(None, self.graph_link) ] self.downloads = [('Download coefficients of newform', url_for(".download_EC_qexp", label=self.lmfdb_iso, limit=1000)), ('Download stored data for all curves', url_for(".download_EC_all", label=self.lmfdb_iso))] if self.lmfdb_iso == self.iso: self.title = "Elliptic Curve Isogeny Class %s" % self.lmfdb_iso else: self.title = "Elliptic Curve Isogeny Class %s (Cremona label %s)" % (self.lmfdb_iso, self.iso) self.bread = [('Elliptic Curves', url_for("ecnf.index")), ('$\Q$', url_for(".rational_elliptic_curves")), ('%s' % N, url_for(".by_conductor", conductor=N)), ('%s' % iso, ' ')] self.code = {} self.code['show'] = {'sage':''} # use default show names self.code['class'] = {'sage':'E = EllipticCurve("%s1")\n'%(self.lmfdb_iso) + 'E.isogeny_class()\n'} self.code['curves'] = {'sage':'E.isogeny_class().curves'} self.code['rank'] = {'sage':'E.rank()'} self.code['q_eigenform'] = {'sage':'E.q_eigenform(10)'} self.code['matrix'] = {'sage':'E.isogeny_class().matrix()'} self.code['plot'] = {'sage':'E.isogeny_graph().plot(edge_labels=True)'}
def render_isogeny_class(iso_class): info = {} credit = 'John Cremona' lmfdb_iso = iso_class # e.g. '11.a' N, iso, number = lmfdb_label_regex.match(lmfdb_iso).groups() CDB = lmfdb.base.getDBConnection().elliptic_curves.curves E1data = CDB.find_one({'lmfdb_label': lmfdb_iso + '1'}) if E1data is None: return elliptic_curve_jump_error(lmfdb_iso, {}) cremona_iso = E1data['iso'] ainvs = [int(a) for a in E1data['ainvs']] E1 = EllipticCurve(ainvs) curves, mat = E1.isogeny_class() size = len(curves) # Create a list of the curves in the class from the database, so # they are in the correct order! db_curves = [E1] optimal_flags = [False] * size degrees = [0] * size if 'degree' in E1data: degrees[0] = E1data['degree'] else: try: degrees[0] = E1.modular_degree() except RuntimeError: pass cremona_labels = [E1data['label']] + [0] * (size - 1) if E1data['number'] == 1: optimal_flags[0] = True for i in range(2, size + 1): Edata = CDB.find_one({'lmfdb_label': lmfdb_iso + str(i)}) E = EllipticCurve([int(a) for a in Edata['ainvs']]) cremona_labels[i - 1] = Edata['label'] if Edata['number'] == 1: optimal_flags[i - 1] = True if 'degree' in Edata: degrees[i - 1] = Edata['degree'] else: try: degrees[i - 1] = E.modular_degree() except RuntimeError: pass db_curves.append(E) if cremona_iso == '990h': # this isogeny class is labeled wrong in Cremona's tables optimal_flags = [False, False, True, False] # Now work out the permutation needed to match the two lists of curves: perm = [db_curves.index(E) for E in curves] # Apply the same permutation to the isogeny matrix: mat = [[mat[perm[i], perm[j]] for j in range(size)] for i in range(size)] info = {'label': lmfdb_iso} info['optimal_ainvs'] = ainvs info['rank'] = E1data['rank'] info['isogeny_matrix'] = latex(matrix(mat)) # info['f'] = ajax_more(E.q_eigenform, 10, 20, 50, 100, 250) info['f'] = web_latex(E.q_eigenform(10)) info['graph_img'] = url_for('plot_iso_graph', label=lmfdb_iso) info['curves'] = [[lmfdb_iso + str(i + 1), cremona_labels[i], str( list(c.ainvs())), c.torsion_order(), degrees[i], optimal_flags[i]] for i, c in enumerate(db_curves)] friends = [] # friends.append(('Quadratic Twist', "/quadratic_twists/%s" % (lmfdb_iso))) friends.append(('L-function', url_for("l_functions.l_function_ec_page", label=lmfdb_iso))) friends.append(('Symmetric square L-function', url_for("l_functions.l_function_ec_sym_page", power='2', label=lmfdb_iso))) friends.append(('Symmetric 4th power L-function', url_for("l_functions.l_function_ec_sym_page", power='4', label=lmfdb_iso))) # render_one_elliptic_modular_form(level,weight,character,label,**kwds) friends.append(('Modular form ' + lmfdb_iso.replace( '.', '.2'), url_for("emf.render_elliptic_modular_forms", level=N, weight=2, character=0, label=iso))) info['friends'] = friends info['downloads'] = [('Download coeffients of q-expansion', url_for("download_EC_qexp", label=lmfdb_iso, limit=100)), ('Download stored data for curves in this class', url_for("download_EC_all", label=lmfdb_iso))] if lmfdb_iso == cremona_iso: t = "Elliptic Curve Isogeny Class %s" % lmfdb_iso else: t = "Elliptic Curve Isogeny Class %s (Cremona label %s)" % (lmfdb_iso, cremona_iso) bread = [('Elliptic Curves ', url_for("rational_elliptic_curves")), ('isogeny class %s' % lmfdb_iso, ' ')] return render_template("elliptic_curve/iso_class.html", info=info, bread=bread, credit=credit, title=t, friends=info['friends'], downloads=info['downloads'])
def class_js(lab): E = EllipticCurve(lab) return Set([E1.j_invariant() for E1 in E.isogeny_class()])