Ticket #6099: 6099-merged.patch
File 6099-merged.patch, 52.7 KB (added by , 13 years ago) |
---|
-
doc/en/reference/homology.rst
# HG changeset patch # User Benjamin Antieau <antieau@math.uic.edu> # Date 1257542166 21600 # Node ID 6014c5979a5976c0228cfacd81318fca57884b53 # Parent f872a92f5f9afff4b4971afc82bf9270faec269b This is the hopefully final patch for ticket #6099, which implements morphisms of simplicial complexes. diff -r f872a92f5f9a -r 6014c5979a59 doc/en/reference/homology.rst
a b 8 8 :maxdepth: 2 9 9 10 10 sage/homology/simplicial_complex 11 sage/homology/simplicial_complex_morphism 12 sage/homology/simplicial_complex_homset 11 13 sage/homology/chain_complex 14 sage/homology/chain_complex_morphism 15 sage/homology/chain_complex_homset 12 16 sage/homology/examples -
sage/categories/category_types.py
diff -r f872a92f5f9a -r 6014c5979a59 sage/categories/category_types.py
a b 1293 1293 Objects : [Sets],\ 1294 1294 Sets : [],\ 1295 1295 GSets : [Sets],\ 1296 SimplicialComplexes : [Sets],\ 1296 1297 Semigroups : [Sets],\ 1297 1298 Monoids : [Semigroups, Sets],\ 1298 1299 Groups : [Monoids, Semigroups, Sets],\ … … 1310 1311 GroupAlgebras : [MonoidAlgebras, Algebras, Sets],\ 1311 1312 MatrixAlgebras : [Algebras, Sets],\ 1312 1313 RingModules : [AbelianGroups, Sets],\ 1314 ChainComplexes : [],\ 1313 1315 FreeModules : [RingModules, AbelianGroups, Sets],\ 1314 1316 VectorSpaces : [FreeModules, RingModules, AbelianGroups, Sets],\ 1315 1317 HeckeModules : [FreeModules, RingModules, AbelianGroups, Sets],\ -
sage/categories/homset.py
diff -r f872a92f5f9a -r 6014c5979a59 sage/categories/homset.py
a b 154 154 from sage.schemes.generic.homset import SchemeHomset 155 155 H = SchemeHomset(X, Y) 156 156 157 elif cat._is_subclass(category_types.SimplicialComplexes): 158 159 from sage.homology.simplicial_complex_homset import SimplicialComplexHomset 160 H = SimplicialComplexHomset(X,Y) 161 162 elif cat._is_subclass(category_types.ChainComplexes): 163 164 from sage.homology.chain_complex_homspace import ChainComplexHomspace 165 H = ChainComplexHomspace(X,Y) 166 167 168 157 169 else: # default 158 170 if hasattr(X, '_base') and X._base is not X and X._base is not None: 159 171 H = HomsetWithBase(X, Y, cat) -
sage/homology/all.py
diff -r f872a92f5f9a -r 6014c5979a59 sage/homology/all.py
a b 1 1 from chain_complex import ChainComplex 2 2 3 from chain_complex_morphism import ChainComplexMorphism 4 3 5 from simplicial_complex import SimplicialComplex 4 6 7 from simplicial_complex_morphism import SimplicialComplexMorphism 8 5 9 from examples import simplicial_complexes -
new file sage/homology/chain_complex_homspace.py
diff -r f872a92f5f9a -r 6014c5979a59 sage/homology/chain_complex_homspace.py
- + 1 r""" 2 Homspaces between chain complexes 3 4 Note that some significant functionality is lacking. Namely, the homspaces 5 are not actually modules over the base ring. It will be necessary to 6 enrich some of the structure of chain complexes for this to be naturally 7 available. On other hand, there are various overloaded operators. __mul__ 8 acts as composition. One can __add__, and one can __mul__ with a ring element 9 on the right. 10 11 EXAMPLES:: 12 13 sage: S = simplicial_complexes.Sphere(2) 14 sage: T = simplicial_complexes.Torus() 15 sage: C = S.chain_complex(augmented=True,cochain=True) 16 sage: D = T.chain_complex(augmented=True,cochain=True) 17 sage: G = Hom(C,D) 18 sage: G 19 Set of Morphisms from Chain complex with at most 4 nonzero terms over Integer Ring. to Chain complex with at most 4 nonzero terms over Integer Ring. in Category of chain complexes over Integer Ring 20 21 sage: S = simplicial_complexes.ChessboardComplex(3,3) 22 sage: H = Hom(S,S) 23 sage: i = H.identity() 24 sage: x = i.associated_chain_complex_morphism(augmented=True) 25 sage: x 26 Chain complex morphism from Chain complex with at most 4 nonzero terms over Integer Ring. to Chain complex with at most 4 nonzero terms over Integer Ring. 27 sage: x._matrix_dictionary 28 {0: [1 0 0 0 0 0 0 0 0] 29 [0 1 0 0 0 0 0 0 0] 30 [0 0 1 0 0 0 0 0 0] 31 [0 0 0 1 0 0 0 0 0] 32 [0 0 0 0 1 0 0 0 0] 33 [0 0 0 0 0 1 0 0 0] 34 [0 0 0 0 0 0 1 0 0] 35 [0 0 0 0 0 0 0 1 0] 36 [0 0 0 0 0 0 0 0 1], 1: [1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] 37 [0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] 38 [0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] 39 [0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0] 40 [0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0] 41 [0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0] 42 [0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0] 43 [0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0] 44 [0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0] 45 [0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0] 46 [0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0] 47 [0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0] 48 [0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0] 49 [0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0] 50 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0] 51 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0] 52 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0] 53 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1], 2: [1 0 0 0 0 0] 54 [0 1 0 0 0 0] 55 [0 0 1 0 0 0] 56 [0 0 0 1 0 0] 57 [0 0 0 0 1 0] 58 [0 0 0 0 0 1], -1: [1]} 59 60 sage: S = simplicial_complexes.Sphere(2) 61 sage: A = Hom(S,S) 62 sage: i = A.identity() 63 sage: x = i.associated_chain_complex_morphism() 64 sage: x 65 Chain complex morphism from Chain complex with at most 3 nonzero terms over Integer Ring. to Chain complex with at most 3 nonzero terms over Integer Ring. 66 sage: y = x*4 67 sage: z = y*y 68 sage: (y+z) 69 Chain complex morphism from Chain complex with at most 3 nonzero terms over Integer Ring. to Chain complex with at most 3 nonzero terms over Integer Ring. 70 sage: f = x._matrix_dictionary 71 sage: C = S.chain_complex() 72 sage: G = Hom(C,C) 73 sage: w = G(f) 74 sage: w==x 75 True 76 77 """ 78 79 #***************************************************************************** 80 # Copyright (C) 2009 D. Benjamin Antieau <d.ben.antieau@gmail.com> 81 # 82 # Distributed under the terms of the GNU General Public License (GPL) 83 # 84 # This code is distributed in the hope that it will be useful, 85 # but WITHOUT ANY WARRANTY; without even the implied warranty 86 # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 87 # 88 # See the GNU General Public License for more details; the full text 89 # is available at: 90 # 91 # http://www.gnu.org/licenses/ 92 # 93 #***************************************************************************** 94 95 import sage.categories.homset 96 import sage.homology.chain_complex as chain_complex 97 import sage.homology.chain_complex_morphism as chain_complex_morphism 98 99 def is_ChainComplexHomspace(x): 100 """ 101 Returns True if and only if x is a morphism of chain complexes. 102 103 EXAMPLES:: 104 105 sage: from sage.homology.chain_complex_homspace import is_ChainComplexHomspace 106 sage: T = SimplicialComplex(17,[[1,2,3,4],[7,8,9]]) 107 sage: C = T.chain_complex(augmented=True,cochain=True) 108 sage: G = Hom(C,C) 109 sage: is_ChainComplexHomspace(G) 110 True 111 112 """ 113 return isinstance(x,ChainComplexHomspace) 114 115 class ChainComplexHomspace(sage.categories.homset.Homset): 116 """ 117 Class of homspaces of chain complex morphisms. 118 119 EXAMPLES:: 120 121 sage: T = SimplicialComplex(17,[[1,2,3,4],[7,8,9]]) 122 sage: C = T.chain_complex(augmented=True,cochain=True) 123 sage: G = Hom(C,C) 124 sage: G 125 Set of Morphisms from Chain complex with at most 5 nonzero terms over Integer Ring. to Chain complex with at most 5 nonzero terms over Integer Ring. in Category of chain complexes over Integer Ring 126 127 """ 128 def __call__(self, f): 129 """ 130 f is a dictionary of matrices in the basis of the chain complex. 131 132 EXAMPLES:: 133 134 sage: S = simplicial_complexes.Sphere(5) 135 sage: H = Hom(S,S) 136 sage: i = H.identity() 137 sage: C = S.chain_complex() 138 sage: G = Hom(C,C) 139 sage: x = i.associated_chain_complex_morphism() 140 sage: f = x._matrix_dictionary 141 sage: y = G(f) 142 sage: x==y 143 True 144 145 """ 146 return chain_complex_morphism.ChainComplexMorphism(f, self.domain(), self.codomain()) -
new file sage/homology/chain_complex_morphism.py
diff -r f872a92f5f9a -r 6014c5979a59 sage/homology/chain_complex_morphism.py
- + 1 r""" 2 Morphisms of chain complexes 3 4 AUTHORS: 5 6 - Benjamin Antieau <d.ben.antieau@gmail.com> (2009.06) 7 8 This module implements morphisms of simplicial complexes. The input is a dictionary whose 9 keys are in the grading group of the chain complex and whose values are matrix morphisms. 10 11 EXAMPLES:: 12 13 from sage.matrix.constructor import zero_matrix 14 sage: S = simplicial_complexes.Sphere(1) 15 sage: S 16 Simplicial complex with vertex set (0, 1, 2) and facets {(1, 2), (0, 2), (0, 1)} 17 sage: C = S.chain_complex() 18 sage: C.differential() 19 {0: [], 1: [ 1 1 0] 20 [ 0 -1 -1] 21 [-1 0 1]} 22 sage: f = {0:zero_matrix(ZZ,3,3),1:zero_matrix(ZZ,3,3)} 23 sage: G = Hom(C,C) 24 sage: x = G(f) 25 sage: x 26 Chain 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 Ring. 27 sage: x._matrix_dictionary 28 {0: [0 0 0] 29 [0 0 0] 30 [0 0 0], 1: [0 0 0] 31 [0 0 0] 32 [0 0 0]} 33 34 """ 35 36 #***************************************************************************** 37 # Copyright (C) 2009 D. Benjamin Antieau <d.ben.antieau@gmail.com> 38 # 39 # Distributed under the terms of the GNU General Public License (GPL) 40 # 41 # This code is distributed in the hope that it will be useful, 42 # but WITHOUT ANY WARRANTY; without even the implied warranty 43 # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 44 # 45 # See the GNU General Public License for more details; the full text 46 # is available at: 47 # 48 # http://www.gnu.org/licenses/ 49 # 50 #***************************************************************************** 51 52 import sage.homology.simplicial_complex as simplicial_complex 53 import sage.matrix.all as matrix 54 import sage.categories.category_types as category_types 55 from sage.rings.integer_ring import ZZ 56 57 def is_ChainComplexMorphism(x): 58 """ 59 Returns True if and only if x is a chain complex morphism. 60 61 EXAMPLES:: 62 63 sage: from sage.homology.chain_complex_morphism import is_ChainComplexMorphism 64 sage: S = simplicial_complexes.Sphere(14) 65 sage: H = Hom(S,S) 66 sage: i = H.identity() 67 sage: S = simplicial_complexes.Sphere(6) 68 sage: H = Hom(S,S) 69 sage: i = H.identity() 70 sage: x = i.associated_chain_complex_morphism() 71 sage: x # indirect doctest 72 Chain 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 Ring. 73 sage: is_ChainComplexMorphism(x) 74 True 75 76 """ 77 return isinstance(x,ChainComplexMorphism) 78 79 class ChainComplexMorphism(category_types.SageObject): 80 """ 81 An element of this class is a morphism of chain complexes. 82 """ 83 def __init__(self,matrices,C,D): 84 """ 85 Create a morphism from a dictionary of matrices. 86 87 EXAMPLES:: 88 89 from sage.matrix.constructor import zero_matrix 90 sage: S = simplicial_complexes.Sphere(1) 91 sage: S 92 Simplicial complex with vertex set (0, 1, 2) and facets {(1, 2), (0, 2), (0, 1)} 93 sage: C = S.chain_complex() 94 sage: C.differential() 95 {0: [], 1: [ 1 1 0] 96 [ 0 -1 -1] 97 [-1 0 1]} 98 sage: f = {0:zero_matrix(ZZ,3,3),1:zero_matrix(ZZ,3,3)} 99 sage: G = Hom(C,C) 100 sage: x = G(f) 101 sage: x 102 Chain 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 Ring. 103 sage: x._matrix_dictionary 104 {0: [0 0 0] 105 [0 0 0] 106 [0 0 0], 1: [0 0 0] 107 [0 0 0] 108 [0 0 0]} 109 110 """ 111 if C._grading_group != ZZ: 112 raise NotImplementedError, "Chain complex morphisms are not implemented over gradings other than ZZ." 113 d = C._degree 114 if d != D._degree: 115 raise ValueError, "Chain complex morphisms are not defined for chain complexes of different degrees." 116 if d != -1 and d != 1: 117 raise NotImplementedError, "Chain complex morphisms are not implemented for degrees besides -1 and 1." 118 dim_min = min(min(C.differential().keys()),min(D.differential().keys())) 119 dim_max = max(max(C.differential().keys()),max(D.differential().keys())) 120 if not C.base_ring()==D.base_ring(): 121 raise NotImplementedError, "Chain complex morphisms between chain complexes of different base rings are not implemented." 122 for i in range(dim_min,dim_max): 123 try: 124 matrices[i] 125 except KeyError: 126 matrices[i] = matrix.zero_matrix(C.base_ring(),D.differential()[i].ncols(),C.differential()[i].ncols(),sparse=True) 127 try: 128 matrices[i+1] 129 except KeyError: 130 matrices[i+1] = matrix.zero_matrix(C.base_ring(),D.differential()[i+1].ncols(),C.differential()[i+1].ncols(),sparse=True) 131 if d==-1: 132 if (i+1) in C.differential().keys() and (i+1) in D.differential().keys(): 133 if not matrices[i]*C.differential()[i+1]==D.differential()[i+1]*matrices[i+1]: 134 raise ValueError, "Matrices must define a chain complex morphism." 135 elif (i+1) in C.differential().keys(): 136 if not matrices[i]*C.differential()[i+1].is_zero(): 137 raise ValueError, "Matrices must define a chain complex morphism." 138 elif (i+1) in D.differential().keys(): 139 if not D.differential()[i+1]*matrices[i+1].is_zero(): 140 raise ValueError, "Matrices must define a chain complex morphism." 141 else: 142 if i in C.differential().keys() and i in D.differential().keys(): 143 if not matrices[i+1]*C.differential()[i]==D.differential()[i]*matrices[i]: 144 raise ValueError, "Matrices must define a chain complex morphism." 145 elif i in C.differential().keys(): 146 if not matrices[i+1]*C.differential()[i].is_zero(): 147 raise ValueError, "Matrices must define a chain complex morphism." 148 elif i in D.differential().keys(): 149 if not D.differential()[i]*matrices[i].is_zero(): 150 raise ValueError, "Matrices must define a chain complex morphism." 151 self._matrix_dictionary = matrices 152 self._domain = C 153 self._codomain = D 154 155 def __neg__(self): 156 """ 157 Returns -x. 158 159 EXAMPLES:: 160 161 sage: S = simplicial_complexes.Sphere(2) 162 sage: H = Hom(S,S) 163 sage: i = H.identity() 164 sage: x = i.associated_chain_complex_morphism() 165 sage: w = -x 166 sage: w._matrix_dictionary 167 {0: [-1 0 0 0] 168 [ 0 -1 0 0] 169 [ 0 0 -1 0] 170 [ 0 0 0 -1], 171 1: [-1 0 0 0 0 0] 172 [ 0 -1 0 0 0 0] 173 [ 0 0 -1 0 0 0] 174 [ 0 0 0 -1 0 0] 175 [ 0 0 0 0 -1 0] 176 [ 0 0 0 0 0 -1], 177 2: [-1 0 0 0] 178 [ 0 -1 0 0] 179 [ 0 0 -1 0] 180 [ 0 0 0 -1]} 181 182 """ 183 f = dict() 184 for i in self._matrix_dictionary.keys(): 185 f[i] = -self._matrix_dictionary[i] 186 return ChainComplexMorphism(f,self._domain,self._codomain) 187 188 def __add__(self,x): 189 """ 190 Returns self+x. 191 192 EXAMPLES:: 193 194 sage: S = simplicial_complexes.Sphere(2) 195 sage: H = Hom(S,S) 196 sage: i = H.identity() 197 sage: x = i.associated_chain_complex_morphism() 198 sage: z = x+x 199 sage: z._matrix_dictionary 200 {0: [2 0 0 0] 201 [0 2 0 0] 202 [0 0 2 0] 203 [0 0 0 2], 204 1: [2 0 0 0 0 0] 205 [0 2 0 0 0 0] 206 [0 0 2 0 0 0] 207 [0 0 0 2 0 0] 208 [0 0 0 0 2 0] 209 [0 0 0 0 0 2], 210 2: [2 0 0 0] 211 [0 2 0 0] 212 [0 0 2 0] 213 [0 0 0 2]} 214 215 """ 216 if not isinstance(x,ChainComplexMorphism) or self._codomain != x._codomain or self._domain != x._domain or self._matrix_dictionary.keys() != x._matrix_dictionary.keys(): 217 raise TypeError, "Unsupported operation." 218 f = dict() 219 for i in self._matrix_dictionary.keys(): 220 f[i] = self._matrix_dictionary[i] + x._matrix_dictionary[i] 221 return ChainComplexMorphism(f,self._domain,self._codomain) 222 223 def __mul__(self,x): 224 """ 225 Returns self*x if self and x are composable morphisms or if x is an element of the base_ring. 226 227 EXAMPLES:: 228 sage: S = simplicial_complexes.Sphere(2) 229 sage: H = Hom(S,S) 230 sage: i = H.identity() 231 sage: x = i.associated_chain_complex_morphism() 232 sage: y = x*2 233 sage: y._matrix_dictionary 234 {0: [2 0 0 0] 235 [0 2 0 0] 236 [0 0 2 0] 237 [0 0 0 2], 238 1: [2 0 0 0 0 0] 239 [0 2 0 0 0 0] 240 [0 0 2 0 0 0] 241 [0 0 0 2 0 0] 242 [0 0 0 0 2 0] 243 [0 0 0 0 0 2], 244 2: [2 0 0 0] 245 [0 2 0 0] 246 [0 0 2 0] 247 [0 0 0 2]} 248 sage: z = y*y 249 sage: z._matrix_dictionary 250 {0: [4 0 0 0] 251 [0 4 0 0] 252 [0 0 4 0] 253 [0 0 0 4], 254 1: [4 0 0 0 0 0] 255 [0 4 0 0 0 0] 256 [0 0 4 0 0 0] 257 [0 0 0 4 0 0] 258 [0 0 0 0 4 0] 259 [0 0 0 0 0 4], 260 2: [4 0 0 0] 261 [0 4 0 0] 262 [0 0 4 0] 263 [0 0 0 4]} 264 265 """ 266 if not isinstance(x,ChainComplexMorphism) or self._codomain != x._domain: 267 try: 268 y = self._domain.base_ring()(x) 269 except TypeError: 270 raise TypeError, "Multiplication is not defined." 271 f = dict() 272 for i in self._matrix_dictionary.keys(): 273 f[i] = y * self._matrix_dictionary[i] 274 return ChainComplexMorphism(f,self._domain,self._codomain) 275 f = dict() 276 for i in self._matrix_dictionary.keys(): 277 f[i] = x._matrix_dictionary[i]*self._matrix_dictionary[i] 278 return ChainComplexMorphism(f,self._domain,x._codomain) 279 280 def __sub__(self,x): 281 """ 282 Returns self-x. 283 284 EXAMPLES:: 285 286 sage: S = simplicial_complexes.Sphere(2) 287 sage: H = Hom(S,S) 288 sage: i = H.identity() 289 sage: x = i.associated_chain_complex_morphism() 290 sage: y = x-x 291 sage: y._matrix_dictionary 292 {0: [0 0 0 0] 293 [0 0 0 0] 294 [0 0 0 0] 295 [0 0 0 0], 296 1: [0 0 0 0 0 0] 297 [0 0 0 0 0 0] 298 [0 0 0 0 0 0] 299 [0 0 0 0 0 0] 300 [0 0 0 0 0 0] 301 [0 0 0 0 0 0], 302 2: [0 0 0 0] 303 [0 0 0 0] 304 [0 0 0 0] 305 [0 0 0 0]} 306 307 """ 308 return self + (-x) 309 310 def __eq__(self,x): 311 """ 312 Returns True if and only if self==x. 313 314 EXAMPLES:: 315 316 sage: S = SimplicialComplex(3) 317 sage: H = Hom(S,S) 318 sage: i = H.identity() 319 sage: x = i.associated_chain_complex_morphism() 320 sage: x 321 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. 322 sage: f = x._matrix_dictionary 323 sage: C = S.chain_complex() 324 sage: G = Hom(C,C) 325 sage: y = G(f) 326 sage: x==y 327 True 328 329 """ 330 if not isinstance(x,ChainComplexMorphism) or self._codomain != x._codomain or self._domain != x._domain or self._matrix_dictionary != x._matrix_dictionary: 331 return False 332 else: 333 return True 334 335 def _repr_(self): 336 """ 337 Returns the string representation of self. 338 339 EXAMPLES:: 340 341 sage: S = SimplicialComplex(3) 342 sage: H = Hom(S,S) 343 sage: i = H.identity() 344 sage: x = i.associated_chain_complex_morphism() 345 sage: x 346 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. 347 sage: x._repr_() 348 '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.' 349 350 """ 351 return "Chain complex morphism from " + self._domain._repr_() + " to " + self._codomain._repr_() -
sage/homology/simplicial_complex.py
diff -r f872a92f5f9a -r 6014c5979a59 sage/homology/simplicial_complex.py
a b 1662 1662 faces.append(Simplex(list(f.set().difference(s.set())))) 1663 1663 return SimplicialComplex(self.vertices(), faces) 1664 1664 1665 def effective_vertices(self): 1666 """ 1667 The set of vertices belonging to some face. Returns a Simplex. 1668 1669 EXAMPLES:: 1670 1671 sage: S = SimplicialComplex(15) 1672 sage: S 1673 Simplicial complex with 16 vertices and facets {()} 1674 sage: S.effective_vertices() 1675 () 1676 1677 sage: S = SimplicialComplex(15,[[0,1,2,3],[6,7]]) 1678 sage: S 1679 Simplicial complex with 16 vertices and facets {(6, 7), (0, 1, 2, 3)} 1680 sage: S.effective_vertices() 1681 (0, 1, 2, 3, 6, 7) 1682 1683 sage: type(S.effective_vertices()) 1684 <class 'sage.homology.simplicial_complex.Simplex'> 1685 1686 """ 1687 try: 1688 v = self.faces()[0] 1689 except KeyError: 1690 return Simplex(-1) 1691 f = [] 1692 for i in v: 1693 f.append(i[0]) 1694 return Simplex(set(f)) 1695 1696 1697 def generated_subcomplex(self,sub_vertex_set): 1698 """ 1699 Returns the largest sub SimplicialComplex of self containing exactly the sub_vertex_set as vertices. 1700 1701 EXAMPLES:: 1702 1703 sage: S = simplicial_complexes.Sphere(2) 1704 sage: S 1705 Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 2, 3), (0, 1, 2), (1, 2, 3), (0, 1, 3)} 1706 sage: S.generated_subcomplex([0,1,2]) 1707 Simplicial complex with vertex set (0, 1, 2) and facets {(0, 1, 2)} 1708 1709 """ 1710 if not self.vertices().set().issuperset(sub_vertex_set): 1711 raise TypeError, "input must be a subset of the vertex set." 1712 faces = [] 1713 for i in range(self.dimension()+1): 1714 for j in self.faces()[i]: 1715 if j.set().issubset(sub_vertex_set): 1716 faces.append(j) 1717 return SimplicialComplex(sub_vertex_set,faces,maximality_check=True) 1718 1665 1719 def _complement(self, simplex): 1666 1720 """ 1667 1721 Return the complement of a simplex in the vertex set of this -
new file sage/homology/simplicial_complex_homset.py
diff -r f872a92f5f9a -r 6014c5979a59 sage/homology/simplicial_complex_homset.py
- + 1 r""" 2 Homsets between simplicial complexes 3 4 EXAMPLES: 5 6 :: 7 8 sage: S = simplicial_complexes.Sphere(1) 9 sage: T = simplicial_complexes.Sphere(2) 10 sage: H = Hom(S,T) 11 sage: from sage.homology.simplicial_complex import Simplex 12 sage: f = {0:0,1:1,2:3} 13 sage: x = H(f) 14 sage: x 15 Simplicial complex morphism {0: 0, 1: 1, 2: 3} from Simplicial complex with vertex set (0, 1, 2) and facets {(1, 2), (0, 2), (0, 1)} to Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 2, 3), (0, 1, 2), (1, 2, 3), (0, 1, 3)} 16 sage: x.is_injective() 17 True 18 sage: x.is_surjective() 19 False 20 sage: x.image() 21 Simplicial complex with vertex set (0, 1, 3) and facets {(1, 3), (0, 3), (0, 1)} 22 sage: s = Simplex([1,2]) 23 sage: x(s) 24 (1, 3) 25 26 TESTS:: 27 28 sage: S = simplicial_complexes.Sphere(1) 29 sage: T = simplicial_complexes.Sphere(2) 30 sage: H = Hom(S,T) 31 sage: loads(dumps(H))==H 32 True 33 34 """ 35 36 #***************************************************************************** 37 # Copyright (C) 2009 D. Benjamin Antieau <d.ben.antieau@gmail.com> 38 # 39 # Distributed under the terms of the GNU General Public License (GPL) 40 # 41 # This code is distributed in the hope that it will be useful, 42 # but WITHOUT ANY WARRANTY; without even the implied warranty 43 # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 44 # 45 # See the GNU General Public License for more details; the full text 46 # is available at: 47 # 48 # http://www.gnu.org/licenses/ 49 # 50 #***************************************************************************** 51 52 import sage.categories.homset 53 import sage.homology.simplicial_complex as simplicial_complex 54 import sage.homology.simplicial_complex_morphism as simplicial_complex_morphism 55 56 def is_SimplicialComplexHomset(x): 57 """ 58 Return True if and only if x is a simplicial complex homspace. 59 60 EXAMPLES:: 61 62 sage: H = Hom(SimplicialComplex(2),SimplicialComplex(3)) 63 sage: H 64 Set of Morphisms from Simplicial complex with vertex set (0, 1, 2) and facets {()} to Simplicial complex with vertex set (0, 1, 2, 3) and facets {()} in Category of simplicial complexes 65 sage: from sage.homology.simplicial_complex_homset import is_SimplicialComplexHomset 66 sage: is_SimplicialComplexHomset(H) 67 True 68 """ 69 return isinstance(x, SimplicialComplexHomset) 70 71 class SimplicialComplexHomset(sage.categories.homset.Homset): 72 def __call__(self, f): 73 """ 74 INPUT: 75 f -- a dictionary with keys exactly the vertices of the domain and values vertices of the codomain 76 77 EXAMPLE:: 78 79 sage: S = simplicial_complexes.Sphere(3) 80 sage: T = simplicial_complexes.Sphere(2) 81 sage: f = {0:0,1:1,2:2,3:2,4:2} 82 sage: H = Hom(S,T) 83 sage: x = H(f) 84 sage: x 85 Simplicial complex morphism {0: 0, 1: 1, 2: 2, 3: 2, 4: 2} from Simplicial complex with vertex set (0, 1, 2, 3, 4) and 5 facets to Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 2, 3), (0, 1, 2), (1, 2, 3), (0, 1, 3)} 86 87 88 """ 89 return simplicial_complex_morphism.SimplicialComplexMorphism(f,self.domain(),self.codomain()) 90 91 def diagonal_morphism(self,rename_vertices=True): 92 """ 93 Returns the diagonal morphism in Hom(S,SxS). 94 95 EXAMPLES:: 96 97 sage: S = simplicial_complexes.Sphere(2) 98 sage: H = Hom(S,S.product(S)) 99 sage: d = H.diagonal_morphism() 100 sage: d 101 Simplicial complex morphism {0: 'L0R0', 1: 'L1R1', 2: 'L2R2', 3: 'L3R3'} from Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 2, 3), (0, 1, 2), (1, 2, 3), (0, 1, 3)} to Simplicial complex with 16 vertices and 96 facets 102 103 sage: T = SimplicialComplex(3) 104 sage: U = T.product(T,rename_vertices = False) 105 sage: G = Hom(T,U) 106 sage: e = G.diagonal_morphism(rename_vertices = False) 107 sage: e 108 Simplicial complex morphism {0: (0, 0), 1: (1, 1), 2: (2, 2), 3: (3, 3)} from Simplicial complex with vertex set (0, 1, 2, 3) and facets {()} to Simplicial complex with 16 vertices and facets {()} 109 110 """ 111 112 if self._codomain == self._domain.product(self._domain,rename_vertices=rename_vertices): 113 X = self._domain.product(self._domain,rename_vertices=rename_vertices) 114 f = dict() 115 if rename_vertices: 116 for i in self._domain.vertices().set(): 117 f[i] = "L"+str(i)+"R"+str(i) 118 else: 119 for i in self._domain.vertices().set(): 120 f[i] = (i,i) 121 return simplicial_complex_morphism.SimplicialComplexMorphism(f,self._domain,X) 122 else: 123 raise TypeError, "Diagonal morphism is only defined for Hom(X,XxX)." 124 125 def identity(self): 126 """ 127 Returns the identity morphism of Hom(S,S). 128 129 EXAMPLES:: 130 131 sage: S = simplicial_complexes.Sphere(2) 132 sage: H = Hom(S,S) 133 sage: i = H.identity() 134 sage: i.is_identity() 135 True 136 137 sage: T = SimplicialComplex(3,[[0,1]]) 138 sage: G = Hom(T,T) 139 sage: G.identity() 140 Simplicial complex morphism {0: 0, 1: 1, 2: 2, 3: 3} from Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 1)} to Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 1)} 141 142 """ 143 if self.is_endomorphism_set(): 144 f = dict() 145 for i in self._domain.vertices().set(): 146 f[i]=i 147 return simplicial_complex_morphism.SimplicialComplexMorphism(f,self._domain,self._codomain) 148 else: 149 raise TypeError, "Identity map is only defined for endomorphism sets." 150 151 def an_element(self): 152 """ 153 Returns a (non-random) element of self. 154 155 EXAMPLES:: 156 157 sage: S = simplicial_complexes.KleinBottle() 158 sage: T = simplicial_complexes.Sphere(5) 159 sage: H = Hom(S,T) 160 sage: x = H.an_element() 161 sage: x 162 Simplicial complex morphism {0: 0, 1: 0, 2: 0, 'R3': 0, 'L4': 0, 'L5': 0, 'L3': 0, 'R5': 0, 'R4': 0} from Simplicial complex with 9 vertices and 18 facets to Simplicial complex with vertex set (0, 1, 2, 3, 4, 5, 6) and 7 facets 163 164 """ 165 X_vertices = self._domain.vertices().set() 166 try: 167 i = self._codomain.vertices().set().__iter__().next() 168 except StopIteration: 169 if len(X_vertices) == 0: 170 return dict() 171 else: 172 raise TypeError, "There are no morphisms from a non-empty simplicial complex to an empty simplicial comples." 173 f = dict() 174 for x in X_vertices: 175 f[x]=i 176 return simplicial_complex_morphism.SimplicialComplexMorphism(f,self._domain,self._codomain) -
new file sage/homology/simplicial_complex_morphism.py
diff -r f872a92f5f9a -r 6014c5979a59 sage/homology/simplicial_complex_morphism.py
- + 1 r""" 2 Morphisms of simplicial complexes 3 4 AUTHORS: 5 6 - Benjamin Antieau <d.ben.antieau@gmail.com> (2009.06) 7 8 This module implements morphisms of simplicial complexes. The input is given 9 by a dictionary on the vertex set or the effective vertex set of a simplicial complex. 10 The initialization checks that faces are sent to faces. 11 12 There is also the capability to create the fiber product of two morphisms with the same codomain. 13 14 EXAMPLES:: 15 16 sage: S = SimplicialComplex(5,[[0,2],[1,5],[3,4]]) 17 sage: H = Hom(S,S.product(S)) 18 sage: H.diagonal_morphism() 19 Simplicial complex morphism {0: 'L0R0', 1: 'L1R1', 2: 'L2R2', 3: 'L3R3', 4: 'L4R4', 5: 'L5R5'} from Simplicial complex with vertex set (0, 1, 2, 3, 4, 5) and facets {(3, 4), (1, 5), (0, 2)} to Simplicial complex with 36 vertices and 18 facets 20 21 sage: S = SimplicialComplex(5,[[0,2],[1,5],[3,4]]) 22 sage: T = SimplicialComplex(4,[[0,2],[1,3]]) 23 sage: f = {0:0,1:1,2:2,3:1,4:3,5:3} 24 sage: H = Hom(S,T) 25 sage: x = H(f) 26 sage: x.image() 27 Simplicial complex with vertex set (0, 1, 2, 3) and facets {(1, 3), (0, 2)} 28 sage: x.is_surjective() 29 False 30 sage: x.is_injective() 31 False 32 sage: x.is_identity() 33 False 34 35 sage: S = simplicial_complexes.Sphere(2) 36 sage: H = Hom(S,S) 37 sage: i = H.identity() 38 sage: i.image() 39 Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 2, 3), (0, 1, 2), (1, 2, 3), (0, 1, 3)} 40 sage: i.is_surjective() 41 True 42 sage: i.is_injective() 43 True 44 sage: i.is_identity() 45 True 46 47 sage: S = simplicial_complexes.Sphere(2) 48 sage: H = Hom(S,S) 49 sage: i = H.identity() 50 sage: j = i.fiber_product(i) 51 sage: j 52 Simplicial complex morphism {'L1R1': 1, 'L3R3': 3, 'L2R2': 2, 'L0R0': 0} from Simplicial complex with 4 vertices and 4 facets to Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 2, 3), (0, 1, 2), (1, 2, 3), (0, 1, 3)} 53 54 sage: S = simplicial_complexes.Sphere(2) 55 sage: T = S.product(SimplicialComplex(1,[[0,1]]),rename_vertices = False) 56 sage: H = Hom(T,S) 57 sage: T 58 Simplicial complex with 8 vertices and 12 facets 59 sage: T.vertices() 60 ((0, 0), (0, 1), (1, 0), (1, 1), (2, 0), (2, 1), (3, 0), (3, 1)) 61 sage: f = {(0, 0): 0, (0, 1): 0, (1, 0): 1, (1, 1): 1, (2, 0): 2, (2, 1): 2, (3, 0): 3, (3, 1): 3} 62 sage: x = H(f) 63 sage: U = simplicial_complexes.Sphere(1) 64 sage: G = Hom(U,S) 65 sage: U 66 Simplicial complex with vertex set (0, 1, 2) and facets {(1, 2), (0, 2), (0, 1)} 67 sage: g = {0:0,1:1,2:2} 68 sage: y = G(g) 69 sage: z = y.fiber_product(x) 70 sage: z # this is the mapping path space 71 Simplicial complex morphism {'L2R(2, 0)': 2, 'L2R(2, 1)': 2, 'L0R(0, 0)': 0, 'L0R(0, 1)': 0, 'L1R(1, 0)': 1, 'L1R(1, 1)': 1} from Simplicial complex with 6 vertices and 6 facets to Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 2, 3), (0, 1, 2), (1, 2, 3), (0, 1, 3)} 72 73 74 """ 75 76 #***************************************************************************** 77 # Copyright (C) 2009 D. Benjamin Antieau <d.ben.antieau@gmail.com> 78 # 79 # Distributed under the terms of the GNU General Public License (GPL) 80 # 81 # This code is distributed in the hope that it will be useful, 82 # but WITHOUT ANY WARRANTY; without even the implied warranty 83 # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 84 # 85 # See the GNU General Public License for more details; the full text 86 # is available at: 87 # 88 # http://www.gnu.org/licenses/ 89 # 90 #***************************************************************************** 91 92 import sage.homology.simplicial_complex as simplicial_complex 93 import sage.matrix.all as matrix 94 import sage.categories.category_types as category_types 95 from sage.rings.integer_ring import ZZ 96 from sage.homology.chain_complex_morphism import ChainComplexMorphism 97 98 def is_SimplicialComplexMorphism(x): 99 """ 100 Returns True if and only if x is a morphism of simplicial complexes. 101 102 EXAMPLES:: 103 104 sage: from sage.homology.simplicial_complex_morphism import is_SimplicialComplexMorphism 105 sage: S = SimplicialComplex(5,[[0,1],[3,4]]) 106 sage: H = Hom(S,S) 107 sage: f = {0:0,1:1,2:2,3:3,4:4,5:5} 108 sage: x = H(f) 109 sage: is_SimplicialComplexMorphism(x) 110 True 111 112 """ 113 return isinstance(x,SimplicialComplexMorphism) 114 115 class SimplicialComplexMorphism(category_types.SageObject): 116 """ 117 An element of this class is a morphism of simplicial complexes. 118 """ 119 def __init__(self,f,X,Y): 120 """ 121 Input is a dictionary f, the domain, and the codomain. 122 123 One can define the dictionary either on the vertices of X or on the effective vertices of X (X.effective_vertices()). Note that this 124 difference does matter. For instance, it changes the result of the image method, and hence it changes the result of the is_surjective method as well. 125 This is because two SimplicialComplexes with the same faces but different vertex sets are not equal. 126 127 EXAMPLES:: 128 129 sage: S = SimplicialComplex(5,[[0,1],[3,4]]) 130 sage: H = Hom(S,S) 131 sage: f = {0:0,1:1,2:2,3:3,4:4,5:5} 132 sage: g = {0:0,1:1,3:3,4:4} 133 sage: x = H(f) 134 sage: y = H(g) 135 sage: x==y 136 False 137 sage: x.image() 138 Simplicial complex with vertex set (0, 1, 2, 3, 4, 5) and facets {(3, 4), (0, 1)} 139 sage: y.image() 140 Simplicial complex with vertex set (0, 1, 3, 4) and facets {(3, 4), (0, 1)} 141 sage: x.image()==y.image() 142 False 143 144 """ 145 if not isinstance(X,simplicial_complex.SimplicialComplex) or not isinstance(Y,simplicial_complex.SimplicialComplex): 146 raise ValueError, "X and Y must be SimplicialComplexes." 147 if not set(f.keys())==X._vertex_set.set() and not set(f.keys())==X.effective_vertices().set(): 148 raise ValueError, "f must be a dictionary from the vertex set of X to single values in the vertex set of Y." 149 dim = X.dimension() 150 Y_faces = Y.faces() 151 for k in range(dim+1): 152 for i in X.faces()[k]: 153 tup = i.tuple() 154 fi = [] 155 for j in tup: 156 fi.append(f[j]) 157 v = simplicial_complex.Simplex(set(fi)) 158 if not v in Y_faces[v.dimension()]: 159 raise ValueError, "f must be a dictionary from the vertices of X to the vertices of Y." 160 self._vertex_dictionary = f 161 self._domain = X 162 self._codomain = Y 163 164 def __eq__(self,x): 165 """ 166 Returns True if and only if self == x. 167 168 EXAMPLES:: 169 170 sage: S = simplicial_complexes.Sphere(2) 171 sage: H = Hom(S,S) 172 sage: i = H.identity() 173 sage: i 174 Simplicial complex morphism {0: 0, 1: 1, 2: 2, 3: 3} from Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 2, 3), (0, 1, 2), (1, 2, 3), (0, 1, 3)} to Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 2, 3), (0, 1, 2), (1, 2, 3), (0, 1, 3)} 175 sage: f = {0:0,1:1,2:2,3:2} 176 sage: j = H(f) 177 sage: i==j 178 False 179 180 sage: T = SimplicialComplex(3,[[1,2]]) 181 sage: T 182 Simplicial complex with vertex set (0, 1, 2, 3) and facets {(1, 2)} 183 sage: G = Hom(T,T) 184 sage: k = G.identity() 185 sage: g = {0:0,1:1,2:2,3:3} 186 sage: l = G(g) 187 sage: k==l 188 True 189 190 """ 191 if not isinstance(x,SimplicialComplexMorphism) or self._codomain != x._codomain or self._domain != x._domain or self._vertex_dictionary != x._vertex_dictionary: 192 return False 193 else: 194 return True 195 196 def __call__(self,x): 197 """ 198 Input is a simplex of the domain. Output is the image simplex. 199 200 EXAMPLES:: 201 202 sage: S = simplicial_complexes.Sphere(2) 203 sage: T = simplicial_complexes.Sphere(3) 204 sage: S 205 Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 2, 3), (0, 1, 2), (1, 2, 3), (0, 1, 3)} 206 sage: T 207 Simplicial complex with vertex set (0, 1, 2, 3, 4) and 5 facets 208 sage: f = {0:0,1:1,2:2,3:3} 209 sage: H = Hom(S,T) 210 sage: x = H(f) 211 sage: from sage.homology.simplicial_complex import Simplex 212 sage: x(Simplex([0,2,3])) 213 (0, 2, 3) 214 215 """ 216 dim = self._domain.dimension() 217 if not isinstance(x,simplicial_complex.Simplex) or x.dimension() > dim or not x in self._domain.faces()[x.dimension()]: 218 raise ValueError, "x must be a simplex of the source of f" 219 tup=x.tuple() 220 fx=[] 221 for j in tup: 222 fx.append(self._vertex_dictionary[j]) 223 return simplicial_complex.Simplex(set(fx)) 224 225 def _repr_(self): 226 """ 227 Print representation 228 229 EXAMPLES:: 230 231 sage: S = simplicial_complexes.Sphere(2) 232 sage: H = Hom(S,S) 233 sage: i = H.identity() 234 sage: i 235 Simplicial complex morphism {0: 0, 1: 1, 2: 2, 3: 3} from Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 2, 3), (0, 1, 2), (1, 2, 3), (0, 1, 3)} to Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 2, 3), (0, 1, 2), (1, 2, 3), (0, 1, 3)} 236 sage: i._repr_() 237 'Simplicial complex morphism {0: 0, 1: 1, 2: 2, 3: 3} from Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 2, 3), (0, 1, 2), (1, 2, 3), (0, 1, 3)} to Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 2, 3), (0, 1, 2), (1, 2, 3), (0, 1, 3)}' 238 239 240 """ 241 return "Simplicial complex morphism " + str(self._vertex_dictionary) + " from " + self._domain._repr_() + " to " + self._codomain._repr_() 242 243 def associated_chain_complex_morphism(self,base_ring=ZZ,augmented=False,cochain=False): 244 """ 245 Returns the associated chain complex morphism of self. 246 247 EXAMPLES:: 248 249 sage: S = simplicial_complexes.Sphere(1) 250 sage: T = simplicial_complexes.Sphere(2) 251 sage: H = Hom(S,T) 252 sage: f = {0:0,1:1,2:2} 253 sage: x = H(f) 254 sage: x 255 Simplicial complex morphism {0: 0, 1: 1, 2: 2} from Simplicial complex with vertex set (0, 1, 2) and facets {(1, 2), (0, 2), (0, 1)} to Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 2, 3), (0, 1, 2), (1, 2, 3), (0, 1, 3)} 256 sage: a = x.associated_chain_complex_morphism() 257 sage: a 258 Chain complex morphism from Chain complex with at most 2 nonzero terms over Integer Ring. to Chain complex with at most 3 nonzero terms over Integer Ring. 259 sage: a._matrix_dictionary 260 {0: [0 0 0] 261 [0 1 0] 262 [0 0 1] 263 [1 0 0], 264 1: [0 0 0] 265 [0 1 0] 266 [0 0 0] 267 [1 0 0] 268 [0 0 0] 269 [0 0 1], 270 2: []} 271 sage: x.associated_chain_complex_morphism(augmented=True) 272 Chain complex morphism from Chain complex with at most 3 nonzero terms over Integer Ring. to Chain complex with at most 4 nonzero terms over Integer Ring. 273 sage: x.associated_chain_complex_morphism(cochain=True) 274 Chain complex morphism from Chain complex with at most 3 nonzero terms over Integer Ring. to Chain complex with at most 2 nonzero terms over Integer Ring. 275 sage: x.associated_chain_complex_morphism(augmented=True,cochain=True) 276 Chain complex morphism from Chain complex with at most 4 nonzero terms over Integer Ring. to Chain complex with at most 3 nonzero terms over Integer Ring. 277 sage: x.associated_chain_complex_morphism(base_ring=GF(11)) 278 Chain complex morphism from Chain complex with at most 2 nonzero terms over Finite Field of size 11. to Chain complex with at most 3 nonzero terms over Finite Field of size 11. 279 280 """ 281 max_dim = max(self._domain.dimension(),self._codomain.dimension()) 282 min_dim = min(self._domain.dimension(),self._codomain.dimension()) 283 matrices = {} 284 if augmented is True: 285 m = matrix.Matrix(base_ring,1,1,1) 286 if not cochain: 287 matrices[-1] = m 288 else: 289 matrices[-1] = m.transpose() 290 for dim in range(min_dim+1): 291 X_faces = list(self._domain.faces()[dim]) 292 Y_faces = list(self._codomain.faces()[dim]) 293 num_faces_X = len(X_faces) 294 num_faces_Y = len(Y_faces) 295 mval = [0 for i in range(num_faces_X*num_faces_Y)] 296 for i in X_faces: 297 y = self(i) 298 if y.dimension() < dim: 299 pass 300 else: 301 mval[X_faces.index(i)+(Y_faces.index(y)*num_faces_X)] = 1 302 m = matrix.Matrix(base_ring,num_faces_Y,num_faces_X,mval,sparse=True) 303 if not cochain: 304 matrices[dim] = m 305 else: 306 matrices[dim] = m.transpose() 307 for dim in range(min_dim+1,max_dim+1): 308 try: 309 l1 = len(self._codomain.faces()[dim]) 310 except KeyError: 311 l1 = 0 312 try: 313 l2 = len(self._domain.faces()[dim]) 314 except KeyError: 315 l2 = 0 316 m = matrix.zero_matrix(base_ring,l1,l2,sparse=True) 317 if not cochain: 318 matrices[dim] = m 319 else: 320 matrices[dim] = m.transpose() 321 if not cochain: 322 return ChainComplexMorphism(matrices,\ 323 self._domain.chain_complex(base_ring=base_ring,augmented=augmented,cochain=cochain),\ 324 self._codomain.chain_complex(base_ring=base_ring,augmented=augmented,cochain=cochain)) 325 else: 326 return ChainComplexMorphism(matrices,\ 327 self._codomain.chain_complex(base_ring=base_ring,augmented=augmented,cochain=cochain),\ 328 self._domain.chain_complex(base_ring=base_ring,augmented=augmented,cochain=cochain)) 329 330 def image(self): 331 """ 332 Computes the image simplicial complex of f. 333 334 EXAMPLES:: 335 336 sage: S = SimplicialComplex(3,[[0,1],[2,3]]) 337 sage: T = SimplicialComplex(1,[[0,1]]) 338 sage: f = {0:0,1:1,2:0,3:1} 339 sage: H = Hom(S,T) 340 sage: x = H(f) 341 sage: x.image() 342 Simplicial complex with vertex set (0, 1) and facets {(0, 1)} 343 344 sage: S = SimplicialComplex(2) 345 sage: H = Hom(S,S) 346 sage: i = H.identity() 347 sage: i.image() 348 Simplicial complex with vertex set (0, 1, 2) and facets {()} 349 sage: i.is_surjective() 350 True 351 sage: S = SimplicialComplex(5,[[0,1]]) 352 sage: T = SimplicialComplex(3,[[0,1]]) 353 sage: f = {0:0,1:1} 354 sage: g = {0:0,1:1,2:2,3:3,4:4,5:5} 355 sage: H = Hom(S,T) 356 sage: x = H(f) 357 sage: y = H(g) 358 sage: x == y 359 False 360 sage: x.image() 361 Simplicial complex with vertex set (0, 1) and facets {(0, 1)} 362 sage: y.image() 363 Simplicial complex with vertex set (0, 1, 2, 3, 4, 5) and facets {(0, 1)} 364 365 """ 366 fa = [self(i) for i in self._domain.facets()] 367 return simplicial_complex.SimplicialComplex(set(self._vertex_dictionary.values()),fa,maximality_check=True) 368 369 def domain(self): 370 """ 371 Returns the domain of the morphism. 372 373 EXAMPLES:: 374 375 sage: S = SimplicialComplex(3,[[0,1],[2,3]]) 376 sage: T = SimplicialComplex(1,[[0,1]]) 377 sage: f = {0:0,1:1,2:0,3:1} 378 sage: H = Hom(S,T) 379 sage: x = H(f) 380 sage: x.domain() 381 Simplicial complex with vertex set (0, 1, 2, 3) and facets {(2, 3), (0, 1)} 382 383 """ 384 return self._domain 385 386 def codomain(self): 387 """ 388 Returns the codomain of the morphism. 389 390 EXAMPLES:: 391 392 sage: S = SimplicialComplex(3,[[0,1],[2,3]]) 393 sage: T = SimplicialComplex(1,[[0,1]]) 394 sage: f = {0:0,1:1,2:0,3:1} 395 sage: H = Hom(S,T) 396 sage: x = H(f) 397 sage: x.codomain() 398 Simplicial complex with vertex set (0, 1) and facets {(0, 1)} 399 400 """ 401 return self._codomain 402 403 def is_surjective(self): 404 """ 405 Returns True if and only if self is surjective. 406 407 EXAMPLES:: 408 409 sage: S = SimplicialComplex(3,[(0,1,2)]) 410 sage: S 411 Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 1, 2)} 412 sage: T = SimplicialComplex(2,[(0,1)]) 413 sage: T 414 Simplicial complex with vertex set (0, 1, 2) and facets {(0, 1)} 415 sage: H = Hom(S,T) 416 sage: x = H({0:0,1:1,2:1,3:2}) 417 sage: x.is_surjective() 418 True 419 420 sage: S = SimplicialComplex(3,[[0,1],[2,3]]) 421 sage: T = SimplicialComplex(1,[[0,1]]) 422 sage: f = {0:0,1:1,2:0,3:1} 423 sage: H = Hom(S,T) 424 sage: x = H(f) 425 sage: x.is_surjective() 426 True 427 428 """ 429 return self._codomain == self.image() 430 431 def is_injective(self): 432 """ 433 Returns True if and only if self is injective. 434 435 EXAMPLES:: 436 437 sage: S = simplicial_complexes.Sphere(1) 438 sage: T = simplicial_complexes.Sphere(2) 439 sage: U = simplicial_complexes.Sphere(3) 440 sage: H = Hom(T,S) 441 sage: G = Hom(T,U) 442 sage: f = {0:0,1:1,2:0,3:1} 443 sage: x = H(f) 444 sage: g = {0:0,1:1,2:2,3:3} 445 sage: y = G(g) 446 sage: x.is_injective() 447 False 448 sage: y.is_injective() 449 True 450 451 """ 452 v = [self._vertex_dictionary[i[0]] for i in self._domain.faces()[0]] 453 for i in v: 454 if v.count(i) > 1: 455 return False 456 return True 457 458 def is_identity(self): 459 """ 460 If x is an identity morphism, returns True. Otherwise, False. 461 462 EXAMPLES:: 463 464 sage: T = simplicial_complexes.Sphere(1) 465 sage: G = Hom(T,T) 466 sage: T 467 Simplicial complex with vertex set (0, 1, 2) and facets {(1, 2), (0, 2), (0, 1)} 468 sage: j = G({0:0,1:1,2:2}) 469 sage: j.is_identity() 470 True 471 472 sage: S = simplicial_complexes.Sphere(2) 473 sage: T = simplicial_complexes.Sphere(3) 474 sage: H = Hom(S,T) 475 sage: f = {0:0,1:1,2:2,3:3} 476 sage: x = H(f) 477 sage: x 478 Simplicial complex morphism {0: 0, 1: 1, 2: 2, 3: 3} from Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 2, 3), (0, 1, 2), (1, 2, 3), (0, 1, 3)} to Simplicial complex with vertex set (0, 1, 2, 3, 4) and 5 facets 479 sage: x.is_identity() 480 False 481 482 """ 483 if self._domain != self._codomain: 484 return False 485 else: 486 f = dict() 487 for i in self._domain.vertices().set(): 488 f[i] = i 489 if self._vertex_dictionary != f: 490 return False 491 else: 492 return True 493 494 def fiber_product(self,other,rename_vertices = True): 495 """ 496 Fiber product of self and other. Both morphisms should have the same codomain. The method returns a morphism of simplicial complexes, which 497 is the morphism from the space of the fiber product to the codomain. 498 499 EXAMPLES:: 500 501 sage: S = SimplicialComplex(2,[[0,1],[1,2]]) 502 sage: T = SimplicialComplex(2,[[0,2]]) 503 sage: U = SimplicialComplex(1,[[0,1]]) 504 sage: H = Hom(S,U) 505 sage: G = Hom(T,U) 506 sage: f = {0:0,1:1,2:0} 507 sage: g = {0:0,1:1,2:1} 508 sage: x = H(f) 509 sage: y = G(g) 510 sage: z = x.fiber_product(y) 511 sage: z 512 Simplicial complex morphism {'L1R2': 1, 'L2R0': 0, 'L0R0': 0} from Simplicial complex with vertex set ('L0R0', 'L1R2', 'L2R0') and facets {('L2R0',), ('L0R0', 'L1R2')} to Simplicial complex with vertex set (0, 1) and facets {(0, 1)} 513 514 """ 515 if self._codomain != other._codomain: 516 raise ValueError, "self and other must have the same codomain." 517 X = self._domain.product(other._domain,rename_vertices = rename_vertices) 518 v = [] 519 f = dict() 520 eff1 = self._domain.effective_vertices() 521 eff2 = other._domain.effective_vertices() 522 for i in eff1: 523 for j in eff2: 524 if self(simplicial_complex.Simplex([i])) == other(simplicial_complex.Simplex([j])): 525 if rename_vertices: 526 v.append("L"+str(i)+"R"+str(j)) 527 f["L"+str(i)+"R"+str(j)] = self._vertex_dictionary[i] 528 else: 529 v.append((i,j)) 530 f[(i,j)] = self._vertex_dictionary[i] 531 return SimplicialComplexMorphism(f,X.generated_subcomplex(v),self._codomain)