Finitely Generated Matrix Groups#
This class is designed for computing with matrix groups defined by a finite set of generating matrices.
EXAMPLES:
sage: F = GF(3)
sage: gens = [matrix(F, 2, [1,0, -1,1]), matrix(F, 2, [1,1,0,1])]
sage: G = MatrixGroup(gens)
sage: G.conjugacy_classes_representatives() # needs sage.libs.gap
(
[1 0] [0 2] [0 1] [2 0] [0 2] [0 1] [0 2]
[0 1], [1 1], [2 1], [0 2], [1 2], [2 2], [1 0]
)
>>> from sage.all import *
>>> F = GF(Integer(3))
>>> gens = [matrix(F, Integer(2), [Integer(1),Integer(0), -Integer(1),Integer(1)]), matrix(F, Integer(2), [Integer(1),Integer(1),Integer(0),Integer(1)])]
>>> G = MatrixGroup(gens)
>>> G.conjugacy_classes_representatives() # needs sage.libs.gap
(
[1 0] [0 2] [0 1] [2 0] [0 2] [0 1] [0 2]
[0 1], [1 1], [2 1], [0 2], [1 2], [2 2], [1 0]
)
The finitely generated matrix groups can also be constructed as subgroups of matrix groups:
sage: SL2Z = SL(2, ZZ)
sage: S, T = SL2Z.gens()
sage: SL2Z.subgroup([T^2])
Subgroup with 1 generators (
[1 2]
[0 1]
) of Special Linear Group of degree 2 over Integer Ring
>>> from sage.all import *
>>> SL2Z = SL(Integer(2), ZZ)
>>> S, T = SL2Z.gens()
>>> SL2Z.subgroup([T**Integer(2)])
Subgroup with 1 generators (
[1 2]
[0 1]
) of Special Linear Group of degree 2 over Integer Ring
AUTHORS:
William Stein: initial version
David Joyner (2006-03-15): degree, base_ring, _contains_, list, random, order methods; examples
William Stein (2006-12): rewrite
David Joyner (2007-12): Added invariant_generators (with Martin Albrecht and Simon King)
David Joyner (2008-08): Added module_composition_factors (interface to GAP’s MeatAxe implementation) and as_permutation_group (returns isomorphic PermutationGroup).
Simon King (2010-05): Improve invariant_generators by using GAP for the construction of the Reynolds operator in Singular.
Volker Braun (2013-1) port to new Parent, libGAP.
Sebastian Oehms (2018-07): Added _permutation_group_element_ (Issue #25706)
Sebastian Oehms (2019-01): Revision of Issue #25706 (Issue #26903 and Issue #27143).
- class sage.groups.matrix_gps.finitely_generated.FinitelyGeneratedMatrixGroup_generic(degree, base_ring, generator_matrices, category=None)[source]#
Bases:
MatrixGroup_generic
- gen(i)[source]#
Return the \(i\)-th generator.
OUTPUT: the \(i\)-th generator of the group
EXAMPLES:
sage: # needs sage.libs.gap sage: H = GL(2, GF(3)) sage: h1, h2 = H([[1,0], [2,1]]), H([[1,1], [0,1]]) sage: G = H.subgroup([h1, h2]) sage: G.gen(0) [1 0] [2 1] sage: G.gen(0).matrix() == h1.matrix() True
>>> from sage.all import * >>> # needs sage.libs.gap >>> H = GL(Integer(2), GF(Integer(3))) >>> h1, h2 = H([[Integer(1),Integer(0)], [Integer(2),Integer(1)]]), H([[Integer(1),Integer(1)], [Integer(0),Integer(1)]]) >>> G = H.subgroup([h1, h2]) >>> G.gen(Integer(0)) [1 0] [2 1] >>> G.gen(Integer(0)).matrix() == h1.matrix() True
- gens()[source]#
Return the generators of the matrix group.
EXAMPLES:
sage: F = GF(3); MS = MatrixSpace(F, 2, 2) sage: gens = [MS([[1,0], [0,1]]), MS([[1,1], [0,1]])] sage: G = MatrixGroup(gens) sage: gens[0] in G True sage: gens = G.gens() sage: gens[0] in G True sage: gens = [MS([[1,0], [0,1]]), MS([[1,1], [0,1]])] sage: F = GF(5); MS = MatrixSpace(F, 2, 2) sage: G = MatrixGroup([MS(1), MS([1,2, 3,4])]) sage: G Matrix group over Finite Field of size 5 with 2 generators ( [1 0] [1 2] [0 1], [3 4] ) sage: G.gens() ( [1 0] [1 2] [0 1], [3 4] )
>>> from sage.all import * >>> F = GF(Integer(3)); MS = MatrixSpace(F, Integer(2), Integer(2)) >>> gens = [MS([[Integer(1),Integer(0)], [Integer(0),Integer(1)]]), MS([[Integer(1),Integer(1)], [Integer(0),Integer(1)]])] >>> G = MatrixGroup(gens) >>> gens[Integer(0)] in G True >>> gens = G.gens() >>> gens[Integer(0)] in G True >>> gens = [MS([[Integer(1),Integer(0)], [Integer(0),Integer(1)]]), MS([[Integer(1),Integer(1)], [Integer(0),Integer(1)]])] >>> F = GF(Integer(5)); MS = MatrixSpace(F, Integer(2), Integer(2)) >>> G = MatrixGroup([MS(Integer(1)), MS([Integer(1),Integer(2), Integer(3),Integer(4)])]) >>> G Matrix group over Finite Field of size 5 with 2 generators ( [1 0] [1 2] [0 1], [3 4] ) >>> G.gens() ( [1 0] [1 2] [0 1], [3 4] )
- ngens()[source]#
Return the number of generators.
OUTPUT: integer; the number of generators
EXAMPLES:
sage: # needs sage.libs.gap sage: H = GL(2, GF(3)) sage: h1, h2 = H([[1,0], [2,1]]), H([[1,1], [0,1]]) sage: G = H.subgroup([h1, h2]) sage: G.ngens() 2
>>> from sage.all import * >>> # needs sage.libs.gap >>> H = GL(Integer(2), GF(Integer(3))) >>> h1, h2 = H([[Integer(1),Integer(0)], [Integer(2),Integer(1)]]), H([[Integer(1),Integer(1)], [Integer(0),Integer(1)]]) >>> G = H.subgroup([h1, h2]) >>> G.ngens() 2
- sage.groups.matrix_gps.finitely_generated.MatrixGroup(*gens, **kwds)[source]#
Return the matrix group with given generators.
INPUT:
*gens
– matrices, or a single list/tuple/iterable of matrices, or a matrix groupcheck
– boolean keyword argument (default:True
); whether to check that each matrix is invertible
EXAMPLES:
sage: F = GF(5) sage: gens = [matrix(F, 2, [1,2, -1,1]), matrix(F,2, [1,1, 0,1])] sage: G = MatrixGroup(gens); G Matrix group over Finite Field of size 5 with 2 generators ( [1 2] [1 1] [4 1], [0 1] )
>>> from sage.all import * >>> F = GF(Integer(5)) >>> gens = [matrix(F, Integer(2), [Integer(1),Integer(2), -Integer(1),Integer(1)]), matrix(F,Integer(2), [Integer(1),Integer(1), Integer(0),Integer(1)])] >>> G = MatrixGroup(gens); G Matrix group over Finite Field of size 5 with 2 generators ( [1 2] [1 1] [4 1], [0 1] )
In the second example, the generators are a matrix over \(\ZZ\), a matrix over a finite field, and the integer \(2\). Sage determines that they both canonically map to matrices over the finite field, so creates that matrix group there:
sage: gens = [matrix(2, [1,2, -1,1]), matrix(GF(7), 2, [1,1, 0,1]), 2] sage: G = MatrixGroup(gens); G Matrix group over Finite Field of size 7 with 3 generators ( [1 2] [1 1] [2 0] [6 1], [0 1], [0 2] )
>>> from sage.all import * >>> gens = [matrix(Integer(2), [Integer(1),Integer(2), -Integer(1),Integer(1)]), matrix(GF(Integer(7)), Integer(2), [Integer(1),Integer(1), Integer(0),Integer(1)]), Integer(2)] >>> G = MatrixGroup(gens); G Matrix group over Finite Field of size 7 with 3 generators ( [1 2] [1 1] [2 0] [6 1], [0 1], [0 2] )
Each generator must be invertible:
sage: G = MatrixGroup([matrix(ZZ, 2, [1,2,3,4])]) Traceback (most recent call last): ... ValueError: each generator must be an invertible matrix sage: F = GF(5); MS = MatrixSpace(F, 2, 2) sage: MatrixGroup([MS.0]) Traceback (most recent call last): ... ValueError: each generator must be an invertible matrix sage: MatrixGroup([MS.0], check=False) # works formally but is mathematical nonsense Matrix group over Finite Field of size 5 with 1 generators ( [1 0] [0 0] )
>>> from sage.all import * >>> G = MatrixGroup([matrix(ZZ, Integer(2), [Integer(1),Integer(2),Integer(3),Integer(4)])]) Traceback (most recent call last): ... ValueError: each generator must be an invertible matrix >>> F = GF(Integer(5)); MS = MatrixSpace(F, Integer(2), Integer(2)) >>> MatrixGroup([MS.gen(0)]) Traceback (most recent call last): ... ValueError: each generator must be an invertible matrix >>> MatrixGroup([MS.gen(0)], check=False) # works formally but is mathematical nonsense Matrix group over Finite Field of size 5 with 1 generators ( [1 0] [0 0] )
Some groups are not supported, or do not have much functionality implemented:
sage: G = SL(0, QQ) Traceback (most recent call last): ... ValueError: the degree must be at least 1 sage: SL2C = SL(2, CC); SL2C Special Linear Group of degree 2 over Complex Field with 53 bits of precision sage: SL2C.gens() Traceback (most recent call last): ... AttributeError: 'LinearMatrixGroup_generic_with_category' object has no attribute 'gens'...
>>> from sage.all import * >>> G = SL(Integer(0), QQ) Traceback (most recent call last): ... ValueError: the degree must be at least 1 >>> SL2C = SL(Integer(2), CC); SL2C Special Linear Group of degree 2 over Complex Field with 53 bits of precision >>> SL2C.gens() Traceback (most recent call last): ... AttributeError: 'LinearMatrixGroup_generic_with_category' object has no attribute 'gens'...
- sage.groups.matrix_gps.finitely_generated.QuaternionMatrixGroupGF3()[source]#
The quaternion group as a set of \(2\times 2\) matrices over \(\GF{3}\).
OUTPUT:
A matrix group consisting of \(2\times 2\) matrices with elements from the finite field of order 3. The group is the quaternion group, the nonabelian group of order 8 that is not isomorphic to the group of symmetries of a square (the dihedral group \(D_4\)).
Note
This group is most easily available via
groups.matrix.QuaternionGF3()
.EXAMPLES:
The generators are the matrix representations of the elements commonly called \(I\) and \(J\), while \(K\) is the product of \(I\) and \(J\).
sage: from sage.groups.matrix_gps.finitely_generated import QuaternionMatrixGroupGF3 sage: # needs sage.libs.gap sage: Q = QuaternionMatrixGroupGF3() sage: Q.order() 8 sage: aye = Q.gens()[0]; aye [1 1] [1 2] sage: jay = Q.gens()[1]; jay [2 1] [1 1] sage: kay = aye*jay; kay [0 2] [1 0]
>>> from sage.all import * >>> from sage.groups.matrix_gps.finitely_generated import QuaternionMatrixGroupGF3 >>> # needs sage.libs.gap >>> Q = QuaternionMatrixGroupGF3() >>> Q.order() 8 >>> aye = Q.gens()[Integer(0)]; aye [1 1] [1 2] >>> jay = Q.gens()[Integer(1)]; jay [2 1] [1 1] >>> kay = aye*jay; kay [0 2] [1 0]
- sage.groups.matrix_gps.finitely_generated.normalize_square_matrices(matrices)[source]#
Find a common space for all matrices.
OUTPUT: a list of matrices, all elements of the same matrix space
EXAMPLES:
sage: from sage.groups.matrix_gps.finitely_generated import normalize_square_matrices sage: m1 = [[1,2], [3,4]] sage: m2 = [2, 3, 4, 5] sage: m3 = matrix(QQ, [[1/2,1/3], [1/4,1/5]]) sage: m4 = MatrixGroup(m3).gen(0) sage: normalize_square_matrices([m1, m2, m3, m4]) [ [1 2] [2 3] [1/2 1/3] [1/2 1/3] [3 4], [4 5], [1/4 1/5], [1/4 1/5] ]
>>> from sage.all import * >>> from sage.groups.matrix_gps.finitely_generated import normalize_square_matrices >>> m1 = [[Integer(1),Integer(2)], [Integer(3),Integer(4)]] >>> m2 = [Integer(2), Integer(3), Integer(4), Integer(5)] >>> m3 = matrix(QQ, [[Integer(1)/Integer(2),Integer(1)/Integer(3)], [Integer(1)/Integer(4),Integer(1)/Integer(5)]]) >>> m4 = MatrixGroup(m3).gen(Integer(0)) >>> normalize_square_matrices([m1, m2, m3, m4]) [ [1 2] [2 3] [1/2 1/3] [1/2 1/3] [3 4], [4 5], [1/4 1/5], [1/4 1/5] ]