Ticket #14291: trac_14291-v2.patch
File trac_14291-v2.patch, 8.3 KB (added by , 8 years ago) |
---|
-
sage/groups/perm_gps/permgroup.py
# HG changeset patch # User Nathann Cohen <nathann.cohen@gmail.com> # Date 1363519490 -3600 # Node ID d06a5ef48d94261e86589a2ee91363e9ae62112d # Parent 5ede04e6bce52102dca9323a193a09257b1dc027 Orbits of more than just points in PermutationGroup.orbit diff --git a/sage/groups/perm_gps/permgroup.py b/sage/groups/perm_gps/permgroup.py
a b 1039 1039 def orbits(self): 1040 1040 """ 1041 1041 Returns the orbits of the elements of the domain under the 1042 group action.1043 1042 default group action. 1043 1044 1044 EXAMPLES:: 1045 1046 sage: G = PermutationGroup([ [(3,4)], [(1,3)] ]) 1045 1046 sage: G = PermutationGroup([ [(3,4)], [(1,3)] ]) 1047 1047 sage: G.orbits() 1048 1048 [[1, 3, 4], [2]] 1049 1049 sage: G = PermutationGroup([[(1,2),(3,4)], [(1,2,3,4,10)]]) … … 1053 1053 sage: G = PermutationGroup([ [('c','d')], [('a','c')],[('b',)]]) 1054 1054 sage: G.orbits() 1055 1055 [['a', 'c', 'd'], ['b']] 1056 1056 1057 1057 The answer is cached:: 1058 1058 1059 1059 sage: G.orbits() is G.orbits() 1060 True 1061 1060 True 1061 1062 1062 AUTHORS: 1063 1063 1064 1064 - Nathan Dunfield … … 1067 1067 self._gap_().Orbits(self._domain_gap()).sage()] 1068 1068 1069 1069 @cached_method 1070 def orbit(self, point ):1070 def orbit(self, point, action = "OnPoints"): 1071 1071 """ 1072 Return the orbit of the given point under the group action. 1072 Return the orbit of a point under a group action. 1073 1074 INPUT: 1075 1076 - ``point`` -- can be a point or any of the list above, depending on the 1077 action to be considered. 1078 1079 - ``action`` (string) -- if ``point`` is an element from the domain, a 1080 tuple of elements of the domain, a tuple of tuples [...], this 1081 variable describes how the group is acting. 1082 1083 The actions currently available through this method are "OnPoints", 1084 "OnTuples", "OnSets", "OnPairs", "OnSetsSets", "OnSetsDisjointSets", 1085 "OnSetsTuples", "OnTuplesSets", "OnTuplesTuples". They are taken from 1086 GAP's list `http://www.gap-system.org/Manuals/doc/ref/chap41.html`_. 1087 1088 It is set to ``"OnPoints"`` by default. See below for examples. 1073 1089 1074 1090 EXAMPLES:: 1075 1091 … … 1077 1093 sage: G.orbit(3) 1078 1094 [3, 4, 1] 1079 1095 sage: G = PermutationGroup([[(1,2),(3,4)], [(1,2,3,4,10)]]) 1080 sage: G.orbit(3) 1096 sage: G.orbit(3) 1081 1097 [3, 4, 10, 1, 2] 1082 1083 1098 sage: G = PermutationGroup([ [('c','d')], [('a','c')] ]) 1084 1099 sage: G.orbit('a') 1085 1100 ['a', 'c', 'd'] 1086 """ 1087 point = self._domain_to_gap[point] 1088 return [self._domain_from_gap[x] for x in self._gap_().Orbit(point).sage()] 1089 1101 1102 Action of `S_3` on sets:: 1103 1104 sage: S3 = groups.permutation.Symmetric(3) 1105 sage: S3.orbit((1,2), action = "OnSets") 1106 [[1, 2], [2, 3], [1, 3]] 1107 1108 On tuples:: 1109 1110 sage: S3.orbit((1,2), action = "OnTuples") 1111 [[1, 2], [2, 3], [2, 1], [3, 1], [1, 3], [3, 2]] 1112 1113 Action of `S_4` on sets of disjoint sets:: 1114 1115 sage: S4 = groups.permutation.Symmetric(4) 1116 sage: S4.orbit(((1,2),(3,4)), action = "OnSetsDisjointSets") 1117 [[[1, 2], [3, 4]], 1118 [[1, 4], [2, 3]], 1119 [[1, 3], [2, 4]]] 1120 1121 Action of `S_4` (on a nonstandard domain) on tuples of sets:: 1122 1123 sage: S4 = PermutationGroup([ [('c','d')], [('a','c')], [('a','b')] ]) 1124 sage: S4.orbit((('a','c'),('b','d')),"OnTuplesSets") 1125 [[['a', 'c'], ['b', 'd']], [['a', 'd'], ['b', 'c']], 1126 [['b', 'c'], ['a', 'd']], [['b', 'd'], ['a', 'c']], 1127 [['c', 'd'], ['a', 'b']], [['a', 'b'], ['c', 'd']]] 1128 1129 Action of `S_4` (on a very nonstandard domain) on tuples of sets:: 1130 1131 sage: S4 = PermutationGroup([ [((11,(12,13)),'d')], [((12,(12,11)),(11,(12,13)))], [((12,(12,11)),'b')] ]) 1132 sage: S4.orbit((( (11,(12,13)), (12,(12,11))),('b','d')),"OnTuplesSets") 1133 [[[(11, (12, 13)), (12, (12, 11))], ['b', 'd']], 1134 [['d', (12, (12, 11))], ['b', (11, (12, 13))]], 1135 [['b', (11, (12, 13))], ['d', (12, (12, 11))]], 1136 [['d', (11, (12, 13))], ['b', (12, (12, 11))]], 1137 [['b', 'd'], [(11, (12, 13)), (12, (12, 11))]], 1138 [['b', (12, (12, 11))], ['d', (11, (12, 13))]]] 1139 1140 """ 1141 def input_to_gap(x, depth, sort): 1142 if depth: 1143 ans = [input_to_gap(xx,depth-1,sort) for xx in x] 1144 if depth == 1 and sort: 1145 ans.sort() 1146 return ans 1147 else: 1148 return self._domain_to_gap[x] 1149 1150 def gap_to_output(x, depth): 1151 if depth: 1152 return [gap_to_output(xx,depth-1) for xx in x] 1153 else: 1154 return self._domain_from_gap[x] 1155 1156 sort = False 1157 1158 actions = { 1159 "OnPoints" : {"depth" : 0, "sort" : False}, 1160 "OnSets" : {"depth" : 1, "sort" : True}, 1161 "OnPairs" : {"depth" : 1, "sort" : False}, 1162 "OnTuples" : {"depth" : 1, "sort" : False}, 1163 "OnTuples" : {"depth" : 1, "sort" : False}, 1164 "OnSetsSets" : {"depth" : 2, "sort" : True}, 1165 "OnSetsDisjointSets" : {"depth" : 2, "sort" : True}, 1166 "OnTuplesSets" : {"depth" : 2, "sort" : True}, 1167 "OnTuplesTuples" : {"depth" : 2, "sort" : False}, 1168 "OnTuplesTuples" : {"depth" : 2, "sort" : False} 1169 } 1170 try: 1171 params = actions[action] 1172 except KeyError: 1173 raise ValueError("This action is not implemented (yet?).") 1174 1175 try: 1176 point = input_to_gap(point, **params) 1177 except KeyError: 1178 raise ValueError("One element does not seem to be part of the domain.") 1179 1180 ans = self._gap_().Orbit(point, action).sage() 1181 1182 return gap_to_output(ans, params['depth']+1) 1183 1090 1184 def transversals(self, point): 1091 1185 """ 1092 If G is a permutation group acting on the set `X = \{1, 2, ...., n\}` 1093 and H is the stabilizer subgroup of <integer>, a right 1094 (respectively left) transversal is a set containing exactly 1095 one element from each right (respectively left) coset of H. This 1096 method returns a right transversal of ``self`` by the stabilizer 1186 If G is a permutation group acting on the set `X = \{1, 2, ...., n\}` 1187 and H is the stabilizer subgroup of <integer>, a right 1188 (respectively left) transversal is a set containing exactly 1189 one element from each right (respectively left) coset of H. This 1190 method returns a right transversal of ``self`` by the stabilizer 1097 1191 of ``self`` on <integer> position. 1098 1192 1099 1193 EXAMPLES:: 1100 1194 1101 sage: G = PermutationGroup([ [(3,4)], [(1,3)] ]) 1195 sage: G = PermutationGroup([ [(3,4)], [(1,3)] ]) 1102 1196 sage: G.transversals(1) 1103 1197 [(), (1,3,4), (1,4,3)] 1104 1198 sage: G = PermutationGroup([[(1,2),(3,4)], [(1,2,3,4,10)]]) 1105 sage: G.transversals(1) 1199 sage: G.transversals(1) 1106 1200 [(), (1,2)(3,4), (1,3,2,10,4), (1,4,2,10,3), (1,10,4,3,2)] 1107 1201 1108 1202 sage: G = PermutationGroup([ [('c','d')], [('a','c')] ]) 1109 1203 sage: G.transversals('a') 1110 [(), ('a','c','d'), ('a','d','c')] 1204 [(), ('a','c','d'), ('a','d','c')] 1111 1205 """ 1112 1206 G = self._gap_() 1113 1207 return [self(G.RepresentativeAction(self._domain_to_gap[point], self._domain_to_gap[i])) … … 1128 1221 sage: G = PermutationGroup([[(1,2),(3,4)], [(1,2,3,4,10)]]) 1129 1222 sage: G.stabilizer(10) 1130 1223 Subgroup of (Permutation Group with generators [(1,2)(3,4), (1,2,3,4,10)]) generated by [(2,3,4), (1,2)(3,4)] 1131 sage: G.stabilizer(1) 1224 sage: G.stabilizer(1) 1132 1225 Subgroup of (Permutation Group with generators [(1,2)(3,4), (1,2,3,4,10)]) generated by [(2,3)(4,10), (2,10,4)] 1133 1226 sage: G = PermutationGroup([[(2,3,4)],[(6,7)]]) 1134 1227 sage: G.stabilizer(1)