# Ticket #14319: trac_14319.patch

File trac_14319.patch, 22.6 KB (added by ncohen, 8 years ago)
• ## sage/geometry/fan_isomorphism.py

```# HG changeset patch
# User Nathann Cohen <nathann.cohen@gmail.com>
# Date 1363778759 -3600
# Node ID a516022fe79005c7f38fabd58219cc46d9314bef
# Parent  b416cb726fd9f824fe86f6f2c031ae610e697d0b
Graph Automorphism group with labeled vertices

diff --git a/sage/geometry/fan_isomorphism.py b/sage/geometry/fan_isomorphism.py```
 a for cone in fan2.generating_cones() ) # iterate over all graph isomorphisms graph1 -> graph2 for perm in graph2.automorphism_group(edge_labels=True): g2 = graph2.relabel({v:(i if i!=0 else graph2.order()) for i,v in enumerate(graph2.vertices())}, inplace = False) for perm in g2.automorphism_group(edge_labels=True): # find a candidate m that maps max_cone to the graph image cone image_ray_indices = [ perm(graph_iso[r]+1)-1 for r in fan1_pivot_rays ] fan2_basis = fan2.rays(image_ray_indices) + fan2.virtual_rays()
• ## sage/geometry/polyhedron/base.py

`diff --git a/sage/geometry/polyhedron/base.py b/sage/geometry/polyhedron/base.py`
 a for edge in self.vertex_graph().edges(): i = edge[0] j = edge[1] G.add_edge(i, j, (self.Vrepresentation(i).type(), self.Vrepresentation(j).type()) ) group, node_dict = G.automorphism_group(edge_labels=True, translation=True) # Relabel the permutation group perm_to_vertex = dict( (i,v+1) for v,i in node_dict.items() ) group = PermutationGroup([ [ tuple([ perm_to_vertex[i] for i in cycle ]) for cycle in generator.cycle_tuples() ] for generator in group.gens() ]) G.add_edge(i+1, j+1, (self.Vrepresentation(i).type(), self.Vrepresentation(j).type()) ) group = G.automorphism_group(edge_labels=True) self._combinatorial_automorphism_group = group return group v_i = v_list[i] v_j = v_list[j] c_ij = rational_approximation( v_i * Qinv * v_j ) G.add_edge(i,j, edge_label(i,j,c_ij)) group, node_dict = G.automorphism_group(edge_labels=True, translation=True) # Relabel the permutation group perm_to_vertex = dict( (i,v+1) for v,i in node_dict.items() ) group = PermutationGroup([ [ tuple([ perm_to_vertex[i] for i in cycle ]) for cycle in generator.cycle_tuples() ] for generator in group.gens() ]) G.add_edge(i+1,j+1, edge_label(i,j,c_ij)) group = G.automorphism_group(edge_labels=True) self._restricted_automorphism_group = group return group
• ## sage/geometry/triangulation/point_configuration.py

`diff --git a/sage/geometry/triangulation/point_configuration.py b/sage/geometry/triangulation/point_configuration.py`
 a for j in range(i+1,len(v_list)): v_i = v_list[i] v_j = v_list[j] G.add_edge(i,j, v_i * Qinv * v_j) G.add_edge(i+1,j+1, v_i * Qinv * v_j) group, node_dict = G.automorphism_group(edge_labels=True, translation=True) # Relabel the permutation group perm_to_vertex = dict( (i,v+1) for v,i in node_dict.items() ) group = PermutationGroup([ [ tuple([ perm_to_vertex[i] for i in cycle ]) for cycle in generator.cycle_tuples() ] for generator in group.gens() ]) group = G.automorphism_group(edge_labels=True) self._restricted_automorphism_group = group return group
• ## sage/graphs/generic_graph.py

`diff --git a/sage/graphs/generic_graph.py b/sage/graphs/generic_graph.py`
 a # The automorphism group, the translation between the vertices of self # and 1..n, and the orbits. ag, tr, orbits = self.automorphism_group([self.vertices()], translation = True, ag, orbits = self.automorphism_group([self.vertices()], order=False, return_group=True, orbits=True) if len(orbits) != 1: return (False, None) if certificate else False # From 1..n to the vertices of self trr = {v:k for k,v in tr.iteritems()} # We go through all conjugacy classes of the automorphism # group, and only keep the cycles of length n for e in ag.conjugacy_classes_representatives(): # add it to the list. parameters = [] cycle = cycles[0] u = trr[cycle[0]] integers = [i for i,v in enumerate(cycle) if self.has_edge(u,trr[v])] u = cycle[0] integers = [i for i,v in enumerate(cycle) if self.has_edge(u,v)] certif_list.append((self.order(),integers)) if not certificate: result = coarsest_equitable_refinement(CG, partition, G._directed) return [[perm_from[b] for b in cell] for cell in result] def automorphism_group(self, partition=None, translation=False, verbosity=0, edge_labels=False, order=False, def automorphism_group(self, partition=None, verbosity=0, edge_labels=False, order=False, return_group=True, orbits=False): """ Returns the largest subgroup of the automorphism group of the (di)graph whose orbit partition is finer than the partition given. If no partition is given, the unit partition is used and the entire automorphism group is given. INPUT: -  ``translation`` - if True, then output includes a dictionary translating from keys == vertices to entries == elements of 1,2,...,n (since permutation groups can currently only act on positive integers). INPUT: -  ``partition`` - default is the unit partition, otherwise computes the subgroup of the full automorphism group respecting the partition. -  ``edge_labels`` - default False, otherwise allows only permutations respecting edge labels. -  ``order`` - (default False) if True, compute the order of the automorphism group -  ``return_group`` - default True -  ``orbits`` - returns the orbits of the group acting on the vertices of the graph OUTPUT: The order of the output is group, translation, order, orbits. However, there are options to turn each of these on or off. EXAMPLES: Graphs:: .. WARNING:: Since :trac:`14319` the domain of the automorphism group is equal to the graph's vertex set, and the ``translation`` argument has become useless. OUTPUT: The order of the output is group, order, orbits. However, there are options to turn each of these on or off. EXAMPLES: Graphs:: sage: graphs_query = GraphQuery(display_cols=['graph6'],num_vertices=4) sage: L = graphs_query.get_graphs_list() sage: graphs_list.show_graphs(L) sage: for g in L: ...    G = g.automorphism_group() ...    G.order(), G.gens() (24, [(2,3), (1,2), (1,4)]) (4, [(2,3), (1,4)]) (24, [(2,3), (1,2), (0,1)]) (4, [(2,3), (0,1)]) (2, [(1,2)]) (6, [(1,2), (1,4)]) (6, [(1,2), (0,1)]) (6, [(2,3), (1,2)]) (8, [(1,2), (1,4)(2,3)]) (2, [(1,4)(2,3)]) (8, [(1,2), (0,1)(2,3)]) (2, [(0,1)(2,3)]) (2, [(1,2)]) (8, [(2,3), (1,3)(2,4), (1,4)]) (4, [(2,3), (1,4)]) (24, [(2,3), (1,2), (1,4)]) (8, [(2,3), (0,1), (0,2)(1,3)]) (4, [(2,3), (0,1)]) (24, [(2,3), (1,2), (0,1)]) sage: C = graphs.CubeGraph(4) sage: G = C.automorphism_group() sage: M = G.character_table() # random order of rows, thus abs() below 712483534798848 sage: G.order() 384 :: :: sage: D = graphs.DodecahedralGraph() sage: G = D.automorphism_group() sage: A5 = AlternatingGroup(5) sage: H = A5.direct_product(Z2)[0] #see documentation for direct_product to explain the [0] sage: G.is_isomorphic(H) True Multigraphs:: sage: G = Graph(multiedges=True,sparse=True) sage: G.add_edge(('a', 'b')) sage: G.add_edge(('a', 'b')) sage: G.add_edge(('a', 'b')) sage: G.automorphism_group() Permutation Group with generators [(1,2)] Permutation Group with generators [('a','b')] Digraphs:: sage: D = DiGraph( { 0:[1], 1:[2], 2:[3], 3:[4], 4:[0] } ) sage: D.automorphism_group() Permutation Group with generators [(1,2,3,4,5)] Permutation Group with generators [(0,1,2,3,4)] Edge labeled graphs:: sage: G = Graph(sparse=True) sage: G.add_edges( [(0,1,'a'),(1,2,'b'),(2,3,'c'),(3,4,'b'),(4,0,'a')] ) sage: G.automorphism_group(edge_labels=True) Permutation Group with generators [(1,4)(2,3)] :: :: sage: G = Graph({0 : {1 : 7}}) sage: G.automorphism_group(translation=True, edge_labels=True) (Permutation Group with generators [(1,2)], {0: 2, 1: 1}) sage: G.automorphism_group(edge_labels=True) Permutation Group with generators [(0,1)] sage: foo = Graph(sparse=True) sage: bar = Graph(implementation='c_graph',sparse=True) sage: foo.add_edges([(0,1,1),(1,2,2), (2,3,3)]) sage: bar.add_edges([(0,1,1),(1,2,2), (2,3,3)]) sage: foo.automorphism_group(translation=True, edge_labels=True) (Permutation Group with generators [()], {0: 4, 1: 1, 2: 2, 3: 3}) sage: foo.automorphism_group(translation=True) (Permutation Group with generators [(1,2)(3,4)], {0: 4, 1: 1, 2: 2, 3: 3}) sage: bar.automorphism_group(translation=True, edge_labels=True) (Permutation Group with generators [()], {0: 4, 1: 1, 2: 2, 3: 3}) sage: bar.automorphism_group(translation=True) (Permutation Group with generators [(1,2)(3,4)], {0: 4, 1: 1, 2: 2, 3: 3}) sage: foo.automorphism_group(edge_labels=True) Permutation Group with generators [()] sage: foo.automorphism_group() Permutation Group with generators [(0,3)(1,2)] sage: bar.automorphism_group(edge_labels=True) Permutation Group with generators [()] You can also ask for just the order of the group:: sage: G = graphs.PetersenGraph() sage: G.automorphism_group(return_group=False, order=True) 120 Or, just the orbits (note that each graph here is vertex transitive) :: :: sage: G = graphs.PetersenGraph() sage: G.automorphism_group(return_group=False, orbits=True) [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]] ... KeyError: 6 """ from sage.groups.perm_gps.partn_ref.refinement_graphs import perm_group_elt, search_tree Labeled automorphism group:: sage: digraphs.DeBruijn(3,2).automorphism_group() Permutation Group with generators [('01','02')('10','20')('11','22')('12','21'), ('00','11')('01','10')('02','12')('20','21')] sage: d = digraphs.DeBruijn(3,2) sage: d.allow_multiple_edges(True) sage: d.add_edge(d.edges()[0]) sage: d.automorphism_group() Permutation Group with generators [('01','02')('10','20')('11','22')('12','21')] The labeling is correct:: sage: g = graphs.PetersenGraph() sage: ag = g.automorphism_group() sage: for u,v in g.edges(labels = False): ...       if len(ag.orbit((u,v),action="OnPairs")) != 30: ...           print "ARggggggggggggg !!!" """ from sage.groups.perm_gps.partn_ref.refinement_graphs import search_tree from sage.groups.perm_gps.permgroup import PermutationGroup dig = (self._directed or self.has_loops()) if partition is None: HB.add_edge(u,v,None,self._directed) GC = HB._cg partition = [[G_to[v] for v in cell] for cell in partition] if translation: if return_group: A = search_tree(GC, partition, dict_rep=True, lab=False, dig=dig, verbosity=verbosity, order=order) if order: a,b,c = A a = search_tree(GC, partition, dict_rep=False, lab=False, dig=dig, verbosity=verbosity, order=order) if order: a,c = a output = [] if return_group: if len(a) != 0: output.append(PermutationGroup([perm_group_elt(aa) for aa in a])) # We translate the integer permutations into a collection of # cycles. from sage.combinat.permutation import Permutation gens = [Permutation([x+1 for x in aa]).to_cycles() for aa in a] # We relabel the cycles using the vertices' names instead of integers n = self.order() int_to_vertex = {((i+1) if i != n else 1):v for v,i in b.iteritems()} gens = [ [ tuple([int_to_vertex[i] for i in cycle]) for cycle in gen] for gen in gens] output.append(PermutationGroup(gens = gens, domain = int_to_vertex.values())) else: output.append(PermutationGroup([[]])) if translation: output.append(b) if order: output.append(c) if orbits:
• ## sage/graphs/graph.py

`diff --git a/sage/graphs/graph.py b/sage/graphs/graph.py`
 a if self.size() == 0: return True A,T = self.automorphism_group(translation=True) A = self.automorphism_group() e = self.edge_iterator(labels=False).next() e = [T[e[0]], T[e[1]]] e = [A._domain_to_gap[e[0]], A._domain_to_gap[e[1]]] return gap("OrbitLength("+str(A._gap_())+",Set(" + str(e) + "),OnSets);") == self.size() def is_arc_transitive(self): if self.size() == 0: return True A,T = self.automorphism_group(translation=True) A = self.automorphism_group() e = self.edge_iterator(labels=False).next() e = [T[e[0]], T[e[1]]] e = [A._domain_to_gap[e[0]], A._domain_to_gap[e[1]]] return gap("OrbitLength("+str(A._gap_())+",Set(" + str(e) + "),OnTuples);") == 2*self.size() def is_half_transitive(self):
• ## sage/groups/perm_gps/partn_ref/refinement_graphs.pyx

`diff --git a/sage/groups/perm_gps/partn_ref/refinement_graphs.pyx b/sage/groups/perm_gps/partn_ref/refinement_graphs.pyx`
 a i[j] = 0 return l def perm_group_elt(lperm): """ Given a list permutation of the set 0, 1, ..., n-1, returns the corresponding PermutationGroupElement where we take 0 = n. EXAMPLE:: sage: from sage.groups.perm_gps.partn_ref.refinement_graphs import perm_group_elt sage: perm_group_elt([0,2,1]) (1,2) sage: perm_group_elt([1,2,0]) (1,2,3) """ from sage.groups.perm_gps.permgroup_named import SymmetricGroup n = len(lperm) S = SymmetricGroup(n) Part = orbit_partition(lperm, list_perm=True) gens = [] for z in Part: if len(z) > 1: if 0 in z: zed = z.index(0) generator = z[:zed] + [n] + z[zed+1:] gens.append(tuple(generator)) else: gens.append(tuple(z)) E = S(gens) return E def coarsest_equitable_refinement(CGraph G, list partition, bint directed): """ Returns the coarsest equitable refinement of ``partition`` for ``G``.
• ## sage/groups/perm_gps/permgroup.py

`diff --git a/sage/groups/perm_gps/permgroup.py b/sage/groups/perm_gps/permgroup.py`
 a Now the full blocks:: sage: ag.blocks_all(representatives = False) [[[1, 16], [8, 17], [14, 19], [2, 12], [7, 18], [5, 10], [15, 20], [4, 9], [3, 13], [6, 11]]] [[[1, 16], [2, 17], [15, 20], [9, 18], [6, 11], [3, 13], [8, 19], [4, 14], [5, 10], [7, 12]]] """ ag = self._gap_() if representatives:
• ## sage/groups/perm_gps/permgroup_element.pyx

`diff --git a/sage/groups/perm_gps/permgroup_element.pyx b/sage/groups/perm_gps/permgroup_element.pyx`
 a ``domain`` of the permutation group. This is function is used when unpickling permutation groups and their elements. their elements. EXAMPLES:: sage: from sage.groups.perm_gps.permgroup_element import make_permgroup_element_v2 def dict(self): """ Returns list of the images of the integers from 1 to n under this permutation as a list of Python ints. .. note:: Returns a dictionary associating each element of the domain with its image. :meth:`.list` returns a zero-indexed list. :meth:`.dict` return the actual mapping of the permutation, which will be indexed starting with 1. EXAMPLES:: sage: G = SymmetricGroup(4) sage: g = G((1,2,3,4)); g (1,2,3,4) {1: 2, 2: 1, 3: 3, 4: 4} """ from_gap = self._parent._domain_from_gap to_gap = self._parent._domain_to_gap cdef int i u = {} for i from 0 <= i < self.n: u[i+1] = from_gap[self.perm[i]+1] return u return {e:from_gap[self.perm[i-1]+1] for e,i in to_gap.iteritems()} def order(self): """ Return the order of this group element, which is the smallest
• ## sage/homology/simplicial_complex.py

`diff --git a/sage/homology/simplicial_complex.py b/sage/homology/simplicial_complex.py`
 a return isisom,tr def automorphism_group(self,translation=False): def automorphism_group(self): r""" Returns the automorphism group of the simplicial complex vertices and facets of the simplicial complex, and computing its automorphism group. INPUT: - ``translation`` (boolean, default: ``False``) whether to return a dictionary associating the vertices of the simplicial complex to elements of the set on which the group acts OUTPUT: - a permutation group if ``translation`` is ``False`` - a permutation group and a dictionary if ``translation`` is ``True`` .. NOTE:: The group is returned as a permutation group acting on integers from ``1`` to the number of vertices. The bijection with vertices is provided if ``translation`` is ``True``. .. WARNING:: Since :trac:`14319` the domain of the automorphism group is equal to the graph's vertex set, and the ``translation`` argument has become useless. EXAMPLES:: sage: Z = SimplicialComplex([[1,2],[2,3,'a']]) sage: Z.automorphism_group().is_isomorphic(CyclicPermutationGroup(2)) True sage: group, dict = Z.automorphism_group(translation=True) sage: Set([dict[s] for s in Z.vertices()]) {1, 2, 3, 4} sage: group = Z.automorphism_group() sage: group.domain() {1, 2, 3, 'a'} """ from sage.groups.perm_gps.permgroup import PermutationGroup from sage.combinat.permutation import Permutation G = Graph() G.add_vertices(self.vertices()) G.add_edges((f.tuple(),v) for f in self.facets() for v in f) groupe, simpl_to_gap = G.automorphism_group(translation=True, partition=[list(self.vertices()), [f.tuple() for f in self.facets()]]) gap_to_simpl = {x_gap:x for x,x_gap in simpl_to_gap.iteritems()} # reverse dictionary gap_to_range = {simpl_to_gap[x]:(i+1) for i,x in enumerate(self.vertices())} permgroup = PermutationGroup([ Permutation([tuple([gap_to_range[x] for x in c]) for c in g.cycle_tuples() if not isinstance(gap_to_simpl[c[0]],tuple)]) for g in groupe.gens()]) if translation: return permgroup, {f:gap_to_range[simpl_to_gap[f]] for f in self.vertices()} else: return permgroup groupe = G.automorphism_group(partition=[list(self.vertices()), [f.tuple() for f in self.facets()]]) gens = [ [tuple(c) for c in g.cycle_tuples() if not isinstance(c[0],tuple)] for g in groupe.gens()] permgroup = PermutationGroup(gens = gens, domain = self.vertices()) return permgroup def _Hom_(self, other, category=None): """