Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/groups/group.pyx
4045 views
1
"""
2
Base class for groups
3
"""
4
5
#*****************************************************************************
6
# Copyright (C) 2005 William Stein <[email protected]>
7
#
8
# Distributed under the terms of the GNU General Public License (GPL)
9
#
10
# This code is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
# General Public License for more details.
14
#
15
# The full text of the GPL is available at:
16
#
17
# http://www.gnu.org/licenses/
18
#*****************************************************************************
19
20
doc="""
21
Base class for all groups
22
"""
23
24
import random
25
26
from sage.rings.infinity import infinity
27
import sage.rings.integer_ring
28
29
cdef class Group(sage.structure.parent_gens.ParentWithGens):
30
"""
31
Generic group class
32
"""
33
def __init__(self, category = None):
34
"""
35
36
TESTS::
37
38
sage: from sage.groups.group import Group
39
sage: G = Group()
40
sage: G.category()
41
Category of groups
42
sage: G = Group(category = Groups()) # todo: do the same test with some subcategory of Groups when there will exist one
43
sage: G.category()
44
Category of groups
45
sage: G = Group(category = CommutativeAdditiveGroups())
46
Traceback (most recent call last):
47
...
48
AssertionError: Category of commutative additive groups is not a subcategory of Category of groups
49
50
Check for #8119::
51
52
sage: G = SymmetricGroup(2)
53
sage: h = hash(G)
54
sage: G.rename('S2')
55
sage: h == hash(G)
56
True
57
"""
58
from sage.categories.basic import Groups
59
if category is None:
60
category = Groups()
61
else:
62
assert category.is_subcategory(Groups()), "%s is not a subcategory of %s"%(category, Groups())
63
64
sage.structure.parent_gens.ParentWithGens.__init__(self,
65
sage.rings.integer_ring.ZZ, category = category)
66
67
#def __call__(self, x): # this gets in the way of the coercion mechanism
68
# """
69
# Coerce x into this group.
70
# """
71
# raise NotImplementedError
72
73
def __contains__(self, x):
74
r"""
75
True if coercion of `x` into self is defined.
76
77
EXAMPLES::
78
79
sage: from sage.groups.group import Group
80
sage: G = Group()
81
sage: 4 in G #indirect doctest
82
Traceback (most recent call last):
83
...
84
NotImplementedError
85
"""
86
try:
87
self(x)
88
except TypeError:
89
return False
90
return True
91
92
# def category(self):
93
# """
94
# The category of all groups
95
# """
96
# import sage.categories.all
97
# return sage.categories.all.Groups()
98
99
def is_atomic_repr(self):
100
"""
101
True if the elements of this group have atomic string
102
representations. For example, integers are atomic but polynomials
103
are not.
104
105
EXAMPLES::
106
107
sage: from sage.groups.group import Group
108
sage: G = Group()
109
sage: G.is_atomic_repr()
110
False
111
"""
112
return False
113
114
def is_abelian(self):
115
"""
116
Return True if this group is abelian.
117
118
EXAMPLES::
119
120
sage: from sage.groups.group import Group
121
sage: G = Group()
122
sage: G.is_abelian()
123
Traceback (most recent call last):
124
...
125
NotImplementedError
126
"""
127
raise NotImplementedError
128
129
def is_commutative(self):
130
r"""
131
Return True if this group is commutative. This is an alias for
132
is_abelian, largely to make groups work well with the Factorization
133
class.
134
135
(Note for developers: Derived classes should override is_abelian, not
136
is_commutative.)
137
138
EXAMPLE::
139
140
sage: SL(2, 7).is_commutative()
141
False
142
"""
143
return self.is_abelian()
144
145
def order(self):
146
"""
147
Returns the number of elements of this group, which is either a
148
positive integer or infinity.
149
150
EXAMPLES::
151
152
sage: from sage.groups.group import Group
153
sage: G = Group()
154
sage: G.order()
155
Traceback (most recent call last):
156
...
157
NotImplementedError
158
"""
159
raise NotImplementedError
160
161
def is_finite(self):
162
"""
163
Returns True if this group is finite.
164
165
EXAMPLES::
166
167
sage: from sage.groups.group import Group
168
sage: G = Group()
169
sage: G.is_finite()
170
Traceback (most recent call last):
171
...
172
NotImplementedError
173
"""
174
return self.order() != infinity
175
176
def is_multiplicative(self):
177
"""
178
Returns True if the group operation is given by \* (rather than
179
+).
180
181
Override for additive groups.
182
183
EXAMPLES::
184
185
sage: from sage.groups.group import Group
186
sage: G = Group()
187
sage: G.is_multiplicative()
188
True
189
"""
190
return True
191
192
def random_element(self, bound=None):
193
"""
194
Return a random element of this group.
195
196
EXAMPLES::
197
198
sage: from sage.groups.group import Group
199
sage: G = Group()
200
sage: G.random_element()
201
Traceback (most recent call last):
202
...
203
NotImplementedError
204
"""
205
raise NotImplementedError
206
207
def quotient(self, H):
208
"""
209
Return the quotient of this group by the normal subgroup
210
`H`.
211
212
EXAMPLES::
213
214
sage: from sage.groups.group import Group
215
sage: G = Group()
216
sage: G.quotient(G)
217
Traceback (most recent call last):
218
...
219
NotImplementedError
220
"""
221
raise NotImplementedError
222
223
cdef class AbelianGroup(Group):
224
"""
225
Generic abelian group.
226
"""
227
def is_abelian(self):
228
"""
229
Return True.
230
231
EXAMPLES::
232
233
sage: from sage.groups.group import AbelianGroup
234
sage: G = AbelianGroup()
235
sage: G.is_abelian()
236
True
237
"""
238
return True
239
240
cdef class FiniteGroup(Group):
241
"""
242
Generic finite group.
243
"""
244
def is_finite(self):
245
"""
246
Return True.
247
248
EXAMPLES::
249
250
sage: from sage.groups.group import FiniteGroup
251
sage: G = FiniteGroup()
252
sage: G.is_finite()
253
True
254
"""
255
return True
256
257
def cayley_graph(self, connecting_set=None):
258
"""
259
Returns the cayley graph for this finite group, as a Sage DiGraph
260
object. To plot the graph with with different colors
261
262
INPUT::
263
264
`connecting_set` - (optional) list of elements to use for edges,
265
default is the stored generators
266
267
EXAMPLES::
268
269
sage: D4 = DihedralGroup(4); D4
270
Dihedral group of order 8 as a permutation group
271
sage: G = D4.cayley_graph()
272
sage: show(G, color_by_label=True, edge_labels=True)
273
sage: A5 = AlternatingGroup(5); A5
274
Alternating group of order 5!/2 as a permutation group
275
sage: G = A5.cayley_graph()
276
sage: G.show3d(color_by_label=True, edge_size=0.01, edge_size2=0.02, vertex_size=0.03)
277
sage: G.show3d(vertex_size=0.03, edge_size=0.01, edge_size2=0.02, vertex_colors={(1,1,1):G.vertices()}, bgcolor=(0,0,0), color_by_label=True, xres=700, yres=700, iterations=200) # long time (less than a minute)
278
sage: G.num_edges()
279
120
280
sage: G = A5.cayley_graph(connecting_set=[A5.gens()[0]])
281
sage: G.num_edges()
282
60
283
sage: g=PermutationGroup([(i+1,j+1) for i in range(5) for j in range(5) if j!=i])
284
sage: g.cayley_graph(connecting_set=[(1,2),(2,3)])
285
Digraph on 120 vertices
286
287
::
288
289
sage: s1 = SymmetricGroup(1); s = s1.cayley_graph(); s.vertices()
290
[()]
291
292
AUTHORS:
293
294
- Bobby Moretti (2007-08-10)
295
296
- Robert Miller (2008-05-01): editing
297
"""
298
if connecting_set is None:
299
connecting_set = self.gens()
300
else:
301
try:
302
for g in connecting_set:
303
assert g in self
304
except AssertionError:
305
raise RuntimeError("Each element of the connecting set must be in the group!")
306
connecting_set = [self(g) for g in connecting_set]
307
from sage.graphs.all import DiGraph
308
arrows = {}
309
for x in self:
310
arrows[x] = {}
311
for g in connecting_set:
312
xg = x*g # cache the multiplication
313
if not xg == x:
314
arrows[x][xg] = g
315
316
return DiGraph(arrows, implementation='networkx')
317
318
cdef class AlgebraicGroup(Group):
319
"""
320
Generic algebraic group.
321
"""
322
323