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 __init__(self,data,group=None): """ Builds a FreeGroupAutomorphism from data. INPUT: - ``data`` - the data used to build the morphism - ``group`` - an optional free group """ if group is not None and not isinstance(group, FreeGroup): raise ValueError, "the group must be a Free Group" WordMorphism.__init__(self,data) if group is None: A = AlphabetWithInverses(self.domain().alphabet()) F = FreeGroup(A) else: F = group A = group.alphabet() self._domain = F self._codomain = F # unuseful... consistency with WordMorphism for letter in self._morph.keys(): self._morph[letter]=F.reduce(self._morph[letter]) self._morph[A.inverse_letter(letter)] = F.inverse_word(self._morph[letter])
def __init__(self, data, group=None): """ Builds a FreeGroupAutomorphism from data. INPUT: - ``data`` - the data used to build the morphism - ``group`` - an optional free group """ if group is not None and not isinstance(group, FreeGroup): raise ValueError, "the group must be a Free Group" WordMorphism.__init__(self, data) if group is None: A = AlphabetWithInverses(self.domain().alphabet()) F = FreeGroup(A) else: F = group A = group.alphabet() self._domain = F self._codomain = F # unuseful... consistency with WordMorphism for letter in self._morph.keys(): self._morph[letter] = F.reduce(self._morph[letter]) self._morph[A.inverse_letter(letter)] = F.inverse_word( self._morph[letter])
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 inverse(self): """A homotopy inverse of ``self``. For ``t1=self.domain().spanning_tree()`` and ``t2=self.codomain().spanning_tree()``. The alphabet ``A`` is made of edges not in ``t1`` identified (by their order in the alphabets of the domain and codomain) to letters not in ``t2``. The automorphism ``phi`` of ``FreeGroup(A)`` is defined using ``t1`` and ``t2``. The inverse map is given by ``phi.inverse()`` using ``t1`` and edges from ``t2`` are mapped to a single point (the root of ``t1``). In particular the inverse maps all vertices to the root of ``t1``. WARNING: ``self`` is assumed to be a homotopy equivalence. """ from free_group import FreeGroup from free_group_automorphism import FreeGroupAutomorphism G1=self.domain() A1=G1.alphabet() t1=G1.spanning_tree() G2=self.codomain() A2=G2.alphabet() t2=G2.spanning_tree() A=AlphabetWithInverses(len(A1)-len(G1.vertices())+1) F=FreeGroup(A) map=dict() translate=dict() i=0 for a in A1.positive_letters(): l=len(t1[G1.initial_vertex(a)])-len(t1[G1.terminal_vertex(a)]) if (l!=1 or t1[G1.initial_vertex(a)][-1]!=A1.inverse_letter(a)) and\ (l!=-1 or t1[G1.terminal_vertex(a)][-1]!=a): # a is not in the spanning tree map[A[i]]=self(t1[G1.initial_vertex(a)]*Word([a])*G1.reverse_path(t1[G1.terminal_vertex(a)])) translate[A[i]]=a translate[A.inverse_letter(A[i])]=A1.inverse_letter(a) i+=1 rename=dict() edge_map=dict() i=0 for a in A2.positive_letters(): l=len(t2[G2.initial_vertex(a)])-len(t2[G2.terminal_vertex(a)]) if (l!=1 or t2[G2.initial_vertex(a)][-1]!=A2.inverse_letter(a)) and\ (l!=-1 or t2[G2.terminal_vertex(a)][-1]!=a): # a is not in the spanning tree rename[a]=A[i] rename[A2.inverse_letter(a)]=A.inverse_letter(A[i]) i+=1 else: edge_map[a]=Word() for a in map: map[a]=F([rename[b] for b in map[a] if b in rename]) phi=FreeGroupAutomorphism(map,F) psi=phi.inverse() i=0 for a in A2.positive_letters(): if a not in edge_map: result=Word() for b in psi.image(A[i]): c=translate[b] result=result*t1[G1.initial_vertex(c)]*Word([c])*G1.reverse_path(t1[G1.terminal_vertex(c)]) edge_map[a]=G1.reduce_path(result) i+=1 return GraphMap(G2,G1,edge_map)
def inverse(self): """A homotopy inverse of ``self``. For ``t1=self.domain().spanning_tree()`` and ``t2=self.codomain().spanning_tree()``. The alphabet ``A`` is made of edges not in ``t1`` identified (by their order in the alphabets of the domain and codomain) to letters not in ``t2``. The automorphism ``phi`` of ``FreeGroup(A)`` is defined using ``t1`` and ``t2``. The inverse map is given by ``phi.inverse()`` using ``t1`` and edges from ``t2`` are mapped to a single point (the root of ``t1``). In particular the inverse maps all vertices to the root of ``t1``. OUTPUT: A homotopy inverse of ``self``. WARNING: ``self`` is assumed to be a homotopy equivalence. EXAMPLES:: sage: G = GraphWithInverses([[0,0,'a'],[0,1,'b'],[1,1,'c']]) sage: A = AlphabetWithInverses(2) sage: H = GraphWithInverses.rose_graph(A) sage: f = GraphMap(G,H,"a->ab,b->b,c->B") sage: print f.inverse() Graph map: Graph with inverses: a: 0->0, b: 0->0 Graph with inverses: a: 0->0, b: 0->1, c: 1->1 edge map: a->abcB, b->bCB """ from free_group import FreeGroup from free_group_automorphism import FreeGroupAutomorphism g1 = self.domain() a1 = g1.alphabet() t1 = g1.spanning_tree() g2 = self.codomain() a2 = g2.alphabet() t2 = g2.spanning_tree() A = AlphabetWithInverses(len(a1) - len(g1.vertices()) + 1) f = FreeGroup(A) map = dict() translate = dict() i = 0 for a in a1.positive_letters(): l = len(t1[g1.initial_vertex(a)]) - len(t1[g1.terminal_vertex(a)]) if (l != 1 or t1[g1.initial_vertex(a)][-1] != a1.inverse_letter( a)) and (l != -1 or t1[g1.terminal_vertex(a)][-1] != a): # a is not in the spanning tree map[A[i]] = self( t1[g1.initial_vertex(a)] * Word([a]) * g1.reverse_path( t1[g1.terminal_vertex(a)])) translate[A[i]] = a translate[A.inverse_letter(A[i])] = a1.inverse_letter(a) i += 1 rename = dict() edge_map = dict() i = 0 for a in a2.positive_letters(): l = len(t2[g2.initial_vertex(a)]) - len(t2[g2.terminal_vertex(a)]) if (l != 1 or t2[g2.initial_vertex(a)][-1] != a2.inverse_letter( a)) and (l != -1 or t2[g2.terminal_vertex(a)][-1] != a): # a is not in the spanning tree rename[a] = A[i] rename[a2.inverse_letter(a)] = A.inverse_letter(A[i]) i += 1 else: edge_map[a] = Word() for a in map: map[a] = f([rename[b] for b in map[a] if b in rename]) phi = FreeGroupAutomorphism(map, f) psi = phi.inverse() i = 0 for a in a2.positive_letters(): if a not in edge_map: result = Word() for b in psi.image(A[i]): c = translate[b] result = result * t1[g1.initial_vertex(c)] * Word( [c]) * g1.reverse_path(t1[g1.terminal_vertex(c)]) edge_map[a] = g1.reduce_path(result) i += 1 return GraphMap(g2, g1, edge_map)
def inverse(self): """A homotopy inverse of ``self``. For ``t1=self.domain().spanning_tree()`` and ``t2=self.codomain().spanning_tree()``. The alphabet ``A`` is made of edges not in ``t1`` identified (by their order in the alphabets of the domain and codomain) to letters not in ``t2``. The automorphism ``phi`` of ``FreeGroup(A)`` is defined using ``t1`` and ``t2``. The inverse map is given by ``phi.inverse()`` using ``t1`` and edges from ``t2`` are mapped to a single point (the root of ``t1``). In particular the inverse maps all vertices to the root of ``t1``. WARNING: ``self`` is assumed to be a homotopy equivalence. """ from free_group import FreeGroup from free_group_automorphism import FreeGroupAutomorphism G1 = self.domain() A1 = G1.alphabet() t1 = G1.spanning_tree() G2 = self.codomain() A2 = G2.alphabet() t2 = G2.spanning_tree() A = AlphabetWithInverses(len(A1) - len(G1.vertices()) + 1) F = FreeGroup(A) map = dict() translate = dict() i = 0 for a in A1.positive_letters(): l = len(t1[G1.initial_vertex(a)]) - len(t1[G1.terminal_vertex(a)]) if (l!=1 or t1[G1.initial_vertex(a)][-1]!=A1.inverse_letter(a)) and\ (l!=-1 or t1[G1.terminal_vertex(a)][-1]!=a): # a is not in the spanning tree map[A[i]] = self(t1[G1.initial_vertex(a)] * Word([a]) * G1.reverse_path(t1[G1.terminal_vertex(a)])) translate[A[i]] = a translate[A.inverse_letter(A[i])] = A1.inverse_letter(a) i += 1 rename = dict() edge_map = dict() i = 0 for a in A2.positive_letters(): l = len(t2[G2.initial_vertex(a)]) - len(t2[G2.terminal_vertex(a)]) if (l!=1 or t2[G2.initial_vertex(a)][-1]!=A2.inverse_letter(a)) and\ (l!=-1 or t2[G2.terminal_vertex(a)][-1]!=a): # a is not in the spanning tree rename[a] = A[i] rename[A2.inverse_letter(a)] = A.inverse_letter(A[i]) i += 1 else: edge_map[a] = Word() for a in map: map[a] = F([rename[b] for b in map[a] if b in rename]) phi = FreeGroupAutomorphism(map, F) psi = phi.inverse() i = 0 for a in A2.positive_letters(): if a not in edge_map: result = Word() for b in psi.image(A[i]): c = translate[b] result = result * t1[G1.initial_vertex(c)] * Word( [c]) * G1.reverse_path(t1[G1.terminal_vertex(c)]) edge_map[a] = G1.reduce_path(result) i += 1 return GraphMap(G2, G1, edge_map)