Free module morphisms¶
The class FiniteRankFreeModuleMorphism implements homomorphisms
between two free modules of finite rank over the same commutative ring.
The subclass FiniteRankFreeModuleEndomorphism implements the
special case of endomorphisms.
AUTHORS:
- Eric Gourgoulhon, Michal Bejger (2014-2015): initial version 
- Matthias Koeppe (2024): add subclass - FiniteRankFreeModuleEndomorphism
REFERENCES:
- class sage.tensor.modules.free_module_morphism.FiniteRankFreeModuleEndomorphism(parent, matrix_rep, bases=None, name=None, latex_name=None, is_identity=False)[source]¶
- Bases: - FiniteRankFreeModuleMorphism- Endomorphism of a free module of finite rank over a commutative ring. - An instance of this class is an endomorphism \[\phi:\ M \longrightarrow M,\]- where \(M\) is a free module of finite rank over a commutative ring \(R\). - This is a Sage element class, the corresponding parent class being - FreeModuleEndset.- INPUT: - parent– Hom-set Hom(M,M) to which the endomorphism belongs
- matrix_rep– matrix representation of the endomorphism with respect to the basis- bases; this entry can actually be any material from which a matrix of size rank(N)*rank(M) of elements of \(R\) can be constructed; the columns of the matrix give the images of the basis of \(M\) (see the convention in the example below)
- bases– (default:- None) pair- (basis_domain, basis_codomain)defining the matrix representation,- basis_domainand- basis_codomainbeing two bases (typically the same) of the same module \(M\); if- None, the default basis of \(M\) is used for both.
- name– (default:- None) string; name given to the endomorphism
- latex_name– (default:- None) string; LaTeX symbol to denote the endomorphism. If- None,- namewill be used.
- is_identity– boolean (default:- False); determines whether the constructed object is the identity endomorphism. If set to- True, then the entry- matrix_repis not used.
 - EXAMPLES: - The identity endomorphism: - sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: e = M.basis('e') sage: Id = End(M).one(); Id Identity endomorphism of Rank-3 free module M over the Integer Ring sage: Id.parent() Set of Morphisms from Rank-3 free module M over the Integer Ring to Rank-3 free module M over the Integer Ring in Category of finite dimensional modules over Integer Ring sage: Id.parent() is End(M) True - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M') >>> e = M.basis('e') >>> Id = End(M).one(); Id Identity endomorphism of Rank-3 free module M over the Integer Ring >>> Id.parent() Set of Morphisms from Rank-3 free module M over the Integer Ring to Rank-3 free module M over the Integer Ring in Category of finite dimensional modules over Integer Ring >>> Id.parent() is End(M) True - The matrix of - Idwith respect to the basis- eis of course the identity matrix:- sage: Id.matrix(e) [1 0 0] [0 1 0] [0 0 1] - >>> from sage.all import * >>> Id.matrix(e) [1 0 0] [0 1 0] [0 0 1] - The identity acting on a module element: - sage: v = M([-2,1,4], basis=e, name='v'); v.display() v = -2 e_0 + e_1 + 4 e_2 sage: Id(v) is v True - >>> from sage.all import * >>> v = M([-Integer(2),Integer(1),Integer(4)], basis=e, name='v'); v.display() v = -2 e_0 + e_1 + 4 e_2 >>> Id(v) is v True - 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(ZZ, 3, name='M') sage: e = M.basis('e') sage: a = M.automorphism(matrix=[[-1,0,0],[0,1,2],[0,1,3]], basis=e) sage: ep = e.new_basis(a, 'ep', latex_symbol="e'") sage: phi = M.endomorphism([[1,2,3], [4,5,6], [7,8,9]], basis=ep) sage: phi.matrix(e) [ 1 -3 1] [-18 39 -18] [-25 54 -25] sage: phi.characteristic_polynomial() x^3 - 15*x^2 - 18*x sage: phi.charpoly() x^3 - 15*x^2 - 18*x sage: phi.charpoly('T') T^3 - 15*T^2 - 18*T - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M') >>> e = M.basis('e') >>> a = M.automorphism(matrix=[[-Integer(1),Integer(0),Integer(0)],[Integer(0),Integer(1),Integer(2)],[Integer(0),Integer(1),Integer(3)]], basis=e) >>> ep = e.new_basis(a, 'ep', latex_symbol="e'") >>> phi = M.endomorphism([[Integer(1),Integer(2),Integer(3)], [Integer(4),Integer(5),Integer(6)], [Integer(7),Integer(8),Integer(9)]], basis=ep) >>> phi.matrix(e) [ 1 -3 1] [-18 39 -18] [-25 54 -25] >>> phi.characteristic_polynomial() x^3 - 15*x^2 - 18*x >>> phi.charpoly() x^3 - 15*x^2 - 18*x >>> phi.charpoly('T') T^3 - 15*T^2 - 18*T 
 - 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(ZZ, 3, name='M') sage: e = M.basis('e') sage: a = M.automorphism(matrix=[[-1,0,0],[0,1,2],[0,1,3]], basis=e) sage: ep = e.new_basis(a, 'ep', latex_symbol="e'") sage: phi = M.endomorphism([[1,2,3], [4,5,6], [7,8,9]], basis=ep) sage: phi.matrix(e) [ 1 -3 1] [-18 39 -18] [-25 54 -25] sage: phi.characteristic_polynomial() x^3 - 15*x^2 - 18*x sage: phi.charpoly() x^3 - 15*x^2 - 18*x sage: phi.charpoly('T') T^3 - 15*T^2 - 18*T - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M') >>> e = M.basis('e') >>> a = M.automorphism(matrix=[[-Integer(1),Integer(0),Integer(0)],[Integer(0),Integer(1),Integer(2)],[Integer(0),Integer(1),Integer(3)]], basis=e) >>> ep = e.new_basis(a, 'ep', latex_symbol="e'") >>> phi = M.endomorphism([[Integer(1),Integer(2),Integer(3)], [Integer(4),Integer(5),Integer(6)], [Integer(7),Integer(8),Integer(9)]], basis=ep) >>> phi.matrix(e) [ 1 -3 1] [-18 39 -18] [-25 54 -25] >>> phi.characteristic_polynomial() x^3 - 15*x^2 - 18*x >>> phi.charpoly() x^3 - 15*x^2 - 18*x >>> phi.charpoly('T') T^3 - 15*T^2 - 18*T 
 - det()[source]¶
- Return the determinant of - self.- OUTPUT: - element of the base ring of the modules on which - selfis defined, equal to the determinant of- self.
 - EXAMPLES: - sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: e = M.basis('e') sage: a = M.automorphism(matrix=[[-1,0,0],[0,1,2],[0,1,3]], basis=e) sage: ep = e.new_basis(a, 'ep', latex_symbol="e'") sage: phi = M.endomorphism([[1,2,3], [4,5,6], [7,8,9]], basis=ep) sage: phi.matrix(e) [ 1 -3 1] [-18 39 -18] [-25 54 -25] sage: phi.det() 0 sage: det(phi) 0 - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M') >>> e = M.basis('e') >>> a = M.automorphism(matrix=[[-Integer(1),Integer(0),Integer(0)],[Integer(0),Integer(1),Integer(2)],[Integer(0),Integer(1),Integer(3)]], basis=e) >>> ep = e.new_basis(a, 'ep', latex_symbol="e'") >>> phi = M.endomorphism([[Integer(1),Integer(2),Integer(3)], [Integer(4),Integer(5),Integer(6)], [Integer(7),Integer(8),Integer(9)]], basis=ep) >>> phi.matrix(e) [ 1 -3 1] [-18 39 -18] [-25 54 -25] >>> phi.det() 0 >>> det(phi) 0 
 - determinant()[source]¶
- Return the determinant of - self.- OUTPUT: - element of the base ring of the modules on which - selfis defined, equal to the determinant of- self.
 - EXAMPLES: - sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: e = M.basis('e') sage: a = M.automorphism(matrix=[[-1,0,0],[0,1,2],[0,1,3]], basis=e) sage: ep = e.new_basis(a, 'ep', latex_symbol="e'") sage: phi = M.endomorphism([[1,2,3], [4,5,6], [7,8,9]], basis=ep) sage: phi.matrix(e) [ 1 -3 1] [-18 39 -18] [-25 54 -25] sage: phi.det() 0 sage: det(phi) 0 - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M') >>> e = M.basis('e') >>> a = M.automorphism(matrix=[[-Integer(1),Integer(0),Integer(0)],[Integer(0),Integer(1),Integer(2)],[Integer(0),Integer(1),Integer(3)]], basis=e) >>> ep = e.new_basis(a, 'ep', latex_symbol="e'") >>> phi = M.endomorphism([[Integer(1),Integer(2),Integer(3)], [Integer(4),Integer(5),Integer(6)], [Integer(7),Integer(8),Integer(9)]], basis=ep) >>> phi.matrix(e) [ 1 -3 1] [-18 39 -18] [-25 54 -25] >>> phi.det() 0 >>> det(phi) 0 
 - fcp()[source]¶
- Return the factorization of the characteristic polynomial of - self.- INPUT: - var– string (default:- 'x'); a variable name
 - EXAMPLES: - sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: e = M.basis('e') sage: a = M.automorphism(matrix=[[-1,0,0],[0,1,2],[0,1,3]], basis=e) sage: ep = e.new_basis(a, 'ep', latex_symbol="e'") sage: phi = M.endomorphism([[1,2,3], [4,5,6], [7,8,9]], basis=ep) sage: phi.matrix(e) [ 1 -3 1] [-18 39 -18] [-25 54 -25] sage: phi.fcp() # needs sage.libs.pari x * (x^2 - 15*x - 18) sage: phi.fcp('T') # needs sage.libs.pari T * (T^2 - 15*T - 18) - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M') >>> e = M.basis('e') >>> a = M.automorphism(matrix=[[-Integer(1),Integer(0),Integer(0)],[Integer(0),Integer(1),Integer(2)],[Integer(0),Integer(1),Integer(3)]], basis=e) >>> ep = e.new_basis(a, 'ep', latex_symbol="e'") >>> phi = M.endomorphism([[Integer(1),Integer(2),Integer(3)], [Integer(4),Integer(5),Integer(6)], [Integer(7),Integer(8),Integer(9)]], basis=ep) >>> phi.matrix(e) [ 1 -3 1] [-18 39 -18] [-25 54 -25] >>> phi.fcp() # needs sage.libs.pari x * (x^2 - 15*x - 18) >>> phi.fcp('T') # needs sage.libs.pari T * (T^2 - 15*T - 18) 
 - 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(ZZ, 3, name='M') sage: e = M.basis('e') sage: a = M.automorphism(matrix=[[-1,0,0],[0,1,2],[0,1,3]], basis=e) sage: ep = e.new_basis(a, 'ep', latex_symbol="e'") sage: phi = M.endomorphism([[1,2,3], [4,5,6], [7,8,9]], basis=ep) sage: phi.matrix(e) [ 1 -3 1] [-18 39 -18] [-25 54 -25] sage: phi.minpoly() # needs sage.libs.pari x^3 - 15*x^2 - 18*x sage: phi.minimal_polynomial() # needs sage.libs.pari x^3 - 15*x^2 - 18*x sage: phi.minimal_polynomial('T') # needs sage.libs.pari T^3 - 15*T^2 - 18*T - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M') >>> e = M.basis('e') >>> a = M.automorphism(matrix=[[-Integer(1),Integer(0),Integer(0)],[Integer(0),Integer(1),Integer(2)],[Integer(0),Integer(1),Integer(3)]], basis=e) >>> ep = e.new_basis(a, 'ep', latex_symbol="e'") >>> phi = M.endomorphism([[Integer(1),Integer(2),Integer(3)], [Integer(4),Integer(5),Integer(6)], [Integer(7),Integer(8),Integer(9)]], basis=ep) >>> phi.matrix(e) [ 1 -3 1] [-18 39 -18] [-25 54 -25] >>> phi.minpoly() # needs sage.libs.pari x^3 - 15*x^2 - 18*x >>> phi.minimal_polynomial() # needs sage.libs.pari x^3 - 15*x^2 - 18*x >>> phi.minimal_polynomial('T') # needs sage.libs.pari T^3 - 15*T^2 - 18*T 
 - 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(ZZ, 3, name='M') sage: e = M.basis('e') sage: a = M.automorphism(matrix=[[-1,0,0],[0,1,2],[0,1,3]], basis=e) sage: ep = e.new_basis(a, 'ep', latex_symbol="e'") sage: phi = M.endomorphism([[1,2,3], [4,5,6], [7,8,9]], basis=ep) sage: phi.matrix(e) [ 1 -3 1] [-18 39 -18] [-25 54 -25] sage: phi.minpoly() # needs sage.libs.pari x^3 - 15*x^2 - 18*x sage: phi.minimal_polynomial() # needs sage.libs.pari x^3 - 15*x^2 - 18*x sage: phi.minimal_polynomial('T') # needs sage.libs.pari T^3 - 15*T^2 - 18*T - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M') >>> e = M.basis('e') >>> a = M.automorphism(matrix=[[-Integer(1),Integer(0),Integer(0)],[Integer(0),Integer(1),Integer(2)],[Integer(0),Integer(1),Integer(3)]], basis=e) >>> ep = e.new_basis(a, 'ep', latex_symbol="e'") >>> phi = M.endomorphism([[Integer(1),Integer(2),Integer(3)], [Integer(4),Integer(5),Integer(6)], [Integer(7),Integer(8),Integer(9)]], basis=ep) >>> phi.matrix(e) [ 1 -3 1] [-18 39 -18] [-25 54 -25] >>> phi.minpoly() # needs sage.libs.pari x^3 - 15*x^2 - 18*x >>> phi.minimal_polynomial() # needs sage.libs.pari x^3 - 15*x^2 - 18*x >>> phi.minimal_polynomial('T') # needs sage.libs.pari T^3 - 15*T^2 - 18*T 
 - trace()[source]¶
- Return the trace of - self.- OUTPUT: - element of the base ring of the modules on which - selfis defined, equal to the trace of- self.
 - EXAMPLES: - sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: e = M.basis('e') sage: a = M.automorphism(matrix=[[-1,0,0],[0,1,2],[0,1,3]], basis=e) sage: ep = e.new_basis(a, 'ep', latex_symbol="e'") sage: phi = M.endomorphism([[1,2,3], [4,5,6], [7,8,9]], basis=ep) sage: phi.matrix(e) [ 1 -3 1] [-18 39 -18] [-25 54 -25] sage: phi.trace() 15 sage: id = M.identity_map() sage: id.trace() 3 - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M') >>> e = M.basis('e') >>> a = M.automorphism(matrix=[[-Integer(1),Integer(0),Integer(0)],[Integer(0),Integer(1),Integer(2)],[Integer(0),Integer(1),Integer(3)]], basis=e) >>> ep = e.new_basis(a, 'ep', latex_symbol="e'") >>> phi = M.endomorphism([[Integer(1),Integer(2),Integer(3)], [Integer(4),Integer(5),Integer(6)], [Integer(7),Integer(8),Integer(9)]], basis=ep) >>> phi.matrix(e) [ 1 -3 1] [-18 39 -18] [-25 54 -25] >>> phi.trace() 15 >>> id = M.identity_map() >>> id.trace() 3 
 
- class sage.tensor.modules.free_module_morphism.FiniteRankFreeModuleMorphism(parent, matrix_rep, bases=None, name=None, latex_name=None, is_identity=False)[source]¶
- Bases: - Morphism- Homomorphism between free modules of finite rank over a commutative ring. - An instance of this class is a homomorphism \[\phi:\ M \longrightarrow N,\]- where \(M\) and \(N\) are two free modules of finite rank over the same commutative ring \(R\). - This is a Sage element class, the corresponding parent class being - FreeModuleHomset.- For the special case of endomorphisms (\(M=N\)), use the subclass - FiniteRankFreeModuleEndomorphism.- INPUT: - parent– Hom-set Hom(M,N) to which the homomorphism belongs
- matrix_rep– matrix representation of the homomorphism with respect to the bases- bases; this entry can actually be any material from which a matrix of size rank(N)*rank(M) of elements of \(R\) can be constructed; the columns of the matrix give the images of the basis of \(M\) (see the convention in the example below)
- bases– (default:- None) pair (basis_M, basis_N) defining the matrix representation, basis_M being a basis of module \(M\) and basis_N a basis of module \(N\) ; if None the pair formed by the default bases of each module is assumed.
- name– (default:- None) string; name given to the homomorphism
- latex_name– (default:- None) string; LaTeX symbol to denote the homomorphism. If- None,- namewill be used.
 - EXAMPLES: - A homomorphism between two free modules over \(\ZZ\) is constructed as an element of the corresponding hom-set, by means of the function - __call__:- sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: N = FiniteRankFreeModule(ZZ, 2, name='N') sage: e = M.basis('e') ; f = N.basis('f') sage: H = Hom(M,N) ; H Set of Morphisms from Rank-3 free module M over the Integer Ring to Rank-2 free module N over the Integer Ring in Category of finite dimensional modules over Integer Ring sage: phi = H([[2,-1,3], [1,0,-4]], name='phi', latex_name=r'\phi') ; phi Generic morphism: From: Rank-3 free module M over the Integer Ring To: Rank-2 free module N over the Integer Ring - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M') >>> N = FiniteRankFreeModule(ZZ, Integer(2), name='N') >>> e = M.basis('e') ; f = N.basis('f') >>> H = Hom(M,N) ; H Set of Morphisms from Rank-3 free module M over the Integer Ring to Rank-2 free module N over the Integer Ring in Category of finite dimensional modules over Integer Ring >>> phi = H([[Integer(2),-Integer(1),Integer(3)], [Integer(1),Integer(0),-Integer(4)]], name='phi', latex_name=r'\phi') ; phi Generic morphism: From: Rank-3 free module M over the Integer Ring To: Rank-2 free module N over the Integer Ring - Since no bases have been specified in the argument list, the provided matrix is relative to the default bases of modules M and N, so that the above is equivalent to: - sage: phi = H([[2,-1,3], [1,0,-4]], bases=(e,f), name='phi', ....: latex_name=r'\phi') ; phi Generic morphism: From: Rank-3 free module M over the Integer Ring To: Rank-2 free module N over the Integer Ring - >>> from sage.all import * >>> phi = H([[Integer(2),-Integer(1),Integer(3)], [Integer(1),Integer(0),-Integer(4)]], bases=(e,f), name='phi', ... latex_name=r'\phi') ; phi Generic morphism: From: Rank-3 free module M over the Integer Ring To: Rank-2 free module N over the Integer Ring - An alternative way to construct a homomorphism is to call the method - hom()on the domain:- sage: phi = M.hom(N, [[2,-1,3], [1,0,-4]], bases=(e,f), name='phi', ....: latex_name=r'\phi') ; phi Generic morphism: From: Rank-3 free module M over the Integer Ring To: Rank-2 free module N over the Integer Ring - >>> from sage.all import * >>> phi = M.hom(N, [[Integer(2),-Integer(1),Integer(3)], [Integer(1),Integer(0),-Integer(4)]], bases=(e,f), name='phi', ... latex_name=r'\phi') ; phi Generic morphism: From: Rank-3 free module M over the Integer Ring To: Rank-2 free module N over the Integer Ring - The parent of a homomorphism is of course the corresponding hom-set: - sage: phi.parent() is H True sage: phi.parent() is Hom(M,N) True - >>> from sage.all import * >>> phi.parent() is H True >>> phi.parent() is Hom(M,N) True - Due to Sage’s category scheme, the actual class of the homomorphism - phiis a derived class of- FiniteRankFreeModuleMorphism:- sage: type(phi) <class 'sage.tensor.modules.free_module_homset.FreeModuleHomset_with_category_with_equality_by_id.element_class'> sage: isinstance(phi, sage.tensor.modules.free_module_morphism.FiniteRankFreeModuleMorphism) True - >>> from sage.all import * >>> type(phi) <class 'sage.tensor.modules.free_module_homset.FreeModuleHomset_with_category_with_equality_by_id.element_class'> >>> isinstance(phi, sage.tensor.modules.free_module_morphism.FiniteRankFreeModuleMorphism) True - The domain and codomain of the homomorphism are returned respectively by the methods - domain()and- codomain(), which are implemented as Sage’s constant functions:- sage: phi.domain() Rank-3 free module M over the Integer Ring sage: phi.codomain() Rank-2 free module N over the Integer Ring sage: type(phi.domain) <... 'sage.misc.constant_function.ConstantFunction'> - >>> from sage.all import * >>> phi.domain() Rank-3 free module M over the Integer Ring >>> phi.codomain() Rank-2 free module N over the Integer Ring >>> type(phi.domain) <... 'sage.misc.constant_function.ConstantFunction'> - The matrix of the homomorphism with respect to a pair of bases is returned by the method - matrix():- sage: phi.matrix(e,f) [ 2 -1 3] [ 1 0 -4] - >>> from sage.all import * >>> phi.matrix(e,f) [ 2 -1 3] [ 1 0 -4] - The convention is that the columns of this matrix give the components of the images of the elements of basis - ew.r.t basis- f:- sage: phi(e[0]).display() phi(e_0) = 2 f_0 + f_1 sage: phi(e[1]).display() phi(e_1) = -f_0 sage: phi(e[2]).display() phi(e_2) = 3 f_0 - 4 f_1 - >>> from sage.all import * >>> phi(e[Integer(0)]).display() phi(e_0) = 2 f_0 + f_1 >>> phi(e[Integer(1)]).display() phi(e_1) = -f_0 >>> phi(e[Integer(2)]).display() phi(e_2) = 3 f_0 - 4 f_1 - Test of the module homomorphism laws: - sage: phi(M.zero()) == N.zero() True sage: u = M([1,2,3], basis=e, name='u') ; u.display() u = e_0 + 2 e_1 + 3 e_2 sage: v = M([-2,1,4], basis=e, name='v') ; v.display() v = -2 e_0 + e_1 + 4 e_2 sage: phi(u).display() phi(u) = 9 f_0 - 11 f_1 sage: phi(v).display() phi(v) = 7 f_0 - 18 f_1 sage: phi(3*u + v).display() 34 f_0 - 51 f_1 sage: phi(3*u + v) == 3*phi(u) + phi(v) True - >>> from sage.all import * >>> phi(M.zero()) == N.zero() True >>> u = M([Integer(1),Integer(2),Integer(3)], basis=e, name='u') ; u.display() u = e_0 + 2 e_1 + 3 e_2 >>> v = M([-Integer(2),Integer(1),Integer(4)], basis=e, name='v') ; v.display() v = -2 e_0 + e_1 + 4 e_2 >>> phi(u).display() phi(u) = 9 f_0 - 11 f_1 >>> phi(v).display() phi(v) = 7 f_0 - 18 f_1 >>> phi(Integer(3)*u + v).display() 34 f_0 - 51 f_1 >>> phi(Integer(3)*u + v) == Integer(3)*phi(u) + phi(v) True - display(basis1=None, basis2=None)[source]¶
- Display - selfas a matrix w.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 domain of- self; if none is provided, the domain’s default basis is assumed
- basis2– (default:- None) basis of the codomain of- self; if none is provided,- basis2is set to- basis1if- selfis an endomorphism, otherwise,- basis2is set to the codomain’s default basis.
 - EXAMPLES: - sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: N = FiniteRankFreeModule(ZZ, 2, name='N') sage: e = M.basis('e'); f = N.basis('f') sage: phi = M.hom(N, [[-1,2,0], [5,1,2]]) sage: phi.display() # default bases e_0 e_1 e_2 f_0⎛ -1 2 0⎞ f_1⎝ 5 1 2⎠ sage: phi.display(e, f) # given bases e_0 e_1 e_2 f_0⎛ -1 2 0⎞ f_1⎝ 5 1 2⎠ - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M') >>> N = FiniteRankFreeModule(ZZ, Integer(2), name='N') >>> e = M.basis('e'); f = N.basis('f') >>> phi = M.hom(N, [[-Integer(1),Integer(2),Integer(0)], [Integer(5),Integer(1),Integer(2)]]) >>> phi.display() # default bases e_0 e_1 e_2 f_0⎛ -1 2 0⎞ f_1⎝ 5 1 2⎠ >>> phi.display(e, f) # given bases e_0 e_1 e_2 f_0⎛ -1 2 0⎞ f_1⎝ 5 1 2⎠ - Matrix of an endomorphism: - sage: a = M.automorphism(matrix=[[-1,0,0],[0,1,2],[0,1,3]], basis=e) sage: ep = e.new_basis(a, 'ep', latex_symbol="e'") sage: phi = M.endomorphism([[1,2,3], [4,5,6], [7,8,9]], basis=ep) sage: phi.display(ep) ep_0 ep_1 ep_2 ep_0⎛ 1 2 3⎞ ep_1⎜ 4 5 6⎟ ep_2⎝ 7 8 9⎠ sage: phi.display(ep, ep) # same as above ep_0 ep_1 ep_2 ep_0⎛ 1 2 3⎞ ep_1⎜ 4 5 6⎟ ep_2⎝ 7 8 9⎠ sage: phi.display() # matrix w.r.t to the module's default basis e_0 e_1 e_2 e_0⎛ 1 -3 1⎞ e_1⎜-18 39 -18⎟ e_2⎝-25 54 -25⎠ - >>> from sage.all import * >>> a = M.automorphism(matrix=[[-Integer(1),Integer(0),Integer(0)],[Integer(0),Integer(1),Integer(2)],[Integer(0),Integer(1),Integer(3)]], basis=e) >>> ep = e.new_basis(a, 'ep', latex_symbol="e'") >>> phi = M.endomorphism([[Integer(1),Integer(2),Integer(3)], [Integer(4),Integer(5),Integer(6)], [Integer(7),Integer(8),Integer(9)]], basis=ep) >>> phi.display(ep) ep_0 ep_1 ep_2 ep_0⎛ 1 2 3⎞ ep_1⎜ 4 5 6⎟ ep_2⎝ 7 8 9⎠ >>> phi.display(ep, ep) # same as above ep_0 ep_1 ep_2 ep_0⎛ 1 2 3⎞ ep_1⎜ 4 5 6⎟ ep_2⎝ 7 8 9⎠ >>> phi.display() # matrix w.r.t to the module's default basis e_0 e_1 e_2 e_0⎛ 1 -3 1⎞ e_1⎜-18 39 -18⎟ e_2⎝-25 54 -25⎠ 
 - is_identity()[source]¶
- Check whether - selfis the identity morphism.- EXAMPLES: - sage: M = FiniteRankFreeModule(ZZ, 2, name='M') sage: e = M.basis('e') sage: phi = M.endomorphism([[1,0], [0,1]]) sage: phi.is_identity() True sage: (phi+phi).is_identity() False sage: End(M).zero().is_identity() False sage: a = M.automorphism() ; a[0,1], a[1,0] = 1, -1 sage: ep = e.new_basis(a, 'ep', latex_symbol="e'") sage: phi = M.endomorphism([[1,0], [0,1]], basis=ep) sage: phi.is_identity() True - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(2), name='M') >>> e = M.basis('e') >>> phi = M.endomorphism([[Integer(1),Integer(0)], [Integer(0),Integer(1)]]) >>> phi.is_identity() True >>> (phi+phi).is_identity() False >>> End(M).zero().is_identity() False >>> a = M.automorphism() ; a[Integer(0),Integer(1)], a[Integer(1),Integer(0)] = Integer(1), -Integer(1) >>> ep = e.new_basis(a, 'ep', latex_symbol="e'") >>> phi = M.endomorphism([[Integer(1),Integer(0)], [Integer(0),Integer(1)]], basis=ep) >>> phi.is_identity() True - Example illustrating that the identity can be constructed from a matrix that is not the identity one, provided that it is relative to different bases: - sage: phi = M.hom(M, [[0,1], [-1,0]], bases=(ep,e)) sage: phi.is_identity() True - >>> from sage.all import * >>> phi = M.hom(M, [[Integer(0),Integer(1)], [-Integer(1),Integer(0)]], bases=(ep,e)) >>> phi.is_identity() True - Of course, if we ask for the matrix in a single basis, it is the identity matrix: - sage: phi.matrix(e) [1 0] [0 1] sage: phi.matrix(ep) [1 0] [0 1] - >>> from sage.all import * >>> phi.matrix(e) [1 0] [0 1] >>> phi.matrix(ep) [1 0] [0 1] 
 - is_injective()[source]¶
- Determine whether - selfis injective.- OUTPUT: - Trueif- selfis an injective homomorphism and- Falseotherwise
 - EXAMPLES: - Homomorphisms between two \(\ZZ\)-modules: - sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: N = FiniteRankFreeModule(ZZ, 2, name='N') sage: e = M.basis('e') ; f = N.basis('f') sage: phi = M.hom(N, [[-1,2,0], [5,1,2]]) sage: phi.matrix(e,f) [-1 2 0] [ 5 1 2] sage: phi.is_injective() False - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M') >>> N = FiniteRankFreeModule(ZZ, Integer(2), name='N') >>> e = M.basis('e') ; f = N.basis('f') >>> phi = M.hom(N, [[-Integer(1),Integer(2),Integer(0)], [Integer(5),Integer(1),Integer(2)]]) >>> phi.matrix(e,f) [-1 2 0] [ 5 1 2] >>> phi.is_injective() False - Indeed, phi has a non trivial kernel: - sage: phi(4*e[0] + 2*e[1] - 11*e[2]).display() 0 - >>> from sage.all import * >>> phi(Integer(4)*e[Integer(0)] + Integer(2)*e[Integer(1)] - Integer(11)*e[Integer(2)]).display() 0 - An injective homomorphism: - sage: psi = N.hom(M, [[1,-1], [0,3], [4,-5]]) sage: psi.matrix(f,e) [ 1 -1] [ 0 3] [ 4 -5] sage: psi.is_injective() True - >>> from sage.all import * >>> psi = N.hom(M, [[Integer(1),-Integer(1)], [Integer(0),Integer(3)], [Integer(4),-Integer(5)]]) >>> psi.matrix(f,e) [ 1 -1] [ 0 3] [ 4 -5] >>> psi.is_injective() True - Of course, the identity endomorphism is injective: - sage: End(M).one().is_injective() True sage: End(N).one().is_injective() True - >>> from sage.all import * >>> End(M).one().is_injective() True >>> End(N).one().is_injective() True 
 - is_surjective()[source]¶
- Determine whether - selfis surjective.- OUTPUT: - Trueif- selfis a surjective homomorphism and- Falseotherwise
 - EXAMPLES: - This method has not been implemented yet: - sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: N = FiniteRankFreeModule(ZZ, 2, name='N') sage: e = M.basis('e') ; f = N.basis('f') sage: phi = M.hom(N, [[-1,2,0], [5,1,2]]) sage: phi.is_surjective() Traceback (most recent call last): ... NotImplementedError: FiniteRankFreeModuleMorphism.is_surjective() has not been implemented yet - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M') >>> N = FiniteRankFreeModule(ZZ, Integer(2), name='N') >>> e = M.basis('e') ; f = N.basis('f') >>> phi = M.hom(N, [[-Integer(1),Integer(2),Integer(0)], [Integer(5),Integer(1),Integer(2)]]) >>> phi.is_surjective() Traceback (most recent call last): ... NotImplementedError: FiniteRankFreeModuleMorphism.is_surjective() has not been implemented yet - except for the identity endomorphism (!): - sage: End(M).one().is_surjective() True sage: End(N).one().is_surjective() True - >>> from sage.all import * >>> End(M).one().is_surjective() True >>> End(N).one().is_surjective() True 
 - 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 domain of- self; if none is provided, the domain’s default basis is assumed
- basis2– (default:- None) basis of the codomain of- self; if none is provided,- basis2is set to- basis1if- selfis an endomorphism, otherwise,- basis2is set to the codomain’s default basis.
 - OUTPUT: - the matrix representing the homomorphism - 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: - Matrix of a homomorphism between two \(\ZZ\)-modules: - sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: N = FiniteRankFreeModule(ZZ, 2, name='N') sage: e = M.basis('e') ; f = N.basis('f') sage: phi = M.hom(N, [[-1,2,0], [5,1,2]]) sage: phi.matrix() # default bases [-1 2 0] [ 5 1 2] sage: phi.matrix(e, f) # given bases [-1 2 0] [ 5 1 2] sage: type(phi.matrix()) # needs sage.libs.flint <class 'sage.matrix.matrix_integer_dense.Matrix_integer_dense'> - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M') >>> N = FiniteRankFreeModule(ZZ, Integer(2), name='N') >>> e = M.basis('e') ; f = N.basis('f') >>> phi = M.hom(N, [[-Integer(1),Integer(2),Integer(0)], [Integer(5),Integer(1),Integer(2)]]) >>> phi.matrix() # default bases [-1 2 0] [ 5 1 2] >>> phi.matrix(e, f) # given bases [-1 2 0] [ 5 1 2] >>> type(phi.matrix()) # needs sage.libs.flint <class 'sage.matrix.matrix_integer_dense.Matrix_integer_dense'> - Matrix in bases different from those in which the homomorphism has been defined: - sage: a = M.automorphism(matrix=[[-1,0,0],[0,1,2],[0,1,3]], basis=e) sage: ep = e.new_basis(a, 'ep', latex_symbol="e'") sage: b = N.automorphism(matrix=[[3,5],[4,7]], basis=f) sage: fp = f.new_basis(b, 'fp', latex_symbol="f'") sage: phi.matrix(ep, fp) [ 32 -1 -12] [-19 1 8] - >>> from sage.all import * >>> a = M.automorphism(matrix=[[-Integer(1),Integer(0),Integer(0)],[Integer(0),Integer(1),Integer(2)],[Integer(0),Integer(1),Integer(3)]], basis=e) >>> ep = e.new_basis(a, 'ep', latex_symbol="e'") >>> b = N.automorphism(matrix=[[Integer(3),Integer(5)],[Integer(4),Integer(7)]], basis=f) >>> fp = f.new_basis(b, 'fp', latex_symbol="f'") >>> phi.matrix(ep, fp) [ 32 -1 -12] [-19 1 8] - Check of the change-of-basis formula: - sage: phi.matrix(ep, fp) == (b^(-1)).matrix(f) * phi.matrix(e,f) * a.matrix(e) True - >>> from sage.all import * >>> phi.matrix(ep, fp) == (b**(-Integer(1))).matrix(f) * phi.matrix(e,f) * a.matrix(e) True - Single change of basis: - sage: phi.matrix(ep, f) [ 1 2 4] [-5 3 8] sage: phi.matrix(ep,f) == phi.matrix(e,f) * a.matrix(e) True sage: phi.matrix(e, fp) [-32 9 -10] [ 19 -5 6] sage: phi.matrix(e, fp) == (b^(-1)).matrix(f) * phi.matrix(e,f) True - >>> from sage.all import * >>> phi.matrix(ep, f) [ 1 2 4] [-5 3 8] >>> phi.matrix(ep,f) == phi.matrix(e,f) * a.matrix(e) True >>> phi.matrix(e, fp) [-32 9 -10] [ 19 -5 6] >>> phi.matrix(e, fp) == (b**(-Integer(1))).matrix(f) * phi.matrix(e,f) True - Matrix of an endomorphism: - sage: phi = M.endomorphism([[1,2,3], [4,5,6], [7,8,9]], basis=ep) sage: phi.matrix(ep) [1 2 3] [4 5 6] [7 8 9] sage: phi.matrix(ep,ep) # same as above [1 2 3] [4 5 6] [7 8 9] sage: phi.matrix() # matrix w.r.t to the module's default basis [ 1 -3 1] [-18 39 -18] [-25 54 -25] - >>> from sage.all import * >>> phi = M.endomorphism([[Integer(1),Integer(2),Integer(3)], [Integer(4),Integer(5),Integer(6)], [Integer(7),Integer(8),Integer(9)]], basis=ep) >>> phi.matrix(ep) [1 2 3] [4 5 6] [7 8 9] >>> phi.matrix(ep,ep) # same as above [1 2 3] [4 5 6] [7 8 9] >>> phi.matrix() # matrix w.r.t to the module's default basis [ 1 -3 1] [-18 39 -18] [-25 54 -25]