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]
示例#2
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])
示例#4
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=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]
示例#6
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)
示例#8
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)