Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/homology/simplicial_complex_morphism.py
4079 views
1
r"""
2
Morphisms of simplicial complexes
3
4
AUTHORS:
5
6
- Benjamin Antieau <[email protected]> (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 <[email protected]>
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
from sage.structure.sage_object import SageObject
95
from sage.rings.integer_ring import ZZ
96
from sage.homology.chain_complex_morphism import ChainComplexMorphism
97
from sage.combinat.permutation import Permutation
98
from sage.algebras.steenrod.steenrod_algebra_misc import convert_perm
99
100
def is_SimplicialComplexMorphism(x):
101
"""
102
Returns True if and only if x is a morphism of simplicial complexes.
103
104
EXAMPLES::
105
106
sage: from sage.homology.simplicial_complex_morphism import is_SimplicialComplexMorphism
107
sage: S = SimplicialComplex(5,[[0,1],[3,4]])
108
sage: H = Hom(S,S)
109
sage: f = {0:0,1:1,2:2,3:3,4:4,5:5}
110
sage: x = H(f)
111
sage: is_SimplicialComplexMorphism(x)
112
True
113
114
"""
115
return isinstance(x,SimplicialComplexMorphism)
116
117
class SimplicialComplexMorphism(SageObject):
118
"""
119
An element of this class is a morphism of simplicial complexes.
120
"""
121
def __init__(self,f,X,Y):
122
"""
123
Input is a dictionary f, the domain, and the codomain.
124
125
One can define the dictionary either on the vertices of X or on the effective vertices of X (X.effective_vertices()). Note that this
126
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.
127
This is because two SimplicialComplexes with the same faces but different vertex sets are not equal.
128
129
EXAMPLES::
130
131
sage: S = SimplicialComplex(5,[[0,1],[3,4]])
132
sage: H = Hom(S,S)
133
sage: f = {0:0,1:1,2:2,3:3,4:4,5:5}
134
sage: g = {0:0,1:1,3:3,4:4}
135
sage: x = H(f)
136
sage: y = H(g)
137
sage: x==y
138
False
139
sage: x.image()
140
Simplicial complex with vertex set (0, 1, 2, 3, 4, 5) and facets {(3, 4), (0, 1)}
141
sage: y.image()
142
Simplicial complex with vertex set (0, 1, 3, 4) and facets {(3, 4), (0, 1)}
143
sage: x.image()==y.image()
144
False
145
146
"""
147
if not isinstance(X,simplicial_complex.SimplicialComplex) or not isinstance(Y,simplicial_complex.SimplicialComplex):
148
raise ValueError, "X and Y must be SimplicialComplexes."
149
if not set(f.keys())==X._vertex_set.set() and not set(f.keys())==X.effective_vertices().set():
150
raise ValueError, "f must be a dictionary from the vertex set of X to single values in the vertex set of Y."
151
dim = X.dimension()
152
Y_faces = Y.faces()
153
for k in range(dim+1):
154
for i in X.faces()[k]:
155
tup = i.tuple()
156
fi = []
157
for j in tup:
158
fi.append(f[j])
159
v = simplicial_complex.Simplex(set(fi))
160
if not v in Y_faces[v.dimension()]:
161
raise ValueError, "f must be a dictionary from the vertices of X to the vertices of Y."
162
self._vertex_dictionary = f
163
self._domain = X
164
self._codomain = Y
165
166
def __eq__(self,x):
167
"""
168
Returns True if and only if self == x.
169
170
EXAMPLES::
171
172
sage: S = simplicial_complexes.Sphere(2)
173
sage: H = Hom(S,S)
174
sage: i = H.identity()
175
sage: i
176
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)}
177
sage: f = {0:0,1:1,2:2,3:2}
178
sage: j = H(f)
179
sage: i==j
180
False
181
182
sage: T = SimplicialComplex(3,[[1,2]])
183
sage: T
184
Simplicial complex with vertex set (0, 1, 2, 3) and facets {(1, 2)}
185
sage: G = Hom(T,T)
186
sage: k = G.identity()
187
sage: g = {0:0,1:1,2:2,3:3}
188
sage: l = G(g)
189
sage: k==l
190
True
191
192
"""
193
if not isinstance(x,SimplicialComplexMorphism) or self._codomain != x._codomain or self._domain != x._domain or self._vertex_dictionary != x._vertex_dictionary:
194
return False
195
else:
196
return True
197
198
def __call__(self,x,orientation=False):
199
"""
200
Input is a simplex of the domain. Output is the image simplex.
201
202
If optional argument ``orientation`` is True, return a pair
203
``(image simplex, oriented)`` where ``oriented`` is 1 or `-1`
204
depending on whether the map preserves or reverses the
205
orientation of the image simplex.
206
207
EXAMPLES::
208
209
sage: S = simplicial_complexes.Sphere(2)
210
sage: T = simplicial_complexes.Sphere(3)
211
sage: S
212
Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 2, 3), (0, 1, 2), (1, 2, 3), (0, 1, 3)}
213
sage: T
214
Simplicial complex with vertex set (0, 1, 2, 3, 4) and 5 facets
215
sage: f = {0:0,1:1,2:2,3:3}
216
sage: H = Hom(S,T)
217
sage: x = H(f)
218
sage: from sage.homology.simplicial_complex import Simplex
219
sage: x(Simplex([0,2,3]))
220
(0, 2, 3)
221
222
An orientation-reversing example::
223
224
sage: X = SimplicialComplex(1, [[0,1]])
225
sage: g = Hom(X,X)({0:1, 1:0})
226
sage: g(Simplex([0,1]))
227
(0, 1)
228
sage: g(Simplex([0,1]), orientation=True)
229
((0, 1), -1)
230
"""
231
dim = self._domain.dimension()
232
if not isinstance(x,simplicial_complex.Simplex) or x.dimension() > dim or not x in self._domain.faces()[x.dimension()]:
233
raise ValueError, "x must be a simplex of the source of f"
234
tup=x.tuple()
235
fx=[]
236
for j in tup:
237
fx.append(self._vertex_dictionary[j])
238
if orientation:
239
if len(set(fx)) == len(tup):
240
oriented = Permutation(convert_perm(fx)).signature()
241
else:
242
oriented = 1
243
return (simplicial_complex.Simplex(set(fx)), oriented)
244
else:
245
return simplicial_complex.Simplex(set(fx))
246
247
def _repr_(self):
248
"""
249
Print representation
250
251
EXAMPLES::
252
253
sage: S = simplicial_complexes.Sphere(2)
254
sage: H = Hom(S,S)
255
sage: i = H.identity()
256
sage: i
257
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)}
258
sage: i._repr_()
259
'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)}'
260
261
262
"""
263
return "Simplicial complex morphism " + str(self._vertex_dictionary) + " from " + self._domain._repr_() + " to " + self._codomain._repr_()
264
265
def associated_chain_complex_morphism(self,base_ring=ZZ,augmented=False,cochain=False):
266
"""
267
Returns the associated chain complex morphism of self.
268
269
EXAMPLES::
270
271
sage: S = simplicial_complexes.Sphere(1)
272
sage: T = simplicial_complexes.Sphere(2)
273
sage: H = Hom(S,T)
274
sage: f = {0:0,1:1,2:2}
275
sage: x = H(f)
276
sage: x
277
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)}
278
sage: a = x.associated_chain_complex_morphism()
279
sage: a
280
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
281
sage: a._matrix_dictionary
282
{0: [0 0 0]
283
[0 1 0]
284
[0 0 1]
285
[1 0 0],
286
1: [0 0 0]
287
[0 1 0]
288
[0 0 0]
289
[1 0 0]
290
[0 0 0]
291
[0 0 1],
292
2: []}
293
sage: x.associated_chain_complex_morphism(augmented=True)
294
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
295
sage: x.associated_chain_complex_morphism(cochain=True)
296
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
297
sage: x.associated_chain_complex_morphism(augmented=True,cochain=True)
298
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
299
sage: x.associated_chain_complex_morphism(base_ring=GF(11))
300
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
301
302
Some simplicial maps which reverse the orientation of a few simplices::
303
304
sage: g = {0:1, 1:2, 2:0}
305
sage: H(g).associated_chain_complex_morphism()._matrix_dictionary
306
{0: [0 0 0]
307
[1 0 0]
308
[0 1 0]
309
[0 0 1], 1: [ 0 0 0]
310
[-1 0 0]
311
[ 0 0 0]
312
[ 0 0 1]
313
[ 0 0 0]
314
[ 0 -1 0], 2: []}
315
316
sage: X = SimplicialComplex(1, [[0, 1]])
317
sage: Hom(X,X)({0:1, 1:0}).associated_chain_complex_morphism()._matrix_dictionary
318
{0: [0 1]
319
[1 0], 1: [-1]}
320
"""
321
max_dim = max(self._domain.dimension(),self._codomain.dimension())
322
min_dim = min(self._domain.dimension(),self._codomain.dimension())
323
matrices = {}
324
if augmented is True:
325
m = matrix.Matrix(base_ring,1,1,1)
326
if not cochain:
327
matrices[-1] = m
328
else:
329
matrices[-1] = m.transpose()
330
for dim in range(min_dim+1):
331
# X_faces = list(self._domain.faces()[dim])
332
# Y_faces = list(self._codomain.faces()[dim])
333
X_faces = list(self._domain.n_cells(dim))
334
Y_faces = list(self._codomain.n_cells(dim))
335
num_faces_X = len(X_faces)
336
num_faces_Y = len(Y_faces)
337
mval = [0 for i in range(num_faces_X*num_faces_Y)]
338
for i in X_faces:
339
y, oriented = self(i, orientation=True)
340
if y.dimension() < dim:
341
pass
342
else:
343
mval[X_faces.index(i)+(Y_faces.index(y)*num_faces_X)] = oriented
344
m = matrix.Matrix(base_ring,num_faces_Y,num_faces_X,mval,sparse=True)
345
if not cochain:
346
matrices[dim] = m
347
else:
348
matrices[dim] = m.transpose()
349
for dim in range(min_dim+1,max_dim+1):
350
try:
351
l1 = len(self._codomain.n_cells(dim))
352
except KeyError:
353
l1 = 0
354
try:
355
l2 = len(self._domain.n_cells(dim))
356
except KeyError:
357
l2 = 0
358
m = matrix.zero_matrix(base_ring,l1,l2,sparse=True)
359
if not cochain:
360
matrices[dim] = m
361
else:
362
matrices[dim] = m.transpose()
363
if not cochain:
364
return ChainComplexMorphism(matrices,\
365
self._domain.chain_complex(base_ring=base_ring,augmented=augmented,cochain=cochain),\
366
self._codomain.chain_complex(base_ring=base_ring,augmented=augmented,cochain=cochain))
367
else:
368
return ChainComplexMorphism(matrices,\
369
self._codomain.chain_complex(base_ring=base_ring,augmented=augmented,cochain=cochain),\
370
self._domain.chain_complex(base_ring=base_ring,augmented=augmented,cochain=cochain))
371
372
def image(self):
373
"""
374
Computes the image simplicial complex of f.
375
376
EXAMPLES::
377
378
sage: S = SimplicialComplex(3,[[0,1],[2,3]])
379
sage: T = SimplicialComplex(1,[[0,1]])
380
sage: f = {0:0,1:1,2:0,3:1}
381
sage: H = Hom(S,T)
382
sage: x = H(f)
383
sage: x.image()
384
Simplicial complex with vertex set (0, 1) and facets {(0, 1)}
385
386
sage: S = SimplicialComplex(2)
387
sage: H = Hom(S,S)
388
sage: i = H.identity()
389
sage: i.image()
390
Simplicial complex with vertex set (0, 1, 2) and facets {()}
391
sage: i.is_surjective()
392
True
393
sage: S = SimplicialComplex(5,[[0,1]])
394
sage: T = SimplicialComplex(3,[[0,1]])
395
sage: f = {0:0,1:1}
396
sage: g = {0:0,1:1,2:2,3:3,4:4,5:5}
397
sage: H = Hom(S,T)
398
sage: x = H(f)
399
sage: y = H(g)
400
sage: x == y
401
False
402
sage: x.image()
403
Simplicial complex with vertex set (0, 1) and facets {(0, 1)}
404
sage: y.image()
405
Simplicial complex with vertex set (0, 1, 2, 3, 4, 5) and facets {(0, 1)}
406
407
"""
408
fa = [self(i) for i in self._domain.facets()]
409
return simplicial_complex.SimplicialComplex(set(self._vertex_dictionary.values()),fa,maximality_check=True)
410
411
def domain(self):
412
"""
413
Returns the domain of the morphism.
414
415
EXAMPLES::
416
417
sage: S = SimplicialComplex(3,[[0,1],[2,3]])
418
sage: T = SimplicialComplex(1,[[0,1]])
419
sage: f = {0:0,1:1,2:0,3:1}
420
sage: H = Hom(S,T)
421
sage: x = H(f)
422
sage: x.domain()
423
Simplicial complex with vertex set (0, 1, 2, 3) and facets {(2, 3), (0, 1)}
424
425
"""
426
return self._domain
427
428
def codomain(self):
429
"""
430
Returns the codomain of the morphism.
431
432
EXAMPLES::
433
434
sage: S = SimplicialComplex(3,[[0,1],[2,3]])
435
sage: T = SimplicialComplex(1,[[0,1]])
436
sage: f = {0:0,1:1,2:0,3:1}
437
sage: H = Hom(S,T)
438
sage: x = H(f)
439
sage: x.codomain()
440
Simplicial complex with vertex set (0, 1) and facets {(0, 1)}
441
442
"""
443
return self._codomain
444
445
def is_surjective(self):
446
"""
447
Returns True if and only if self is surjective.
448
449
EXAMPLES::
450
451
sage: S = SimplicialComplex(3,[(0,1,2)])
452
sage: S
453
Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 1, 2)}
454
sage: T = SimplicialComplex(2,[(0,1)])
455
sage: T
456
Simplicial complex with vertex set (0, 1, 2) and facets {(0, 1)}
457
sage: H = Hom(S,T)
458
sage: x = H({0:0,1:1,2:1,3:2})
459
sage: x.is_surjective()
460
True
461
462
sage: S = SimplicialComplex(3,[[0,1],[2,3]])
463
sage: T = SimplicialComplex(1,[[0,1]])
464
sage: f = {0:0,1:1,2:0,3:1}
465
sage: H = Hom(S,T)
466
sage: x = H(f)
467
sage: x.is_surjective()
468
True
469
470
"""
471
return self._codomain == self.image()
472
473
def is_injective(self):
474
"""
475
Returns True if and only if self is injective.
476
477
EXAMPLES::
478
479
sage: S = simplicial_complexes.Sphere(1)
480
sage: T = simplicial_complexes.Sphere(2)
481
sage: U = simplicial_complexes.Sphere(3)
482
sage: H = Hom(T,S)
483
sage: G = Hom(T,U)
484
sage: f = {0:0,1:1,2:0,3:1}
485
sage: x = H(f)
486
sage: g = {0:0,1:1,2:2,3:3}
487
sage: y = G(g)
488
sage: x.is_injective()
489
False
490
sage: y.is_injective()
491
True
492
493
"""
494
v = [self._vertex_dictionary[i[0]] for i in self._domain.faces()[0]]
495
for i in v:
496
if v.count(i) > 1:
497
return False
498
return True
499
500
def is_identity(self):
501
"""
502
If x is an identity morphism, returns True. Otherwise, False.
503
504
EXAMPLES::
505
506
sage: T = simplicial_complexes.Sphere(1)
507
sage: G = Hom(T,T)
508
sage: T
509
Simplicial complex with vertex set (0, 1, 2) and facets {(1, 2), (0, 2), (0, 1)}
510
sage: j = G({0:0,1:1,2:2})
511
sage: j.is_identity()
512
True
513
514
sage: S = simplicial_complexes.Sphere(2)
515
sage: T = simplicial_complexes.Sphere(3)
516
sage: H = Hom(S,T)
517
sage: f = {0:0,1:1,2:2,3:3}
518
sage: x = H(f)
519
sage: x
520
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
521
sage: x.is_identity()
522
False
523
524
"""
525
if self._domain != self._codomain:
526
return False
527
else:
528
f = dict()
529
for i in self._domain.vertices().set():
530
f[i] = i
531
if self._vertex_dictionary != f:
532
return False
533
else:
534
return True
535
536
def fiber_product(self,other,rename_vertices = True):
537
"""
538
Fiber product of self and other. Both morphisms should have the same codomain. The method returns a morphism of simplicial complexes, which
539
is the morphism from the space of the fiber product to the codomain.
540
541
EXAMPLES::
542
543
sage: S = SimplicialComplex(2,[[0,1],[1,2]])
544
sage: T = SimplicialComplex(2,[[0,2]])
545
sage: U = SimplicialComplex(1,[[0,1]])
546
sage: H = Hom(S,U)
547
sage: G = Hom(T,U)
548
sage: f = {0:0,1:1,2:0}
549
sage: g = {0:0,1:1,2:1}
550
sage: x = H(f)
551
sage: y = G(g)
552
sage: z = x.fiber_product(y)
553
sage: z
554
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)}
555
556
"""
557
if self._codomain != other._codomain:
558
raise ValueError, "self and other must have the same codomain."
559
X = self._domain.product(other._domain,rename_vertices = rename_vertices)
560
v = []
561
f = dict()
562
eff1 = self._domain.effective_vertices()
563
eff2 = other._domain.effective_vertices()
564
for i in eff1:
565
for j in eff2:
566
if self(simplicial_complex.Simplex([i])) == other(simplicial_complex.Simplex([j])):
567
if rename_vertices:
568
v.append("L"+str(i)+"R"+str(j))
569
f["L"+str(i)+"R"+str(j)] = self._vertex_dictionary[i]
570
else:
571
v.append((i,j))
572
f[(i,j)] = self._vertex_dictionary[i]
573
return SimplicialComplexMorphism(f,X.generated_subcomplex(v),self._codomain)
574
575