Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/groups/matrix_gps/matrix_group_element.py
4056 views
1
"""
2
Matrix Group Elements
3
4
AUTHORS:
5
6
- David Joyner (2006-05): initial version David Joyner
7
8
- David Joyner (2006-05): various modifications to address William
9
Stein's TODO's.
10
11
- William Stein (2006-12-09): many revisions.
12
13
EXAMPLES::
14
15
sage: F = GF(3); MS = MatrixSpace(F,2,2)
16
sage: gens = [MS([[1,0],[0,1]]),MS([[1,1],[0,1]])]
17
sage: G = MatrixGroup(gens); G
18
Matrix group over Finite Field of size 3 with 2 generators:
19
[[[1, 0], [0, 1]], [[1, 1], [0, 1]]]
20
sage: g = G([[1,1],[0,1]])
21
sage: h = G([[1,2],[0,1]])
22
sage: g*h
23
[1 0]
24
[0 1]
25
26
You cannot add two matrices, since this is not a group operation.
27
You can coerce matrices back to the matrix space and add them
28
there::
29
30
sage: g + h
31
Traceback (most recent call last):
32
...
33
TypeError: unsupported operand type(s) for +: 'MatrixGroup_gens_finite_field_with_category.element_class' and 'MatrixGroup_gens_finite_field_with_category.element_class'
34
35
::
36
37
sage: g.matrix() + h.matrix()
38
[2 0]
39
[0 2]
40
41
::
42
43
sage: 2*g
44
Traceback (most recent call last):
45
...
46
TypeError: unsupported operand parent(s) for '*': 'Integer Ring' and 'Matrix group over Finite Field of size 3 with 2 generators:
47
[[[1, 0], [0, 1]], [[1, 1], [0, 1]]]'
48
sage: 2*g.matrix()
49
[2 2]
50
[0 2]
51
"""
52
53
#*****************************************************************************
54
# Copyright (C) 2006 David Joyner and William Stein <[email protected]>
55
#
56
# Distributed under the terms of the GNU General Public License (GPL)
57
#
58
# http://www.gnu.org/licenses/
59
#*****************************************************************************
60
61
from sage.rings.all import Integer, Infinity
62
from sage.interfaces.gap import gap
63
import sage.structure.element as element
64
from sage.matrix.matrix import Matrix
65
from sage.structure.factorization import Factorization
66
from sage.structure.sage_object import have_same_parent
67
68
def is_MatrixGroupElement(x):
69
return isinstance(x, MatrixGroupElement)
70
71
class MatrixGroupElement(element.MultiplicativeGroupElement):
72
"""
73
An element of a matrix group.
74
75
EXAMPLES::
76
77
sage: F = GF(3); MS = MatrixSpace(F,2,2)
78
sage: gens = [MS([[1,0],[0,1]]),MS([[1,1],[0,1]])]
79
sage: G = MatrixGroup(gens)
80
sage: g = G.random_element()
81
sage: type(g)
82
<class 'sage.groups.matrix_gps.matrix_group_element.MatrixGroup_gens_finite_field_with_category.element_class'>
83
"""
84
def __init__(self, g, parent, check = True):
85
r"""
86
Create element of a matrix group.
87
88
INPUT:
89
90
91
- ``g`` - a Matrix
92
93
- ``parent`` - defines parent group (g must be in
94
parent or a TypeError is raised).
95
96
- ``check`` - bool (default: True), if true does some
97
type checking.
98
99
100
TESTS::
101
102
sage: F = GF(3); MS = MatrixSpace(F,2,2)
103
sage: gens = [MS([[1,0],[0,1]]),MS([[1,1],[0,1]])]
104
sage: G = MatrixGroup(gens)
105
sage: g = G.random_element()
106
sage: TestSuite(g).run()
107
"""
108
if check:
109
if not isinstance(g, Matrix):
110
raise TypeError, "g must be a matrix"
111
if not (g.parent() is parent):
112
g = parent.matrix_space()(g)
113
element.Element.__init__(self, parent)
114
self.__mat = g
115
116
def matrix(self):
117
"""
118
Obtain the usual matrix (as an element of a matrix space)
119
associated to this matrix group element.
120
121
One reason to compute the associated matrix is that matrices
122
support a huge range of functionality.
123
124
EXAMPLES::
125
126
sage: k = GF(7); G = MatrixGroup([matrix(k,2,[1,1,0,1]), matrix(k,2,[1,0,0,2])])
127
sage: g = G.0
128
sage: g.matrix()
129
[1 1]
130
[0 1]
131
sage: parent(g.matrix())
132
Full MatrixSpace of 2 by 2 dense matrices over Finite Field of size 7
133
134
Matrices have extra functionality that matrix group elements do not
135
have.
136
137
::
138
139
sage: g.matrix().charpoly('t')
140
t^2 + 5*t + 1
141
"""
142
return self.__mat.__copy__()
143
144
def _gap_init_(self):
145
"""
146
Return a string representation of a Gap object corresponding to
147
this matrix group element.
148
149
EXAMPLES::
150
151
sage: k = GF(7); G = MatrixGroup([matrix(k,2,[1,1,0,1]), matrix(k,2,[1,0,0,2])]); g = G.1
152
sage: g._gap_init_() # The variable $sage27 belongs to gap(k) and is somehow random
153
'[[Z(7)^0,0*Z(7)],[0*Z(7),Z(7)^2]]*One($sage27)'
154
sage: gap(g._gap_init_())
155
[ [ Z(7)^0, 0*Z(7) ], [ 0*Z(7), Z(7)^2 ] ]
156
157
It may be better to use gap(the matrix), since the result is
158
cached.
159
160
::
161
162
sage: gap(G.1)
163
[ [ Z(7)^0, 0*Z(7) ], [ 0*Z(7), Z(7)^2 ] ]
164
sage: gap(G.1).IsMatrix()
165
true
166
"""
167
return self.__mat._gap_init_()
168
169
def _gap_latex_(self):
170
r"""
171
Return the GAP latex version of this matrix.
172
173
AUTHORS:
174
175
- S. Kohl: Wrote the GAP function.
176
177
EXAMPLES::
178
179
sage: F = GF(3); MS = MatrixSpace(F,2,2)
180
sage: gens = [MS([[1,0],[0,1]]),MS([[1,1],[0,1]])]
181
sage: G = MatrixGroup(gens)
182
sage: g = G([[1, 1], [0, 1]])
183
sage: print g._gap_latex_()
184
\left(\begin{array}{rr}%
185
Z(3)^{0}&Z(3)^{0}\\%
186
0*Z(3)&Z(3)^{0}\\%
187
\end{array}\right)%
188
189
Type view(g._latex_()) to see the object in an xdvi window
190
(assuming you have latex and xdvi installed).
191
"""
192
s1 = self.__mat._gap_init_()
193
s2 = gap.eval("LaTeX("+s1+")")
194
return eval(s2)
195
196
def _repr_(self):
197
"""
198
Return string representation of this matrix.
199
200
EXAMPLES::
201
202
sage: F = GF(3); MS = MatrixSpace(F,2,2)
203
sage: gens = [MS([[1,0],[0,1]]),MS([[1,1],[0,1]])]
204
sage: G = MatrixGroup(gens)
205
sage: g = G([[1, 1], [0, 1]])
206
sage: g # indirect doctest
207
[1 1]
208
[0 1]
209
"""
210
return str(self.__mat)
211
212
def _latex_(self):
213
r"""
214
EXAMPLES::
215
216
sage: F = GF(3); MS = MatrixSpace(F,2,2)
217
sage: gens = [MS([[1,0],[0,1]]),MS([[1,1],[0,1]])]
218
sage: G = MatrixGroup(gens)
219
sage: g = G([[1, 1], [0, 1]])
220
sage: print g._latex_()
221
\left(\begin{array}{rr}
222
1 & 1 \\
223
0 & 1
224
\end{array}\right)
225
226
Type ``view(g._latex_())`` to see the object in an
227
xdvi window (assuming you have latex and xdvi installed).
228
"""
229
return self.__mat._latex_()
230
231
def _mul_(self,other):
232
"""
233
Return the product of self and other, which must have identical
234
parents.
235
236
EXAMPLES::
237
238
sage: F = GF(3); MS = MatrixSpace(F,2)
239
sage: gens = [MS([1,0, 0,1]), MS([1,1, 0,1])]
240
sage: G = MatrixGroup(gens)
241
sage: g = G([1,1, 0,1])
242
sage: h = G([1,1, 0,1])
243
sage: g*h # indirect doctest
244
[1 2]
245
[0 1]
246
"""
247
parent = self.parent()
248
return parent.element_class(self.__mat * other.__mat, parent, check=False)
249
250
def _act_on_(self, x, self_on_left):
251
"""
252
EXAMPLES::
253
254
sage: G = GL(4,7)
255
sage: G.0 * vector([1,2,3,4])
256
(3, 2, 3, 4)
257
sage: v = vector(GF(7), [3,2,1,-1])
258
sage: g = G.1
259
sage: v * g == v * g.matrix() # indirect doctest
260
True
261
"""
262
if not is_MatrixGroupElement(x) and x not in self.parent().base_ring():
263
try:
264
if self_on_left:
265
return self.matrix() * x
266
else:
267
return x * self.matrix()
268
except TypeError:
269
return None
270
271
def __invert__(self):
272
parent = self.parent()
273
return parent.element_class(~self.__mat, parent, check=False)
274
275
def __cmp__(self, other):
276
"""
277
EXAMPLES::
278
279
sage: F = GF(3); MS = MatrixSpace(F,2)
280
sage: gens = [MS([1,0, 0,1]), MS([1,1, 0,1])]
281
sage: G = MatrixGroup(gens)
282
sage: g = G([1,1, 0,1])
283
sage: h = G([1,1, 0,1])
284
sage: g == h
285
True
286
"""
287
return cmp(self.__mat, other.__mat)
288
289
def __eq__(self, other):
290
"""
291
EXAMPLES::
292
293
sage: F = GF(3); MS = MatrixSpace(F,2)
294
sage: gens = [MS([1,0, 0,1]), MS([1,1, 0,1])]
295
sage: G = MatrixGroup(gens)
296
sage: H = MatrixGroup(gens)
297
sage: g = G([1,1, 0,1])
298
sage: h = H([1,1, 0,1])
299
sage: g == h
300
True
301
"""
302
return have_same_parent(self, other) and self.__mat == other.__mat
303
304
def __ne__(self, other):
305
"""
306
EXAMPLES::
307
308
sage: F = GF(3); MS = MatrixSpace(F,2)
309
sage: gens = [MS([1,0, 0,1]), MS([1,1, 0,1])]
310
sage: G = MatrixGroup(gens)
311
sage: H = MatrixGroup(gens)
312
sage: g = G([1,1, 0,1])
313
sage: h = H([1,1, 0,1])
314
sage: g != h
315
False
316
"""
317
return not self.__eq__(other)
318
319
def order(self):
320
"""
321
Return the order of this group element, which is the smallest
322
positive integer `n` such that `g^n = 1`, or
323
+Infinity if no such integer exists.
324
325
EXAMPLES::
326
327
sage: k = GF(7); G = MatrixGroup([matrix(k,2,[1,1,0,1]), matrix(k,2,[1,0,0,2])])
328
sage: G
329
Matrix group over Finite Field of size 7 with 2 generators:
330
[[[1, 1], [0, 1]], [[1, 0], [0, 2]]]
331
sage: G.order()
332
21
333
334
See trac #1170
335
336
::
337
338
sage: gl=GL(2,ZZ); gl
339
General Linear Group of degree 2 over Integer Ring
340
sage: g=gl.gens()[2]; g
341
[1 1]
342
[0 1]
343
sage: g.order()
344
+Infinity
345
"""
346
try:
347
return self.__order
348
except AttributeError:
349
try:
350
self.__order = Integer(self._gap_().Order())
351
except TypeError:
352
self.__order = Infinity
353
return self.__order
354
355
def word_problem(self, gens=None):
356
r"""
357
Write this group element in terms of the elements of the list
358
``gens``, or the standard generators of the parent of self if
359
``gens`` is None.
360
361
INPUT:
362
363
- ``gens`` - a list of elements that can be coerced into the parent of
364
self, or None.
365
366
ALGORITHM: Use GAP, which has optimized algorithms for solving the
367
word problem (the GAP functions EpimorphismFromFreeGroup and
368
PreImagesRepresentative).
369
370
EXAMPLE::
371
372
sage: G = GL(2,5); G
373
General Linear Group of degree 2 over Finite Field of size 5
374
sage: G.gens()
375
[
376
[2 0]
377
[0 1],
378
[4 1]
379
[4 0]
380
]
381
sage: G(1).word_problem([G.1, G.0])
382
1
383
384
Next we construct a more complicated element of the group from the
385
generators::
386
387
sage: s,t = G.0, G.1
388
sage: a = (s * t * s); b = a.word_problem(); b
389
([2 0]
390
[0 1]) *
391
([4 1]
392
[4 0]) *
393
([2 0]
394
[0 1])
395
sage: b.prod() == a
396
True
397
398
We solve the word problem using some different generators::
399
400
sage: s = G([2,0,0,1]); t = G([1,1,0,1]); u = G([0,-1,1,0])
401
sage: a.word_problem([s,t,u])
402
([2 0]
403
[0 1])^-1 *
404
([1 1]
405
[0 1])^-1 *
406
([0 4]
407
[1 0]) *
408
([2 0]
409
[0 1])^-1
410
411
We try some elements that don't actually generate the group::
412
413
sage: a.word_problem([t,u])
414
Traceback (most recent call last):
415
...
416
ValueError: Could not solve word problem
417
418
AUTHORS:
419
420
- David Joyner and William Stein
421
- David Loeffler (2010): fixed some bugs
422
"""
423
G = self.parent()
424
gg = gap(G)
425
if not gens:
426
gens = gg.GeneratorsOfGroup()
427
else:
428
gens = gap([G(x) for x in gens])
429
H = gens.Group()
430
hom = H.EpimorphismFromFreeGroup()
431
in_terms_of_gens = str(hom.PreImagesRepresentative(self))
432
if 'identity' in in_terms_of_gens:
433
return Factorization([])
434
elif in_terms_of_gens == 'fail':
435
raise ValueError, "Could not solve word problem"
436
v = list(H.GeneratorsOfGroup())
437
F = G.field_of_definition()
438
w = [G(x._matrix_(F)) for x in v]
439
factors = [Factorization([(x,1)]) for x in w]
440
d = dict([('x%s'%(i+1),factors[i]) for i in range(len(factors))])
441
442
from sage.misc.sage_eval import sage_eval
443
F = sage_eval(str(in_terms_of_gens), d)
444
F._set_cr(True)
445
return F
446
447
def list(self):
448
"""
449
Return list representation of this matrix.
450
451
EXAMPLES::
452
453
sage: F = GF(3); MS = MatrixSpace(F,2,2)
454
sage: gens = [MS([[1,0],[0,1]]),MS([[1,1],[0,1]])]
455
sage: G = MatrixGroup(gens)
456
sage: g = G.0
457
sage: g.list()
458
[[1, 0], [0, 1]]
459
"""
460
rws = (self.__mat).rows()
461
lrws = [list(x) for x in rws]
462
return lrws
463
464
465
466