Free module morphisms#
The class FiniteRankFreeModuleMorphism
implements homomorphisms
between two free modules of finite rank over the same commutative ring.
AUTHORS:
Eric Gourgoulhon, Michal Bejger (2014-2015): initial version
REFERENCES:
- class sage.tensor.modules.free_module_morphism.FiniteRankFreeModuleMorphism(parent, matrix_rep, bases=None, name=None, latex_name=None, is_identity=False)#
Bases:
sage.categories.morphism.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
.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; if None,name
will be used.is_identity
– (default:False
) determines whether the constructed object is the identity endomorphism; if set toTrue
, then N must be M and the entrymatrix_rep
is not 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
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
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
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
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
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'>
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]
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
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
The identity endomorphism:
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
The matrix of Id with respect to the basis e is of course the identity matrix:
sage: Id.matrix(e) [1 0 0] [0 1 0] [0 0 1]
The identity acting on a module element:
sage: Id(v) is v True
- is_identity()#
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
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
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]
- is_injective()#
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
Indeed, phi has a non trivial kernel:
sage: phi(4*e[0] + 2*e[1] - 11*e[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
Of course, the identity endomorphism is injective:
sage: End(M).one().is_injective() True sage: End(N).one().is_injective() True
- is_surjective()#
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
except for the identity endomorphism (!):
sage: End(M).one().is_surjective() True sage: End(N).one().is_surjective() True
- matrix(basis1=None, basis2=None)#
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()) <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]
Check of the change-of-basis formula:
sage: phi.matrix(ep, fp) == (b^(-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
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]