Ticket #14319: trac_14319.patch
File trac_14319.patch, 22.6 KB (added by , 10 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 b 122 122 for cone in fan2.generating_cones() ) 123 123 124 124 # iterate over all graph isomorphisms graph1 -> graph2 125 for perm in graph2.automorphism_group(edge_labels=True): 125 g2 = graph2.relabel({v:(i if i!=0 else graph2.order()) for i,v in enumerate(graph2.vertices())}, inplace = False) 126 127 for perm in g2.automorphism_group(edge_labels=True): 126 128 # find a candidate m that maps max_cone to the graph image cone 127 129 image_ray_indices = [ perm(graph_iso[r]+1)-1 for r in fan1_pivot_rays ] 128 130 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 b 3891 3891 for edge in self.vertex_graph().edges(): 3892 3892 i = edge[0] 3893 3893 j = edge[1] 3894 G.add_edge(i, j, (self.Vrepresentation(i).type(), self.Vrepresentation(j).type()) ) 3895 3896 group, node_dict = G.automorphism_group(edge_labels=True, translation=True) 3897 3898 # Relabel the permutation group 3899 perm_to_vertex = dict( (i,v+1) for v,i in node_dict.items() ) 3900 group = PermutationGroup([ [ tuple([ perm_to_vertex[i] for i in cycle ]) 3901 for cycle in generator.cycle_tuples() ] 3902 for generator in group.gens() ]) 3903 3894 G.add_edge(i+1, j+1, (self.Vrepresentation(i).type(), self.Vrepresentation(j).type()) ) 3895 3896 group = G.automorphism_group(edge_labels=True) 3904 3897 self._combinatorial_automorphism_group = group 3905 3898 return group 3906 3899 … … 4151 4144 v_i = v_list[i] 4152 4145 v_j = v_list[j] 4153 4146 c_ij = rational_approximation( v_i * Qinv * v_j ) 4154 G.add_edge(i,j, edge_label(i,j,c_ij)) 4155 4156 group, node_dict = G.automorphism_group(edge_labels=True, translation=True) 4157 4158 # Relabel the permutation group 4159 perm_to_vertex = dict( (i,v+1) for v,i in node_dict.items() ) 4160 group = PermutationGroup([ [ tuple([ perm_to_vertex[i] for i in cycle ]) 4161 for cycle in generator.cycle_tuples() ] 4162 for generator in group.gens() ]) 4163 4147 G.add_edge(i+1,j+1, edge_label(i,j,c_ij)) 4148 4149 group = G.automorphism_group(edge_labels=True) 4164 4150 self._restricted_automorphism_group = group 4165 4151 return group 4166 4152 -
sage/geometry/triangulation/point_configuration.py
diff --git a/sage/geometry/triangulation/point_configuration.py b/sage/geometry/triangulation/point_configuration.py
a b 1149 1149 for j in range(i+1,len(v_list)): 1150 1150 v_i = v_list[i] 1151 1151 v_j = v_list[j] 1152 G.add_edge(i ,j, v_i * Qinv * v_j)1152 G.add_edge(i+1,j+1, v_i * Qinv * v_j) 1153 1153 1154 group, node_dict = G.automorphism_group(edge_labels=True, translation=True) 1155 1156 # Relabel the permutation group 1157 perm_to_vertex = dict( (i,v+1) for v,i in node_dict.items() ) 1158 group = PermutationGroup([ [ tuple([ perm_to_vertex[i] for i in cycle ]) 1159 for cycle in generator.cycle_tuples() ] 1160 for generator in group.gens() ]) 1161 1154 group = G.automorphism_group(edge_labels=True) 1162 1155 self._restricted_automorphism_group = group 1163 1156 return group 1164 1157 -
sage/graphs/generic_graph.py
diff --git a/sage/graphs/generic_graph.py b/sage/graphs/generic_graph.py
a b 10492 10492 10493 10493 # The automorphism group, the translation between the vertices of self 10494 10494 # and 1..n, and the orbits. 10495 ag, tr, orbits = self.automorphism_group([self.vertices()], 10496 translation = True, 10495 ag, orbits = self.automorphism_group([self.vertices()], 10497 10496 order=False, 10498 10497 return_group=True, 10499 10498 orbits=True) … … 10502 10501 if len(orbits) != 1: 10503 10502 return (False, None) if certificate else False 10504 10503 10505 # From 1..n to the vertices of self10506 trr = {v:k for k,v in tr.iteritems()}10507 10508 10504 # We go through all conjugacy classes of the automorphism 10509 10505 # group, and only keep the cycles of length n 10510 10506 for e in ag.conjugacy_classes_representatives(): … … 10525 10521 # add it to the list. 10526 10522 parameters = [] 10527 10523 cycle = cycles[0] 10528 u = trr[cycle[0]]10529 integers = [i for i,v in enumerate(cycle) if self.has_edge(u, trr[v])]10524 u = cycle[0] 10525 integers = [i for i,v in enumerate(cycle) if self.has_edge(u,v)] 10530 10526 certif_list.append((self.order(),integers)) 10531 10527 10532 10528 if not certificate: … … 16179 16175 result = coarsest_equitable_refinement(CG, partition, G._directed) 16180 16176 return [[perm_from[b] for b in cell] for cell in result] 16181 16177 16182 def automorphism_group(self, partition=None, translation=False,16183 verbosity=0,edge_labels=False, order=False,16178 def automorphism_group(self, partition=None, verbosity=0, 16179 edge_labels=False, order=False, 16184 16180 return_group=True, orbits=False): 16185 16181 """ 16186 16182 Returns the largest subgroup of the automorphism group of the 16187 16183 (di)graph whose orbit partition is finer than the partition given. 16188 16184 If no partition is given, the unit partition is used and the entire 16189 16185 automorphism group is given. 16190 16191 INPUT: 16192 16193 16194 - ``translation`` - if True, then output includes a 16195 dictionary translating from keys == vertices to entries == elements 16196 of 1,2,...,n (since permutation groups can currently only act on 16197 positive integers). 16198 16186 16187 INPUT: 16188 16199 16189 - ``partition`` - default is the unit partition, 16200 16190 otherwise computes the subgroup of the full automorphism group 16201 16191 respecting the partition. 16202 16192 16203 16193 - ``edge_labels`` - default False, otherwise allows 16204 16194 only permutations respecting edge labels. 16205 16195 16206 16196 - ``order`` - (default False) if True, compute the 16207 16197 order of the automorphism group 16208 16198 16209 16199 - ``return_group`` - default True 16210 16200 16211 16201 - ``orbits`` - returns the orbits of the group acting 16212 16202 on the vertices of the graph 16213 16214 16215 OUTPUT: The order of the output is group, translation, order, 16216 orbits. However, there are options to turn each of these on or 16217 off. 16218 16219 EXAMPLES: Graphs:: 16220 16203 16204 .. WARNING:: 16205 16206 Since :trac:`14319` the domain of the automorphism group is equal to 16207 the graph's vertex set, and the ``translation`` argument has become 16208 useless. 16209 16210 OUTPUT: The order of the output is group, order, orbits. However, there 16211 are options to turn each of these on or off. 16212 16213 EXAMPLES: 16214 16215 Graphs:: 16216 16221 16217 sage: graphs_query = GraphQuery(display_cols=['graph6'],num_vertices=4) 16222 16218 sage: L = graphs_query.get_graphs_list() 16223 16219 sage: graphs_list.show_graphs(L) 16224 16220 sage: for g in L: 16225 16221 ... G = g.automorphism_group() 16226 16222 ... G.order(), G.gens() 16227 (24, [(2,3), (1,2), ( 1,4)])16228 (4, [(2,3), ( 1,4)])16223 (24, [(2,3), (1,2), (0,1)]) 16224 (4, [(2,3), (0,1)]) 16229 16225 (2, [(1,2)]) 16230 (6, [(1,2), ( 1,4)])16226 (6, [(1,2), (0,1)]) 16231 16227 (6, [(2,3), (1,2)]) 16232 (8, [(1,2), ( 1,4)(2,3)])16233 (2, [( 1,4)(2,3)])16228 (8, [(1,2), (0,1)(2,3)]) 16229 (2, [(0,1)(2,3)]) 16234 16230 (2, [(1,2)]) 16235 (8, [(2,3), ( 1,3)(2,4), (1,4)])16236 (4, [(2,3), ( 1,4)])16237 (24, [(2,3), (1,2), ( 1,4)])16231 (8, [(2,3), (0,1), (0,2)(1,3)]) 16232 (4, [(2,3), (0,1)]) 16233 (24, [(2,3), (1,2), (0,1)]) 16238 16234 sage: C = graphs.CubeGraph(4) 16239 16235 sage: G = C.automorphism_group() 16240 16236 sage: M = G.character_table() # random order of rows, thus abs() below … … 16242 16238 712483534798848 16243 16239 sage: G.order() 16244 16240 384 16245 16246 :: 16247 16241 16242 :: 16243 16248 16244 sage: D = graphs.DodecahedralGraph() 16249 16245 sage: G = D.automorphism_group() 16250 16246 sage: A5 = AlternatingGroup(5) … … 16252 16248 sage: H = A5.direct_product(Z2)[0] #see documentation for direct_product to explain the [0] 16253 16249 sage: G.is_isomorphic(H) 16254 16250 True 16255 16251 16256 16252 Multigraphs:: 16257 16253 16258 16254 sage: G = Graph(multiedges=True,sparse=True) 16259 16255 sage: G.add_edge(('a', 'b')) 16260 16256 sage: G.add_edge(('a', 'b')) 16261 16257 sage: G.add_edge(('a', 'b')) 16262 16258 sage: G.automorphism_group() 16263 Permutation Group with generators [( 1,2)]16264 16259 Permutation Group with generators [('a','b')] 16260 16265 16261 Digraphs:: 16266 16262 16267 16263 sage: D = DiGraph( { 0:[1], 1:[2], 2:[3], 3:[4], 4:[0] } ) 16268 16264 sage: D.automorphism_group() 16269 Permutation Group with generators [( 1,2,3,4,5)]16270 16265 Permutation Group with generators [(0,1,2,3,4)] 16266 16271 16267 Edge labeled graphs:: 16272 16268 16273 16269 sage: G = Graph(sparse=True) 16274 16270 sage: G.add_edges( [(0,1,'a'),(1,2,'b'),(2,3,'c'),(3,4,'b'),(4,0,'a')] ) 16275 16271 sage: G.automorphism_group(edge_labels=True) 16276 16272 Permutation Group with generators [(1,4)(2,3)] 16277 16278 :: 16279 16273 16274 :: 16275 16280 16276 sage: G = Graph({0 : {1 : 7}}) 16281 sage: G.automorphism_group( translation=True,edge_labels=True)16282 (Permutation Group with generators [(1,2)], {0: 2, 1: 1})16277 sage: G.automorphism_group(edge_labels=True) 16278 Permutation Group with generators [(0,1)] 16283 16279 16284 16280 sage: foo = Graph(sparse=True) 16285 16281 sage: bar = Graph(implementation='c_graph',sparse=True) 16286 16282 sage: foo.add_edges([(0,1,1),(1,2,2), (2,3,3)]) 16287 16283 sage: bar.add_edges([(0,1,1),(1,2,2), (2,3,3)]) 16288 sage: foo.automorphism_group(translation=True, edge_labels=True) 16289 (Permutation Group with generators [()], {0: 4, 1: 1, 2: 2, 3: 3}) 16290 sage: foo.automorphism_group(translation=True) 16291 (Permutation Group with generators [(1,2)(3,4)], {0: 4, 1: 1, 2: 2, 3: 3}) 16292 sage: bar.automorphism_group(translation=True, edge_labels=True) 16293 (Permutation Group with generators [()], {0: 4, 1: 1, 2: 2, 3: 3}) 16294 sage: bar.automorphism_group(translation=True) 16295 (Permutation Group with generators [(1,2)(3,4)], {0: 4, 1: 1, 2: 2, 3: 3}) 16284 sage: foo.automorphism_group(edge_labels=True) 16285 Permutation Group with generators [()] 16286 sage: foo.automorphism_group() 16287 Permutation Group with generators [(0,3)(1,2)] 16288 sage: bar.automorphism_group(edge_labels=True) 16289 Permutation Group with generators [()] 16296 16290 16297 16291 You can also ask for just the order of the group:: 16298 16292 16299 16293 sage: G = graphs.PetersenGraph() 16300 16294 sage: G.automorphism_group(return_group=False, order=True) 16301 16295 120 16302 16296 16303 16297 Or, just the orbits (note that each graph here is vertex transitive) 16304 16305 :: 16306 16298 16299 :: 16300 16307 16301 sage: G = graphs.PetersenGraph() 16308 16302 sage: G.automorphism_group(return_group=False, orbits=True) 16309 16303 [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]] … … 16324 16318 ... 16325 16319 KeyError: 6 16326 16320 16327 """ 16328 from sage.groups.perm_gps.partn_ref.refinement_graphs import perm_group_elt, search_tree 16321 Labeled automorphism group:: 16322 16323 sage: digraphs.DeBruijn(3,2).automorphism_group() 16324 Permutation Group with generators [('01','02')('10','20')('11','22')('12','21'), ('00','11')('01','10')('02','12')('20','21')] 16325 sage: d = digraphs.DeBruijn(3,2) 16326 sage: d.allow_multiple_edges(True) 16327 sage: d.add_edge(d.edges()[0]) 16328 sage: d.automorphism_group() 16329 Permutation Group with generators [('01','02')('10','20')('11','22')('12','21')] 16330 16331 The labeling is correct:: 16332 16333 sage: g = graphs.PetersenGraph() 16334 sage: ag = g.automorphism_group() 16335 sage: for u,v in g.edges(labels = False): 16336 ... if len(ag.orbit((u,v),action="OnPairs")) != 30: 16337 ... print "ARggggggggggggg !!!" 16338 """ 16339 from sage.groups.perm_gps.partn_ref.refinement_graphs import search_tree 16329 16340 from sage.groups.perm_gps.permgroup import PermutationGroup 16330 16341 dig = (self._directed or self.has_loops()) 16331 16342 if partition is None: … … 16392 16403 HB.add_edge(u,v,None,self._directed) 16393 16404 GC = HB._cg 16394 16405 partition = [[G_to[v] for v in cell] for cell in partition] 16395 if translation: 16406 16407 if return_group: 16396 16408 A = search_tree(GC, partition, dict_rep=True, lab=False, dig=dig, verbosity=verbosity, order=order) 16397 16409 if order: 16398 16410 a,b,c = A … … 16406 16418 a = search_tree(GC, partition, dict_rep=False, lab=False, dig=dig, verbosity=verbosity, order=order) 16407 16419 if order: 16408 16420 a,c = a 16421 16409 16422 output = [] 16410 16423 if return_group: 16411 16424 if len(a) != 0: 16412 output.append(PermutationGroup([perm_group_elt(aa) for aa in a])) 16425 # We translate the integer permutations into a collection of 16426 # cycles. 16427 from sage.combinat.permutation import Permutation 16428 gens = [Permutation([x+1 for x in aa]).to_cycles() for aa in a] 16429 16430 # We relabel the cycles using the vertices' names instead of integers 16431 n = self.order() 16432 int_to_vertex = {((i+1) if i != n else 1):v for v,i in b.iteritems()} 16433 gens = [ [ tuple([int_to_vertex[i] for i in cycle]) for cycle in gen] for gen in gens] 16434 output.append(PermutationGroup(gens = gens, domain = int_to_vertex.values())) 16413 16435 else: 16414 16436 output.append(PermutationGroup([[]])) 16415 if translation:16416 output.append(b)16417 16437 if order: 16418 16438 output.append(c) 16419 16439 if orbits: -
sage/graphs/graph.py
diff --git a/sage/graphs/graph.py b/sage/graphs/graph.py
a b 2650 2650 if self.size() == 0: 2651 2651 return True 2652 2652 2653 A ,T = self.automorphism_group(translation=True)2653 A = self.automorphism_group() 2654 2654 e = self.edge_iterator(labels=False).next() 2655 e = [T[e[0]], T[e[1]]] 2655 e = [A._domain_to_gap[e[0]], A._domain_to_gap[e[1]]] 2656 2656 2657 return gap("OrbitLength("+str(A._gap_())+",Set(" + str(e) + "),OnSets);") == self.size() 2657 2658 2658 2659 def is_arc_transitive(self): … … 2691 2692 if self.size() == 0: 2692 2693 return True 2693 2694 2694 A ,T = self.automorphism_group(translation=True)2695 A = self.automorphism_group() 2695 2696 e = self.edge_iterator(labels=False).next() 2696 e = [T[e[0]], T[e[1]]] 2697 e = [A._domain_to_gap[e[0]], A._domain_to_gap[e[1]]] 2698 2697 2699 return gap("OrbitLength("+str(A._gap_())+",Set(" + str(e) + "),OnTuples);") == 2*self.size() 2698 2700 2699 2701 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 b 912 912 i[j] = 0 913 913 return l 914 914 915 def perm_group_elt(lperm):916 """917 Given a list permutation of the set 0, 1, ..., n-1, returns the918 corresponding PermutationGroupElement where we take 0 = n.919 920 EXAMPLE::921 922 sage: from sage.groups.perm_gps.partn_ref.refinement_graphs import perm_group_elt923 sage: perm_group_elt([0,2,1])924 (1,2)925 sage: perm_group_elt([1,2,0])926 (1,2,3)927 """928 from sage.groups.perm_gps.permgroup_named import SymmetricGroup929 n = len(lperm)930 S = SymmetricGroup(n)931 Part = orbit_partition(lperm, list_perm=True)932 gens = []933 for z in Part:934 if len(z) > 1:935 if 0 in z:936 zed = z.index(0)937 generator = z[:zed] + [n] + z[zed+1:]938 gens.append(tuple(generator))939 else:940 gens.append(tuple(z))941 E = S(gens)942 return E943 944 915 def coarsest_equitable_refinement(CGraph G, list partition, bint directed): 945 916 """ 946 917 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 b 2797 2797 Now the full blocks:: 2798 2798 2799 2799 sage: ag.blocks_all(representatives = False) 2800 [[[1, 16], [8, 17], [14, 19], [2, 12], [7, 18], [5, 10], [15, 20], [4, 9], [3, 13], [6, 11]]] 2800 [[[1, 16], [2, 17], [15, 20], [9, 18], [6, 11], [3, 13], [8, 19], [4, 14], [5, 10], [7, 12]]] 2801 2801 2802 """ 2802 2803 ag = self._gap_() 2803 2804 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 b 104 104 ``domain`` of the permutation group. 105 105 106 106 This is function is used when unpickling permutation groups and 107 their elements. 108 107 their elements. 108 109 109 EXAMPLES:: 110 110 111 111 sage: from sage.groups.perm_gps.permgroup_element import make_permgroup_element_v2 … … 996 996 997 997 def dict(self): 998 998 """ 999 Returns list of the images of the integers from 1 to n under this 1000 permutation as a list of Python ints. 1001 1002 .. note:: 999 Returns a dictionary associating each element of the domain with its 1000 image. 1003 1001 1004 :meth:`.list` returns a zero-indexed list. :meth:`.dict`1005 return the actual mapping of the permutation, which will be1006 indexed starting with 1.1007 1008 1002 EXAMPLES:: 1009 1003 1010 1004 sage: G = SymmetricGroup(4) 1011 1005 sage: g = G((1,2,3,4)); g 1012 1006 (1,2,3,4) … … 1020 1014 {1: 2, 2: 1, 3: 3, 4: 4} 1021 1015 """ 1022 1016 from_gap = self._parent._domain_from_gap 1017 to_gap = self._parent._domain_to_gap 1023 1018 cdef int i 1024 u = {} 1025 for i from 0 <= i < self.n: 1026 u[i+1] = from_gap[self.perm[i]+1] 1027 return u 1028 1019 return {e:from_gap[self.perm[i-1]+1] for e,i in to_gap.iteritems()} 1020 1029 1021 def order(self): 1030 1022 """ 1031 1023 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 b 3103 3103 3104 3104 return isisom,tr 3105 3105 3106 def automorphism_group(self ,translation=False):3106 def automorphism_group(self): 3107 3107 r""" 3108 3108 Returns the automorphism group of the simplicial complex 3109 3109 … … 3111 3111 vertices and facets of the simplicial complex, and computing 3112 3112 its automorphism group. 3113 3113 3114 INPUT: 3115 3116 - ``translation`` (boolean, default: ``False``) whether to return 3117 a dictionary associating the vertices of the simplicial 3118 complex to elements of the set on which the group acts 3119 3120 OUTPUT: 3121 3122 - a permutation group if ``translation`` is ``False`` 3123 - a permutation group and a dictionary if ``translation`` is ``True`` 3124 3125 .. NOTE:: 3126 3127 The group is returned as a permutation group acting on 3128 integers from ``1`` to the number of vertices. The bijection 3129 with vertices is provided if ``translation`` is ``True``. 3114 .. WARNING:: 3115 3116 Since :trac:`14319` the domain of the automorphism group is equal to 3117 the graph's vertex set, and the ``translation`` argument has become 3118 useless. 3130 3119 3131 3120 EXAMPLES:: 3132 3121 … … 3141 3130 sage: Z = SimplicialComplex([[1,2],[2,3,'a']]) 3142 3131 sage: Z.automorphism_group().is_isomorphic(CyclicPermutationGroup(2)) 3143 3132 True 3144 sage: group , dict = Z.automorphism_group(translation=True)3145 sage: Set([dict[s] for s in Z.vertices()])3146 {1, 2, 3, 4}3133 sage: group = Z.automorphism_group() 3134 sage: group.domain() 3135 {1, 2, 3, 'a'} 3147 3136 """ 3148 3137 from sage.groups.perm_gps.permgroup import PermutationGroup 3149 from sage.combinat.permutation import Permutation 3138 3150 3139 G = Graph() 3151 3140 G.add_vertices(self.vertices()) 3152 3141 G.add_edges((f.tuple(),v) for f in self.facets() for v in f) 3153 groupe, simpl_to_gap = G.automorphism_group(translation=True, 3154 partition=[list(self.vertices()), 3155 [f.tuple() for f in self.facets()]]) 3156 gap_to_simpl = {x_gap:x for x,x_gap in simpl_to_gap.iteritems()} # reverse dictionary 3157 gap_to_range = {simpl_to_gap[x]:(i+1) for i,x in enumerate(self.vertices())} 3158 permgroup = PermutationGroup([ 3159 Permutation([tuple([gap_to_range[x] for x in c]) 3160 for c in g.cycle_tuples() 3161 if not isinstance(gap_to_simpl[c[0]],tuple)]) 3162 for g in groupe.gens()]) 3163 if translation: 3164 return permgroup, {f:gap_to_range[simpl_to_gap[f]] for f in self.vertices()} 3165 else: 3166 return permgroup 3142 groupe = G.automorphism_group(partition=[list(self.vertices()), 3143 [f.tuple() for f in self.facets()]]) 3144 3145 3146 gens = [ [tuple(c) for c in g.cycle_tuples() if not isinstance(c[0],tuple)] 3147 for g in groupe.gens()] 3148 3149 permgroup = PermutationGroup(gens = gens, domain = self.vertices()) 3150 3151 return permgroup 3167 3152 3168 3153 def _Hom_(self, other, category=None): 3169 3154 """