Path: blob/master/sage/homology/chain_complex_morphism.py
4094 views
r"""1Morphisms of chain complexes23AUTHORS:45- Benjamin Antieau <[email protected]> (2009.06)67This module implements morphisms of chain complexes. The input is a dictionary whose8keys are in the grading group of the chain complex and whose values are matrix morphisms.910EXAMPLES::1112from sage.matrix.constructor import zero_matrix13sage: S = simplicial_complexes.Sphere(1)14sage: S15Simplicial complex with vertex set (0, 1, 2) and facets {(1, 2), (0, 2), (0, 1)}16sage: C = S.chain_complex()17sage: C.differential()18{0: [], 1: [ 1 1 0]19[ 0 -1 -1]20[-1 0 1]}21sage: f = {0:zero_matrix(ZZ,3,3),1:zero_matrix(ZZ,3,3)}22sage: G = Hom(C,C)23sage: x = G(f)24sage: x25Chain complex morphism from Chain complex with at most 2 nonzero terms over Integer Ring to Chain complex with at most 2 nonzero terms over Integer Ring26sage: x._matrix_dictionary27{0: [0 0 0]28[0 0 0]29[0 0 0], 1: [0 0 0]30[0 0 0]31[0 0 0]}3233"""3435#*****************************************************************************36# Copyright (C) 2009 D. Benjamin Antieau <[email protected]>37#38# Distributed under the terms of the GNU General Public License (GPL)39#40# This code is distributed in the hope that it will be useful,41# but WITHOUT ANY WARRANTY; without even the implied warranty42# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.43#44# See the GNU General Public License for more details; the full text45# is available at:46#47# http://www.gnu.org/licenses/48#49#*****************************************************************************5051import sage.matrix.all as matrix52from sage.structure.sage_object import SageObject53from sage.rings.integer_ring import ZZ5455def is_ChainComplexMorphism(x):56"""57Returns True if and only if x is a chain complex morphism.5859EXAMPLES::6061sage: from sage.homology.chain_complex_morphism import is_ChainComplexMorphism62sage: S = simplicial_complexes.Sphere(14)63sage: H = Hom(S,S)64sage: i = H.identity() # long time (8s on sage.math, 2011)65sage: S = simplicial_complexes.Sphere(6)66sage: H = Hom(S,S)67sage: i = H.identity()68sage: x = i.associated_chain_complex_morphism()69sage: x # indirect doctest70Chain complex morphism from Chain complex with at most 7 nonzero terms over Integer Ring to Chain complex with at most 7 nonzero terms over Integer Ring71sage: is_ChainComplexMorphism(x)72True7374"""75return isinstance(x,ChainComplexMorphism)7677class ChainComplexMorphism(SageObject):78"""79An element of this class is a morphism of chain complexes.80"""81def __init__(self,matrices,C,D):82"""83Create a morphism from a dictionary of matrices.8485EXAMPLES::8687from sage.matrix.constructor import zero_matrix88sage: S = simplicial_complexes.Sphere(1)89sage: S90Simplicial complex with vertex set (0, 1, 2) and facets {(1, 2), (0, 2), (0, 1)}91sage: C = S.chain_complex()92sage: C.differential()93{0: [], 1: [ 1 1 0]94[ 0 -1 -1]95[-1 0 1]}96sage: f = {0:zero_matrix(ZZ,3,3),1:zero_matrix(ZZ,3,3)}97sage: G = Hom(C,C)98sage: x = G(f)99sage: x100Chain complex morphism from Chain complex with at most 2 nonzero terms over Integer Ring to Chain complex with at most 2 nonzero terms over Integer Ring101sage: x._matrix_dictionary102{0: [0 0 0]103[0 0 0]104[0 0 0], 1: [0 0 0]105[0 0 0]106[0 0 0]}107108"""109if C._grading_group != ZZ:110raise NotImplementedError, "Chain complex morphisms are not implemented over gradings other than ZZ."111d = C._degree112if d != D._degree:113raise ValueError, "Chain complex morphisms are not defined for chain complexes of different degrees."114if d != -1 and d != 1:115raise NotImplementedError, "Chain complex morphisms are not implemented for degrees besides -1 and 1."116dim_min = min(min(C.differential().keys()),min(D.differential().keys()))117dim_max = max(max(C.differential().keys()),max(D.differential().keys()))118if not C.base_ring()==D.base_ring():119raise NotImplementedError, "Chain complex morphisms between chain complexes of different base rings are not implemented."120for i in range(dim_min,dim_max):121try:122matrices[i]123except KeyError:124matrices[i] = matrix.zero_matrix(C.base_ring(),D.differential()[i].ncols(),C.differential()[i].ncols(),sparse=True)125try:126matrices[i+1]127except KeyError:128matrices[i+1] = matrix.zero_matrix(C.base_ring(),D.differential()[i+1].ncols(),C.differential()[i+1].ncols(),sparse=True)129if d==-1:130if (i+1) in C.differential().keys() and (i+1) in D.differential().keys():131if not matrices[i]*C.differential()[i+1]==D.differential()[i+1]*matrices[i+1]:132raise ValueError, "Matrices must define a chain complex morphism."133elif (i+1) in C.differential().keys():134if not matrices[i]*C.differential()[i+1].is_zero():135raise ValueError, "Matrices must define a chain complex morphism."136elif (i+1) in D.differential().keys():137if not D.differential()[i+1]*matrices[i+1].is_zero():138raise ValueError, "Matrices must define a chain complex morphism."139else:140if i in C.differential().keys() and i in D.differential().keys():141if not matrices[i+1]*C.differential()[i]==D.differential()[i]*matrices[i]:142raise ValueError, "Matrices must define a chain complex morphism."143elif i in C.differential().keys():144if not matrices[i+1]*C.differential()[i].is_zero():145raise ValueError, "Matrices must define a chain complex morphism."146elif i in D.differential().keys():147if not D.differential()[i]*matrices[i].is_zero():148raise ValueError, "Matrices must define a chain complex morphism."149self._matrix_dictionary = matrices150self._domain = C151self._codomain = D152153def __neg__(self):154"""155Returns -x.156157EXAMPLES::158159sage: S = simplicial_complexes.Sphere(2)160sage: H = Hom(S,S)161sage: i = H.identity()162sage: x = i.associated_chain_complex_morphism()163sage: w = -x164sage: w._matrix_dictionary165{0: [-1 0 0 0]166[ 0 -1 0 0]167[ 0 0 -1 0]168[ 0 0 0 -1],1691: [-1 0 0 0 0 0]170[ 0 -1 0 0 0 0]171[ 0 0 -1 0 0 0]172[ 0 0 0 -1 0 0]173[ 0 0 0 0 -1 0]174[ 0 0 0 0 0 -1],1752: [-1 0 0 0]176[ 0 -1 0 0]177[ 0 0 -1 0]178[ 0 0 0 -1]}179180"""181f = dict()182for i in self._matrix_dictionary.keys():183f[i] = -self._matrix_dictionary[i]184return ChainComplexMorphism(f,self._domain,self._codomain)185186def __add__(self,x):187"""188Returns self+x.189190EXAMPLES::191192sage: S = simplicial_complexes.Sphere(2)193sage: H = Hom(S,S)194sage: i = H.identity()195sage: x = i.associated_chain_complex_morphism()196sage: z = x+x197sage: z._matrix_dictionary198{0: [2 0 0 0]199[0 2 0 0]200[0 0 2 0]201[0 0 0 2],2021: [2 0 0 0 0 0]203[0 2 0 0 0 0]204[0 0 2 0 0 0]205[0 0 0 2 0 0]206[0 0 0 0 2 0]207[0 0 0 0 0 2],2082: [2 0 0 0]209[0 2 0 0]210[0 0 2 0]211[0 0 0 2]}212213"""214if not isinstance(x,ChainComplexMorphism) or self._codomain != x._codomain or self._domain != x._domain or self._matrix_dictionary.keys() != x._matrix_dictionary.keys():215raise TypeError, "Unsupported operation."216f = dict()217for i in self._matrix_dictionary.keys():218f[i] = self._matrix_dictionary[i] + x._matrix_dictionary[i]219return ChainComplexMorphism(f,self._domain,self._codomain)220221def __mul__(self,x):222"""223Returns self*x if self and x are composable morphisms or if x is an element of the base_ring.224225EXAMPLES::226227sage: S = simplicial_complexes.Sphere(2)228sage: H = Hom(S,S)229sage: i = H.identity()230sage: x = i.associated_chain_complex_morphism()231sage: y = x*2232sage: y._matrix_dictionary233{0: [2 0 0 0]234[0 2 0 0]235[0 0 2 0]236[0 0 0 2],2371: [2 0 0 0 0 0]238[0 2 0 0 0 0]239[0 0 2 0 0 0]240[0 0 0 2 0 0]241[0 0 0 0 2 0]242[0 0 0 0 0 2],2432: [2 0 0 0]244[0 2 0 0]245[0 0 2 0]246[0 0 0 2]}247sage: z = y*y248sage: z._matrix_dictionary249{0: [4 0 0 0]250[0 4 0 0]251[0 0 4 0]252[0 0 0 4],2531: [4 0 0 0 0 0]254[0 4 0 0 0 0]255[0 0 4 0 0 0]256[0 0 0 4 0 0]257[0 0 0 0 4 0]258[0 0 0 0 0 4],2592: [4 0 0 0]260[0 4 0 0]261[0 0 4 0]262[0 0 0 4]}263264"""265if not isinstance(x,ChainComplexMorphism) or self._codomain != x._domain:266try:267y = self._domain.base_ring()(x)268except TypeError:269raise TypeError, "Multiplication is not defined."270f = dict()271for i in self._matrix_dictionary.keys():272f[i] = self._matrix_dictionary[i] * y273return ChainComplexMorphism(f,self._domain,self._codomain)274f = dict()275for i in self._matrix_dictionary.keys():276f[i] = x._matrix_dictionary[i]*self._matrix_dictionary[i]277return ChainComplexMorphism(f,self._domain,x._codomain)278279def __rmul__(self,x):280"""281Returns x*self if x is an element of the base_ring.282283EXAMPLES::284285sage: S = simplicial_complexes.Sphere(2)286sage: H = Hom(S,S)287sage: i = H.identity()288sage: x = i.associated_chain_complex_morphism()289sage: 2*x == x*2290True291sage: 3*x == x*2292False293"""294try:295y = self._domain.base_ring()(x)296except TypeError:297raise TypeError, "Multiplication is not defined."298f = dict()299for i in self._matrix_dictionary.keys():300f[i] = y * self._matrix_dictionary[i]301return ChainComplexMorphism(f,self._domain,self._codomain)302303def __sub__(self,x):304"""305Returns self-x.306307EXAMPLES::308309sage: S = simplicial_complexes.Sphere(2)310sage: H = Hom(S,S)311sage: i = H.identity()312sage: x = i.associated_chain_complex_morphism()313sage: y = x-x314sage: y._matrix_dictionary315{0: [0 0 0 0]316[0 0 0 0]317[0 0 0 0]318[0 0 0 0],3191: [0 0 0 0 0 0]320[0 0 0 0 0 0]321[0 0 0 0 0 0]322[0 0 0 0 0 0]323[0 0 0 0 0 0]324[0 0 0 0 0 0],3252: [0 0 0 0]326[0 0 0 0]327[0 0 0 0]328[0 0 0 0]}329330"""331return self + (-x)332333def __eq__(self,x):334"""335Returns True if and only if self==x.336337EXAMPLES::338339sage: S = SimplicialComplex(3)340sage: H = Hom(S,S)341sage: i = H.identity()342sage: x = i.associated_chain_complex_morphism()343sage: x344Chain complex morphism from Chain complex with at most 0 nonzero terms over Integer Ring to Chain complex with at most 0 nonzero terms over Integer Ring345sage: f = x._matrix_dictionary346sage: C = S.chain_complex()347sage: G = Hom(C,C)348sage: y = G(f)349sage: x==y350True351352"""353if not isinstance(x,ChainComplexMorphism) or self._codomain != x._codomain or self._domain != x._domain or self._matrix_dictionary != x._matrix_dictionary:354return False355else:356return True357358def _repr_(self):359"""360Returns the string representation of self.361362EXAMPLES::363364sage: S = SimplicialComplex(3)365sage: H = Hom(S,S)366sage: i = H.identity()367sage: x = i.associated_chain_complex_morphism()368sage: x369Chain complex morphism from Chain complex with at most 0 nonzero terms over Integer Ring to Chain complex with at most 0 nonzero terms over Integer Ring370sage: x._repr_()371'Chain complex morphism from Chain complex with at most 0 nonzero terms over Integer Ring to Chain complex with at most 0 nonzero terms over Integer Ring'372373"""374return "Chain complex morphism from " + self._domain._repr_() + " to " + self._codomain._repr_()375376377