def cartan_matrix_as_graph(self, q=None): from sage.graphs.graph import DiGraph G = DiGraph() G.add_vertices(self.idempotents()) for (e,f),coeff in self.cartan_matrix_as_table(q).iteritems(): G.add_edge(e,f, None if coeff == 1 else coeff) return G
def remove_edge(self, e): """ Removes the edge ``e`` (together with its inverse). Removes ``e`` (and its inverse) from the alphabet. INPUT: - ``e`` edge to remove (and its inverse) from the alphabet. EXAMPLES:: sage: G = GraphWithInverses([[0,0,'a'],[0,1,'b'],[1,0,'c']]) sage: G.remove_edge('b') sage: print G Graph with inverses: a: 0->0, c: 1->0 sage: G.alphabet() Alphabet with inverses on ['a', 'c'] """ pe = self._alphabet.to_positive_letter(e) ee = self._alphabet.inverse_letter(e) DiGraph.delete_edge(self, self.initial_vertex(pe), self.terminal_vertex(pe), pe) self._alphabet.remove_letter(e) self._initial.pop(e) self._initial.pop(ee) self._terminal.pop(e) self._terminal.pop(ee)
def add_vertex(self, i=None): """ Add a new vertex with label ``i`` or the least integer which is not already a vertex. INPUT: - ``i`` -- (default: ``None``) new vertex with label ``i`` or the least integer which is not already a vertex OUTPUT: The new vertex. EXAMPLES:: sage: from train_track.inverse_graph import GraphWithInverses sage: G = GraphWithInverses([[0,0,'a'],[0,1,'b'],[1,0,'c']]) sage: G.add_vertex() 2 sage: print (G) a: 0->0, b: 0->1, c: 1->0 sage: print (G.vertices()) [0, 1, 2] """ if i is None: i = self.new_vertex() DiGraph.add_vertex(self, i) return i
def remove_edge(self, e): """ Remove the edge ``e`` (together with its inverse). Removes ``e`` (and its inverse) from the alphabet. INPUT: - ``e`` -- edge to remove (and its inverse) from the alphabet EXAMPLES:: sage: from train_track.inverse_graph import GraphWithInverses sage: G = GraphWithInverses([[0,0,'a'],[0,1,'b'],[1,0,'c']]) sage: G.remove_edge('b') sage: print(G) a: 0->0, c: 1->0 sage: G.alphabet() Alphabet with inverses on ['a', 'c'] """ pe = self._alphabet.to_positive_letter(e) ee = self._alphabet.inverse_letter(e) DiGraph.delete_edge(self, self.initial_vertex(pe), self.terminal_vertex(pe), pe) self._alphabet.remove_letter(e) self._initial.pop(e) self._initial.pop(ee) self._terminal.pop(e) self._terminal.pop(ee)
def add_vertex(self, i=None): """ Add a new vertex with label ``i`` or the least integer which is not already a vertex. INPUT: - ``i`` -- (default None) new vertex with label ``i`` or the least integer which is not already a vertex. OUTPUT: the new vertex. EXAMPLES:: sage: G = GraphWithInverses([[0,0,'a'],[0,1,'b'],[1,0,'c']]) sage: G.add_vertex() 2 sage: print G Graph with inverses: a: 0->0, b: 0->1, c: 1->0 sage: print G.vertices() [0, 1, 2] """ if i is None: i = self.new_vertex() DiGraph.add_vertex(self, i) return i
def j_poset(self): r""" Returns the j-order on the j-classes, as a poset on the indices of the j-classes. For two such indices `i` and `j`, and `x` and `y` in corresponding J-classes, one has: `i \le j \Leftrightarrow x \in S y S \Leftrightarrow S x S \subset S y S` In particular, the identity (when it exists) is the unique maximal element of this poset. EXAMPLES:: sage: S = Semigroups().Finite().example(alphabet=('a','b', 'c')) sage: P = S.j_poset(); P Finite poset containing 7 elements sage: P.cover_relations() # random (arbitrary choice) [['cab', 'ca'], ['cab', 'cb'], ['cab', 'ab'], ['ca', 'c'], ['ca', 'a'], ['cb', 'b'], ['cb', 'c'], ['ab', 'b'], ['ab', 'a']] sage: len(P.cover_relations()) 9 """ from sage.graphs.graph import DiGraph from sage.combinat.posets.posets import Poset # This is more or less duplicating what strongly_connected_components_digraph does!!! G = DiGraph() G.add_vertices(self.j_classes().keys()) for (x,y,_) in self.cayley_graph_cached(side="twosided", simple=True).edge_iterator(): G.add_edge(self.j_class_index(y), self.j_class_index(x)) return Poset(G)
def plot(self, edge_labels=True, graph_border=True, **kwds): """ Plot ``self``. INPUT: - ``edge_labels`` -- (default True) if edge label visible - ``graph_border`` -- (default True) if graph border visible OUTPUT: Launched png viewer for Graphics object EXAMPLES:: sage: from train_track.inverse_graph import GraphWithInverses sage: G = GraphWithInverses([[0,0,'a'],[0,1,'b'],[1,0,'c']]) sage: G.plot() Graphics object consisting of 11 graphics primitives """ return DiGraph.plot(DiGraph(self), edge_labels=edge_labels, graph_border=graph_border, **kwds)
def add_edge(self, u, v=None, label=None): """ Add a new edge. The following forms are all accepted - G.add_edge(1,2,'a') - G.add_edge((1,2,'a')) - G.add_edge(1,2,['a','A']) - G.add_edge((1,2,['a','A'])) INPUT: - ``u`` -- edge to add - ``v`` -- (default: ``None``) - ``label`` -- (default: ``None``) the label of the new edge OUTPUT: The label of the new edge. .. WARNING:: Does not change the alphabet of ``self``. (the new label is assumed to be already in the alphabet). EXAMPLES:: sage: from train_track.inverse_graph import GraphWithInverses sage: G = GraphWithInverses([[0,0,'a'],[0,1,'b'],[1,0,'c']]) sage: a = G.alphabet().add_new_letter() sage: G.add_edge(1,1,a) 'd' sage: print(G) a: 0->0, b: 0->1, c: 1->0, d: 1->1 """ if label is None: v = u[1] label = u[2] u = u[0] if isinstance(label, list): DiGraph.add_edge(self, u, v, label[0]) self._initial[label[0]] = u self._initial[label[1]] = v self._terminal[label[1]] = u self._terminal[label[0]] = v label = label[0] else: DiGraph.add_edge(self, u, v, label) self._initial[label] = u self._terminal[label] = v inv_label = self.alphabet().inverse_letter(label) self._initial[inv_label] = v self._terminal[inv_label] = u return label
def remove_vertex(self, v): """ Removes the vertex ``v`` from ``self``. WARNING: ``v`` must be an isolated vertex. """ DiGraph.delete_vertex(self, v)
def remove_vertex(self,v): """ Removes the vertex ``v`` from ``self``. WARNING: ``v`` must be an isolated vertex. """ DiGraph.delete_vertex(self,v)
def add_vertex(self,i=None): """ Add a new vertex with label ``i`` or the least integer which is not already a vertex. OUTPUT: the new vertex. """ if i==None: i=self.new_vertex() DiGraph.add_vertex(self,i) return i
def remove_edge(self,e): """ Removes the edge ``e`` (together with its inverse). Removes ``e`` (and its inverse) from the alphabet. """ pe=self._alphabet.to_positive_letter(e) ee=self._alphabet.inverse_letter(e) DiGraph.delete_edge(self,self.initial_vertex(pe),self.terminal_vertex(pe),pe) self._alphabet.remove_letter(e) self._initial.pop(e) self._initial.pop(ee) self._terminal.pop(e) self._terminal.pop(ee)
def add_vertex(self, i=None): """ Add a new vertex with label ``i`` or the least integer which is not already a vertex. OUTPUT: the new vertex. """ if i == None: i = self.new_vertex() DiGraph.add_vertex(self, i) return i
def set_terminal_vertex(self, e, v): """ Sets the terminal vertex of the edge ``e`` to the vertex ``v``. Consistantly sets the initial vertex of the edge label by the inverse of ``e`` to the vertex ``v``. INPUT: - ``e`` -- the edge - ``v`` -- the vertex EXAMPLES:: sage: from train_track.inverse_graph import GraphWithInverses sage: G = GraphWithInverses([[0,0,'a'],[0,1,'b'],[1,0,'c']]) sage: G.set_terminal_vertex('a',1) sage: print(G) a: 0->1, b: 0->1, c: 1->0 """ w = self.initial_vertex(e) ww = self.terminal_vertex(e) pe = self._alphabet.to_positive_letter(e) if e == pe: DiGraph.delete_edge(self, w, ww, pe) DiGraph.add_edge(self, w, v, pe) else: DiGraph.delete_edge(self, ww, w, pe) DiGraph.add_edge(self, v, w, pe) self._terminal[e] = v self._initial[self._alphabet.inverse_letter(e)] = v
def set_terminal_vertex(self, e, v): """ Sets the terminal vertex of the edge ``e`` to the vertex ``v``. Consistantly sets the initial vertex of the edge label by the inverse of ``e`` to the vertex ``v``. INPUT: - ``e`` the edge - ``v`` the vertex EXAMPLES:: sage: G = GraphWithInverses([[0,0,'a'],[0,1,'b'],[1,0,'c']]) sage: G.set_terminal_vertex('a',1) sage: print G Graph with inverses: a: 0->1, b: 0->1, c: 1->0 """ w = self.initial_vertex(e) ww = self.terminal_vertex(e) pe = self._alphabet.to_positive_letter(e) if e == pe: DiGraph.delete_edge(self, w, ww, pe) DiGraph.add_edge(self, w, v, pe) else: DiGraph.delete_edge(self, ww, w, pe) DiGraph.add_edge(self, v, w, pe) self._terminal[e] = v self._initial[self._alphabet.inverse_letter(e)] = v
def remove_edge(self, e): """ Removes the edge ``e`` (together with its inverse). Removes ``e`` (and its inverse) from the alphabet. """ pe = self._alphabet.to_positive_letter(e) ee = self._alphabet.inverse_letter(e) DiGraph.delete_edge(self, self.initial_vertex(pe), self.terminal_vertex(pe), pe) self._alphabet.remove_letter(e) self._initial.pop(e) self._initial.pop(ee) self._terminal.pop(e) self._terminal.pop(ee)
def __init__(self,data=None,alphabet=None): self._initial={} self._terminal={} letters=[] if isinstance(data,dict): new_data=dict() for a in data: letters.append(a) if data[a][0] in new_data: if data[a][1] in new_data[data[a][0]]: new_data[data[a][0]][data[a][1]].append(a) else: new_data[data[a][0]][data[a][1]]=[a] else: new_data[data[a][0]]={data[a][1]:[a]} data=new_data elif isinstance(data,list): new_data=dict() for e in data: letters.append(e[2]) if e[0] in new_data: if e[1] in new_data[e[0]]: new_data[e[0]][e[1]].append(e[2]) else: new_data[e[0]][e[1]]=[e[2]] else: new_data[e[0]]={e[1]:[e[2]]} data=new_data if alphabet is None: from inverse_alphabet import AlphabetWithInverses alphabet = AlphabetWithInverses(self._initial.keys()) self._alphabet=alphabet DiGraph.__init__(self,data=data,loops=True,multiedges=True,vertex_labels=True,pos=None,format=None,\ boundary=[],weighted=None,implementation='c_graph',sparse=True) for e in self.edges(): self._initial[e[2]]=e[0] self._terminal[e[2]]=e[1] self._initial[alphabet.inverse_letter(e[2])]=e[1] self._terminal[alphabet.inverse_letter(e[2])]=e[0]
def __init__(self, data=None, alphabet=None): self._initial = {} self._terminal = {} letters = [] if isinstance(data, dict): new_data = dict() for a in data: letters.append(a) if data[a][0] in new_data: if data[a][1] in new_data[data[a][0]]: new_data[data[a][0]][data[a][1]].append(a) else: new_data[data[a][0]][data[a][1]] = [a] else: new_data[data[a][0]] = {data[a][1]: [a]} data = new_data elif isinstance(data, list): new_data = dict() for e in data: letters.append(e[2]) if e[0] in new_data: if e[1] in new_data[e[0]]: new_data[e[0]][e[1]].append(e[2]) else: new_data[e[0]][e[1]] = [e[2]] else: new_data[e[0]] = {e[1]: [e[2]]} data = new_data if alphabet is None: from inverse_alphabet import AlphabetWithInverses alphabet = AlphabetWithInverses(self._initial.keys()) self._alphabet = alphabet DiGraph.__init__(self,data=data,loops=True,multiedges=True,vertex_labels=True,pos=None,format=None,\ boundary=[],weighted=None,implementation='c_graph',sparse=True) for e in self.edges(): self._initial[e[2]] = e[0] self._terminal[e[2]] = e[1] self._initial[alphabet.inverse_letter(e[2])] = e[1] self._terminal[alphabet.inverse_letter(e[2])] = e[0]
def bruhat_graph(self, x, y): """ The Bruhat graph Gamma(x,y), defined if x <= y in the Bruhat order, has as its vertices the Bruhat interval, {t | x <= t <= y}, and as its edges the pairs u, v such that u = r.v where r is a reflection, that is, a conjugate of a simple reflection. Returns the Bruhat graph as a directed graph, with an edge u --> v if and only if u < v in the Bruhat order, and u = r.v. See: Carrell, The Bruhat graph of a Coxeter group, a conjecture of Deodhar, and rational smoothness of Schubert varieties. Algebraic groups and their generalizations: classical methods (University Park, PA, 1991), 53--61, Proc. Sympos. Pure Math., 56, Part 1, Amer. Math. Soc., Providence, RI, 1994. EXAMPLES: sage: W = WeylGroup("A3", prefix = "s") sage: [s1,s2,s3] = W.simple_reflections() sage: W.bruhat_graph(s1*s3,s1*s2*s3*s2*s1) Digraph on 10 vertices """ g = self.bruhat_interval(x, y) ref = self.reflections() d = {} for x in g: d[x] = [y for y in g if x.length() < y.length() and ref.has_key(x*y.inverse())] return DiGraph(d)
def graph(self): """ Convert ``self`` to a digraph EXAMPLE:: sage: t1 = BinaryTree([[], None]) sage: t1.graph() Digraph on 5 vertices sage: t1 = BinaryTree([[], [[], None]]) sage: t1.graph() Digraph on 9 vertices sage: t1.graph().edges() [(0, 1, None), (0, 4, None), (1, 2, None), (1, 3, None), (4, 5, None), (4, 8, None), (5, 6, None), (5, 7, None)] """ from sage.graphs.graph import DiGraph res = DiGraph() def rec(tr, idx): if not tr: return else: nbl = 2*tr[0].node_number() + 1 res.add_edges([[idx,idx+1], [idx,idx+1+nbl]]) rec(tr[0], idx + 1) rec(tr[1], idx + nbl + 1) rec(self, 0) return res
def connected_components(self,edge_list=None): """ The list of connected components (each as a list of edges) of the subgraph of ``self`` spanned by ``edge_list``. """ if edge_list==None: return DiGraph.connected_components(self) components=[] vertices=[] for e in edge_list: v=self.initial_vertex(e) vv=self.terminal_vertex(e) t=[i for i in xrange(len(components)) if v in vertices[i] or vv in vertices[i]] if len(t)==0: components.append([e]) if v!=vv: vertices.append([v,vv]) else: vertices.append([v]) elif len(t)==1: components[t[0]].append(e) if v not in vertices[t[0]]: vertices[t[0]].append(v) elif vv not in vertices[t[0]]: vertices[t[0]].append(vv) elif len(t)==2: components[t[0]]=components[t[0]]+components[t[1]]+[e] vertices[t[0]]=vertices[t[0]]+vertices[t[1]] components.pop(t[1]) vertices.pop(t[1]) return components
def connected_components(self, edge_list=None): """ The list of connected components (each as a list of edges) of the subgraph of ``self`` spanned by ``edge_list``. """ if edge_list == None: return DiGraph.connected_components(self) components = [] vertices = [] for e in edge_list: v = self.initial_vertex(e) vv = self.terminal_vertex(e) t = [ i for i in xrange(len(components)) if v in vertices[i] or vv in vertices[i] ] if len(t) == 0: components.append([e]) if v != vv: vertices.append([v, vv]) else: vertices.append([v]) elif len(t) == 1: components[t[0]].append(e) if v not in vertices[t[0]]: vertices[t[0]].append(v) elif vv not in vertices[t[0]]: vertices[t[0]].append(vv) elif len(t) == 2: components[t[0]] = components[t[0]] + components[t[1]] + [e] vertices[t[0]] = vertices[t[0]] + vertices[t[1]] components.pop(t[1]) vertices.pop(t[1]) return components
def add_edge(self, u, v=None, label=None): """ Add a new edge. INPUT: The following forms are all accepted - G.add_edge(1,2,'a') - G.add_edge((1,2,'a')) - G.add_edge(1,2,['a','A']) - G.add_edge((1,2,['a','A'])) OUTPUT: the label of the new edge. WARNING: Does not change the alphabet of ``self``. (the new label is assumed to be already in the alphabet). """ if label is None: v = u[1] label = u[2] u = u[0] if isinstance(label, list): DiGraph.add_edge(self, u, v, label[0]) self._initial[label[0]] = u self._initial[label[1]] = v self._terminal[label[1]] = u self._terminal[label[0]] = v label = label[0] else: DiGraph.add_edge(self, u, v, label) self._initial[label] = u self._terminal[label] = v inv_label = self.alphabet().inverse_letter(label) self._initial[inv_label] = v self._terminal[inv_label] = u return label
def add_edge(self,u,v=None,label=None): """ Add a new edge. INPUT: The following forms are all accepted - G.add_edge(1,2,'a') - G.add_edge((1,2,'a')) - G.add_edge(1,2,['a','A']) - G.add_edge((1,2,['a','A'])) OUTPUT: the label of the new edge. WARNING: Does not change the alphabet of ``self``. (the new label is assumed to be already in the alphabet). """ if label is None: v=u[1] label=u[2] u=u[0] if isinstance(label,list): DiGraph.add_edge(self,u,v,label[0]) self._initial[label[0]]=u self._initial[label[1]]=v self._terminal[label[1]]=u self._terminal[label[0]]=v label=label[0] else: DiGraph.add_edge(self,u,v,label) self._initial[label]=u self._terminal[label]=v inv_label=self.alphabet().inverse_letter(label) self._initial[inv_label]=v self._terminal[inv_label]=u return label
def remove_vertex(self, v): """ Removes the vertex ``v`` from ``self``. INPUT: - ``v`` vertex to remove (and its inverse) from the alphabet. WARNING: ``v`` must be an isolated vertex. EXAMPLES:: sage: G = GraphWithInverses([[0,0,'a'],[0,1,'b'],[0,0,'c']]) sage: G.remove_edge('b') sage: G.remove_vertex(1) sage: print G Graph with inverses: a: 0->0, c: 0->0 """ DiGraph.delete_vertex(self, v)
def quiver(self, edge_labels=True, index=False): """ Returns the quiver of ``self`` INPUT: - ``edges_labels`` -- whether to use the quiver element as label for the edges between the idempotents; if False, this may lead to multiple edges when the monoid is not generated by idempotents (default: True) - ``index`` -- whether to index the vertices of the graph by the indices of the simple modules rather than the corresponding idempotents (default: False) OUTPUT: the quiver of ``self``, as a graph with the idempotents of this monoid as vertices .. todo:: should index default to True? .. todo:: use a meaningful example EXAMPLES:: sage: import sage_semigroups.monoids.catalog as semigroups sage: M = semigroups.NDPFMonoidPoset(Posets(3)[3]) sage: G = M.quiver() sage: G Digraph on 4 vertices sage: G.edges() [([1], [2], [3])] sage: M.quiver(edge_labels=False).edges() [([1], [2], None)] sage: M.quiver(index=True).edges() [(2, 1, [3])] sage: M.quiver(index=True, edge_labels=False).edges() [(2, 1, None)] """ from sage.graphs.graph import DiGraph res = DiGraph() if index: res.add_vertices(self.simple_modules_index_set()) symbol = attrcall("symbol_index") else: res.add_vertices(self.idempotents()) symbol = attrcall("symbol") for x in self.quiver_elements(): res.add_edge(symbol(x,"left"), symbol(x, "right"), x if edge_labels else None) return res
def remove_vertex(self, v): """ Remove the vertex ``v`` from ``self``. INPUT: - ``v`` -- vertex to remove (and its inverse) from the alphabet .. WARNING:: ``v`` must be an isolated vertex. EXAMPLES:: sage: from train_track.inverse_graph import GraphWithInverses sage: G = GraphWithInverses([[0,0,'a'],[0,1,'b'],[0,0,'c']]) sage: G.remove_edge('b') sage: G.remove_vertex(1) sage: print(G) a: 0->0, c: 0->0 """ DiGraph.delete_vertex(self, v)
def connected_components(self, edge_list=None): """ The list of connected components (each as a list of edges) of the subgraph of ``self`` spanned by ``edge_list``. INPUT: - ``edge_list`` -- (default: ``None``) list of edge OUTPUT: List of Connected components (each as a list of edges) of the subgraph of ``self`` spanned by ``edge_list``. EXAMPLES:: sage: from train_track.inverse_graph import GraphWithInverses sage: G = GraphWithInverses([[0,0,'a'],[0,0,'b'],[1,1,'c']]) sage: G.connected_components() [[0], [1]] """ if edge_list is None: return DiGraph.connected_components(self) components = [] vertices = [] for e in edge_list: v = self.initial_vertex(e) vv = self.terminal_vertex(e) t = [ i for i in range(len(components)) if v in vertices[i] or vv in vertices[i] ] if len(t) == 0: components.append([e]) if v != vv: vertices.append([v, vv]) else: vertices.append([v]) elif len(t) == 1: components[t[0]].append(e) if v not in vertices[t[0]]: vertices[t[0]].append(v) elif vv not in vertices[t[0]]: vertices[t[0]].append(vv) elif len(t) == 2: components[t[0]] = components[t[0]] + components[t[1]] + [e] vertices[t[0]] = vertices[t[0]] + vertices[t[1]] components.pop(t[1]) vertices.pop(t[1]) return components
def plot(self, edge_labels=True, graph_border=True, **kwds): """ INPUT: - ``edge_labels`` -- (default True) if edge label visible - ``graph_border`` -- (default True) if graph border visible OUTPUT: Launched png viewer for Graphics object """ return DiGraph.plot(DiGraph(self), edge_labels=edge_labels, graph_border=graph_border, **kwds)
def connected_components(self, edge_list=None): """ The list of connected components (each as a list of edges) of the subgraph of ``self`` spanned by ``edge_list``. INPUT: - ``edge_list`` -- (default: ``None``) list of edge OUTPUT: List of Connected components (each as a list of edges) of the subgraph of ``self`` spanned by ``edge_list``. EXAMPLES:: sage: from train_track.inverse_graph import GraphWithInverses sage: G = GraphWithInverses([[0,0,'a'],[0,0,'b'],[1,1,'c']]) sage: G.connected_components() [[0], [1]] """ if edge_list is None: return DiGraph.connected_components(self) components = [] vertices = [] for e in edge_list: v = self.initial_vertex(e) vv = self.terminal_vertex(e) t = [i for i in range(len(components)) if v in vertices[i] or vv in vertices[i]] if len(t) == 0: components.append([e]) if v != vv: vertices.append([v, vv]) else: vertices.append([v]) elif len(t) == 1: components[t[0]].append(e) if v not in vertices[t[0]]: vertices[t[0]].append(v) elif vv not in vertices[t[0]]: vertices[t[0]].append(vv) elif len(t) == 2: components[t[0]] = components[t[0]] + components[t[1]] + [e] vertices[t[0]] = vertices[t[0]] + vertices[t[1]] components.pop(t[1]) vertices.pop(t[1]) return components
def set_terminal_vertex(self, e, v): """ Sets the terminal vertex of the edge ``e`` to the vertex ``v``. Consistantly sets the initial vertex of the edge label by the inverse of ``e`` to the vertex ``v``. """ w = self.initial_vertex(e) ww = self.terminal_vertex(e) pe = self._alphabet.to_positive_letter(e) if e == pe: DiGraph.delete_edge(self, w, ww, pe) DiGraph.add_edge(self, w, v, pe) else: DiGraph.delete_edge(self, ww, w, pe) DiGraph.add_edge(self, v, w, pe) self._terminal[e] = v self._initial[self._alphabet.inverse_letter(e)] = v
def set_terminal_vertex(self,e,v): """ Sets the terminal vertex of the edge ``e`` to the vertex ``v``. Consistantly sets the initial vertex of the edge label by the inverse of ``e`` to the vertex ``v``. """ w=self.initial_vertex(e) ww=self.terminal_vertex(e) pe=self._alphabet.to_positive_letter(e) if e==pe: DiGraph.delete_edge(self,w,ww,pe) DiGraph.add_edge(self,w,v,pe) else: DiGraph.delete_edge(self,ww,w,pe) DiGraph.add_edge(self,v,w,pe) self._terminal[e]=v self._initial[self._alphabet.inverse_letter(e)]=v
def bruhat_graph(self, x, y): r""" Return the Bruhat graph as a directed graph, with an edge `u \to v` if and only if `u < v` in the Bruhat order, and `u = r \cdot v`. The Bruhat graph `\Gamma(x,y)`, defined if `x \leq y` in the Bruhat order, has as its vertices the Bruhat interval `\{ t | x \leq t \leq y \}`, and as its edges are the pairs `(u, v)` such that `u = r \cdot v` where `r` is a reflection, that is, a conjugate of a simple reflection. REFERENCES: Carrell, The Bruhat graph of a Coxeter group, a conjecture of Deodhar, and rational smoothness of Schubert varieties. Algebraic groups and their generalizations: classical methods (University Park, PA, 1991), 53--61, Proc. Sympos. Pure Math., 56, Part 1, Amer. Math. Soc., Providence, RI, 1994. EXAMPLES:: sage: W = WeylGroup("A3", prefix="s") sage: s1, s2, s3 = W.simple_reflections() sage: G = W.bruhat_graph(s1*s3, s1*s2*s3*s2*s1); G Digraph on 10 vertices Check that the graph has the correct number of edges (see :trac:`17744`):: sage: len(G.edges()) 16 """ g = self.bruhat_interval(x, y) ref = self.reflections() d = {} for u in g: d[u] = [ v for v in g if u.length() < v.length() and u * v.inverse() in ref ] return DiGraph(d)
def subsets_lattice(self): """ Return the lattice of subsets ordered by containment. EXAMPLES:: sage: X = Set([1,2,3]) sage: X.subsets_lattice() Finite lattice containing 8 elements sage: Y = Set() sage: Y.subsets_lattice() Finite lattice containing 1 elements """ if not self.is_finite(): raise NotImplementedError( "this method is only implemented for finite sets") from sage.combinat.posets.lattices import FiniteLatticePoset from sage.graphs.graph import DiGraph from sage.rings.integer import Integer n = self.cardinality() # list, contains at position 0 <= i < 2^n # the i-th subset of self subset_of_index = [ Set([self[i] for i in range(n) if v & (1 << i)]) for v in range(2**n) ] # list, contains at position 0 <= i < 2^n # the list of indices of all immediate supersets upper_covers = [[ Integer(x | (1 << y)) for y in range(n) if not x & (1 << y) ] for x in range(2**n)] # DiGraph, every subset points to all immediate supersets D = DiGraph({ subset_of_index[v]: [subset_of_index[w] for w in upper_covers[v]] for v in range(2**n) }) # Lattice poset, defined by hasse diagram D L = FiniteLatticePoset(hasse_diagram=D) return L
def plot(self, edge_labels=True, graph_border=True, **kwds): return DiGraph.plot(DiGraph(self), edge_labels=edge_labels, graph_border=graph_border, **kwds)
def __init__(self, data=None, alphabet=None): """ INPUT: - ``data`` -- (default None) a list or dictionary from a list of edges: ``[initial_vertex,terminal_vertex,letter]``. a dictionnary that maps letters of the alphabet to lists ``(initial_vertex,terminal_vertex)`` - ``alphabet`` -- (default None ) alphabet AlphabetWithInverses by default EXAMPLES:: sage: from train_track.inverse_graph import GraphWithInverses sage: print(GraphWithInverses({'a':(0,0),'b':(0,1),'c':(1,0)})) a: 0->0, c: 1->0, b: 0->1 """ self._initial = {} self._terminal = {} letters = [] if isinstance(data, dict): new_data = dict() for a in data: letters.append(a) if data[a][0] in new_data: if data[a][1] in new_data[data[a][0]]: new_data[data[a][0]][data[a][1]].append(a) else: new_data[data[a][0]][data[a][1]] = [a] else: new_data[data[a][0]] = {data[a][1]: [a]} data = new_data elif isinstance(data, list): new_data = dict() for e in data: letters.append(e[2]) if e[0] in new_data: if e[1] in new_data[e[0]]: new_data[e[0]][e[1]].append(e[2]) else: new_data[e[0]][e[1]] = [e[2]] else: new_data[e[0]] = {e[1]: [e[2]]} data = new_data if alphabet is None: from .inverse_alphabet import AlphabetWithInverses alphabet = AlphabetWithInverses(letters) self._alphabet = alphabet DiGraph.__init__( self, data=data, loops=True, multiedges=True, vertex_labels=True, pos=None, format=None, weighted=None, #implementation='c_graph', sparse=True) # DiGraph.__init__(self,data=data, loops=True,multiedges=True, # vertex_labels=True, pos=None, format=None, # boundary=[], weighted=None, # implementation='c_graph', sparse=True) for e in self.edges(): self._initial[e[2]] = e[0] self._terminal[e[2]] = e[1] self._initial[alphabet.inverse_letter(e[2])] = e[1] self._terminal[alphabet.inverse_letter(e[2])] = e[0]
def plot(self,edge_labels=True,graph_border=True,**kwds): return DiGraph.plot(DiGraph(self),edge_labels=edge_labels,graph_border=graph_border,**kwds)
def __init__(self, data=None, alphabet=None): """ INPUT: - ``data`` -- (default None) a list or dictionary from a list of edges: ``[initial_vertex,terminal_vertex,letter]``. a dictionnary that maps letters of the alphabet to lists ``(initial_vertex,terminal_vertex)`` - ``alphabet`` -- (default None ) alphabet AlphabetWithInverses by default """ self._initial = {} self._terminal = {} letters = [] if isinstance(data, dict): new_data = dict() for a in data: letters.append(a) if data[a][0] in new_data: if data[a][1] in new_data[data[a][0]]: new_data[data[a][0]][data[a][1]].append(a) else: new_data[data[a][0]][data[a][1]] = [a] else: new_data[data[a][0]] = {data[a][1]: [a]} data = new_data elif isinstance(data, list): new_data = dict() for e in data: letters.append(e[2]) if e[0] in new_data: if e[1] in new_data[e[0]]: new_data[e[0]][e[1]].append(e[2]) else: new_data[e[0]][e[1]] = [e[2]] else: new_data[e[0]] = {e[1]: [e[2]]} data = new_data if alphabet is None: from inverse_alphabet import AlphabetWithInverses alphabet = AlphabetWithInverses(letters) self._alphabet = alphabet DiGraph.__init__(self, data=data, loops=True, multiedges=True, vertex_labels=True, pos=None, format=None, weighted=None, implementation='c_graph', sparse=True) # DiGraph.__init__(self,data=data, loops=True,multiedges=True, # vertex_labels=True, pos=None, format=None, # boundary=[], weighted=None, # implementation='c_graph', sparse=True) for e in self.edges(): self._initial[e[2]] = e[0] self._terminal[e[2]] = e[1] self._initial[alphabet.inverse_letter(e[2])] = e[1] self._terminal[alphabet.inverse_letter(e[2])] = e[0]
def test_some_specific_examples(): r""" Tests our ClassicalCrystalOfAlcovePaths against some specific examples. EXAMPLES:: sage: sage.combinat.crystals.alcove_path.test_some_specific_examples() # long time (12s on sage.math, 2011) G2 example passed. C3 example passed. B3 example 1 passed. B3 example 2 passed. True """ # This appears in Lenart. C = ClassicalCrystalOfAlcovePaths(['G', 2], [0, 1]) G = C.digraph() GT = DiGraph({ (): { (0): 2 }, (0): { (0, 8): 1 }, (0, 1): { (0, 1, 7): 2 }, (0, 1, 2): { (0, 1, 2, 9): 1 }, (0, 1, 2, 3): { (0, 1, 2, 3, 4): 2 }, (0, 1, 2, 6): { (0, 1, 2, 3): 1 }, (0, 1, 2, 9): { (0, 1, 2, 6): 1 }, (0, 1, 7): { (0, 1, 2): 2 }, (0, 1, 7, 9): { (0, 1, 2, 9): 2 }, (0, 5): { (0, 1): 1, (0, 5, 7): 2 }, (0, 5, 7): { (0, 5, 7, 9): 1 }, (0, 5, 7, 9): { (0, 1, 7, 9): 1 }, (0, 8): { (0, 5): 1 } }) if (G.is_isomorphic(GT) != True): return False else: print "G2 example passed." # Some examples from Hong--Kang: # type C, ex. 8.3.5, pg. 189 C = ClassicalCrystalOfAlcovePaths(['C', 3], [0, 0, 1]) G = C.digraph() GT = DiGraph({ (): { (0): 3 }, (0): { (0, 6): 2 }, (0, 1): { (0, 1, 3): 3, (0, 1, 7): 1 }, (0, 1, 2): { (0, 1, 2, 3): 3 }, (0, 1, 2, 3): { (0, 1, 2, 3, 8): 2 }, (0, 1, 2, 3, 4): { (0, 1, 2, 3, 4, 5): 3 }, (0, 1, 2, 3, 8): { (0, 1, 2, 3, 4): 2 }, (0, 1, 3): { (0, 1, 3, 7): 1 }, (0, 1, 3, 7): { (0, 1, 2, 3): 1, (0, 1, 3, 7, 8): 2 }, (0, 1, 3, 7, 8): { (0, 1, 2, 3, 8): 1 }, (0, 1, 7): { (0, 1, 2): 1, (0, 1, 3, 7): 3 }, (0, 6): { (0, 1): 2, (0, 6, 7): 1 }, (0, 6, 7): { (0, 1, 7): 2 } }) if (G.is_isomorphic(GT) != True): return False else: print "C3 example passed." # type B, fig. 8.1 pg. 172 C = ClassicalCrystalOfAlcovePaths(['B', 3], [2, 0, 0]) G = C.digraph() GT = DiGraph({ (): { (6): 1 }, (0): { (0, 7): 2 }, (0, 1): { (0, 1, 11): 3 }, (0, 1, 2): { (0, 1, 2, 9): 2 }, (0, 1, 2, 3): { (0, 1, 2, 3, 10): 1 }, (0, 1, 2, 3, 10): { (0, 1, 2, 3, 4): 1 }, (0, 1, 2, 9): { (0, 1, 2, 3): 2, (0, 1, 2, 9, 10): 1 }, (0, 1, 2, 9, 10): { (0, 1, 2, 3, 10): 2 }, (0, 1, 5): { (0, 1, 2): 3, (0, 1, 5, 9): 2 }, (0, 1, 5, 9): { (0, 1, 2, 9): 3, (0, 1, 5, 9, 10): 1 }, (0, 1, 5, 9, 10): { (0, 1, 2, 9, 10): 3 }, (0, 1, 8): { (0, 1, 5): 3 }, (0, 1, 8, 9): { (0, 1, 5, 9): 3, (0, 1, 8, 9, 10): 1 }, (0, 1, 8, 9, 10): { (0, 1, 5, 9, 10): 3 }, (0, 1, 11): { (0, 1, 8): 3 }, (0, 7): { (0, 1): 2, (0, 7, 11): 3 }, (0, 7, 8): { (0, 7, 8, 9): 2 }, (0, 7, 8, 9): { (0, 1, 8, 9): 2 }, (0, 7, 8, 9, 10): { (0, 1, 8, 9, 10): 2 }, (0, 7, 11): { (0, 1, 11): 2, (0, 7, 8): 3 }, (6): { (0): 1, (6, 7): 2 }, (6, 7): { (0, 7): 1, (6, 7, 11): 3 }, (6, 7, 8): { (0, 7, 8): 1, (6, 7, 8, 9): 2 }, (6, 7, 8, 9): { (6, 7, 8, 9, 10): 1 }, (6, 7, 8, 9, 10): { (0, 7, 8, 9, 10): 1 }, (6, 7, 11): { (0, 7, 11): 1, (6, 7, 8): 3 } }) if (G.is_isomorphic(GT) != True): return False else: print "B3 example 1 passed." C = ClassicalCrystalOfAlcovePaths(['B', 3], [0, 1, 0]) G = C.digraph() GT = DiGraph({ (): { (0): 2 }, (0): { (0, 1): 1, (0, 7): 3 }, (0, 1): { (0, 1, 7): 3 }, (0, 1, 2): { (0, 1, 2, 8): 2 }, (0, 1, 2, 3): { (0, 1, 2, 3, 5): 1, (0, 1, 2, 3, 9): 3 }, (0, 1, 2, 3, 4): { (0, 1, 2, 3, 4, 5): 1 }, (0, 1, 2, 3, 4, 5): { (0, 1, 2, 3, 4, 5, 6): 2 }, (0, 1, 2, 3, 5): { (0, 1, 2, 3, 5, 9): 3 }, (0, 1, 2, 3, 5, 9): { (0, 1, 2, 3, 4, 5): 3 }, (0, 1, 2, 3, 9): { (0, 1, 2, 3, 4): 3, (0, 1, 2, 3, 5, 9): 1 }, (0, 1, 2, 5): { (0, 1, 2, 3, 5): 2 }, (0, 1, 2, 8): { (0, 1, 2, 3): 2 }, (0, 1, 2, 8, 9): { (0, 1, 2, 3, 9): 2 }, (0, 1, 7): { (0, 1, 2): 3, (0, 1, 7, 8): 2 }, (0, 1, 7, 8): { (0, 1, 7, 8, 9): 3 }, (0, 1, 7, 8, 9): { (0, 1, 2, 8, 9): 3 }, (0, 2): { (0, 1, 2): 1, (0, 2, 5): 2 }, (0, 2, 5): { (0, 2, 5, 8): 1 }, (0, 2, 5, 8): { (0, 1, 2, 5): 1 }, (0, 7): { (0, 1, 7): 1, (0, 2): 3 } }) if (G.is_isomorphic(GT) != True): return False else: print "B3 example 2 passed." # type B, fig. 8.3 pg. 174 return True