Path: blob/master/sage/modules/free_module_homspace.py
4056 views
r"""1Homspaces between free modules23EXAMPLES: We create `\mathrm{End}(\ZZ^2)` and compute a4basis.56::78sage: M = FreeModule(IntegerRing(),2)9sage: E = End(M)10sage: B = E.basis()11sage: len(B)12413sage: B[0]14Free module morphism defined by the matrix15[1 0]16[0 0]17Domain: Ambient free module of rank 2 over the principal ideal domain ...18Codomain: Ambient free module of rank 2 over the principal ideal domain ...1920We create `\mathrm{Hom}(\ZZ^3, \ZZ^2)` and21compute a basis.2223::2425sage: V3 = FreeModule(IntegerRing(),3)26sage: V2 = FreeModule(IntegerRing(),2)27sage: H = Hom(V3,V2)28sage: H29Set of Morphisms from Ambient free module of rank 330over the principal ideal domain Integer Ring to31Ambient free module of rank 232over the principal ideal domain Integer Ring33in Category of modules with basis over Integer Ring34sage: B = H.basis()35sage: len(B)36637sage: B[0]38Free module morphism defined by the matrix39[1 0]40[0 0]41[0 0]...4243TESTS::4445sage: H = Hom(QQ^2, QQ^1)46sage: loads(dumps(H)) == H47True4849See trac 5886::5051sage: V = (ZZ^2).span_of_basis([[1,2],[3,4]])52sage: V.hom([V.0, V.1])53Free module morphism defined by the matrix54[1 0]55[0 1]...5657"""5859#*****************************************************************************60# Copyright (C) 2005 William Stein <[email protected]>61#62# Distributed under the terms of the GNU General Public License (GPL)63#64# This code is distributed in the hope that it will be useful,65# but WITHOUT ANY WARRANTY; without even the implied warranty66# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.67#68# See the GNU General Public License for more details; the full text69# is available at:70#71# http://www.gnu.org/licenses/72#*****************************************************************************7374import sage.categories.homset75import sage.matrix.all as matrix76import free_module_morphism77from inspect import isfunction787980def is_FreeModuleHomspace(x):81r"""82Return ``True`` if ``x`` is a free module homspace.8384EXAMPLES:8586Notice that every vector space is a field, but when we construct a set of87morphisms between two vector spaces, it is a ``VectorSpaceHomspace``,88which qualifies as a ``FreeModuleHomspace``, since the former is89special case of the latter.9091sage: H = Hom(ZZ^3, ZZ^2)92sage: type(H)93<class 'sage.modules.free_module_homspace.FreeModuleHomspace_with_category'>94sage: sage.modules.free_module_homspace.is_FreeModuleHomspace(H)95True9697sage: K = Hom(QQ^3, ZZ^2)98sage: type(K)99<class 'sage.modules.free_module_homspace.FreeModuleHomspace_with_category'>100sage: sage.modules.free_module_homspace.is_FreeModuleHomspace(K)101True102103sage: L = Hom(ZZ^3, QQ^2)104sage: type(L)105<class 'sage.modules.free_module_homspace.FreeModuleHomspace_with_category'>106sage: sage.modules.free_module_homspace.is_FreeModuleHomspace(L)107True108109sage: P = Hom(QQ^3, QQ^2)110sage: type(P)111<class 'sage.modules.vector_space_homspace.VectorSpaceHomspace_with_category'>112sage: sage.modules.free_module_homspace.is_FreeModuleHomspace(P)113True114115sage: sage.modules.free_module_homspace.is_FreeModuleHomspace('junk')116False117"""118return isinstance(x, FreeModuleHomspace)119120class FreeModuleHomspace(sage.categories.homset.HomsetWithBase):121def __call__(self, A, check=True):122r"""123INPUT:124125- A -- either a matrix or a list/tuple of images of generators,126or a function returning elements of the codomain for elements127of the domain.128- check -- bool (default: True)129130If A is a matrix, then it is the matrix of this linear131transformation, with respect to the basis for the domain and132codomain. Thus the identity matrix always defines the133identity morphism.134135EXAMPLES::136137sage: V = (ZZ^3).span_of_basis([[1,1,0],[1,0,2]])138sage: H = V.Hom(V); H139Set of Morphisms from ...140sage: H([V.0,V.1]) # indirect doctest141Free module morphism defined by the matrix142[1 0]143[0 1]...144sage: phi = H([V.1,V.0]); phi145Free module morphism defined by the matrix146[0 1]147[1 0]...148sage: phi(V.1) == V.0149True150sage: phi(V.0) == V.1151True152153The following tests against a bug that was fixed in trac154ticket #9944. The method ``zero()`` calls this hom space with155a function, not with a matrix, and that case had previously156not been taken care of::157158sage: V = span([[1/2,1,1],[3/2,2,1],[0,0,1]],ZZ)159sage: V.Hom(V).zero() # indirect doctest160Free module morphism defined by the matrix161[0 0 0]162[0 0 0]163[0 0 0]164Domain: Free module of degree 3 and rank 3 over Integer Ring165Echelon ...166Codomain: Free module of degree 3 and rank 3 over Integer Ring167Echelon ...168169"""170if not matrix.is_Matrix(A):171# Compute the matrix of the morphism that sends the172# generators of the domain to the elements of A.173C = self.codomain()174if isfunction(A):175try:176v = [C(A(g)) for g in self.domain().gens()]177A = matrix.matrix([C.coordinates(a) for a in v])178except TypeError, msg:179# Let us hope that FreeModuleMorphism knows to handle that case180pass181else:182try:183v = [C(a) for a in A]184A = matrix.matrix([C.coordinates(a) for a in v])185except TypeError, msg:186# Let us hope that FreeModuleMorphism knows to handle that case187pass188return free_module_morphism.FreeModuleMorphism(self, A)189190def _matrix_space(self):191"""192Return underlying matrix space that contains the matrices that define193the homomorphisms in this free module homspace.194195OUTPUT:196197- matrix space198199EXAMPLES::200201sage: H = Hom(QQ^3, QQ^2)202sage: H._matrix_space()203Full MatrixSpace of 3 by 2 dense matrices over Rational Field204"""205try:206return self.__matrix_space207except AttributeError:208R = self.domain().base_ring()209M = matrix.MatrixSpace(R, self.domain().rank(), self.codomain().rank())210self.__matrix_space = M211return M212213def basis(self):214"""215Return a basis for this space of free module homomorphisms.216217OUTPUT:218219- tuple220221EXAMPLES::222223sage: H = Hom(ZZ^2, ZZ^1)224sage: H.basis()225(Free module morphism defined by the matrix226[1]227[0]228Domain: Ambient free module of rank 2 over the principal ideal domain ...229Codomain: Ambient free module of rank 1 over the principal ideal domain ..., Free module morphism defined by the matrix230[0]231[1]232Domain: Ambient free module of rank 2 over the principal ideal domain ...233Codomain: Ambient free module of rank 1 over the principal ideal domain ...)234"""235try:236return self.__basis237except AttributeError:238M = self._matrix_space()239B = M.basis()240self.__basis = tuple([self(x) for x in B])241return self.__basis242243def identity(self):244r"""245Return identity morphism in an endomorphism ring.246247EXAMPLE::248249sage: V=FreeModule(ZZ,5)250sage: H=V.Hom(V)251sage: H.identity()252Free module morphism defined by the matrix253[1 0 0 0 0]254[0 1 0 0 0]255[0 0 1 0 0]256[0 0 0 1 0]257[0 0 0 0 1]258Domain: Ambient free module of rank 5 over the principal ideal domain ...259Codomain: Ambient free module of rank 5 over the principal ideal domain ...260"""261if self.is_endomorphism_set():262return self(matrix.identity_matrix(self.base_ring(),self.domain().rank()))263else:264raise TypeError, "Identity map only defined for endomorphisms. Try natural_map() instead."265266267268