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 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 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 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 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 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 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 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