# Groups of isometries#

Let $$M = \ZZ^n$$ or $$\QQ^n$$, $$b: M \times M \rightarrow \QQ$$ a bilinear form and $$f: M \rightarrow M$$ a linear map. We say that $$f$$ is an isometry if for all elements $$x,y$$ of $$M$$ we have that $$b(x,y)=b(f(x),f(y))$$. A group of isometries is a subgroup of $$GL(M)$$ consisting of isometries.

EXAMPLES:

sage: L = IntegralLattice("D4")                                                     # needs sage.graphs
sage: O = L.orthogonal_group(); O                                                   # needs sage.graphs
Group of isometries with 3 generators (
[0 0 0 1]  [ 1  1  0  0]  [ 1  0  0  0]
[0 1 0 0]  [ 0  0  1  0]  [-1 -1 -1 -1]
[0 0 1 0]  [ 0  1  0  1]  [ 0  0  1  0]
[1 0 0 0], [ 0 -1 -1  0], [ 0  0  0  1]
)

>>> from sage.all import *
>>> L = IntegralLattice("D4")                                                     # needs sage.graphs
>>> O = L.orthogonal_group(); O                                                   # needs sage.graphs
Group of isometries with 3 generators (
[0 0 0 1]  [ 1  1  0  0]  [ 1  0  0  0]
[0 1 0 0]  [ 0  0  1  0]  [-1 -1 -1 -1]
[0 0 1 0]  [ 0  1  0  1]  [ 0  0  1  0]
[1 0 0 0], [ 0 -1 -1  0], [ 0  0  0  1]
)


Basic functionality is provided by GAP:

sage: O.cardinality()                                                               # needs sage.graphs
1152
sage: len(O.conjugacy_classes_representatives())                                    # needs sage.graphs
25

>>> from sage.all import *
>>> O.cardinality()                                                               # needs sage.graphs
1152
>>> len(O.conjugacy_classes_representatives())                                    # needs sage.graphs
25


AUTHORS:

• Simon Brandhorst (2018-02): First created

class sage.groups.matrix_gps.isometries.GroupActionOnQuotientModule(MatrixGroup, quotient_module, is_left=False)[source]#

Bases: Action

Matrix group action on a quotient module from the right.

INPUT:

• MatrixGroup – the group acting GroupOfIsometries

• submodule – an invariant quotient module

• is_left – boolean (default: False)

EXAMPLES:

sage: from sage.groups.matrix_gps.isometries import GroupOfIsometries
sage: S = span(ZZ,[[0,1]])
sage: Q = S/(6*S)
sage: g = Matrix(QQ,2,[1,0,0,-1])
sage: G = GroupOfIsometries(2, ZZ, [g], invariant_bilinear_form=matrix.identity(2), invariant_quotient_module=Q)
sage: g = G.an_element()
sage: x = Q.an_element()
sage: x*g
(5)
sage: (x*g).parent()
Finitely generated module V/W over Integer Ring with invariants (6)

>>> from sage.all import *
>>> from sage.groups.matrix_gps.isometries import GroupOfIsometries
>>> S = span(ZZ,[[Integer(0),Integer(1)]])
>>> Q = S/(Integer(6)*S)
>>> g = Matrix(QQ,Integer(2),[Integer(1),Integer(0),Integer(0),-Integer(1)])
>>> G = GroupOfIsometries(Integer(2), ZZ, [g], invariant_bilinear_form=matrix.identity(Integer(2)), invariant_quotient_module=Q)
>>> g = G.an_element()
>>> x = Q.an_element()
>>> x*g
(5)
>>> (x*g).parent()
Finitely generated module V/W over Integer Ring with invariants (6)

class sage.groups.matrix_gps.isometries.GroupActionOnSubmodule(MatrixGroup, submodule, is_left=False)[source]#

Bases: Action

Matrix group action on a submodule from the right.

INPUT:

• MatrixGroup – an instance of GroupOfIsometries

• submodule – an invariant submodule

• is_left – bool (default: False)

EXAMPLES:

sage: from sage.groups.matrix_gps.isometries import GroupOfIsometries
sage: S = span(ZZ, [[0,1]])
sage: g = Matrix(QQ, 2, [1,0,0,-1])
sage: G = GroupOfIsometries(2, ZZ, [g],
....:                       invariant_bilinear_form=matrix.identity(2),
....:                       invariant_submodule=S)
sage: g = G.an_element()
sage: x = S.an_element()
sage: x*g
(0, -1)
sage: (x*g).parent()
Free module of degree 2 and rank 1 over Integer Ring
Echelon basis matrix:
[0 1]

>>> from sage.all import *
>>> from sage.groups.matrix_gps.isometries import GroupOfIsometries
>>> S = span(ZZ, [[Integer(0),Integer(1)]])
>>> g = Matrix(QQ, Integer(2), [Integer(1),Integer(0),Integer(0),-Integer(1)])
>>> G = GroupOfIsometries(Integer(2), ZZ, [g],
...                       invariant_bilinear_form=matrix.identity(Integer(2)),
...                       invariant_submodule=S)
>>> g = G.an_element()
>>> x = S.an_element()
>>> x*g
(0, -1)
>>> (x*g).parent()
Free module of degree 2 and rank 1 over Integer Ring
Echelon basis matrix:
[0 1]

class sage.groups.matrix_gps.isometries.GroupOfIsometries(degree, base_ring, gens, invariant_bilinear_form, category=None, check=True, invariant_submodule=None, invariant_quotient_module=None)[source]#

A base class for Orthogonal matrix groups with a gap backend.

Main difference to OrthogonalMatrixGroup_gap is that we can specify generators and a bilinear form. Following GAP, the group action is from the right.

INPUT:

• degree – integer, the degree (matrix size) of the matrix

• base_ring – ring, the base ring of the matrices

• gens – a list of matrices over the base ring

• invariant_bilinear_form – a symmetric matrix

• category – (default: None) a category of groups

• check – bool (default: True) check if the generators preserve the bilinear form

• invariant_submodule – a submodule preserved by the group action (default: None) registers an action on this submodule

• invariant_quotient_module – a quotient module preserved by the group action (default: None) registers an action on this quotient module

EXAMPLES:

sage: from sage.groups.matrix_gps.isometries import GroupOfIsometries
sage: bil = Matrix(ZZ, 2, [3,2,2,3])
sage: gens = [-Matrix(ZZ, 2, [0,1,1,0])]
sage: O = GroupOfIsometries(2, ZZ, gens, bil)
sage: O
Group of isometries with 1 generator (
[ 0 -1]
[-1  0]
)
sage: O.order()
2

>>> from sage.all import *
>>> from sage.groups.matrix_gps.isometries import GroupOfIsometries
>>> bil = Matrix(ZZ, Integer(2), [Integer(3),Integer(2),Integer(2),Integer(3)])
>>> gens = [-Matrix(ZZ, Integer(2), [Integer(0),Integer(1),Integer(1),Integer(0)])]
>>> O = GroupOfIsometries(Integer(2), ZZ, gens, bil)
>>> O
Group of isometries with 1 generator (
[ 0 -1]
[-1  0]
)
>>> O.order()
2


Infinite groups are O.K. too:

sage: bil = Matrix(ZZ,4,[0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0])
sage: f = Matrix(ZZ,4,[0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, -1, 1, 1, 1])
sage: O = GroupOfIsometries(2, ZZ, [f], bil)
sage: O.cardinality()
+Infinity

>>> from sage.all import *
>>> bil = Matrix(ZZ,Integer(4),[Integer(0), Integer(1), Integer(1), Integer(1), Integer(1), Integer(0), Integer(1), Integer(1), Integer(1), Integer(1), Integer(0), Integer(1), Integer(1), Integer(1), Integer(1), Integer(0)])
>>> f = Matrix(ZZ,Integer(4),[Integer(0), Integer(1), Integer(0), Integer(0), Integer(0), Integer(0), Integer(1), Integer(0), Integer(0), Integer(0), Integer(0), Integer(1), -Integer(1), Integer(1), Integer(1), Integer(1)])
>>> O = GroupOfIsometries(Integer(2), ZZ, [f], bil)
>>> O.cardinality()
+Infinity

invariant_bilinear_form()[source]#

Return the symmetric bilinear form preserved by the orthogonal group.

OUTPUT: the matrix defining the bilinear form

EXAMPLES:

sage: from sage.groups.matrix_gps.isometries import GroupOfIsometries
sage: bil = Matrix(ZZ,2,[3,2,2,3])
sage: gens = [-Matrix(ZZ,2,[0,1,1,0])]
sage: O = GroupOfIsometries(2,ZZ,gens,bil)
sage: O.invariant_bilinear_form()
[3 2]
[2 3]

>>> from sage.all import *
>>> from sage.groups.matrix_gps.isometries import GroupOfIsometries
>>> bil = Matrix(ZZ,Integer(2),[Integer(3),Integer(2),Integer(2),Integer(3)])
>>> gens = [-Matrix(ZZ,Integer(2),[Integer(0),Integer(1),Integer(1),Integer(0)])]
>>> O = GroupOfIsometries(Integer(2),ZZ,gens,bil)
>>> O.invariant_bilinear_form()
[3 2]
[2 3]