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 belongsmatrix_rep
– matrix representation of the endomorphism with respect to the basisbases
; 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_domain
andbasis_codomain
being two bases (typically the same) of the same module \(M\); ifNone
, the default basis of \(M\) is used for both.name
– (default:None
) string; name given to the endomorphismlatex_name
– (default:None
) string; LaTeX symbol to denote the endomorphism; ifNone
,name
will be used.is_identity
– (default:False
) determines whether the constructed object is the identity endomorphism; if set toTrue
, then the entrymatrix_rep
is 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
Id
with respect to the basise
is 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()
andcharpoly()
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()
andcharpoly()
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
self
is defined, equal to the determinant ofself
.
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
self
is defined, equal to the determinant ofself
.
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()
andminpoly()
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()
andminpoly()
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
self
is defined, equal to the trace ofself
.
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 belongsmatrix_rep
– matrix representation of the homomorphism with respect to the basesbases
; 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 homomorphismlatex_name
– (default:None
) string; LaTeX symbol to denote the homomorphism; ifNone
,name
will 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
phi
is a derived class ofFiniteRankFreeModuleMorphism
: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()
andcodomain()
, 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
e
w.r.t basisf
: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
self
as 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 ofself
; if none is provided, the domain’s default basis is assumedbasis2
– (default:None
) basis of the codomain ofself
; if none is provided,basis2
is set tobasis1
ifself
is an endomorphism, otherwise,basis2
is 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
self
is 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
self
is injective.OUTPUT:
True
ifself
is an injective homomorphism andFalse
otherwise
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
self
is surjective.OUTPUT:
True
ifself
is a surjective homomorphism andFalse
otherwise
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
self
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 ofself
; if none is provided, the domain’s default basis is assumedbasis2
– (default:None
) basis of the codomain ofself
; if none is provided,basis2
is set tobasis1
ifself
is an endomorphism, otherwise,basis2
is set to the codomain’s default basis.
OUTPUT:
the matrix representing the homomorphism
self
w.r.t to basesbasis1
andbasis2
; more precisely, the columns of this matrix are formed by the components w.r.t.basis2
of the images of the elements ofbasis1
.
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]