General linear group of a free module#
The set \(\mathrm{GL}(M)\) of automorphisms (i.e. invertible endomorphisms) of a free module of finite rank \(M\) is a group under composition of automorphisms, named the general linear group of \(M\). In other words, \(\mathrm{GL}(M)\) is the group of units (i.e. invertible elements) of \(\mathrm{End}(M)\), the endomorphism ring of \(M\).
The group \(\mathrm{GL}(M)\) is implemented via the class
FreeModuleLinearGroup
.
AUTHORS:
Eric Gourgoulhon (2015): initial version
Michael Jung (2019): improve treatment of the identity element
REFERENCES:
Chap. 15 of R. Godement : Algebra [God1968]
- class sage.tensor.modules.free_module_linear_group.FreeModuleLinearGroup(fmodule)[source]#
Bases:
UniqueRepresentation
,Parent
General linear group of a free module of finite rank over a commutative ring.
Given a free module of finite rank \(M\) over a commutative ring \(R\), the general linear group of \(M\) is the group \(\mathrm{GL}(M)\) of automorphisms (i.e. invertible endomorphisms) of \(M\). It is the group of units (i.e. invertible elements) of \(\mathrm{End}(M)\), the endomorphism ring of \(M\).
This is a Sage parent class, whose element class is
FreeModuleAutomorphism
.INPUT:
fmodule
– free module \(M\) of finite rank over a commutative ring \(R\), as an instance ofFiniteRankFreeModule
EXAMPLES:
General linear group of a free \(\ZZ\)-module of rank 3:
sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: e = M.basis('e') sage: from sage.tensor.modules.free_module_linear_group import FreeModuleLinearGroup sage: GL = FreeModuleLinearGroup(M) ; GL General linear group of the Rank-3 free module M over the Integer Ring
>>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M') >>> e = M.basis('e') >>> from sage.tensor.modules.free_module_linear_group import FreeModuleLinearGroup >>> GL = FreeModuleLinearGroup(M) ; GL General linear group of the Rank-3 free module M over the Integer Ring
Instead of importing FreeModuleLinearGroup in the global name space, it is recommended to use the module’s method
general_linear_group()
:sage: GL = M.general_linear_group() ; GL General linear group of the Rank-3 free module M over the Integer Ring sage: latex(GL) \mathrm{GL}\left( M \right)
>>> from sage.all import * >>> GL = M.general_linear_group() ; GL General linear group of the Rank-3 free module M over the Integer Ring >>> latex(GL) \mathrm{GL}\left( M \right)
As most parents, the general linear group has a unique instance:
sage: GL is M.general_linear_group() True
>>> from sage.all import * >>> GL is M.general_linear_group() True
\(\mathrm{GL}(M)\) is in the category of groups:
sage: GL.category() Category of groups sage: GL in Groups() True
>>> from sage.all import * >>> GL.category() Category of groups >>> GL in Groups() True
GL
is a parent object, whose elements are automorphisms of \(M\), represented by instances of the classFreeModuleAutomorphism
:sage: GL.Element <class 'sage.tensor.modules.free_module_automorphism.FreeModuleAutomorphism'> sage: a = GL.an_element() ; a Automorphism of the Rank-3 free module M over the Integer Ring sage: a.matrix(e) [ 1 0 0] [ 0 -1 0] [ 0 0 1] sage: a in GL True sage: GL.is_parent_of(a) True
>>> from sage.all import * >>> GL.Element <class 'sage.tensor.modules.free_module_automorphism.FreeModuleAutomorphism'> >>> a = GL.an_element() ; a Automorphism of the Rank-3 free module M over the Integer Ring >>> a.matrix(e) [ 1 0 0] [ 0 -1 0] [ 0 0 1] >>> a in GL True >>> GL.is_parent_of(a) True
As an endomorphism,
a
maps elements of \(M\) to elements of \(M\):sage: v = M.an_element() ; v Element of the Rank-3 free module M over the Integer Ring sage: v.display() e_0 + e_1 + e_2 sage: a(v) Element of the Rank-3 free module M over the Integer Ring sage: a(v).display() e_0 - e_1 + e_2
>>> from sage.all import * >>> v = M.an_element() ; v Element of the Rank-3 free module M over the Integer Ring >>> v.display() e_0 + e_1 + e_2 >>> a(v) Element of the Rank-3 free module M over the Integer Ring >>> a(v).display() e_0 - e_1 + e_2
An automorphism can also be viewed as a tensor of type \((1,1)\) on \(M\):
sage: a.tensor_type() (1, 1) sage: a.display(e) e_0⊗e^0 - e_1⊗e^1 + e_2⊗e^2 sage: type(a) <class 'sage.tensor.modules.free_module_linear_group.FreeModuleLinearGroup_with_category.element_class'>
>>> from sage.all import * >>> a.tensor_type() (1, 1) >>> a.display(e) e_0⊗e^0 - e_1⊗e^1 + e_2⊗e^2 >>> type(a) <class 'sage.tensor.modules.free_module_linear_group.FreeModuleLinearGroup_with_category.element_class'>
As for any group, the identity element is obtained by the method
one()
:sage: id = GL.one() ; id Identity map of the Rank-3 free module M over the Integer Ring sage: id*a == a True sage: a*id == a True sage: a*a^(-1) == id True sage: a^(-1)*a == id True
>>> from sage.all import * >>> id = GL.one() ; id Identity map of the Rank-3 free module M over the Integer Ring >>> id*a == a True >>> a*id == a True >>> a*a**(-Integer(1)) == id True >>> a**(-Integer(1))*a == id True
The identity element is of course the identity map of the module \(M\):
sage: id(v) == v True sage: id.matrix(e) [1 0 0] [0 1 0] [0 0 1]
>>> from sage.all import * >>> id(v) == v True >>> id.matrix(e) [1 0 0] [0 1 0] [0 0 1]
The module’s changes of basis are stored as elements of the general linear group:
sage: f = M.basis('f', from_family=(-e[1], 4*e[0]+3*e[2], 7*e[0]+5*e[2])) sage: f Basis (f_0,f_1,f_2) on the Rank-3 free module M over the Integer Ring sage: M.change_of_basis(e,f) Automorphism of the Rank-3 free module M over the Integer Ring sage: M.change_of_basis(e,f) in GL True sage: M.change_of_basis(e,f).parent() General linear group of the Rank-3 free module M over the Integer Ring sage: M.change_of_basis(e,f).matrix(e) [ 0 4 7] [-1 0 0] [ 0 3 5] sage: M.change_of_basis(e,f) == M.change_of_basis(f,e).inverse() True
>>> from sage.all import * >>> f = M.basis('f', from_family=(-e[Integer(1)], Integer(4)*e[Integer(0)]+Integer(3)*e[Integer(2)], Integer(7)*e[Integer(0)]+Integer(5)*e[Integer(2)])) >>> f Basis (f_0,f_1,f_2) on the Rank-3 free module M over the Integer Ring >>> M.change_of_basis(e,f) Automorphism of the Rank-3 free module M over the Integer Ring >>> M.change_of_basis(e,f) in GL True >>> M.change_of_basis(e,f).parent() General linear group of the Rank-3 free module M over the Integer Ring >>> M.change_of_basis(e,f).matrix(e) [ 0 4 7] [-1 0 0] [ 0 3 5] >>> M.change_of_basis(e,f) == M.change_of_basis(f,e).inverse() True
Since every automorphism is an endomorphism, there is a coercion \(\mathrm{GL}(M) \rightarrow \mathrm{End}(M)\) (the endomorphism ring of module \(M\)):
sage: End(M).has_coerce_map_from(GL) True
>>> from sage.all import * >>> End(M).has_coerce_map_from(GL) True
(see
FreeModuleHomset
for details), but not in the reverse direction, since only bijective endomorphisms are automorphisms:sage: GL.has_coerce_map_from(End(M)) False
>>> from sage.all import * >>> GL.has_coerce_map_from(End(M)) False
A bijective endomorphism can be converted to an element of \(\mathrm{GL}(M)\):
sage: h = M.endomorphism([[1,0,0], [0,-1,2], [0,1,-3]]) ; h Generic endomorphism of Rank-3 free module M over the Integer Ring sage: h.parent() is End(M) True sage: ah = GL(h) ; ah Automorphism of the Rank-3 free module M over the Integer Ring sage: ah.parent() is GL True
>>> from sage.all import * >>> h = M.endomorphism([[Integer(1),Integer(0),Integer(0)], [Integer(0),-Integer(1),Integer(2)], [Integer(0),Integer(1),-Integer(3)]]) ; h Generic endomorphism of Rank-3 free module M over the Integer Ring >>> h.parent() is End(M) True >>> ah = GL(h) ; ah Automorphism of the Rank-3 free module M over the Integer Ring >>> ah.parent() is GL True
As maps \(M\rightarrow M\),
ah
andh
are identical:sage: v # recall Element of the Rank-3 free module M over the Integer Ring sage: ah(v) == h(v) True sage: ah.matrix(e) == h.matrix(e) True
>>> from sage.all import * >>> v # recall Element of the Rank-3 free module M over the Integer Ring >>> ah(v) == h(v) True >>> ah.matrix(e) == h.matrix(e) True
Of course, non-invertible endomorphisms cannot be converted to elements of \(\mathrm{GL}(M)\):
sage: GL(M.endomorphism([[0,0,0], [0,-1,2], [0,1,-3]])) Traceback (most recent call last): ... TypeError: the Generic endomorphism of Rank-3 free module M over the Integer Ring is not invertible
>>> from sage.all import * >>> GL(M.endomorphism([[Integer(0),Integer(0),Integer(0)], [Integer(0),-Integer(1),Integer(2)], [Integer(0),Integer(1),-Integer(3)]])) Traceback (most recent call last): ... TypeError: the Generic endomorphism of Rank-3 free module M over the Integer Ring is not invertible
Similarly, there is a coercion \(\mathrm{GL}(M)\rightarrow T^{(1,1)}(M)\) (module of type-\((1,1)\) tensors):
sage: M.tensor_module(1,1).has_coerce_map_from(GL) True
>>> from sage.all import * >>> M.tensor_module(Integer(1),Integer(1)).has_coerce_map_from(GL) True
(see
TensorFreeModule
for details), but not in the reverse direction, since not every type-\((1,1)\) tensor can be considered as an automorphism:sage: GL.has_coerce_map_from(M.tensor_module(1,1)) False
>>> from sage.all import * >>> GL.has_coerce_map_from(M.tensor_module(Integer(1),Integer(1))) False
Invertible type-\((1,1)\) tensors can be converted to automorphisms:
sage: t = M.tensor((1,1), name='t') sage: t[e,:] = [[-1,0,0], [0,1,2], [0,1,3]] sage: at = GL(t) ; at Automorphism t of the Rank-3 free module M over the Integer Ring sage: at.matrix(e) [-1 0 0] [ 0 1 2] [ 0 1 3] sage: at.matrix(e) == t[e,:] True
>>> from sage.all import * >>> t = M.tensor((Integer(1),Integer(1)), name='t') >>> t[e,:] = [[-Integer(1),Integer(0),Integer(0)], [Integer(0),Integer(1),Integer(2)], [Integer(0),Integer(1),Integer(3)]] >>> at = GL(t) ; at Automorphism t of the Rank-3 free module M over the Integer Ring >>> at.matrix(e) [-1 0 0] [ 0 1 2] [ 0 1 3] >>> at.matrix(e) == t[e,:] True
Non-invertible ones cannot:
sage: t0 = M.tensor((1,1), name='t_0') sage: t0[e,0,0] = 1 sage: t0[e,:] # the matrix is clearly not invertible [1 0 0] [0 0 0] [0 0 0] sage: GL(t0) Traceback (most recent call last): ... TypeError: the Type-(1,1) tensor t_0 on the Rank-3 free module M over the Integer Ring is not invertible sage: t0[e,1,1], t0[e,2,2] = 2, 3 sage: t0[e,:] # the matrix is not invertible in Mat_3(ZZ) [1 0 0] [0 2 0] [0 0 3] sage: GL(t0) Traceback (most recent call last): ... TypeError: the Type-(1,1) tensor t_0 on the Rank-3 free module M over the Integer Ring is not invertible
>>> from sage.all import * >>> t0 = M.tensor((Integer(1),Integer(1)), name='t_0') >>> t0[e,Integer(0),Integer(0)] = Integer(1) >>> t0[e,:] # the matrix is clearly not invertible [1 0 0] [0 0 0] [0 0 0] >>> GL(t0) Traceback (most recent call last): ... TypeError: the Type-(1,1) tensor t_0 on the Rank-3 free module M over the Integer Ring is not invertible >>> t0[e,Integer(1),Integer(1)], t0[e,Integer(2),Integer(2)] = Integer(2), Integer(3) >>> t0[e,:] # the matrix is not invertible in Mat_3(ZZ) [1 0 0] [0 2 0] [0 0 3] >>> GL(t0) Traceback (most recent call last): ... TypeError: the Type-(1,1) tensor t_0 on the Rank-3 free module M over the Integer Ring is not invertible
- Element[source]#
alias of
FreeModuleAutomorphism
- base_module()[source]#
Return the free module of which
self
is the general linear group.OUTPUT:
instance of
FiniteRankFreeModule
representing the free module of whichself
is the general linear group
EXAMPLES:
sage: M = FiniteRankFreeModule(ZZ, 2, name='M') sage: GL = M.general_linear_group() sage: GL.base_module() Rank-2 free module M over the Integer Ring sage: GL.base_module() is M True
>>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(2), name='M') >>> GL = M.general_linear_group() >>> GL.base_module() Rank-2 free module M over the Integer Ring >>> GL.base_module() is M True
- one()[source]#
Return the group identity element of
self
.The group identity element is nothing but the module identity map.
OUTPUT:
instance of
FreeModuleAutomorphism
representing the identity element.
EXAMPLES:
Identity element of the general linear group of a rank-2 free module:
sage: M = FiniteRankFreeModule(ZZ, 2, name='M', start_index=1) sage: GL = M.general_linear_group() sage: GL.one() Identity map of the Rank-2 free module M over the Integer Ring
>>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(2), name='M', start_index=Integer(1)) >>> GL = M.general_linear_group() >>> GL.one() Identity map of the Rank-2 free module M over the Integer Ring
The identity element is cached:
sage: GL.one() is GL.one() True
>>> from sage.all import * >>> GL.one() is GL.one() True
Check that the element returned is indeed the neutral element for the group law:
sage: e = M.basis('e') sage: a = GL([[3,4],[5,7]], basis=e) ; a Automorphism of the Rank-2 free module M over the Integer Ring sage: a.matrix(e) [3 4] [5 7] sage: GL.one() * a == a True sage: a * GL.one() == a True sage: a * a^(-1) == GL.one() True sage: a^(-1) * a == GL.one() True
>>> from sage.all import * >>> e = M.basis('e') >>> a = GL([[Integer(3),Integer(4)],[Integer(5),Integer(7)]], basis=e) ; a Automorphism of the Rank-2 free module M over the Integer Ring >>> a.matrix(e) [3 4] [5 7] >>> GL.one() * a == a True >>> a * GL.one() == a True >>> a * a**(-Integer(1)) == GL.one() True >>> a**(-Integer(1)) * a == GL.one() True
The unit element of \(\mathrm{GL}(M)\) is the identity map of \(M\):
sage: GL.one()(e[1]) Element e_1 of the Rank-2 free module M over the Integer Ring sage: GL.one()(e[2]) Element e_2 of the Rank-2 free module M over the Integer Ring
>>> from sage.all import * >>> GL.one()(e[Integer(1)]) Element e_1 of the Rank-2 free module M over the Integer Ring >>> GL.one()(e[Integer(2)]) Element e_2 of the Rank-2 free module M over the Integer Ring
Its matrix is the identity matrix in any basis:
sage: GL.one().matrix(e) [1 0] [0 1] sage: f = M.basis('f', from_family=(e[1]+2*e[2], e[1]+3*e[2])) sage: GL.one().matrix(f) [1 0] [0 1]
>>> from sage.all import * >>> GL.one().matrix(e) [1 0] [0 1] >>> f = M.basis('f', from_family=(e[Integer(1)]+Integer(2)*e[Integer(2)], e[Integer(1)]+Integer(3)*e[Integer(2)])) >>> GL.one().matrix(f) [1 0] [0 1]