def matrix(self, fill=True): """ Returns the matrix whose entries give the minimal degrees of isogenies between curves in this class. INPUT: - ``fill`` -- boolean (default True). If False then the matrix will contain only zeros and prime entries; if True it will fill in the other degrees. EXAMPLES:: sage: isocls = EllipticCurve('15a3').isogeny_class(use_tuple=False) sage: isocls.matrix() [ 1 2 2 2 4 4 8 8] [ 2 1 4 4 8 8 16 16] [ 2 4 1 4 8 8 16 16] [ 2 4 4 1 2 2 4 4] [ 4 8 8 2 1 4 8 8] [ 4 8 8 2 4 1 2 2] [ 8 16 16 4 8 2 1 4] [ 8 16 16 4 8 2 4 1] sage: isocls.matrix(fill=False) [0 2 2 2 0 0 0 0] [2 0 0 0 0 0 0 0] [2 0 0 0 0 0 0 0] [2 0 0 0 2 2 0 0] [0 0 0 2 0 0 0 0] [0 0 0 2 0 0 2 2] [0 0 0 0 0 2 0 0] [0 0 0 0 0 2 0 0] """ if self._mat is None: self._compute_matrix() mat = self._mat if fill and mat[0,0] == 0: from sage.schemes.elliptic_curves.ell_curve_isogeny import fill_isogeny_matrix mat = fill_isogeny_matrix(mat) if not fill and mat[0,0] == 1: from sage.schemes.elliptic_curves.ell_curve_isogeny import unfill_isogeny_matrix mat = unfill_isogeny_matrix(mat) return mat
def matrix(self, fill=True): """ Returns the matrix whose entries give the minimal degrees of isogenies between curves in this class. INPUT: - ``fill`` -- boolean (default True). If False then the matrix will contain only zeros and prime entries; if True it will fill in the other degrees. EXAMPLES:: sage: isocls = EllipticCurve('15a3').isogeny_class(use_tuple=False) sage: isocls.matrix() [ 1 2 2 2 4 4 8 8] [ 2 1 4 4 8 8 16 16] [ 2 4 1 4 8 8 16 16] [ 2 4 4 1 2 2 4 4] [ 4 8 8 2 1 4 8 8] [ 4 8 8 2 4 1 2 2] [ 8 16 16 4 8 2 1 4] [ 8 16 16 4 8 2 4 1] sage: isocls.matrix(fill=False) [0 2 2 2 0 0 0 0] [2 0 0 0 0 0 0 0] [2 0 0 0 0 0 0 0] [2 0 0 0 2 2 0 0] [0 0 0 2 0 0 0 0] [0 0 0 2 0 0 2 2] [0 0 0 0 0 2 0 0] [0 0 0 0 0 2 0 0] """ if self._mat is None: self._compute_matrix() mat = self._mat if fill and mat[0, 0] == 0: from sage.schemes.elliptic_curves.ell_curve_isogeny import fill_isogeny_matrix mat = fill_isogeny_matrix(mat) if not fill and mat[0, 0] == 1: from sage.schemes.elliptic_curves.ell_curve_isogeny import unfill_isogeny_matrix mat = unfill_isogeny_matrix(mat) return mat
def make_graph(M): """ Code extracted from Sage's elliptic curve isogeny class (reshaped in the case maxdegree==12) """ from sage.schemes.elliptic_curves.ell_curve_isogeny import fill_isogeny_matrix, unfill_isogeny_matrix from sage.graphs.graph import Graph n = M.nrows() # = M.ncols() G = Graph(unfill_isogeny_matrix(M), format='weighted_adjacency_matrix') MM = fill_isogeny_matrix(M) # The maximum degree classifies the shape of the isogeny # graph, though the number of vertices is often enough. # This only holds over Q, so this code will need to change # once other isogeny classes are implemented. if n == 1: # one vertex pass elif n == 2: # one edge, two vertices. We align horizontally and put # the lower number on the left vertex. G.set_pos(pos={0:[-0.5,0],1:[0.5,0]}) else: maxdegree = max(max(MM)) if n == 3: # o--o--o centervert = [i for i in range(3) if max(MM.row(i)) < maxdegree][0] other = [i for i in range(3) if i != centervert] G.set_pos(pos={centervert:[0,0],other[0]:[-1,0],other[1]:[1,0]}) elif maxdegree == 4: # o--o<8 centervert = [i for i in range(4) if max(MM.row(i)) < maxdegree][0] other = [i for i in range(4) if i != centervert] G.set_pos(pos={centervert:[0,0],other[0]:[0,1],other[1]:[-0.8660254,-0.5],other[2]:[0.8660254,-0.5]}) elif maxdegree == 27: # o--o--o--o centers = [i for i in range(4) if list(MM.row(i)).count(3) == 2] left = [j for j in range(4) if MM[centers[0],j] == 3 and j not in centers][0] right = [j for j in range(4) if MM[centers[1],j] == 3 and j not in centers][0] G.set_pos(pos={left:[-1.5,0],centers[0]:[-0.5,0],centers[1]:[0.5,0],right:[1.5,0]}) elif n == 4: # square opp = [i for i in range(1,4) if not MM[0,i].is_prime()][0] other = [i for i in range(1,4) if i != opp] G.set_pos(pos={0:[1,1],other[0]:[-1,1],opp:[-1,-1],other[1]:[1,-1]}) elif maxdegree == 8: # 8>o--o<8 centers = [i for i in range(6) if list(MM.row(i)).count(2) == 3] left = [j for j in range(6) if MM[centers[0],j] == 2 and j not in centers] right = [j for j in range(6) if MM[centers[1],j] == 2 and j not in centers] G.set_pos(pos={centers[0]:[-0.5,0],left[0]:[-1,0.8660254],left[1]:[-1,-0.8660254],centers[1]:[0.5,0],right[0]:[1,0.8660254],right[1]:[1,-0.8660254]}) elif maxdegree == 18: # two squares joined on an edge centers = [i for i in range(6) if list(MM.row(i)).count(3) == 2] top = [j for j in range(6) if MM[centers[0],j] == 3] bl = [j for j in range(6) if MM[top[0],j] == 2][0] br = [j for j in range(6) if MM[top[1],j] == 2][0] G.set_pos(pos={centers[0]:[0,0.5],centers[1]:[0,-0.5],top[0]:[-1,0.5],top[1]:[1,0.5],bl:[-1,-0.5],br:[1,-0.5]}) elif maxdegree == 16: # tree from bottom, 3 regular except for the leaves. centers = [i for i in range(8) if list(MM.row(i)).count(2) == 3] center = [i for i in centers if len([j for j in centers if MM[i,j] == 2]) == 2][0] centers.remove(center) bottom = [j for j in range(8) if MM[center,j] == 2 and j not in centers][0] left = [j for j in range(8) if MM[centers[0],j] == 2 and j != center] right = [j for j in range(8) if MM[centers[1],j] == 2 and j != center] G.set_pos(pos={center:[0,0],bottom:[0,-1],centers[0]:[-0.8660254,0.5],centers[1]:[0.8660254,0.5],left[0]:[-0.8660254,1.5],right[0]:[0.8660254,1.5],left[1]:[-1.7320508,0],right[1]:[1.7320508,0]}) elif maxdegree == 12: # tent centers = [i for i in range(8) if list(MM.row(i)).count(2) == 3] left = [j for j in range(8) if MM[centers[0],j] == 2] right = [] for i in range(3): right.append([j for j in range(8) if MM[centers[1],j] == 2 and MM[left[i],j] == 3][0]) G.set_pos(pos={centers[0]:[-0.3,0],centers[1]:[0.3,0], left[0]:[-0.14,0.15], right[0]:[0.14,0.15], left[1]:[-0.14,-0.15],right[1]:[0.14,-0.15], left[2]:[-0.14,-0.3],right[2]:[0.14,-0.3]}) G.relabel(range(1,n+1)) return G