Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/groups/matrix_gps/group_element.py
8815 views
1
"""
2
Matrix Group Elements
3
4
EXAMPLES::
5
6
sage: F = GF(3); MS = MatrixSpace(F,2,2)
7
sage: gens = [MS([[1,0],[0,1]]),MS([[1,1],[0,1]])]
8
sage: G = MatrixGroup(gens); G
9
Matrix group over Finite Field of size 3 with 2 generators (
10
[1 0] [1 1]
11
[0 1], [0 1]
12
)
13
sage: g = G([[1,1],[0,1]])
14
sage: h = G([[1,2],[0,1]])
15
sage: g*h
16
[1 0]
17
[0 1]
18
19
You cannot add two matrices, since this is not a group operation.
20
You can coerce matrices back to the matrix space and add them
21
there::
22
23
sage: g + h
24
Traceback (most recent call last):
25
...
26
TypeError: unsupported operand type(s) for +:
27
'FinitelyGeneratedMatrixGroup_gap_with_category.element_class' and
28
'FinitelyGeneratedMatrixGroup_gap_with_category.element_class'
29
30
sage: g.matrix() + h.matrix()
31
[2 0]
32
[0 2]
33
34
Similarly, you cannot multiply group elements by scalars but you can
35
do it with the underlying matrices::
36
37
sage: 2*g
38
Traceback (most recent call last):
39
...
40
TypeError: unsupported operand parent(s) for '*': 'Integer Ring' and 'Matrix group over Finite Field of size 3 with 2 generators (
41
[1 0] [1 1]
42
[0 1], [0 1]
43
)'
44
45
AUTHORS:
46
47
- David Joyner (2006-05): initial version David Joyner
48
49
- David Joyner (2006-05): various modifications to address William
50
Stein's TODO's.
51
52
- William Stein (2006-12-09): many revisions.
53
54
- Volker Braun (2013-1) port to new Parent, libGAP.
55
"""
56
57
#*****************************************************************************
58
# Copyright (C) 2006 David Joyner and William Stein <[email protected]>
59
# Copyright (C) 2013 Volker Braun <[email protected]>
60
#
61
# Distributed under the terms of the GNU General Public License (GPL)
62
#
63
# http://www.gnu.org/licenses/
64
#*****************************************************************************
65
66
from sage.interfaces.gap import gap
67
from sage.structure.element import MultiplicativeGroupElement
68
from sage.matrix.matrix import Matrix, is_Matrix
69
from sage.structure.factorization import Factorization
70
from sage.structure.sage_object import have_same_parent
71
from sage.libs.gap.element import GapElement, GapElement_List
72
from sage.misc.cachefunc import cached_method
73
from sage.groups.libgap_wrapper import ElementLibGAP
74
from sage.groups.libgap_mixin import GroupElementMixinLibGAP
75
76
77
def is_MatrixGroupElement(x):
78
"""
79
Test whether ``x`` is a matrix group element
80
81
INPUT:
82
83
- ``x`` -- anything.
84
85
OUTPUT:
86
87
Boolean.
88
89
EXAMPLES::
90
91
sage: from sage.groups.matrix_gps.group_element import is_MatrixGroupElement
92
sage: is_MatrixGroupElement('helloooo')
93
False
94
95
sage: G = GL(2,3)
96
sage: is_MatrixGroupElement(G.an_element())
97
True
98
"""
99
return isinstance(x, MatrixGroupElement_base)
100
101
102
103
class MatrixGroupElement_base(MultiplicativeGroupElement):
104
"""
105
Base class for elements of matrix groups.
106
107
You should use one of the two subclasses:
108
109
* :class:`MatrixGroupElement_sage` implements the group
110
mulitplication using Sage matrices.
111
112
* :class:`MatrixGroupElement_gap` implements the group
113
mulitplication using libGAP matrices.
114
115
The base class only assumes that derived classes implement
116
:meth:`matrix`.
117
118
EXAMPLES::
119
120
sage: F = GF(3); MS = MatrixSpace(F,2,2)
121
sage: gens = [MS([[1,0],[0,1]]),MS([[1,1],[0,1]])]
122
sage: G = MatrixGroup(gens)
123
sage: g = G.random_element()
124
sage: type(g)
125
<class 'sage.groups.matrix_gps.group_element.FinitelyGeneratedMatrixGroup_gap_with_category.element_class'>
126
"""
127
128
def _repr_(self):
129
"""
130
Return string representation of this matrix.
131
132
EXAMPLES::
133
134
sage: F = GF(3); MS = MatrixSpace(F,2,2)
135
sage: gens = [MS([[1,0],[0,1]]),MS([[1,1],[0,1]])]
136
sage: G = MatrixGroup(gens)
137
sage: g = G([[1, 1], [0, 1]])
138
sage: g # indirect doctest
139
[1 1]
140
[0 1]
141
sage: g._repr_()
142
'[1 1]\n[0 1]'
143
"""
144
return str(self.matrix())
145
146
def _latex_(self):
147
r"""
148
EXAMPLES::
149
150
sage: F = GF(3); MS = MatrixSpace(F,2,2)
151
sage: gens = [MS([[1,0],[0,1]]),MS([[1,1],[0,1]])]
152
sage: G = MatrixGroup(gens)
153
sage: g = G([[1, 1], [0, 1]])
154
sage: print g._latex_()
155
\left(\begin{array}{rr}
156
1 & 1 \\
157
0 & 1
158
\end{array}\right)
159
160
Type ``view(g._latex_())`` to see the object in an
161
xdvi window (assuming you have latex and xdvi installed).
162
"""
163
return self.matrix()._latex_()
164
165
def _act_on_(self, x, self_on_left):
166
"""
167
EXAMPLES::
168
169
sage: G = GL(4,7)
170
sage: G.0 * vector([1,2,3,4])
171
(3, 2, 3, 4)
172
sage: v = vector(GF(7), [3,2,1,-1])
173
sage: g = G.1
174
sage: v * g == v * g.matrix() # indirect doctest
175
True
176
"""
177
if not is_MatrixGroupElement(x) and x not in self.parent().base_ring():
178
try:
179
if self_on_left:
180
return self.matrix() * x
181
else:
182
return x * self.matrix()
183
except TypeError:
184
return None
185
186
def __cmp__(self, other):
187
"""
188
EXAMPLES::
189
190
sage: F = GF(3); MS = MatrixSpace(F,2)
191
sage: gens = [MS([1,0, 0,1]), MS([1,1, 0,1])]
192
sage: G = MatrixGroup(gens)
193
sage: g = G([1,1, 0,1])
194
sage: h = G([1,1, 0,1])
195
sage: g == h
196
True
197
sage: g == G.one()
198
False
199
"""
200
return cmp(self.matrix(), other.matrix())
201
202
def list(self):
203
"""
204
Return list representation of this matrix.
205
206
EXAMPLES::
207
208
sage: F = GF(3); MS = MatrixSpace(F,2,2)
209
sage: gens = [MS([[1,0],[0,1]]),MS([[1,1],[0,1]])]
210
sage: G = MatrixGroup(gens)
211
sage: g = G.0
212
sage: g
213
[1 0]
214
[0 1]
215
sage: g.list()
216
[[1, 0], [0, 1]]
217
"""
218
return map(list, self.matrix().rows())
219
220
221
###################################################################
222
#
223
# Matrix groups elements implemented with Sage matrices
224
#
225
###################################################################
226
227
class MatrixGroupElement_generic(MatrixGroupElement_base):
228
229
def __init__(self, parent, M, check=True, convert=True):
230
r"""
231
Element of a matrix group over a generic ring.
232
233
The group elements are implemented as Sage matrices.
234
235
INPUT:
236
237
- ``M`` -- a matrix.
238
239
- ``parent`` -- the parent.
240
241
- ``check`` -- bool (default: ``True``). If true does some
242
type checking.
243
244
- ``convert`` -- bool (default: ``True``). If true convert
245
``M`` to the right matrix space.
246
247
TESTS::
248
249
sage: F = GF(3); MS = MatrixSpace(F,2,2)
250
sage: gens = [MS([[1,0],[0,1]]),MS([[1,1],[0,1]])]
251
sage: G = MatrixGroup(gens)
252
sage: g = G.random_element()
253
sage: TestSuite(g).run()
254
"""
255
if convert:
256
M = parent.matrix_space()(M)
257
if check:
258
if not is_Matrix(M):
259
raise TypeError('M must be a matrix')
260
if M.parent() is not parent.matrix_space():
261
raise TypeError('M must be a in the matrix space of the group')
262
parent._check_matrix(M)
263
super(MatrixGroupElement_generic, self).__init__(parent)
264
if M.is_immutable():
265
self._matrix = M
266
else:
267
self._matrix = M.__copy__()
268
self._matrix.set_immutable()
269
270
def matrix(self):
271
"""
272
Obtain the usual matrix (as an element of a matrix space)
273
associated to this matrix group element.
274
275
One reason to compute the associated matrix is that matrices
276
support a huge range of functionality.
277
278
EXAMPLES::
279
280
sage: k = GF(7); G = MatrixGroup([matrix(k,2,[1,1,0,1]), matrix(k,2,[1,0,0,2])])
281
sage: g = G.0
282
sage: g.matrix()
283
[1 1]
284
[0 1]
285
sage: parent(g.matrix())
286
Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 7
287
288
Matrices have extra functionality that matrix group elements
289
do not have::
290
291
sage: g.matrix().charpoly('t')
292
t^2 + 5*t + 1
293
"""
294
return self._matrix
295
296
def _mul_(self,other):
297
"""
298
Return the product of self and other, which must have identical
299
parents.
300
301
EXAMPLES::
302
303
sage: F = GF(3); MS = MatrixSpace(F,2)
304
sage: gens = [MS([1,0, 0,1]), MS([1,1, 0,1])]
305
sage: G = MatrixGroup(gens)
306
sage: g = G([1,1, 0,1])
307
sage: h = G([1,1, 0,1])
308
sage: g*h # indirect doctest
309
[1 2]
310
[0 1]
311
"""
312
parent = self.parent()
313
return parent.element_class(parent, self._matrix * other._matrix,
314
check=False, convert=False)
315
316
def __invert__(self):
317
"""
318
Return the inverse group element
319
320
OUTPUT:
321
322
A matrix group element.
323
324
EXAMPLES::
325
326
sage: G = GL(2,3)
327
sage: g = G([1,2,1,0]); g
328
[1 2]
329
[1 0]
330
sage: g.__invert__()
331
[0 1]
332
[2 1]
333
sage: g * (~g)
334
[1 0]
335
[0 1]
336
"""
337
parent = self.parent()
338
return parent.element_class(parent, ~self._matrix, check=False, convert=False)
339
340
inverse = __invert__
341
342
def conjugacy_class(self):
343
r"""
344
Return the conjugacy class of ``self``.
345
346
OUTPUT:
347
348
The conjugacy class of ``g`` in the group ``self``. If ``self`` is the
349
group denoted by `G`, this method computes the set
350
`\{x^{-1}gx\ \vert\ x\in G\}`.
351
352
EXAMPLES::
353
354
sage: G = SL(2, GF(2))
355
sage: g = G.gens()[0]
356
sage: g.conjugacy_class()
357
Conjugacy class of [1 1]
358
[0 1] in Special Linear Group of degree 2 over Finite Field of size 2
359
"""
360
from sage.groups.conjugacy_classes import ConjugacyClass
361
return ConjugacyClass(self.parent(), self)
362
363
364
###################################################################
365
#
366
# Matrix group elements implemented in GAP
367
#
368
###################################################################
369
370
class MatrixGroupElement_gap(GroupElementMixinLibGAP, MatrixGroupElement_base, ElementLibGAP):
371
372
def __init__(self, parent, M, check=True, convert=True):
373
r"""
374
Element of a matrix group over a generic ring.
375
376
The group elements are implemented as Sage matrices.
377
378
INPUT:
379
380
- ``M`` -- a matrix.
381
382
- ``parent`` -- the parent.
383
384
- ``check`` -- bool (default: ``True``). If true does some
385
type checking.
386
387
- ``convert`` -- bool (default: ``True``). If true convert
388
``M`` to the right matrix space.
389
390
TESTS::
391
392
sage: MS = MatrixSpace(GF(3),2,2)
393
sage: G = MatrixGroup(MS([[1,0],[0,1]]), MS([[1,1],[0,1]]))
394
sage: G.gen(0)
395
[1 0]
396
[0 1]
397
sage: g = G.random_element()
398
sage: TestSuite(g).run()
399
"""
400
if isinstance(M, GapElement):
401
ElementLibGAP.__init__(self, parent, M)
402
return
403
if convert:
404
M = parent.matrix_space()(M)
405
from sage.libs.gap.libgap import libgap
406
M_gap = libgap(M)
407
if check:
408
if not is_Matrix(M):
409
raise TypeError('M must be a matrix')
410
if M.parent() is not parent.matrix_space():
411
raise TypeError('M must be a in the matrix space of the group')
412
parent._check_matrix(M, M_gap)
413
ElementLibGAP.__init__(self, parent, M_gap)
414
415
def __reduce__(self):
416
"""
417
Implement pickling.
418
419
TESTS::
420
421
sage: MS = MatrixSpace(GF(3), 2, 2)
422
sage: G = MatrixGroup(MS([[1,0],[0,1]]), MS([[1,1],[0,1]]))
423
sage: loads(G.gen(0).dumps())
424
[1 0]
425
[0 1]
426
"""
427
return (self.parent(), (self.matrix(),))
428
429
@cached_method
430
def matrix(self):
431
"""
432
Obtain the usual matrix (as an element of a matrix space)
433
associated to this matrix group element.
434
435
EXAMPLES::
436
437
sage: F = GF(3); MS = MatrixSpace(F,2,2)
438
sage: gens = [MS([[1,0],[0,1]]),MS([[1,1],[0,1]])]
439
sage: G = MatrixGroup(gens)
440
sage: G.gen(0).matrix()
441
[1 0]
442
[0 1]
443
sage: _.parent()
444
Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 3
445
"""
446
g = self.gap()
447
m = g.matrix(self.base_ring())
448
m.set_immutable()
449
return m
450
451
def conjugacy_class(self):
452
r"""
453
Return the conjugacy class of ``self``.
454
455
OUTPUT:
456
457
The conjugacy class of ``g`` in the group ``self``. If ``self`` is the
458
group denoted by `G`, this method computes the set
459
`\{x^{-1}gx\ \vert\ x\in G\}`.
460
461
EXAMPLES::
462
463
sage: G = SL(2, QQ)
464
sage: g = G([[1,1],[0,1]])
465
sage: g.conjugacy_class()
466
Conjugacy class of [1 1]
467
[0 1] in Special Linear Group of degree 2 over Rational Field
468
"""
469
from sage.groups.conjugacy_classes import ConjugacyClassGAP
470
return ConjugacyClassGAP(self.parent(), self)
471
472
473
474