Free module automorphisms¶
Given a free module \(M\) of finite rank over a commutative ring \(R\), an automorphism of \(M\) is a map
that is linear (i.e. is a module homomorphism) and bijective.
Automorphisms of a free module of finite rank are implemented via the class
FreeModuleAutomorphism.
AUTHORS:
- Eric Gourgoulhon (2015): initial version 
- Michael Jung (2019): improve treatment of the identity element 
REFERENCES:
- Chaps. 15, 24 of R. Godement: Algebra [God1968] 
- class sage.tensor.modules.free_module_automorphism.FreeModuleAutomorphism(fmodule, name=None, latex_name=None)[source]¶
- Bases: - FreeModuleTensor,- MultiplicativeGroupElement- Automorphism of a free module of finite rank over a commutative ring. - This is a Sage element class, the corresponding parent class being - FreeModuleLinearGroup.- This class inherits from the classes - FreeModuleTensorand- MultiplicativeGroupElement.- INPUT: - fmodule– free module \(M\) of finite rank over a commutative ring \(R\), as an instance of- FiniteRankFreeModule
- name– (default:- None) name given to the automorphism
- latex_name– (default:- None) LaTeX symbol to denote the automorphism; if none is provided, the LaTeX symbol is set to- name
- is_identity– boolean (default:- False); determines whether the constructed object is the identity automorphism, i.e. the identity map of \(M\) considered as an automorphism (the identity element of the general linear group)
 - EXAMPLES: - Automorphism of a rank-2 free module over \(\ZZ\): - sage: M = FiniteRankFreeModule(ZZ, 2, name='M', start_index=1) sage: a = M.automorphism(name='a', latex_name=r'\alpha') ; a Automorphism a of the Rank-2 free module M over the Integer Ring sage: a.parent() General linear group of the Rank-2 free module M over the Integer Ring sage: a.parent() is M.general_linear_group() True sage: latex(a) \alpha - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(2), name='M', start_index=Integer(1)) >>> a = M.automorphism(name='a', latex_name=r'\alpha') ; a Automorphism a of the Rank-2 free module M over the Integer Ring >>> a.parent() General linear group of the Rank-2 free module M over the Integer Ring >>> a.parent() is M.general_linear_group() True >>> latex(a) \alpha - Setting the components of - aw.r.t. a basis of module- M:- sage: e = M.basis('e') ; e Basis (e_1,e_2) on the Rank-2 free module M over the Integer Ring sage: a[:] = [[1,2],[1,3]] sage: a.matrix(e) [1 2] [1 3] sage: a(e[1]).display() a(e_1) = e_1 + e_2 sage: a(e[2]).display() a(e_2) = 2 e_1 + 3 e_2 - >>> from sage.all import * >>> e = M.basis('e') ; e Basis (e_1,e_2) on the Rank-2 free module M over the Integer Ring >>> a[:] = [[Integer(1),Integer(2)],[Integer(1),Integer(3)]] >>> a.matrix(e) [1 2] [1 3] >>> a(e[Integer(1)]).display() a(e_1) = e_1 + e_2 >>> a(e[Integer(2)]).display() a(e_2) = 2 e_1 + 3 e_2 - Actually, the components w.r.t. a given basis can be specified at the construction of the object: - sage: a = M.automorphism(matrix=[[1,2],[1,3]], basis=e, name='a', ....: latex_name=r'\alpha') ; a Automorphism a of the Rank-2 free module M over the Integer Ring sage: a.matrix(e) [1 2] [1 3] - >>> from sage.all import * >>> a = M.automorphism(matrix=[[Integer(1),Integer(2)],[Integer(1),Integer(3)]], basis=e, name='a', ... latex_name=r'\alpha') ; a Automorphism a of the Rank-2 free module M over the Integer Ring >>> a.matrix(e) [1 2] [1 3] - Since e is the module’s default basis, it can be omitted in the argument list: - sage: a == M.automorphism(matrix=[[1,2],[1,3]], name='a', ....: latex_name=r'\alpha') True - >>> from sage.all import * >>> a == M.automorphism(matrix=[[Integer(1),Integer(2)],[Integer(1),Integer(3)]], name='a', ... latex_name=r'\alpha') True - The matrix of the automorphism can be obtained in any basis: - sage: f = M.basis('f', from_family=(3*e[1]+4*e[2], 5*e[1]+7*e[2])) ; f Basis (f_1,f_2) on the Rank-2 free module M over the Integer Ring sage: a.matrix(f) [2 3] [1 2] - >>> from sage.all import * >>> f = M.basis('f', from_family=(Integer(3)*e[Integer(1)]+Integer(4)*e[Integer(2)], Integer(5)*e[Integer(1)]+Integer(7)*e[Integer(2)])) ; f Basis (f_1,f_2) on the Rank-2 free module M over the Integer Ring >>> a.matrix(f) [2 3] [1 2] - Automorphisms are tensors of type \((1,1)\): - sage: a.tensor_type() (1, 1) sage: a.tensor_rank() 2 - >>> from sage.all import * >>> a.tensor_type() (1, 1) >>> a.tensor_rank() 2 - In particular, they can be displayed as such: - sage: a.display(e) a = e_1⊗e^1 + 2 e_1⊗e^2 + e_2⊗e^1 + 3 e_2⊗e^2 sage: a.display(f) a = 2 f_1⊗f^1 + 3 f_1⊗f^2 + f_2⊗f^1 + 2 f_2⊗f^2 - >>> from sage.all import * >>> a.display(e) a = e_1⊗e^1 + 2 e_1⊗e^2 + e_2⊗e^1 + 3 e_2⊗e^2 >>> a.display(f) a = 2 f_1⊗f^1 + 3 f_1⊗f^2 + f_2⊗f^1 + 2 f_2⊗f^2 - The automorphism acting on a module element: - sage: v = M([-2,3], name='v') ; v Element v of the Rank-2 free module M over the Integer Ring sage: a(v) Element a(v) of the Rank-2 free module M over the Integer Ring sage: a(v).display() a(v) = 4 e_1 + 7 e_2 - >>> from sage.all import * >>> v = M([-Integer(2),Integer(3)], name='v') ; v Element v of the Rank-2 free module M over the Integer Ring >>> a(v) Element a(v) of the Rank-2 free module M over the Integer Ring >>> a(v).display() a(v) = 4 e_1 + 7 e_2 - A second automorphism of the module - M:- sage: b = M.automorphism([[0,1],[-1,0]], name='b') ; b Automorphism b of the Rank-2 free module M over the Integer Ring sage: b.matrix(e) [ 0 1] [-1 0] sage: b(e[1]).display() b(e_1) = -e_2 sage: b(e[2]).display() b(e_2) = e_1 - >>> from sage.all import * >>> b = M.automorphism([[Integer(0),Integer(1)],[-Integer(1),Integer(0)]], name='b') ; b Automorphism b of the Rank-2 free module M over the Integer Ring >>> b.matrix(e) [ 0 1] [-1 0] >>> b(e[Integer(1)]).display() b(e_1) = -e_2 >>> b(e[Integer(2)]).display() b(e_2) = e_1 - The composition of automorphisms is performed via the multiplication operator: - sage: s = a*b ; s Automorphism of the Rank-2 free module M over the Integer Ring sage: s(v) == a(b(v)) True sage: s.matrix(f) [ 11 19] [ -7 -12] sage: s.matrix(f) == a.matrix(f) * b.matrix(f) True - >>> from sage.all import * >>> s = a*b ; s Automorphism of the Rank-2 free module M over the Integer Ring >>> s(v) == a(b(v)) True >>> s.matrix(f) [ 11 19] [ -7 -12] >>> s.matrix(f) == a.matrix(f) * b.matrix(f) True - It is not commutative: - sage: a*b != b*a True - >>> from sage.all import * >>> a*b != b*a True - In other words, the parent of - aand- b, i.e. the group \(\mathrm{GL}(M)\), is not abelian:- sage: M.general_linear_group() in CommutativeAdditiveGroups() False - >>> from sage.all import * >>> M.general_linear_group() in CommutativeAdditiveGroups() False - The neutral element for the composition law is the module identity map: - sage: id = M.identity_map() ; id Identity map of the Rank-2 free module M over the Integer Ring sage: id.parent() General linear group of the Rank-2 free module M over the Integer Ring sage: id(v) == v True sage: id.matrix(f) [1 0] [0 1] sage: id*a == a True sage: a*id == a True - >>> from sage.all import * >>> id = M.identity_map() ; id Identity map of the Rank-2 free module M over the Integer Ring >>> id.parent() General linear group of the Rank-2 free module M over the Integer Ring >>> id(v) == v True >>> id.matrix(f) [1 0] [0 1] >>> id*a == a True >>> a*id == a True - The inverse of an automorphism is obtained via the method - inverse(), or the operator ~, or the exponent -1:- sage: a.inverse() Automorphism a^(-1) of the Rank-2 free module M over the Integer Ring sage: a.inverse() is ~a True sage: a.inverse() is a^(-1) True sage: (a^(-1)).matrix(e) [ 3 -2] [-1 1] sage: a*a^(-1) == id True sage: a^(-1)*a == id True sage: a^(-1)*s == b True sage: (a^(-1))(a(v)) == v True - >>> from sage.all import * >>> a.inverse() Automorphism a^(-1) of the Rank-2 free module M over the Integer Ring >>> a.inverse() is ~a True >>> a.inverse() is a**(-Integer(1)) True >>> (a**(-Integer(1))).matrix(e) [ 3 -2] [-1 1] >>> a*a**(-Integer(1)) == id True >>> a**(-Integer(1))*a == id True >>> a**(-Integer(1))*s == b True >>> (a**(-Integer(1)))(a(v)) == v True - The module’s changes of basis are stored as automorphisms: - sage: M.change_of_basis(e,f) Automorphism of the Rank-2 free module M over the Integer Ring sage: M.change_of_basis(e,f).parent() General linear group of the Rank-2 free module M over the Integer Ring sage: M.change_of_basis(e,f).matrix(e) [3 5] [4 7] sage: M.change_of_basis(f,e) == M.change_of_basis(e,f).inverse() True - >>> from sage.all import * >>> M.change_of_basis(e,f) Automorphism of the Rank-2 free module M over the Integer Ring >>> M.change_of_basis(e,f).parent() General linear group of the Rank-2 free module M over the Integer Ring >>> M.change_of_basis(e,f).matrix(e) [3 5] [4 7] >>> M.change_of_basis(f,e) == M.change_of_basis(e,f).inverse() True - The opposite of an automorphism is still an automorphism: - sage: -a Automorphism -a of the Rank-2 free module M over the Integer Ring sage: (-a).parent() General linear group of the Rank-2 free module M over the Integer Ring sage: (-a).matrix(e) == - (a.matrix(e)) True - >>> from sage.all import * >>> -a Automorphism -a of the Rank-2 free module M over the Integer Ring >>> (-a).parent() General linear group of the Rank-2 free module M over the Integer Ring >>> (-a).matrix(e) == - (a.matrix(e)) True - Adding two automorphisms results in a generic type-\((1,1)\) tensor: - sage: s = a + b ; s Type-(1,1) tensor a+b on the Rank-2 free module M over the Integer Ring sage: s.parent() Free module of type-(1,1) tensors on the Rank-2 free module M over the Integer Ring sage: a[:], b[:], s[:] ( [1 2] [ 0 1] [1 3] [1 3], [-1 0], [0 3] ) - >>> from sage.all import * >>> s = a + b ; s Type-(1,1) tensor a+b on the Rank-2 free module M over the Integer Ring >>> s.parent() Free module of type-(1,1) tensors on the Rank-2 free module M over the Integer Ring >>> a[:], b[:], s[:] ( [1 2] [ 0 1] [1 3] [1 3], [-1 0], [0 3] ) - To get the result as an endomorphism, one has to explicitly convert it via the parent of endomorphisms, \(\mathrm{End}(M)\): - sage: s = End(M)(a+b) ; s Generic endomorphism of Rank-2 free module M over the Integer Ring sage: s(v) == a(v) + b(v) True sage: s.matrix(e) == a.matrix(e) + b.matrix(e) True sage: s.matrix(f) == a.matrix(f) + b.matrix(f) True - >>> from sage.all import * >>> s = End(M)(a+b) ; s Generic endomorphism of Rank-2 free module M over the Integer Ring >>> s(v) == a(v) + b(v) True >>> s.matrix(e) == a.matrix(e) + b.matrix(e) True >>> s.matrix(f) == a.matrix(f) + b.matrix(f) True - add_comp(basis=None)[source]¶
- Return the components of - selfw.r.t. a given module basis for assignment, keeping the components w.r.t. other bases.- To delete the components w.r.t. other bases, use the method - set_comp()instead.- INPUT: - basis– (default:- None) basis in which the components are defined; if none is provided, the components are assumed to refer to the module’s default basis
 - Warning - If the automorphism has already components in other bases, it is the user’s responsibility to make sure that the components to be added are consistent with them. - OUTPUT: - components in the given basis, as an instance of the class - Components; if such components did not exist previously, they are created
 - EXAMPLES: - Adding components to an automorphism of a rank-3 free \(\ZZ\)-module: - sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: e = M.basis('e') sage: a = M.automorphism(name='a') sage: a[e,:] = [[1,0,0],[0,-1,2],[0,1,-3]] sage: f = M.basis('f', from_family=(-e[0], 3*e[1]+4*e[2], ....: 5*e[1]+7*e[2])) ; f Basis (f_0,f_1,f_2) on the Rank-3 free module M over the Integer Ring sage: a.add_comp(f)[:] = [[1,0,0], [0, 80, 143], [0, -47, -84]] - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M') >>> e = M.basis('e') >>> a = M.automorphism(name='a') >>> a[e,:] = [[Integer(1),Integer(0),Integer(0)],[Integer(0),-Integer(1),Integer(2)],[Integer(0),Integer(1),-Integer(3)]] >>> f = M.basis('f', from_family=(-e[Integer(0)], Integer(3)*e[Integer(1)]+Integer(4)*e[Integer(2)], ... Integer(5)*e[Integer(1)]+Integer(7)*e[Integer(2)])) ; f Basis (f_0,f_1,f_2) on the Rank-3 free module M over the Integer Ring >>> a.add_comp(f)[:] = [[Integer(1),Integer(0),Integer(0)], [Integer(0), Integer(80), Integer(143)], [Integer(0), -Integer(47), -Integer(84)]] - The components in basis - ehave been kept:- sage: a._components # random (dictionary output) {Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring: 2-indices components w.r.t. Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring, Basis (f_0,f_1,f_2) on the Rank-3 free module M over the Integer Ring: 2-indices components w.r.t. Basis (f_0,f_1,f_2) on the Rank-3 free module M over the Integer Ring} - >>> from sage.all import * >>> a._components # random (dictionary output) {Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring: 2-indices components w.r.t. Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring, Basis (f_0,f_1,f_2) on the Rank-3 free module M over the Integer Ring: 2-indices components w.r.t. Basis (f_0,f_1,f_2) on the Rank-3 free module M over the Integer Ring} - For the identity map, it is not permitted to invoke - add_comp():- sage: id = M.identity_map() sage: id.add_comp(e) Traceback (most recent call last): ... ValueError: the components of the identity map cannot be changed - >>> from sage.all import * >>> id = M.identity_map() >>> id.add_comp(e) Traceback (most recent call last): ... ValueError: the components of the identity map cannot be changed - Indeed, the components are set automatically: - sage: id.comp(e) Kronecker delta of size 3x3 sage: id.comp(f) Kronecker delta of size 3x3 - >>> from sage.all import * >>> id.comp(e) Kronecker delta of size 3x3 >>> id.comp(f) Kronecker delta of size 3x3 
 - characteristic_polynomial()[source]¶
- Return the characteristic polynomial of - self.- characteristic_polynomial()and- charpoly()are the same method.- INPUT: - var– string (default:- 'x'); a variable name
 - EXAMPLES: - sage: M = FiniteRankFreeModule(QQ, 2, name='M') sage: e = M.basis('e') sage: a = M.automorphism([[1,1],[0,2]], name='a') sage: a.matrix(e) [1 1] [0 2] sage: a.characteristic_polynomial() x^2 - 3*x + 2 sage: a.charpoly() x^2 - 3*x + 2 sage: a.charpoly('T') T^2 - 3*T + 2 - >>> from sage.all import * >>> M = FiniteRankFreeModule(QQ, Integer(2), name='M') >>> e = M.basis('e') >>> a = M.automorphism([[Integer(1),Integer(1)],[Integer(0),Integer(2)]], name='a') >>> a.matrix(e) [1 1] [0 2] >>> a.characteristic_polynomial() x^2 - 3*x + 2 >>> a.charpoly() x^2 - 3*x + 2 >>> a.charpoly('T') T^2 - 3*T + 2 
 - charpoly()[source]¶
- Return the characteristic polynomial of - self.- characteristic_polynomial()and- charpoly()are the same method.- INPUT: - var– string (default:- 'x'); a variable name
 - EXAMPLES: - sage: M = FiniteRankFreeModule(QQ, 2, name='M') sage: e = M.basis('e') sage: a = M.automorphism([[1,1],[0,2]], name='a') sage: a.matrix(e) [1 1] [0 2] sage: a.characteristic_polynomial() x^2 - 3*x + 2 sage: a.charpoly() x^2 - 3*x + 2 sage: a.charpoly('T') T^2 - 3*T + 2 - >>> from sage.all import * >>> M = FiniteRankFreeModule(QQ, Integer(2), name='M') >>> e = M.basis('e') >>> a = M.automorphism([[Integer(1),Integer(1)],[Integer(0),Integer(2)]], name='a') >>> a.matrix(e) [1 1] [0 2] >>> a.characteristic_polynomial() x^2 - 3*x + 2 >>> a.charpoly() x^2 - 3*x + 2 >>> a.charpoly('T') T^2 - 3*T + 2 
 - det()[source]¶
- Return the determinant of - self.- OUTPUT: - element of the base ring of the module on which - selfis defined, equal to the determinant of- self.
 - EXAMPLES: - Determinant of an automorphism on a \(\ZZ\)-module of rank 2: - sage: M = FiniteRankFreeModule(ZZ, 2, name='M') sage: e = M.basis('e') sage: a = M.automorphism([[4,7],[3,5]], name='a') sage: a.matrix(e) [4 7] [3 5] sage: a.det() -1 sage: det(a) -1 sage: ~a.det() # determinant of the inverse automorphism -1 sage: id = M.identity_map() sage: id.det() 1 - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(2), name='M') >>> e = M.basis('e') >>> a = M.automorphism([[Integer(4),Integer(7)],[Integer(3),Integer(5)]], name='a') >>> a.matrix(e) [4 7] [3 5] >>> a.det() -1 >>> det(a) -1 >>> ~a.det() # determinant of the inverse automorphism -1 >>> id = M.identity_map() >>> id.det() 1 
 - determinant()[source]¶
- Return the determinant of - self.- OUTPUT: - element of the base ring of the module on which - selfis defined, equal to the determinant of- self.
 - EXAMPLES: - Determinant of an automorphism on a \(\ZZ\)-module of rank 2: - sage: M = FiniteRankFreeModule(ZZ, 2, name='M') sage: e = M.basis('e') sage: a = M.automorphism([[4,7],[3,5]], name='a') sage: a.matrix(e) [4 7] [3 5] sage: a.det() -1 sage: det(a) -1 sage: ~a.det() # determinant of the inverse automorphism -1 sage: id = M.identity_map() sage: id.det() 1 - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(2), name='M') >>> e = M.basis('e') >>> a = M.automorphism([[Integer(4),Integer(7)],[Integer(3),Integer(5)]], name='a') >>> a.matrix(e) [4 7] [3 5] >>> a.det() -1 >>> det(a) -1 >>> ~a.det() # determinant of the inverse automorphism -1 >>> id = M.identity_map() >>> id.det() 1 
 - fcp()[source]¶
- Return the factorization of the characteristic polynomial of - self.- INPUT: - var– string (default:- 'x'); a variable name
 - EXAMPLES: - sage: M = FiniteRankFreeModule(QQ, 2, name='M') sage: e = M.basis('e') sage: a = M.automorphism([[1,1],[0,2]], name='a') sage: a.matrix(e) [1 1] [0 2] sage: a.fcp() # needs sage.libs.pari (x - 2) * (x - 1) sage: a.fcp('T') # needs sage.libs.pari (T - 2) * (T - 1) - >>> from sage.all import * >>> M = FiniteRankFreeModule(QQ, Integer(2), name='M') >>> e = M.basis('e') >>> a = M.automorphism([[Integer(1),Integer(1)],[Integer(0),Integer(2)]], name='a') >>> a.matrix(e) [1 1] [0 2] >>> a.fcp() # needs sage.libs.pari (x - 2) * (x - 1) >>> a.fcp('T') # needs sage.libs.pari (T - 2) * (T - 1) 
 - inverse()[source]¶
- Return the inverse automorphism. - OUTPUT: - instance of - FreeModuleAutomorphismrepresenting the automorphism that is the inverse of- self.
 - EXAMPLES: - Inverse of an automorphism of a rank-3 free module: - sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: e = M.basis('e') sage: a = M.automorphism(name='a') sage: a[e,:] = [[1,0,0],[0,-1,2],[0,1,-3]] sage: a.inverse() Automorphism a^(-1) of the Rank-3 free module M over the Integer Ring sage: a.inverse().parent() 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') >>> a = M.automorphism(name='a') >>> a[e,:] = [[Integer(1),Integer(0),Integer(0)],[Integer(0),-Integer(1),Integer(2)],[Integer(0),Integer(1),-Integer(3)]] >>> a.inverse() Automorphism a^(-1) of the Rank-3 free module M over the Integer Ring >>> a.inverse().parent() General linear group of the Rank-3 free module M over the Integer Ring - Check that - a.inverse()is indeed the inverse automorphism:- sage: a.inverse() * a Identity map of the Rank-3 free module M over the Integer Ring sage: a * a.inverse() Identity map of the Rank-3 free module M over the Integer Ring sage: a.inverse().inverse() == a True - >>> from sage.all import * >>> a.inverse() * a Identity map of the Rank-3 free module M over the Integer Ring >>> a * a.inverse() Identity map of the Rank-3 free module M over the Integer Ring >>> a.inverse().inverse() == a True - Another check is: - sage: a.inverse().matrix(e) [ 1 0 0] [ 0 -3 -2] [ 0 -1 -1] sage: a.inverse().matrix(e) == (a.matrix(e))^(-1) True - >>> from sage.all import * >>> a.inverse().matrix(e) [ 1 0 0] [ 0 -3 -2] [ 0 -1 -1] >>> a.inverse().matrix(e) == (a.matrix(e))**(-Integer(1)) True - The inverse is cached (as long as - ais not modified):- sage: a.inverse() is a.inverse() True - >>> from sage.all import * >>> a.inverse() is a.inverse() True - If - ais modified, the inverse is automatically recomputed:- sage: a[0,0] = -1 sage: a.matrix(e) [-1 0 0] [ 0 -1 2] [ 0 1 -3] sage: a.inverse().matrix(e) # compare with above [-1 0 0] [ 0 -3 -2] [ 0 -1 -1] - >>> from sage.all import * >>> a[Integer(0),Integer(0)] = -Integer(1) >>> a.matrix(e) [-1 0 0] [ 0 -1 2] [ 0 1 -3] >>> a.inverse().matrix(e) # compare with above [-1 0 0] [ 0 -3 -2] [ 0 -1 -1] - Shortcuts for - inverse()are the operator- ~and the exponent- -1:- sage: ~a is a.inverse() True sage: (a)^(-1) is a.inverse() True - >>> from sage.all import * >>> ~a is a.inverse() True >>> (a)**(-Integer(1)) is a.inverse() True - The inverse of the identity map is of course itself: - sage: id = M.identity_map() sage: id.inverse() is id True - >>> from sage.all import * >>> id = M.identity_map() >>> id.inverse() is id True - and we have: - sage: a*(a)^(-1) == id True sage: (a)^(-1)*a == id True - >>> from sage.all import * >>> a*(a)**(-Integer(1)) == id True >>> (a)**(-Integer(1))*a == id True - If the name could cause some confusion, a bracket is added around the element before taking the inverse: - sage: c = M.automorphism(name='a^(-1)*b') sage: c[e,:] = [[1,0,0],[0,-1,1],[0,2,-1]] sage: c.inverse() Automorphism (a^(-1)*b)^(-1) of the Rank-3 free module M over the Integer Ring - >>> from sage.all import * >>> c = M.automorphism(name='a^(-1)*b') >>> c[e,:] = [[Integer(1),Integer(0),Integer(0)],[Integer(0),-Integer(1),Integer(1)],[Integer(0),Integer(2),-Integer(1)]] >>> c.inverse() Automorphism (a^(-1)*b)^(-1) of the Rank-3 free module M over the Integer Ring 
 - matrix(basis1=None, basis2=None)[source]¶
- Return the matrix of - selfw.r.t to a pair of bases.- If the matrix is not known already, it is computed from the matrix in another pair of bases by means of the change-of-basis formula. - INPUT: - basis1– (default:- None) basis of the free module on which- selfis defined; if none is provided, the module’s default basis is assumed
- basis2– (default:- None) basis of the free module on which- selfis defined; if none is provided,- basis2is set to- basis1
 - OUTPUT: - the matrix representing the automorphism - selfw.r.t to bases- basis1and- basis2; more precisely, the columns of this matrix are formed by the components w.r.t.- basis2of the images of the elements of- basis1.
 - EXAMPLES: - Matrices of an automorphism of a rank-3 free \(\ZZ\)-module: - sage: M = FiniteRankFreeModule(ZZ, 3, name='M', start_index=1) sage: e = M.basis('e') sage: a = M.automorphism([[-1,0,0],[0,1,2],[0,1,3]], name='a') sage: a.matrix(e) [-1 0 0] [ 0 1 2] [ 0 1 3] sage: a.matrix() [-1 0 0] [ 0 1 2] [ 0 1 3] sage: f = M.basis('f', from_family=(-e[2], 4*e[1]+3*e[3], 7*e[1]+5*e[3])) ; f Basis (f_1,f_2,f_3) on the Rank-3 free module M over the Integer Ring sage: a.matrix(f) [ 1 -6 -10] [ -7 83 140] [ 4 -48 -81] - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M', start_index=Integer(1)) >>> e = M.basis('e') >>> a = M.automorphism([[-Integer(1),Integer(0),Integer(0)],[Integer(0),Integer(1),Integer(2)],[Integer(0),Integer(1),Integer(3)]], name='a') >>> a.matrix(e) [-1 0 0] [ 0 1 2] [ 0 1 3] >>> a.matrix() [-1 0 0] [ 0 1 2] [ 0 1 3] >>> f = M.basis('f', from_family=(-e[Integer(2)], Integer(4)*e[Integer(1)]+Integer(3)*e[Integer(3)], Integer(7)*e[Integer(1)]+Integer(5)*e[Integer(3)])) ; f Basis (f_1,f_2,f_3) on the Rank-3 free module M over the Integer Ring >>> a.matrix(f) [ 1 -6 -10] [ -7 83 140] [ 4 -48 -81] - Check of the above matrix: - sage: a(f[1]).display(f) a(f_1) = f_1 - 7 f_2 + 4 f_3 sage: a(f[2]).display(f) a(f_2) = -6 f_1 + 83 f_2 - 48 f_3 sage: a(f[3]).display(f) a(f_3) = -10 f_1 + 140 f_2 - 81 f_3 - >>> from sage.all import * >>> a(f[Integer(1)]).display(f) a(f_1) = f_1 - 7 f_2 + 4 f_3 >>> a(f[Integer(2)]).display(f) a(f_2) = -6 f_1 + 83 f_2 - 48 f_3 >>> a(f[Integer(3)]).display(f) a(f_3) = -10 f_1 + 140 f_2 - 81 f_3 - Check of the change-of-basis formula: - sage: P = M.change_of_basis(e,f).matrix(e) sage: a.matrix(f) == P^(-1) * a.matrix(e) * P True - >>> from sage.all import * >>> P = M.change_of_basis(e,f).matrix(e) >>> a.matrix(f) == P**(-Integer(1)) * a.matrix(e) * P True - Check that the matrix of the product of two automorphisms is the product of their matrices: - sage: b = M.change_of_basis(e,f) ; b Automorphism of the Rank-3 free module M over the Integer Ring sage: b.matrix(e) [ 0 4 7] [-1 0 0] [ 0 3 5] sage: (a*b).matrix(e) == a.matrix(e) * b.matrix(e) True - >>> from sage.all import * >>> b = M.change_of_basis(e,f) ; b Automorphism of the Rank-3 free module M over the Integer Ring >>> b.matrix(e) [ 0 4 7] [-1 0 0] [ 0 3 5] >>> (a*b).matrix(e) == a.matrix(e) * b.matrix(e) True - Check that the matrix of the inverse automorphism is the inverse of the automorphism’s matrix: - sage: (~a).matrix(e) [-1 0 0] [ 0 3 -2] [ 0 -1 1] sage: (~a).matrix(e) == ~(a.matrix(e)) True - >>> from sage.all import * >>> (~a).matrix(e) [-1 0 0] [ 0 3 -2] [ 0 -1 1] >>> (~a).matrix(e) == ~(a.matrix(e)) True - Matrices of the identity map: - sage: id = M.identity_map() sage: id.matrix(e) [1 0 0] [0 1 0] [0 0 1] sage: id.matrix(f) [1 0 0] [0 1 0] [0 0 1] - >>> from sage.all import * >>> id = M.identity_map() >>> id.matrix(e) [1 0 0] [0 1 0] [0 0 1] >>> id.matrix(f) [1 0 0] [0 1 0] [0 0 1] 
 - minimal_polynomial()[source]¶
- Return the minimal polynomial of - self.- minimal_polynomial()and- minpoly()are the same method.- INPUT: - var– string (default:- 'x'); a variable name
 - EXAMPLES: - sage: M = FiniteRankFreeModule(GF(7), 3, name='M') sage: e = M.basis('e') sage: a = M.automorphism([[0,1,2], [-1,0,3], [2,4,1]], name='a') sage: a.minpoly() # needs sage.libs.pari x^3 + 6*x^2 + 6*x + 1 sage: a.minimal_polynomial() # needs sage.libs.pari x^3 + 6*x^2 + 6*x + 1 sage: a.minimal_polynomial('T') # needs sage.libs.pari T^3 + 6*T^2 + 6*T + 1 - >>> from sage.all import * >>> M = FiniteRankFreeModule(GF(Integer(7)), Integer(3), name='M') >>> e = M.basis('e') >>> a = M.automorphism([[Integer(0),Integer(1),Integer(2)], [-Integer(1),Integer(0),Integer(3)], [Integer(2),Integer(4),Integer(1)]], name='a') >>> a.minpoly() # needs sage.libs.pari x^3 + 6*x^2 + 6*x + 1 >>> a.minimal_polynomial() # needs sage.libs.pari x^3 + 6*x^2 + 6*x + 1 >>> a.minimal_polynomial('T') # needs sage.libs.pari T^3 + 6*T^2 + 6*T + 1 
 - minpoly()[source]¶
- Return the minimal polynomial of - self.- minimal_polynomial()and- minpoly()are the same method.- INPUT: - var– string (default:- 'x'); a variable name
 - EXAMPLES: - sage: M = FiniteRankFreeModule(GF(7), 3, name='M') sage: e = M.basis('e') sage: a = M.automorphism([[0,1,2], [-1,0,3], [2,4,1]], name='a') sage: a.minpoly() # needs sage.libs.pari x^3 + 6*x^2 + 6*x + 1 sage: a.minimal_polynomial() # needs sage.libs.pari x^3 + 6*x^2 + 6*x + 1 sage: a.minimal_polynomial('T') # needs sage.libs.pari T^3 + 6*T^2 + 6*T + 1 - >>> from sage.all import * >>> M = FiniteRankFreeModule(GF(Integer(7)), Integer(3), name='M') >>> e = M.basis('e') >>> a = M.automorphism([[Integer(0),Integer(1),Integer(2)], [-Integer(1),Integer(0),Integer(3)], [Integer(2),Integer(4),Integer(1)]], name='a') >>> a.minpoly() # needs sage.libs.pari x^3 + 6*x^2 + 6*x + 1 >>> a.minimal_polynomial() # needs sage.libs.pari x^3 + 6*x^2 + 6*x + 1 >>> a.minimal_polynomial('T') # needs sage.libs.pari T^3 + 6*T^2 + 6*T + 1 
 - set_comp(basis=None)[source]¶
- Return the components of - selfw.r.t. a given module basis for assignment.- The components with respect to other bases are deleted, in order to avoid any inconsistency. To keep them, use the method - add_comp()instead.- INPUT: - basis– (default:- None) basis in which the components are defined; if none is provided, the components are assumed to refer to the module’s default basis
 - OUTPUT: - components in the given basis, as an instance of the class - Components; if such components did not exist previously, they are created.
 - EXAMPLES: - Setting the components of an automorphism of a rank-3 free \(\ZZ\)-module: - sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: e = M.basis('e') sage: a = M.automorphism(name='a') sage: a.set_comp(e) 2-indices components w.r.t. Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring sage: a.set_comp(e)[:] = [[1,0,0],[0,1,2],[0,1,3]] sage: a.matrix(e) [1 0 0] [0 1 2] [0 1 3] - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M') >>> e = M.basis('e') >>> a = M.automorphism(name='a') >>> a.set_comp(e) 2-indices components w.r.t. Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring >>> a.set_comp(e)[:] = [[Integer(1),Integer(0),Integer(0)],[Integer(0),Integer(1),Integer(2)],[Integer(0),Integer(1),Integer(3)]] >>> a.matrix(e) [1 0 0] [0 1 2] [0 1 3] - Since - eis the module’s default basis, one has:- sage: a.set_comp() is a.set_comp(e) True - >>> from sage.all import * >>> a.set_comp() is a.set_comp(e) True - The method - set_comp()can be used to modify a single component:- sage: a.set_comp(e)[0,0] = -1 sage: a.matrix(e) [-1 0 0] [ 0 1 2] [ 0 1 3] - >>> from sage.all import * >>> a.set_comp(e)[Integer(0),Integer(0)] = -Integer(1) >>> a.matrix(e) [-1 0 0] [ 0 1 2] [ 0 1 3] - A short cut to - set_comp()is the bracket operator, with the basis as first argument:- sage: a[e,:] = [[1,0,0],[0,-1,2],[0,1,-3]] sage: a.matrix(e) [ 1 0 0] [ 0 -1 2] [ 0 1 -3] sage: a[e,0,0] = -1 sage: a.matrix(e) [-1 0 0] [ 0 -1 2] [ 0 1 -3] - >>> from sage.all import * >>> a[e,:] = [[Integer(1),Integer(0),Integer(0)],[Integer(0),-Integer(1),Integer(2)],[Integer(0),Integer(1),-Integer(3)]] >>> a.matrix(e) [ 1 0 0] [ 0 -1 2] [ 0 1 -3] >>> a[e,Integer(0),Integer(0)] = -Integer(1) >>> a.matrix(e) [-1 0 0] [ 0 -1 2] [ 0 1 -3] - The call to - set_comp()erases the components previously defined in other bases; to keep them, use the method- add_comp()instead:- sage: f = M.basis('f', from_family=(-e[0], 3*e[1]+4*e[2], ....: 5*e[1]+7*e[2])) ; f Basis (f_0,f_1,f_2) on the Rank-3 free module M over the Integer Ring sage: a._components {Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring: 2-indices components w.r.t. Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring} sage: a.set_comp(f)[:] = [[-1,0,0], [0,1,0], [0,0,-1]] - >>> from sage.all import * >>> f = M.basis('f', from_family=(-e[Integer(0)], Integer(3)*e[Integer(1)]+Integer(4)*e[Integer(2)], ... Integer(5)*e[Integer(1)]+Integer(7)*e[Integer(2)])) ; f Basis (f_0,f_1,f_2) on the Rank-3 free module M over the Integer Ring >>> a._components {Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring: 2-indices components w.r.t. Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring} >>> a.set_comp(f)[:] = [[-Integer(1),Integer(0),Integer(0)], [Integer(0),Integer(1),Integer(0)], [Integer(0),Integer(0),-Integer(1)]] - The components w.r.t. basis - ehave been erased:- sage: a._components {Basis (f_0,f_1,f_2) on the Rank-3 free module M over the Integer Ring: 2-indices components w.r.t. Basis (f_0,f_1,f_2) on the Rank-3 free module M over the Integer Ring} - >>> from sage.all import * >>> a._components {Basis (f_0,f_1,f_2) on the Rank-3 free module M over the Integer Ring: 2-indices components w.r.t. Basis (f_0,f_1,f_2) on the Rank-3 free module M over the Integer Ring} - Of course, they can be computed from those in basis - fby means of a change-of-basis formula, via the method- comp()or- matrix():- sage: a.matrix(e) [ -1 0 0] [ 0 41 -30] [ 0 56 -41] - >>> from sage.all import * >>> a.matrix(e) [ -1 0 0] [ 0 41 -30] [ 0 56 -41] - For the identity map, it is not permitted to set components: - sage: id = M.identity_map() sage: id.set_comp(e) Traceback (most recent call last): ... ValueError: the components of the identity map cannot be changed - >>> from sage.all import * >>> id = M.identity_map() >>> id.set_comp(e) Traceback (most recent call last): ... ValueError: the components of the identity map cannot be changed - Indeed, the components are set automatically: - sage: id.comp(e) Kronecker delta of size 3x3 sage: id.comp(f) Kronecker delta of size 3x3 - >>> from sage.all import * >>> id.comp(e) Kronecker delta of size 3x3 >>> id.comp(f) Kronecker delta of size 3x3 
 - trace()[source]¶
- Return the trace of - self.- OUTPUT: - element of the base ring of the module on which - selfis defined, equal to the trace of- self.
 - EXAMPLES: - Trace of an automorphism on a \(\ZZ\)-module of rank 2: - sage: M = FiniteRankFreeModule(ZZ, 2, name='M') sage: e = M.basis('e') sage: a = M.automorphism([[4,7],[3,5]], name='a') sage: a.matrix(e) [4 7] [3 5] sage: a.trace() 9 sage: id = M.identity_map() sage: id.trace() 2 - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(2), name='M') >>> e = M.basis('e') >>> a = M.automorphism([[Integer(4),Integer(7)],[Integer(3),Integer(5)]], name='a') >>> a.matrix(e) [4 7] [3 5] >>> a.trace() 9 >>> id = M.identity_map() >>> id.trace() 2