passagemath-kenzo 10.6.35__cp312-abi3-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1988 @@
1
+ # sage_setup: distribution = sagemath-kenzo
2
+ # sage.doctest: optional - kenzo
3
+ r"""
4
+ Library interface to Kenzo
5
+
6
+ Kenzo is a set of lisp functions to compute homology and
7
+ homotopy groups of topological spaces.
8
+
9
+ AUTHORS:
10
+
11
+ - Miguel Marco, Ana Romero (2019-01): Initial version
12
+
13
+
14
+ For this interface, Kenzo is loaded into ECL which is itself loaded
15
+ as a C library in Sage. Kenzo objects in this interface are nothing
16
+ but wrappers around ECL objects.
17
+ """
18
+ # ****************************************************************************
19
+ # Copyright (C) 2019 Miguel Marco <mmarco@unizar.es>
20
+ # and Ana Romero <ana.romero@unirioja.es>
21
+ #
22
+ # This program is free software: you can redistribute it and/or modify
23
+ # it under the terms of the GNU General Public License as published by
24
+ # the Free Software Foundation, either version 2 of the License, or
25
+ # (at your option) any later version.
26
+ # https://www.gnu.org/licenses/
27
+ # ****************************************************************************
28
+
29
+ from sage.structure.sage_object import SageObject
30
+ from sage.homology.homology_group import HomologyGroup
31
+ from sage.rings.integer_ring import ZZ
32
+ from sage.groups.additive_abelian.additive_abelian_group import AdditiveAbelianGroup
33
+ from sage.groups.abelian_gps.abelian_group import AbelianGroup
34
+ from sage.categories.commutative_additive_groups import CommutativeAdditiveGroups
35
+
36
+ from sage.matrix.constructor import matrix
37
+ from sage.homology.chain_complex import ChainComplex
38
+ from sage.topology.simplicial_set import AbstractSimplex, SimplicialSet
39
+
40
+ from sage.libs.ecl import EclObject, ecl_eval, EclListIterator
41
+ from sage.features.kenzo import Kenzo
42
+
43
+ # defining the auxiliary functions as wrappers over the kenzo ones
44
+ kenzo_names = ['add',
45
+ 'array-dimensions',
46
+ 'basis_aux1',
47
+ 'basis_aux1',
48
+ 'bicomplex-spectral-sequence',
49
+ 'build-finite-ss2',
50
+ 'build-mrph-aux',
51
+ 'change-sorc-trgt-aux',
52
+ 'chcm-mat',
53
+ 'chcm-mat2',
54
+ 'classifying-space',
55
+ 'cmps',
56
+ 'convertmatrice',
57
+ 'crts-prdc',
58
+ 'degr-aux',
59
+ 'dffr-aux',
60
+ 'dffr_aux1',
61
+ 'dgop',
62
+ 'dgop-int-ext',
63
+ 'dstr-change-sorc-trgt-aux',
64
+ 'echcm',
65
+ 'eilenberg-moore-spectral-sequence',
66
+ 'evaluation-aux1',
67
+ 'gmsm',
68
+ 'homologie',
69
+ 'homotopy-list',
70
+ 'idnt-mrph',
71
+ 'join',
72
+ 'k-z',
73
+ 'k-z2',
74
+ 'k-zp',
75
+ 'kabstractsimplex_aux1',
76
+ 'kchaincomplex_aux1',
77
+ 'kmorphismchaincomplex_aux1',
78
+ 'loop-space',
79
+ 'make-array-from-lists',
80
+ 'make-array-to-lists',
81
+ 'moore',
82
+ 'ncol',
83
+ 'nlig',
84
+ 'nreverse',
85
+ 'nth',
86
+ 'opps',
87
+ 'orgn_aux1',
88
+ 'sbtr',
89
+ 'serre-spectral-sequence-product',
90
+ 'serre-whitehead-spectral-sequence',
91
+ 'sfinitesimplicialset_aux1',
92
+ 'smash-product',
93
+ 'sorc-aux',
94
+ 'spectral-sequence-differential-matrix',
95
+ 'spectral-sequence-group',
96
+ 'sphere',
97
+ 'suspension',
98
+ 'tnsr-prdc',
99
+ 'trgt-aux',
100
+ 'wedge',
101
+ 'zero-mrph']
102
+
103
+
104
+ # Now initialize Kenzo. For each string s in kenzo_names, the
105
+ # following defines __s__, a wrapper for a Kenzo function. For
106
+ # example __sphere__ is defined as EclObject("sphere"). Hyphens
107
+ # are replaced with underscores to get valid Python identifiers.
108
+ if Kenzo().is_present():
109
+ from sage.env import KENZO_FAS
110
+ if KENZO_FAS:
111
+ ecl_eval("(require :kenzo \"{}\")".format(KENZO_FAS))
112
+ else:
113
+ ecl_eval("(require :kenzo)")
114
+
115
+ ecl_eval("(in-package :cat)")
116
+ ecl_eval("(setf *HOMOLOGY-VERBOSE* nil)")
117
+ for s in kenzo_names:
118
+ name = '__{}__'.format(s.replace('-', '_'))
119
+ exec('{} = EclObject("{}")'.format(name, s))
120
+
121
+
122
+ def Sphere(n):
123
+ r"""
124
+ Return the `n` dimensional sphere as a Kenzo simplicial set.
125
+
126
+ INPUT:
127
+
128
+ - ``n`` -- the dimension of the sphere
129
+
130
+ OUTPUT: a :class:`KenzoSimplicialSet`
131
+
132
+ EXAMPLES::
133
+
134
+ sage: # optional - kenzo
135
+ sage: from sage.interfaces.kenzo import Sphere
136
+ sage: s2 = Sphere(2)
137
+ sage: s2
138
+ [K1 Simplicial-Set]
139
+ sage: [s2.homology(i) for i in range(8)]
140
+ [Z, 0, Z, 0, 0, 0, 0, 0]
141
+ """
142
+ kenzosphere = __sphere__(n)
143
+ return KenzoSimplicialSet(kenzosphere)
144
+
145
+
146
+ def MooreSpace(m, n):
147
+ r"""
148
+ Return the Moore space `M(m, n)` as a Kenzo simplicial set.
149
+
150
+ The Moore space `M(m, n)` is the space whose `n`-th homology group
151
+ is isomorphic to the cyclic group of order `m`, and the rest of the
152
+ homology groups are trivial.
153
+
154
+ INPUT:
155
+
156
+ - ``m`` -- positive integer; the order of the nontrivial homology group
157
+
158
+ - ``n`` -- the dimension in which the homology is not trivial
159
+
160
+ OUTPUT: a KenzoSimplicialSet
161
+
162
+ EXAMPLES::
163
+
164
+ sage: # optional - kenzo
165
+ sage: from sage.interfaces.kenzo import MooreSpace
166
+ sage: m24 = MooreSpace(2,4)
167
+ sage: m24
168
+ [K10 Simplicial-Set]
169
+ sage: [m24.homology(i) for i in range(8)]
170
+ [Z, 0, 0, 0, C2, 0, 0, 0]
171
+ """
172
+ kenzomoore = __moore__(m, n)
173
+ return KenzoSimplicialSet(kenzomoore)
174
+
175
+
176
+ def EilenbergMacLaneSpace(G, n):
177
+ r"""
178
+ Return the Eilenberg-MacLane space ``K(G, n)`` as a Kenzo simplicial group.
179
+
180
+ The Eilenberg-MacLane space ``K(G, n)`` is the space whose has n'th homotopy
181
+ group isomorphic to ``G``, and the rest of the homotopy groups are trivial.
182
+
183
+ INPUT:
184
+
185
+ - ``G`` -- group; currently only ``ZZ`` and the additive group of two
186
+ elements are supported
187
+
188
+ - ``n`` -- the dimension in which the homotopy is not trivial
189
+
190
+ OUTPUT: a :class:`KenzoSimplicialGroup`
191
+
192
+ EXAMPLES::
193
+
194
+ sage: # optional - kenzo
195
+ sage: from sage.interfaces.kenzo import EilenbergMacLaneSpace
196
+ sage: e3 = EilenbergMacLaneSpace(ZZ, 3)
197
+ sage: [e3.homology(i) for i in range(8)]
198
+ [Z, 0, 0, Z, 0, C2, 0, C3]
199
+ sage: f3 = EilenbergMacLaneSpace(AdditiveAbelianGroup([2]), 3)
200
+ sage: [f3.homology(i) for i in range(8)]
201
+ [Z, 0, 0, C2, 0, C2, C2, C2]
202
+ """
203
+ if G == ZZ:
204
+ kenzospace = __k_z__(n)
205
+ return KenzoSimplicialGroup(kenzospace)
206
+ elif G == AdditiveAbelianGroup([2]):
207
+ kenzospace = __k_z2__(n)
208
+ return KenzoSimplicialGroup(kenzospace)
209
+ elif G in CommutativeAdditiveGroups() and G.is_cyclic():
210
+ kenzospace = __k_zp__(G.cardinality(), n)
211
+ return KenzoSimplicialGroup(kenzospace)
212
+ else:
213
+ raise NotImplementedError("Eilenberg-MacLane spaces are only supported over ZZ and ZZ_n")
214
+
215
+
216
+ class KenzoObject(SageObject):
217
+ r"""
218
+ Wrapper to Kenzo objects.
219
+
220
+ INPUT:
221
+
222
+ - ``kenzo_object`` -- a wrapper around a Kenzo object
223
+ (which is an ecl object)
224
+ """
225
+
226
+ def __init__(self, kenzo_object):
227
+ r"""
228
+ Construct the chain complex.
229
+
230
+ TESTS::
231
+
232
+ sage: # optional - kenzo
233
+ sage: from sage.interfaces.kenzo import KenzoObject
234
+ sage: from sage.interfaces.kenzo import __sphere__
235
+ sage: ks = __sphere__(2)
236
+ sage: ks
237
+ <ECL: [K1 Simplicial-Set]>
238
+ sage: s2 = KenzoObject(ks)
239
+ sage: s2
240
+ [K1 Simplicial-Set]
241
+ sage: TestSuite(s2).run(skip='_test_pickling')
242
+ """
243
+ self._kenzo = kenzo_object
244
+
245
+ def _repr_(self):
246
+ r"""
247
+ Represent the object.
248
+
249
+ It just uses the ecl representation, removing the
250
+ ecl decoration.
251
+
252
+ EXAMPLES::
253
+
254
+ sage: from sage.interfaces.kenzo import MooreSpace # optional - kenzo
255
+ sage: m2 = MooreSpace(2,4) # optional - kenzo
256
+ sage: m2._repr_() # optional - kenzo
257
+ '[K10 Simplicial-Set]'
258
+ """
259
+ kenzo_string = repr(self._kenzo)
260
+ return kenzo_string[6:-1]
261
+
262
+
263
+ class KenzoSpectralSequence(KenzoObject):
264
+ r"""
265
+ Wrapper around Kenzo spectral sequences
266
+ """
267
+
268
+ def group(self, p, i, j):
269
+ r"""
270
+ Return the ``i,j``-th group of the ``p`` page.
271
+
272
+ INPUT:
273
+
274
+ - ``p`` -- the page to take the group from
275
+
276
+ - ``i`` -- the column where the group is taken from
277
+
278
+ - ``j`` -- the row where the group is taken from
279
+
280
+ EXAMPLES::
281
+
282
+ sage: # optional - kenzo
283
+ sage: from sage.interfaces.kenzo import Sphere
284
+ sage: S2 = Sphere(2)
285
+ sage: EMS = S2.em_spectral_sequence()
286
+ sage: EMS.group(0, -1, 2)
287
+ Additive abelian group isomorphic to Z
288
+ sage: EMS.group(0, -1, 3)
289
+ Trivial group
290
+ """
291
+ invs = __spectral_sequence_group__(self._kenzo, p, i, j).python()
292
+ if not invs:
293
+ invs = []
294
+ return AdditiveAbelianGroup(invs)
295
+
296
+ def matrix(self, p, i, j):
297
+ r"""
298
+ Return the matrix that determines the differential from the
299
+ ``i,j``-th group of the ``p``-th page.
300
+
301
+ INPUT:
302
+
303
+ - ``p`` -- the page
304
+
305
+ - ``i`` -- the column of the differential domain
306
+
307
+ - ``j`` -- the row of the differential domain
308
+
309
+ EXAMPLES::
310
+
311
+ sage: # optional - kenzo
312
+ sage: from sage.interfaces.kenzo import Sphere
313
+ sage: S3 = Sphere(3)
314
+ sage: L = S3.loop_space()
315
+ sage: EMS = L.em_spectral_sequence()
316
+ sage: EMS.table(1, -5, -2, 5, 8)
317
+ 0 Z Z + Z + Z Z + Z + Z
318
+ 0 0 0 0
319
+ 0 0 Z Z + Z
320
+ 0 0 0 0
321
+ sage: EMS.matrix(1, -2 ,8)
322
+ [ 3 -2 0]
323
+ [ 3 0 -3]
324
+ [ 0 2 -3]
325
+ """
326
+ klist = __spectral_sequence_differential_matrix__(self._kenzo, p, i, j)
327
+ plist = klist.python()
328
+ if plist is None or plist == [None]:
329
+ i = len(self.group(p, i, j).invariants())
330
+ j = len(self.group(p, i - p, j + p - 1).invariants())
331
+ return matrix(i, j)
332
+ return matrix(plist)
333
+
334
+ def differential(self, p, i, j):
335
+ r"""
336
+ Return the ``(p, i, j)`` differential morphism of the spectral sequence.
337
+
338
+ INPUT:
339
+
340
+ - ``p`` -- the page
341
+
342
+ - ``i`` -- the column of the differential domain
343
+
344
+ - ``j`` -- the row of the differential domain
345
+
346
+ EXAMPLES::
347
+
348
+ sage: # optional - kenzo
349
+ sage: from sage.interfaces.kenzo import Sphere
350
+ sage: S3 = Sphere(3)
351
+ sage: L = S3.loop_space()
352
+ sage: EMS = L.em_spectral_sequence()
353
+ sage: EMS.table(1,-5,-2,5,8)
354
+ 0 Z Z + Z + Z Z + Z + Z
355
+ 0 0 0 0
356
+ 0 0 Z Z + Z
357
+ 0 0 0 0
358
+ sage: EMS.matrix(1, -3, 8)
359
+ [ 2 -2 2]
360
+ sage: EMS.differential(1, -3, 8)
361
+ Morphism from module over Integer Ring with invariants (0, 0, 0) to module with invariants (0,) that sends the generators to [(2), (-2), (2)]
362
+ """
363
+ domain = self.group(p, i, j)
364
+ codomain = self.group(p, i - p, j + p - 1)
365
+ M = self.matrix(p, i, j)
366
+ images = [codomain(r) for r in M.columns()]
367
+ return domain.hom(images, codomain=codomain)
368
+
369
+ def table(self, p, i1, i2, j1, j2):
370
+ r"""
371
+ Return a table printing the groups in the ``p`` page.
372
+
373
+ INPUT:
374
+
375
+ - ``p`` -- the page to print
376
+
377
+ -- ``i1`` -- the first column to print
378
+
379
+ -- ``i2`` -- the last column to print
380
+
381
+ -- ``j1`` -- the first row to print
382
+
383
+ -- ``j2`` -- the last row to print
384
+
385
+ EXAMPLES::
386
+
387
+ sage: # optional - kenzo
388
+ sage: from sage.interfaces.kenzo import Sphere
389
+ sage: S2 = Sphere(2)
390
+ sage: EMS = S2.em_spectral_sequence()
391
+ sage: EMS.table(0, -2, 2, -2, 2)
392
+ 0 Z 0 0 0
393
+ 0 0 0 0 0
394
+ 0 0 Z 0 0
395
+ 0 0 0 0 0
396
+ 0 0 0 0 0
397
+ """
398
+ from sage.misc.table import table
399
+ groups = []
400
+ for j in range(j2 - j1 + 1):
401
+ row = []
402
+ for i in range(i1, i2 + 1):
403
+ group = self.group(p, i, j2 - j)
404
+ if group.invariants():
405
+ row.append(group.short_name())
406
+ else:
407
+ row.append('0')
408
+ groups.append(row)
409
+ return table(groups)
410
+
411
+
412
+ class KenzoChainComplex(KenzoObject):
413
+ r"""
414
+ Wrapper to Kenzo chain complexes. Kenzo simplicial sets are a particular case
415
+ of Kenzo chain complexes.
416
+ """
417
+ def homology(self, n):
418
+ r"""
419
+ Return the `n`-th homology group of the chain complex associated to this
420
+ kenzo object.
421
+
422
+ INPUT:
423
+
424
+ - ``n`` -- the dimension in which compute the homology
425
+
426
+ OUTPUT: a homology group
427
+
428
+ EXAMPLES::
429
+
430
+ sage: # optional - kenzo
431
+ sage: from sage.interfaces.kenzo import Sphere
432
+ sage: s2 = Sphere(2)
433
+ sage: s2
434
+ [K1 Simplicial-Set]
435
+ sage: s2.homology(2)
436
+ Z
437
+ """
438
+ echcm1 = __echcm__(self._kenzo)
439
+ m1 = __chcm_mat__(echcm1, n)
440
+ m2 = __chcm_mat__(echcm1, n + 1)
441
+ homology = __homologie__(m1, m2)
442
+ lhomomology = list(EclListIterator(homology))
443
+ res = []
444
+ for component in lhomomology:
445
+ pair = list(EclListIterator(component))
446
+ res.append(pair[0].python())
447
+ return HomologyGroup(len(res), ZZ, res)
448
+
449
+ def tensor_product(self, other):
450
+ r"""
451
+ Return the tensor product of ``self`` and ``other``.
452
+
453
+ INPUT:
454
+
455
+ - ``other`` -- The Kenzo object with which to compute the tensor product
456
+
457
+ OUTPUT: a :class:`KenzoChainComplex`
458
+
459
+ EXAMPLES::
460
+
461
+ sage: # optional - kenzo
462
+ sage: from sage.interfaces.kenzo import Sphere
463
+ sage: s2 = Sphere(2)
464
+ sage: s3 = Sphere(3)
465
+ sage: p = s2.tensor_product(s3)
466
+ sage: type(p)
467
+ <class 'sage.interfaces.kenzo.KenzoChainComplex'>
468
+ sage: [p.homology(i) for i in range(8)]
469
+ [Z, 0, Z, Z, 0, Z, 0, 0]
470
+ """
471
+ return KenzoChainComplex(__tnsr_prdc__(self._kenzo, other._kenzo))
472
+
473
+ def basis(self, dim):
474
+ r"""
475
+ Return the list of generators of the chain complex associated to the kenzo
476
+ object ``self`` in dimension ``dim``.
477
+
478
+ INPUT:
479
+
480
+ - ``dim`` -- integer
481
+
482
+ OUTPUT: list of the form ['G"dim"G0', 'G"dim"G1', 'G"dim"G2', ...]
483
+
484
+ EXAMPLES::
485
+
486
+ sage: # optional - kenzo
487
+ sage: from sage.interfaces.kenzo import KChainComplex
488
+ sage: m1 = matrix(ZZ, 3, 2, [-1, 1, 3, -4, 5, 6])
489
+ sage: m4 = matrix(ZZ, 2, 2, [1, 2, 3, 6])
490
+ sage: m5 = matrix(ZZ, 2, 3, [2, 2, 2, -1, -1, -1])
491
+ sage: sage_chcm = ChainComplex({1: m1, 4: m4, 5: m5}, degree = -1)
492
+ sage: kenzo_chcm = KChainComplex(sage_chcm)
493
+ sage: kenzo_chcm
494
+ [K... Chain-Complex]
495
+ sage: for i in range(6):
496
+ ....: print("Basis in dimension %i: %s" % (i, kenzo_chcm.basis(i)))
497
+ Basis in dimension 0: ['G0G0', 'G0G1', 'G0G2']
498
+ Basis in dimension 1: ['G1G0', 'G1G1']
499
+ Basis in dimension 2: None
500
+ Basis in dimension 3: ['G3G0', 'G3G1']
501
+ Basis in dimension 4: ['G4G0', 'G4G1']
502
+ Basis in dimension 5: ['G5G0', 'G5G1', 'G5G2']
503
+ """
504
+ return __basis_aux1__(self._kenzo, dim).python()
505
+
506
+ def identity_morphism(self):
507
+ r"""
508
+ Return the identity morphism (degree 0) between ``self`` and itself.
509
+
510
+ OUTPUT: a :class:`KenzoChainComplexMorphism`
511
+
512
+ EXAMPLES::
513
+
514
+ sage: # optional - kenzo
515
+ sage: from sage.interfaces.kenzo import Sphere
516
+ sage: s2 = Sphere(2)
517
+ sage: tp = s2.tensor_product(s2)
518
+ sage: idnt = tp.identity_morphism()
519
+ sage: type(idnt)
520
+ <class 'sage.interfaces.kenzo.KenzoChainComplexMorphism'>
521
+ """
522
+ return KenzoChainComplexMorphism(__idnt_mrph__(self._kenzo))
523
+
524
+ def null_morphism(self, target=None, degree=None):
525
+ r"""
526
+ Return the null morphism between the chain complexes ``self`` and ``target``
527
+ of degree ``degree``.
528
+
529
+ INPUT:
530
+
531
+ - ``target`` -- a KenzoChainComplex or ``None`` (default)
532
+ - ``degree`` -- integer or ``None`` (default)
533
+
534
+ OUTPUT:
535
+
536
+ - A :class:`KenzoChainComplexMorphism` representing the null morphism between
537
+ ``self`` and ``target`` of degree ``degree``. If ``target`` takes ``None`` value,
538
+ ``self`` is assumed as the target chain complex; if ``degree`` takes ``None`` value,
539
+ 0 is assumed as the degree of the null morphism.
540
+
541
+ EXAMPLES::
542
+
543
+ sage: # optional - kenzo
544
+ sage: from sage.interfaces.kenzo import Sphere
545
+ sage: s2 = Sphere(2)
546
+ sage: s3 = Sphere(3)
547
+ sage: tp22 = s2.tensor_product(s2)
548
+ sage: tp22
549
+ [K... Chain-Complex]
550
+ sage: tp23 = s2.tensor_product(s3)
551
+ sage: tp23
552
+ [K... Chain-Complex]
553
+ sage: null1 = tp22.null_morphism()
554
+ sage: null1
555
+ [K... Morphism (degree 0): K... -> K...]
556
+ sage: null2 = tp22.null_morphism(target = tp23, degree = -3)
557
+ sage: null2
558
+ [K... Morphism (degree -3): K... -> K...]
559
+ """
560
+ if target is None:
561
+ target = self
562
+ if degree is None:
563
+ degree = 0
564
+ if not isinstance(target, KenzoChainComplex):
565
+ raise ValueError("'target' parameter must be a KenzoChainComplex instance")
566
+ elif (not degree == 0) and (not degree.is_integer()):
567
+ raise ValueError("'degree' parameter must be an Integer number")
568
+ else:
569
+ return KenzoChainComplexMorphism(__zero_mrph__(self._kenzo, target._kenzo, degree))
570
+
571
+ def differential(self, dim=None, comb=None):
572
+ r"""
573
+ Return the differential of a combination.
574
+
575
+ INPUT:
576
+
577
+ - ``dim`` -- integer or ``None`` (default)
578
+
579
+ - ``comb`` -- list representing a formal sum of generators in the module
580
+ of dimension ``dim`` or ``None`` (default). For example, to represent
581
+ G7G12 + 3*G7G0 - 5*G7G3 we use the list [3, 'G7G0', -5, 'G7G3', 1, 'G7G12'].
582
+ Note that the generators must be in ascending order respect to the number
583
+ after the second G in their representation; the parameter
584
+ ``comb`` = [1, 'G7G12', 3, 'G7G0', -5, 'G7G3'] will produce an error in
585
+ Kenzo.
586
+
587
+ OUTPUT:
588
+
589
+ - If ``dim`` and ``comb`` are not ``None``, it returns a Kenzo combination
590
+ representing the differential of the formal combination represented by
591
+ ``comb`` in the chain complex ``self`` in dimension ``dim``. On the other
592
+ hand, if ``dim`` or ``comb`` (or both) take ``None`` value, the differential
593
+ :class:`KenzoMorphismChainComplex` of ``self`` is returned.
594
+
595
+ EXAMPLES::
596
+
597
+ sage: # optional - kenzo
598
+ sage: from sage.interfaces.kenzo import KChainComplex
599
+ sage: m1 = matrix(ZZ, 3, 2, [-1, 1, 3, -4, 5, 6])
600
+ sage: m4 = matrix(ZZ, 2, 2, [1, 2, 3, 6])
601
+ sage: m5 = matrix(ZZ, 2, 3, [2, 2, 2, -1, -1, -1])
602
+ sage: sage_chcm = ChainComplex({1: m1, 4: m4, 5: m5}, degree = -1)
603
+ sage: kenzo_chcm = KChainComplex(sage_chcm)
604
+ sage: kenzo_chcm
605
+ [K... Chain-Complex]
606
+ sage: kenzo_chcm.basis(4)
607
+ ['G4G0', 'G4G1']
608
+ sage: kenzo_chcm.differential(4, [1, 'G4G0'])
609
+ <BLANKLINE>
610
+ ----------------------------------------------------------------------{CMBN 3}
611
+ <1 * G3G0>
612
+ <3 * G3G1>
613
+ ------------------------------------------------------------------------------
614
+ <BLANKLINE>
615
+ sage: kenzo_chcm.basis(5)
616
+ ['G5G0', 'G5G1', 'G5G2']
617
+ sage: kenzo_chcm.differential(5, [1, 'G5G0', 2, 'G5G2'])
618
+ <BLANKLINE>
619
+ ----------------------------------------------------------------------{CMBN 4}
620
+ <6 * G4G0>
621
+ <-3 * G4G1>
622
+ ------------------------------------------------------------------------------
623
+ <BLANKLINE>
624
+ """
625
+ if dim is not None and comb is not None:
626
+ cmbn_list = pairing(comb)
627
+ return KenzoObject(__dffr_aux1__(self._kenzo, dim, cmbn_list))
628
+ else:
629
+ return KenzoChainComplexMorphism(__dffr_aux__(self._kenzo))
630
+
631
+ def orgn(self):
632
+ r"""
633
+ Return the :orgn slot of Kenzo, which stores as a list the origin of the object.
634
+
635
+ EXAMPLES::
636
+
637
+ sage: # optional - kenzo
638
+ sage: from sage.interfaces.kenzo import Sphere
639
+ sage: s2 = Sphere(2)
640
+ sage: l2 = s2.loop_space()
641
+ sage: l2.orgn()
642
+ '(LOOP-SPACE [K... Simplicial-Set])'
643
+ sage: A = l2.cartesian_product(s2)
644
+ sage: A.orgn()
645
+ '(CRTS-PRDC [K... Simplicial-Group] [K... Simplicial-Set])'
646
+ """
647
+ return str(__orgn_aux1__(self._kenzo))
648
+
649
+
650
+ class KenzoSimplicialSet(KenzoChainComplex):
651
+ r"""
652
+ Wrapper to Kenzo simplicial sets.
653
+
654
+ In Kenzo, the homology of a simplicial set in computed from its associated
655
+ chain complex. Hence, this class inherits from `KenzoChainComplex`.
656
+ """
657
+
658
+ def loop_space(self, n=1):
659
+ r"""
660
+ Return the `n`-th iterated loop space.
661
+
662
+ INPUT:
663
+
664
+ - ``n`` -- (default: 1) the number of times to iterate the loop space
665
+ construction
666
+
667
+ OUTPUT: a :class:`KenzoSimplicialGroup`
668
+
669
+ EXAMPLES::
670
+
671
+ sage: # optional - kenzo
672
+ sage: from sage.interfaces.kenzo import Sphere
673
+ sage: s2 = Sphere(2)
674
+ sage: l2 = s2.loop_space()
675
+ sage: type(l2)
676
+ <class 'sage.interfaces.kenzo.KenzoSimplicialGroup'>
677
+ sage: l2 = s2.loop_space()
678
+ sage: [l2.homology(i) for i in range(8)]
679
+ [Z, Z, Z, Z, Z, Z, Z, Z]
680
+ """
681
+ return KenzoSimplicialGroup(__loop_space__(self._kenzo, n))
682
+
683
+ def cartesian_product(self, other):
684
+ r"""
685
+ Return the cartesian product of ``self`` and ``other``.
686
+
687
+ INPUT:
688
+
689
+ - ``other`` -- the Kenzo simplicial set with which the product is made
690
+
691
+ OUTPUT: a :class:`KenzoSimplicialSet`
692
+
693
+ EXAMPLES::
694
+
695
+ sage: # optional - kenzo
696
+ sage: from sage.interfaces.kenzo import Sphere
697
+ sage: s2 = Sphere(2)
698
+ sage: s3 = Sphere(3)
699
+ sage: p = s2.cartesian_product(s3)
700
+ sage: type(p)
701
+ <class 'sage.interfaces.kenzo.KenzoSimplicialSet'>
702
+ sage: [p.homology(i) for i in range(6)]
703
+ [Z, 0, Z, Z, 0, Z]
704
+ """
705
+ prod_kenzo = __crts_prdc__(self._kenzo, other._kenzo)
706
+ return KenzoSimplicialSet(prod_kenzo)
707
+
708
+ def suspension(self):
709
+ r"""
710
+ Return the suspension of the simplicial set.
711
+
712
+ OUTPUT: a :class:`KenzoSimplicialSet`
713
+
714
+ EXAMPLES::
715
+
716
+ sage: # optional - kenzo
717
+ sage: from sage.interfaces.kenzo import EilenbergMacLaneSpace
718
+ sage: e3 = EilenbergMacLaneSpace(ZZ, 3)
719
+ sage: s = e3.suspension()
720
+ sage: type(s)
721
+ <class 'sage.interfaces.kenzo.KenzoSimplicialSet'>
722
+ sage: [s.homology(i) for i in range(6)]
723
+ [Z, 0, 0, 0, Z, 0]
724
+ """
725
+ return KenzoSimplicialSet(__suspension__(self._kenzo))
726
+
727
+ def homotopy_group(self, n):
728
+ """
729
+ Return the `n`-th homotopy group of ``self``.
730
+
731
+ INPUT:
732
+
733
+ - ``n`` -- the dimension of the homotopy group to be computed
734
+
735
+ EXAMPLES::
736
+
737
+ sage: # optional - kenzo
738
+ sage: from sage.interfaces.kenzo import Sphere
739
+ sage: s2 = Sphere(2)
740
+ sage: p = s2.cartesian_product(s2)
741
+ sage: p.homotopy_group(3)
742
+ Multiplicative Abelian group isomorphic to Z x Z
743
+
744
+
745
+ .. WARNING::
746
+
747
+ This method assumes that the underlying space is simply connected.
748
+ You might get wrong answers if it is not.
749
+ """
750
+ if n not in ZZ or n < 2:
751
+ raise ValueError("""homotopy groups can only be computed
752
+ for dimensions greater than 1""")
753
+ lgens = __homotopy_list__(self._kenzo, n).python()
754
+ if lgens is not None:
755
+ trgens = [0 if i == 1 else i for i in sorted(lgens)]
756
+ return AbelianGroup(trgens)
757
+ else:
758
+ return AbelianGroup([])
759
+
760
+ def em_spectral_sequence(self):
761
+ r"""
762
+ Return the Eilenberg-Moore spectral sequence of ``self``.
763
+
764
+ OUTPUT: a :class:`KenzoSpectralSequence`
765
+
766
+ EXAMPLES::
767
+
768
+ sage: # optional - kenzo
769
+ sage: from sage.interfaces.kenzo import Sphere
770
+ sage: S2 = Sphere(2)
771
+ sage: EMS = S2.em_spectral_sequence()
772
+ sage: EMS.table(0, -2, 2, -2, 2)
773
+ 0 Z 0 0 0
774
+ 0 0 0 0 0
775
+ 0 0 Z 0 0
776
+ 0 0 0 0 0
777
+ 0 0 0 0 0
778
+
779
+
780
+ .. WARNING::
781
+
782
+ This method assumes that the underlying space is simply connected.
783
+ You might get wrong answers if it is not.
784
+ """
785
+ if self.homology(1).invariants():
786
+ raise ValueError("""Eilenberg-Moore spectral sequence implemented
787
+ only for 1-reduced simplicial sets""")
788
+ return KenzoSpectralSequence(__eilenberg_moore_spectral_sequence__(self._kenzo))
789
+
790
+ def sw_spectral_sequence(self):
791
+ r"""
792
+ Return the Serre sequence of the first step of the Whitehead tower.
793
+
794
+ OUTPUT: a :class:`KenzoSpectralSequence`
795
+
796
+ EXAMPLES::
797
+
798
+ sage: # optional - kenzo
799
+ sage: from sage.interfaces.kenzo import Sphere
800
+ sage: S3 = Sphere(3)
801
+ sage: E = S3.sw_spectral_sequence()
802
+ sage: T = E.table(0, 0, 4, 0, 4)
803
+ sage: T
804
+ Z 0 0 Z 0
805
+ 0 0 0 0 0
806
+ Z 0 0 Z 0
807
+ 0 0 0 0 0
808
+ Z 0 0 Z 0
809
+ """
810
+ if self.homology(1).invariants():
811
+ raise ValueError("""Eilenberg-Moore spectral sequence implemented
812
+ only for 1-reduced simplicial sets""")
813
+ return KenzoSpectralSequence(__serre_whitehead_spectral_sequence__(self._kenzo))
814
+
815
+ def serre_spectral_sequence(self):
816
+ r"""
817
+ Return the spectral sequence of ``self``.
818
+
819
+ The object ``self`` must be created as a cartesian product (twisted or not).
820
+
821
+ OUTPUT: a :class:`KenzoSpectralSequence`
822
+
823
+ EXAMPLES::
824
+
825
+ sage: # optional - kenzo
826
+ sage: from sage.interfaces.kenzo import Sphere
827
+ sage: S2 = Sphere(2)
828
+ sage: S3 = Sphere(3)
829
+ sage: P = S2.cartesian_product(S3)
830
+ sage: E = P.serre_spectral_sequence()
831
+ sage: E.table(0, 0, 2, 0, 3)
832
+ Z 0 Z
833
+ 0 0 0
834
+ 0 0 0
835
+ Z 0 Z
836
+
837
+ .. WARNING::
838
+
839
+ This method assumes that the underlying space is simply connected.
840
+ You might get wrong answers if it is not.
841
+ """
842
+ if self.homology(1).invariants():
843
+ raise ValueError("""Eilenberg-Moore spectral sequence implemented
844
+ only for 1-reduced simplicial sets""")
845
+ return KenzoSpectralSequence(__serre_spectral_sequence_product__(self._kenzo))
846
+
847
+ def wedge(self, other):
848
+ r"""
849
+ Return the wedge of ``self`` and ``other``.
850
+
851
+ INPUT:
852
+
853
+ - ``other`` -- the Kenzo simplicial set with which the wedge is made
854
+
855
+ OUTPUT: a :class:`KenzoSimplicialSet`
856
+
857
+ EXAMPLES::
858
+
859
+ sage: # optional - kenzo
860
+ sage: from sage.interfaces.kenzo import Sphere
861
+ sage: s2 = Sphere(2)
862
+ sage: s3 = Sphere(3)
863
+ sage: w = s2.wedge(s3)
864
+ sage: type(w)
865
+ <class 'sage.interfaces.kenzo.KenzoSimplicialSet'>
866
+ sage: [w.homology(i) for i in range(6)]
867
+ [Z, 0, Z, Z, 0, 0]
868
+ """
869
+ wedge_kenzo = __wedge__(self._kenzo, other._kenzo)
870
+ return KenzoSimplicialSet(wedge_kenzo)
871
+
872
+ def join(self, other):
873
+ r"""
874
+ Return the join of ``self`` and ``other``.
875
+
876
+ INPUT:
877
+
878
+ - ``other`` -- the Kenzo simplicial set with which the join is made
879
+
880
+ OUTPUT: a :class:`KenzoSimplicialSet`
881
+
882
+ EXAMPLES::
883
+
884
+ sage: # optional - kenzo
885
+ sage: from sage.interfaces.kenzo import Sphere
886
+ sage: s2 = Sphere(2)
887
+ sage: s3 = Sphere(3)
888
+ sage: j = s2.join(s3)
889
+ sage: type(j)
890
+ <class 'sage.interfaces.kenzo.KenzoSimplicialSet'>
891
+ sage: [j.homology(i) for i in range(6)]
892
+ [Z, 0, 0, 0, 0, 0]
893
+ """
894
+ join_kenzo = __join__(self._kenzo, other._kenzo)
895
+ return KenzoSimplicialSet(join_kenzo)
896
+
897
+ def smash_product(self, other):
898
+ r"""
899
+ Return the smash product of ``self`` and ``other``.
900
+
901
+ INPUT:
902
+
903
+ - ``other`` -- the Kenzo simplicial set with which the smash product is made
904
+
905
+ OUTPUT: a :class:`KenzoSimplicialSet`
906
+
907
+ EXAMPLES::
908
+
909
+ sage: # optional - kenzo
910
+ sage: from sage.interfaces.kenzo import Sphere
911
+ sage: s2 = Sphere(2)
912
+ sage: s3 = Sphere(3)
913
+ sage: s = s2.smash_product(s3)
914
+ sage: type(s)
915
+ <class 'sage.interfaces.kenzo.KenzoSimplicialSet'>
916
+ sage: [s.homology(i) for i in range(6)]
917
+ [Z, 0, 0, 0, 0, Z]
918
+ """
919
+ smash_kenzo = __smash_product__(self._kenzo, other._kenzo)
920
+ return KenzoSimplicialSet(smash_kenzo)
921
+
922
+
923
+ class KenzoSimplicialGroup(KenzoSimplicialSet):
924
+ r"""
925
+ Wrapper around Kenzo simplicial groups.
926
+ """
927
+
928
+ def classifying_space(self):
929
+ r"""
930
+ Return the classifying space.
931
+
932
+ OUTPUT: a :class:`KenzoSimplicialGroup`
933
+
934
+ EXAMPLES::
935
+
936
+ sage: # optional - kenzo
937
+ sage: from sage.interfaces.kenzo import MooreSpace
938
+ sage: m2 = MooreSpace(2,4)
939
+ sage: l2 = m2.loop_space()
940
+ sage: c = l2.classifying_space()
941
+ sage: type(c)
942
+ <class 'sage.interfaces.kenzo.KenzoSimplicialGroup'>
943
+ sage: [c.homology(i) for i in range(8)]
944
+ [Z, 0, 0, 0, C2, 0, 0, 0]
945
+ """
946
+ return KenzoSimplicialGroup(__classifying_space__(self._kenzo))
947
+
948
+
949
+ def k2s_matrix(kmatrix):
950
+ r"""
951
+ Convert an array of ECL to a matrix of Sage.
952
+
953
+ INPUT:
954
+
955
+ - ``kmatrix`` -- an array in ECL
956
+
957
+ EXAMPLES::
958
+
959
+ sage: from sage.interfaces.kenzo import k2s_matrix # optional - kenzo
960
+ sage: from sage.libs.ecl import EclObject
961
+ sage: M = EclObject("#2A((1 2 3) (3 2 1) (1 1 1))")
962
+ sage: k2s_matrix(M) # optional - kenzo
963
+ [1 2 3]
964
+ [3 2 1]
965
+ [1 1 1]
966
+ """
967
+ dimensions = __array_dimensions__(kmatrix).python()
968
+ kmatrix_list = __make_array_to_lists__(kmatrix).python()
969
+ return matrix(dimensions[0], dimensions[1], kmatrix_list)
970
+
971
+
972
+ def s2k_matrix(smatrix):
973
+ r"""
974
+ Convert a matrix of Sage to an array of ECL.
975
+
976
+ INPUT:
977
+
978
+ - ``smatrix`` -- a matrix in Sage
979
+
980
+ OUTPUT: a :class:`EclObject`
981
+
982
+ EXAMPLES::
983
+
984
+ sage: from sage.interfaces.kenzo import s2k_matrix # optional - kenzo
985
+ sage: A = Matrix([[1,2,3],[3,2,1],[1,1,1]])
986
+ sage: s2k_matrix(A) # optional - kenzo
987
+ <ECL: #2A((1 2 3) (3 2 1) (1 1 1))>
988
+ """
989
+ initcontents = []
990
+ dimensions = smatrix.dimensions()
991
+ for i in smatrix.rows():
992
+ initcontents.append(i.list())
993
+ return __make_array_from_lists__(dimensions[0], dimensions[1], initcontents)
994
+
995
+
996
+ def s2k_dictmat(sdictmat):
997
+ r"""
998
+ Convert a dictionary in Sage, whose values are matrices, to an assoc list
999
+ in ECL.
1000
+
1001
+ INPUT:
1002
+
1003
+ - ``sdictmat`` -- dictionary in Sage
1004
+
1005
+ OUTPUT: a :class:`EclObject`
1006
+
1007
+ EXAMPLES::
1008
+
1009
+ sage: from sage.interfaces.kenzo import s2k_dictmat # optional - kenzo
1010
+ sage: A = Matrix([[1,2,3],[3,2,1],[1,1,1]])
1011
+ sage: B = Matrix([[1,2],[2,1],[1,1]])
1012
+ sage: d = {1 : A, 2 : B}
1013
+ sage: s2k_dictmat(d) # optional - kenzo
1014
+ <ECL: ((2 . #2A((1 2) (2 1) (1 1))) (1 . #2A((1 2 3) (3 2 1) (1 1 1))))>
1015
+ """
1016
+ rslt = EclObject([])
1017
+ for k in sdictmat.keys():
1018
+ rslt = EclObject(k).cons(s2k_matrix(sdictmat[k])).cons(rslt)
1019
+ return rslt
1020
+
1021
+
1022
+ def pairing(slist):
1023
+ r"""
1024
+ Convert a list of Sage (which has an even length) to an assoc list in ECL.
1025
+
1026
+ INPUT:
1027
+
1028
+ - ``slist`` -- list in Sage
1029
+
1030
+ OUTPUT: a :class:`EclObject`
1031
+
1032
+ EXAMPLES::
1033
+
1034
+ sage: from sage.interfaces.kenzo import pairing # optional - kenzo
1035
+ sage: l = [1,2,3]
1036
+ sage: pairing(l) # optional - kenzo
1037
+ <ECL: ((2 . 3))>
1038
+ """
1039
+ rslt = EclObject([])
1040
+ for k in range(len(slist) - 1, 0, -2):
1041
+ rslt = EclObject(slist[k - 1]).cons(EclObject(slist[k])).cons(rslt)
1042
+ return rslt
1043
+
1044
+
1045
+ def KChainComplex(chain_complex):
1046
+ r"""
1047
+ Construct a KenzoChainComplex from a ChainComplex of degree `-1` in
1048
+ Sage.
1049
+
1050
+ INPUT:
1051
+
1052
+ - ``chain_complex`` -- a ChainComplex of degree `-1`
1053
+
1054
+ OUTPUT: a KenzoChainComplex
1055
+
1056
+ EXAMPLES::
1057
+
1058
+ sage: # optional - kenzo
1059
+ sage: from sage.interfaces.kenzo import KChainComplex
1060
+ sage: m1 = matrix(ZZ, 3, 2, [-1, 1, 3, -4, 5, 6])
1061
+ sage: m4 = matrix(ZZ, 2, 2, [1, 2, 3, 6])
1062
+ sage: m5 = matrix(ZZ, 2, 3, [2, 2, 2, -1, -1, -1])
1063
+ sage: sage_chcm = ChainComplex({1: m1, 4: m4, 5: m5}, degree = -1)
1064
+ sage: kenzo_chcm = KChainComplex(sage_chcm)
1065
+ sage: kenzo_chcm
1066
+ [K... Chain-Complex]
1067
+ sage: kenzo_chcm.homology(5)
1068
+ Z x Z
1069
+ """
1070
+ d = chain_complex.differential()
1071
+ chcm = s2k_dictmat(d)
1072
+ str_orgn = str(d)[1:-1].replace(":", " ").replace(" ", ".").replace("\n", "").replace(",", "")
1073
+ return KenzoChainComplex(__kchaincomplex_aux1__(chcm, str_orgn))
1074
+
1075
+
1076
+ def SChainComplex(kchaincomplex, start=0, end=15):
1077
+ r"""
1078
+ Convert the KenzoChainComplex ``kchcm`` (between dimensions ``start`` and
1079
+ ``end``) to a ChainComplex.
1080
+
1081
+ INPUT:
1082
+
1083
+ - ``kchaincomplex`` -- a KenzoChainComplex
1084
+
1085
+ - ``start`` -- integer (default: 0)
1086
+
1087
+ - ``end`` -- integer greater than or equal to ``start`` (default: 15)
1088
+
1089
+ OUTPUT: a ChainComplex
1090
+
1091
+ EXAMPLES::
1092
+
1093
+ sage: from sage.interfaces.kenzo import KChainComplex, SChainComplex # optional - kenzo
1094
+ sage: m1 = matrix(ZZ, 3, 2, [-1, 1, 3, -4, 5, 6])
1095
+ sage: m4 = matrix(ZZ, 2, 2, [1, 2, 3, 6])
1096
+ sage: m5 = matrix(ZZ, 2, 3, [2, 2, 2, -1, -1, -1])
1097
+ sage: sage_chcm = ChainComplex({1: m1, 4: m4, 5: m5}, degree = -1) # optional - kenzo
1098
+ sage: SChainComplex(KChainComplex(sage_chcm)) == sage_chcm # optional - kenzo
1099
+ True
1100
+
1101
+ ::
1102
+
1103
+ sage: # optional - kenzo
1104
+ sage: from sage.interfaces.kenzo import SChainComplex, Sphere
1105
+ sage: S4 = Sphere(4)
1106
+ sage: C = SChainComplex(S4)
1107
+ sage: C
1108
+ Chain complex with at most 3 nonzero terms over Integer Ring
1109
+ sage: C._ascii_art_()
1110
+ 0 <-- C_4 <-- 0 ... 0 <-- C_0 <-- 0
1111
+ sage: [C.homology(i) for i in range(6)]
1112
+ [Z, 0, 0, 0, Z, 0]
1113
+ """
1114
+ matrices = {}
1115
+ for i in range(start, end):
1116
+ dffr_i = __chcm_mat2__(kchaincomplex._kenzo, i)
1117
+ nlig = __nlig__(dffr_i).python()
1118
+ ncol = __ncol__(dffr_i).python()
1119
+ if ((nlig != 0) and (ncol != 0)):
1120
+ matrices[i] = k2s_matrix(__convertmatrice__(dffr_i))
1121
+ else:
1122
+ matrices[i] = matrix(nlig, ncol)
1123
+ return ChainComplex(matrices, degree=-1)
1124
+
1125
+
1126
+ def SAbstractSimplex(simplex, dim):
1127
+ r"""
1128
+ Convert an abstract simplex of Kenzo to an AbstractSimplex.
1129
+
1130
+ INPUT:
1131
+
1132
+ - ``simplex`` -- an abstract simplex of Kenzo
1133
+
1134
+ - ``dim`` -- the dimension of ``simplex``
1135
+
1136
+ OUTPUT: an AbstractSimplex
1137
+
1138
+ EXAMPLES::
1139
+
1140
+ sage: # optional - kenzo
1141
+ sage: from sage.libs.ecl import EclObject, ecl_eval
1142
+ sage: from sage.interfaces.kenzo import (
1143
+ ....: KenzoObject, SAbstractSimplex)
1144
+ sage: KAbSm = KenzoObject(ecl_eval("(ABSM 15 'K)"))
1145
+ sage: SAbSm1 = SAbstractSimplex(KAbSm, 2)
1146
+ sage: SAbSm2 = SAbstractSimplex(KAbSm, 7)
1147
+ sage: SAbSm1.degeneracies()
1148
+ [3, 2, 1, 0]
1149
+ sage: SAbSm1.dimension()
1150
+ 6
1151
+ sage: SAbSm2.dimension()
1152
+ 11
1153
+ """
1154
+ degeneracies = __dgop_int_ext__(__dgop__(simplex._kenzo)).python()
1155
+ if degeneracies is None:
1156
+ degeneracies = []
1157
+ else:
1158
+ degeneracies = tuple(degeneracies)
1159
+ name = __gmsm__(simplex._kenzo).python()
1160
+ return AbstractSimplex(dim, degeneracies, name=name)
1161
+
1162
+
1163
+ def KAbstractSimplex(simplex):
1164
+ r"""
1165
+ Convert an AbstractSimplex in Sage to an abstract simplex of Kenzo.
1166
+
1167
+ INPUT:
1168
+
1169
+ - ``simplex`` -- an AbstractSimplex
1170
+
1171
+ OUTPUT: an abstract simplex of Kenzo
1172
+
1173
+ EXAMPLES::
1174
+
1175
+ sage: # optional - kenzo
1176
+ sage: from sage.topology.simplicial_set import AbstractSimplex
1177
+ sage: from sage.interfaces.kenzo import (
1178
+ ....: KAbstractSimplex, SAbstractSimplex)
1179
+ sage: SAbSm = AbstractSimplex(1, (2,0,3,2,1), name = 'SAbSm')
1180
+ sage: KAbSm = KAbstractSimplex(SAbSm)
1181
+ sage: SAbSm2 = SAbstractSimplex(KAbSm, 1)
1182
+ sage: SAbSm.degeneracies() == SAbSm2.degeneracies()
1183
+ True
1184
+ sage: SAbSm.dimension() == SAbSm2.dimension()
1185
+ True
1186
+ """
1187
+ return KenzoObject(__kabstractsimplex_aux1__(simplex.degeneracies(),
1188
+ 's' + str(hash(simplex))))
1189
+
1190
+
1191
+ def KFiniteSimplicialSet(sset):
1192
+ r"""
1193
+ Convert a finite SimplicialSet in Sage to a finite simplicial set of Kenzo.
1194
+
1195
+ INPUT:
1196
+
1197
+ - ``sset`` -- a finite SimplicialSet
1198
+
1199
+ OUTPUT: a finite simplicial set of Kenzo
1200
+
1201
+ EXAMPLES::
1202
+
1203
+ sage: # optional - kenzo
1204
+ sage: from sage.topology.simplicial_set import AbstractSimplex, SimplicialSet
1205
+ sage: from sage.interfaces.kenzo import KFiniteSimplicialSet
1206
+ sage: s0 = AbstractSimplex(0, name='s0')
1207
+ sage: s1 = AbstractSimplex(0, name='s1')
1208
+ sage: s2 = AbstractSimplex(0, name='s2')
1209
+ sage: s01 = AbstractSimplex(1, name='s01')
1210
+ sage: s02 = AbstractSimplex(1, name='s02')
1211
+ sage: s12 = AbstractSimplex(1, name='s12')
1212
+ sage: s012 = AbstractSimplex(2, name='s012')
1213
+ sage: Triangle = SimplicialSet({s01: (s1, s0),\
1214
+ ....: s02: (s2, s0), s12: (s2, s1)}, base_point = s0)
1215
+ sage: KTriangle = KFiniteSimplicialSet(Triangle)
1216
+ sage: KTriangle.homology(1)
1217
+ Z
1218
+ sage: KTriangle.basis(1)
1219
+ ['CELL_1_0', 'CELL_1_1', 'CELL_1_2']
1220
+ sage: S1 = simplicial_sets.Sphere(1)
1221
+ sage: S3 = simplicial_sets.Sphere(3)
1222
+ sage: KS1vS3 = KFiniteSimplicialSet(S1.wedge(S3))
1223
+ sage: KS1vS3.homology(3)
1224
+ Z
1225
+ """
1226
+ from sage.topology.simplicial_set_constructions import ProductOfSimplicialSets
1227
+ if isinstance(sset, ProductOfSimplicialSets):
1228
+ f0 = KFiniteSimplicialSet(sset.factor(0))
1229
+ for f1 in sset.factors()[1:]:
1230
+ f0 = f0.cartesian_product(KFiniteSimplicialSet(f1))
1231
+ return f0
1232
+ else:
1233
+ allcells = sset.cells()
1234
+ namecells = {c: 'cell_{}_{}'.format(d, allcells[d].index(c))
1235
+ for d in allcells for c in allcells[d]}
1236
+ dim = sset.dimension()
1237
+ list_rslt = [namecells[i] for i in sset.n_cells(0)]
1238
+ if (dim > 0):
1239
+ for k in range(1, dim + 1):
1240
+ k_cells = sset.n_cells(k)
1241
+ if k_cells:
1242
+ list_rslt.append(k)
1243
+ for x in k_cells:
1244
+ list_rslt.append(namecells[x])
1245
+ auxiliar_list = []
1246
+ for z in sset.faces(x):
1247
+ degen_z = z.degeneracies()
1248
+ name = namecells[z.nondegenerate()]
1249
+ degen_z.append(name)
1250
+ auxiliar_list.append(degen_z)
1251
+ list_rslt.append(auxiliar_list)
1252
+ return KenzoSimplicialSet(__build_finite_ss2__(list_rslt))
1253
+
1254
+
1255
+ def SFiniteSimplicialSet(ksimpset, limit):
1256
+ r"""
1257
+ Convert the ``limit``-skeleton of a finite simplicial set in Kenzo to a
1258
+ finite SimplicialSet in Sage.
1259
+
1260
+ INPUT:
1261
+
1262
+ - ``ksimpset`` -- a finite simplicial set in Kenzo
1263
+
1264
+ - ``limit`` -- a natural number
1265
+
1266
+ OUTPUT: a finite SimplicialSet
1267
+
1268
+ EXAMPLES::
1269
+
1270
+ sage: # optional - kenzo
1271
+ sage: from sage.topology.simplicial_set import SimplicialSet
1272
+ sage: from sage.interfaces.kenzo import (
1273
+ ....: AbstractSimplex, KFiniteSimplicialSet,
1274
+ ....: SFiniteSimplicialSet, Sphere)
1275
+ sage: s0 = AbstractSimplex(0, name='s0')
1276
+ sage: s1 = AbstractSimplex(0, name='s1')
1277
+ sage: s2 = AbstractSimplex(0, name='s2')
1278
+ sage: s01 = AbstractSimplex(1, name='s01')
1279
+ sage: s02 = AbstractSimplex(1, name='s02')
1280
+ sage: s12 = AbstractSimplex(1, name='s12')
1281
+ sage: s012 = AbstractSimplex(2, name='s012')
1282
+ sage: Triangle = SimplicialSet({s01: (s1, s0),
1283
+ ....: s02: (s2, s0),
1284
+ ....: s12: (s2, s1)},
1285
+ ....: base_point = s0)
1286
+ sage: KTriangle = KFiniteSimplicialSet(Triangle)
1287
+ sage: STriangle = SFiniteSimplicialSet(KTriangle, 1)
1288
+ sage: STriangle.homology()
1289
+ {0: 0, 1: Z}
1290
+ sage: S1 = simplicial_sets.Sphere(1)
1291
+ sage: S3 = simplicial_sets.Sphere(3)
1292
+ sage: KS1vS3 = KFiniteSimplicialSet(S1.wedge(S3))
1293
+ sage: SS1vS3 = SFiniteSimplicialSet(KS1vS3, 3)
1294
+ sage: SS1vS3.homology()
1295
+ {0: 0, 1: Z, 2: 0, 3: Z}
1296
+ """
1297
+ list_orgn = __orgn_aux1__(ksimpset._kenzo).python()
1298
+ if __nth__(0, list_orgn).python()[0] == 'CRTS-PRDC':
1299
+ return SFiniteSimplicialSet(
1300
+ KenzoSimplicialSet(__nth__(1, list_orgn)), limit).cartesian_product(
1301
+ SFiniteSimplicialSet(KenzoSimplicialSet(__nth__(2, list_orgn)), limit))
1302
+ rslt = {}
1303
+ simplices = []
1304
+ faces = []
1305
+ bases = []
1306
+ names = []
1307
+ for k in range(limit + 1):
1308
+ basis_k = __basis_aux1__(ksimpset._kenzo, k)
1309
+ names_k = ksimpset.basis(k)
1310
+ lbasis_k = [AbstractSimplex(k, name=i) for i in EclListIterator(basis_k)]
1311
+ bases.append(lbasis_k)
1312
+ names.append(names_k)
1313
+ all_simplices = __sfinitesimplicialset_aux1__(ksimpset._kenzo, limit)
1314
+ lall_simplices = list(EclListIterator(all_simplices))
1315
+ dim = 1
1316
+ for Kdim in lall_simplices:
1317
+ for simp in Kdim:
1318
+ index1 = names[dim].index(str(simp.car()))
1319
+ lKdim_cdr = []
1320
+ for i in EclListIterator(simp.cdr()):
1321
+ degenop = __dgop_int_ext__(__dgop__(i)).python()
1322
+ if degenop is None:
1323
+ degenop = []
1324
+ index2 = names[dim - len(degenop) - 1].index(str(__gmsm__(i)))
1325
+ lKdim_cdr.append(bases[dim - len(degenop) - 1][index2].apply_degeneracies(*degenop))
1326
+ simplices.append(bases[dim][index1])
1327
+ faces.append(tuple(lKdim_cdr))
1328
+ dim += 1
1329
+ for i in range(len(simplices)):
1330
+ rslt[simplices[i]] = faces[i]
1331
+ return SimplicialSet(rslt)
1332
+
1333
+
1334
+ class KenzoChainComplexMorphism(KenzoObject):
1335
+ r"""
1336
+ Wrapper to Kenzo morphisms between chain complexes.
1337
+ """
1338
+
1339
+ def source_complex(self):
1340
+ r"""
1341
+ Return the source chain complex of the morphism.
1342
+
1343
+ OUTPUT: a :class:`KenzoChainComplex`
1344
+
1345
+ EXAMPLES::
1346
+
1347
+ sage: # optional - kenzo
1348
+ sage: from sage.interfaces.kenzo import KChainComplex
1349
+ sage: m1 = matrix(ZZ, 3, 2, [-1, 1, 3, -4, 5, 6])
1350
+ sage: m4 = matrix(ZZ, 2, 2, [1, 2, 3, 6])
1351
+ sage: m5 = matrix(ZZ, 2, 3, [2, 2, 2, -1, -1, -1])
1352
+ sage: sage_chcm = ChainComplex({1: m1, 4: m4, 5: m5}, degree = -1)
1353
+ sage: kenzo_chcm = KChainComplex(sage_chcm)
1354
+ sage: kenzo_chcm
1355
+ [K... Chain-Complex]
1356
+ sage: differential_morphism = kenzo_chcm.differential()
1357
+ sage: differential_morphism
1358
+ [K... Morphism (degree -1): K... -> K...]
1359
+ sage: differential_morphism.source_complex()
1360
+ [K... Chain-Complex]
1361
+ """
1362
+ return KenzoChainComplex(__sorc_aux__(self._kenzo))
1363
+
1364
+ def target_complex(self):
1365
+ r"""
1366
+ Return the target chain complex of the morphism.
1367
+
1368
+ OUTPUT: a :class:`KenzoChainComplex`
1369
+
1370
+ EXAMPLES::
1371
+
1372
+ sage: # optional - kenzo
1373
+ sage: from sage.interfaces.kenzo import KChainComplex
1374
+ sage: m1 = matrix(ZZ, 3, 2, [-1, 1, 3, -4, 5, 6])
1375
+ sage: m4 = matrix(ZZ, 2, 2, [1, 2, 3, 6])
1376
+ sage: m5 = matrix(ZZ, 2, 3, [2, 2, 2, -1, -1, -1])
1377
+ sage: sage_chcm = ChainComplex({1: m1, 4: m4, 5: m5}, degree = -1)
1378
+ sage: kenzo_chcm = KChainComplex(sage_chcm)
1379
+ sage: kenzo_chcm
1380
+ [K... Chain-Complex]
1381
+ sage: differential_morphism = kenzo_chcm.differential()
1382
+ sage: differential_morphism
1383
+ [K... Morphism (degree -1): K... -> K...]
1384
+ sage: differential_morphism.target_complex()
1385
+ [K... Chain-Complex]
1386
+ """
1387
+ return KenzoChainComplex(__trgt_aux__(self._kenzo))
1388
+
1389
+ def degree(self):
1390
+ r"""
1391
+ Return the degree of the morphism.
1392
+
1393
+ OUTPUT: integer; the degree of the morphism
1394
+
1395
+ EXAMPLES::
1396
+
1397
+ sage: # optional - kenzo
1398
+ sage: from sage.interfaces.kenzo import KChainComplex
1399
+ sage: m1 = matrix(ZZ, 3, 2, [-1, 1, 3, -4, 5, 6])
1400
+ sage: m4 = matrix(ZZ, 2, 2, [1, 2, 3, 6])
1401
+ sage: m5 = matrix(ZZ, 2, 3, [2, 2, 2, -1, -1, -1])
1402
+ sage: sage_chcm = ChainComplex({1: m1, 4: m4, 5: m5}, degree=-1)
1403
+ sage: kenzo_chcm = KChainComplex(sage_chcm)
1404
+ sage: kenzo_chcm
1405
+ [K... Chain-Complex]
1406
+ sage: differential_morphism = kenzo_chcm.differential()
1407
+ sage: differential_morphism
1408
+ [K... Morphism (degree -1): K... -> K...]
1409
+ sage: differential_morphism.degree()
1410
+ -1
1411
+ sage: differential_morphism.composite(differential_morphism).degree()
1412
+ -2
1413
+ sage: kenzo_chcm.null_morphism().degree()
1414
+ 0
1415
+ """
1416
+ return __degr_aux__(self._kenzo).python()
1417
+
1418
+ def evaluation(self, dim, comb):
1419
+ r"""
1420
+ Apply the morphism on a combination ``comb`` of dimension ``dim``.
1421
+
1422
+ INPUT:
1423
+
1424
+ - ``dim`` -- integer
1425
+
1426
+ - ``comb`` -- list representing a formal sum of generators in the module
1427
+ of dimension ``dim``. For example, to represent G7G12 + 3*G7G0 - 5*G7G3
1428
+ we use the list [3, 'G7G0', -5, 'G7G3', 1, 'G7G12']. Note that the
1429
+ generators must be in ascending order respect to the number after the
1430
+ second G in their representation; the parameter
1431
+ ``comb`` = [1, 'G7G12', 3, 'G7G0', -5, 'G7G3'] will produce an error in
1432
+ Kenzo.
1433
+
1434
+ OUTPUT:
1435
+
1436
+ - A Kenzo combination representing the result of applying the morphism on the formal
1437
+ combination represented by ``comb`` in the chain complex ``self`` in
1438
+ dimension ``dim``.
1439
+
1440
+ EXAMPLES::
1441
+
1442
+ sage: # optional - kenzo
1443
+ sage: from sage.interfaces.kenzo import KChainComplex
1444
+ sage: m1 = matrix(ZZ, 3, 2, [-1, 1, 3, -4, 5, 6])
1445
+ sage: m4 = matrix(ZZ, 2, 2, [1, 2, 3, 6])
1446
+ sage: m5 = matrix(ZZ, 2, 3, [2, 2, 2, -1, -1, -1])
1447
+ sage: sage_chcm = ChainComplex({1: m1, 4: m4, 5: m5}, degree = -1)
1448
+ sage: kenzo_chcm = KChainComplex(sage_chcm)
1449
+ sage: kenzo_chcm
1450
+ [K... Chain-Complex]
1451
+ sage: differential_morphism = kenzo_chcm.differential()
1452
+ sage: differential_morphism
1453
+ [K... Morphism (degree -1): K... -> K...]
1454
+ sage: dif_squared = differential_morphism.composite(differential_morphism)
1455
+ sage: dif_squared
1456
+ [K... Morphism (degree -2): K... -> K...]
1457
+ sage: kenzo_chcm.basis(5)
1458
+ ['G5G0', 'G5G1', 'G5G2']
1459
+ sage: kenzo_chcm.differential(5, [1, 'G5G0', 2, 'G5G2'])
1460
+ <BLANKLINE>
1461
+ ----------------------------------------------------------------------{CMBN 4}
1462
+ <6 * G4G0>
1463
+ <-3 * G4G1>
1464
+ ------------------------------------------------------------------------------
1465
+ <BLANKLINE>
1466
+ sage: differential_morphism.evaluation(5, [1, 'G5G0', 2, 'G5G2'])
1467
+ <BLANKLINE>
1468
+ ----------------------------------------------------------------------{CMBN 4}
1469
+ <6 * G4G0>
1470
+ <-3 * G4G1>
1471
+ ------------------------------------------------------------------------------
1472
+ <BLANKLINE>
1473
+ sage: dif_squared.evaluation(5, [1, 'G5G0', 2, 'G5G2'])
1474
+ <BLANKLINE>
1475
+ ----------------------------------------------------------------------{CMBN 3}
1476
+ ------------------------------------------------------------------------------
1477
+ <BLANKLINE>
1478
+ sage: idnt = kenzo_chcm.identity_morphism()
1479
+ sage: idx2 = idnt.sum(idnt)
1480
+ sage: idnt.evaluation(5, [1, 'G5G0', 2, 'G5G2'])
1481
+ <BLANKLINE>
1482
+ ----------------------------------------------------------------------{CMBN 5}
1483
+ <1 * G5G0>
1484
+ <2 * G5G2>
1485
+ ------------------------------------------------------------------------------
1486
+ <BLANKLINE>
1487
+ sage: idx2.evaluation(5, [1, 'G5G0', 2, 'G5G2'])
1488
+ <BLANKLINE>
1489
+ ----------------------------------------------------------------------{CMBN 5}
1490
+ <2 * G5G0>
1491
+ <4 * G5G2>
1492
+ ------------------------------------------------------------------------------
1493
+ <BLANKLINE>
1494
+ """
1495
+ if dim.is_integer():
1496
+ if isinstance(comb, list):
1497
+ cmbn_list = pairing(comb)
1498
+ return KenzoObject(__evaluation_aux1__(self._kenzo, dim, cmbn_list))
1499
+ else:
1500
+ raise ValueError("'comb' parameter must be a list")
1501
+ else:
1502
+ raise ValueError("'dim' parameter must be an integer number")
1503
+
1504
+ def opposite(self):
1505
+ r"""
1506
+ Return the opposite morphism of ``self``, i.e., -1 x ``self``.
1507
+
1508
+ OUTPUT: a :class:`KenzoChainComplexMorphism`
1509
+
1510
+ EXAMPLES::
1511
+
1512
+ sage: # optional - kenzo
1513
+ sage: from sage.interfaces.kenzo import KChainComplex
1514
+ sage: m1 = matrix(ZZ, 3, 2, [-1, 1, 3, -4, 5, 6])
1515
+ sage: m4 = matrix(ZZ, 2, 2, [1, 2, 3, 6])
1516
+ sage: m5 = matrix(ZZ, 2, 3, [2, 2, 2, -1, -1, -1])
1517
+ sage: sage_chcm = ChainComplex({1: m1, 4: m4, 5: m5}, degree = -1)
1518
+ sage: kenzo_chcm = KChainComplex(sage_chcm)
1519
+ sage: kenzo_chcm
1520
+ [K... Chain-Complex]
1521
+ sage: idnt = kenzo_chcm.identity_morphism()
1522
+ sage: idnt
1523
+ [K... Morphism (degree 0): K... -> K...]
1524
+ sage: opps_id = idnt.opposite()
1525
+ sage: opps_id
1526
+ [K... Morphism (degree 0): K... -> K...]
1527
+ sage: kenzo_chcm.basis(4)
1528
+ ['G4G0', 'G4G1']
1529
+ sage: idnt.evaluation(4, [2, 'G4G0', -5, 'G4G1'])
1530
+ <BLANKLINE>
1531
+ ----------------------------------------------------------------------{CMBN 4}
1532
+ <2 * G4G0>
1533
+ <-5 * G4G1>
1534
+ ------------------------------------------------------------------------------
1535
+ <BLANKLINE>
1536
+ sage: opps_id.evaluation(4, [2, 'G4G0', -5, 'G4G1'])
1537
+ <BLANKLINE>
1538
+ ----------------------------------------------------------------------{CMBN 4}
1539
+ <-2 * G4G0>
1540
+ <5 * G4G1>
1541
+ ------------------------------------------------------------------------------
1542
+ <BLANKLINE>
1543
+ """
1544
+ return KenzoChainComplexMorphism(__opps__(self._kenzo))
1545
+
1546
+ def composite(self, object=None):
1547
+ r"""
1548
+ Return the composite of ``self`` and the morphism(s) given by the parameter ``object``.
1549
+
1550
+ INPUT:
1551
+
1552
+ - ``object`` -- a KenzoChainComplexMorphism instance, a
1553
+ KenzoChainComplex instance, a tuple of KenzoChainComplexMorphism and
1554
+ KenzoChainComplex instances, or ``None`` (default).
1555
+
1556
+ OUTPUT:
1557
+
1558
+ - A :class:`KenzoChainComplexMorphism`: if ``object`` is a KenzoChainComplexMorphism, the
1559
+ composite of ``self`` and ``object`` is returned; if ``object`` is a KenzoChainComplex,
1560
+ the composite of ``self`` and the differential morphism of ``object`` is returned; if
1561
+ ``object`` is a tuple, the composite of ``self`` and the morphisms or the differential
1562
+ morphisms of the given chain complexes in ``object`` is returned (if ``object`` is
1563
+ ``None``, ``self`` morphism is returned).
1564
+
1565
+ EXAMPLES::
1566
+
1567
+ sage: # optional - kenzo
1568
+ sage: from sage.interfaces.kenzo import Sphere
1569
+ sage: s2 = Sphere(2)
1570
+ sage: s3 = Sphere(3)
1571
+ sage: tp22 = s2.tensor_product(s2)
1572
+ sage: tp23 = s2.tensor_product(s3)
1573
+ sage: idnt = tp22.identity_morphism()
1574
+ sage: idnt
1575
+ [K... Morphism (degree 0): K... -> K...]
1576
+ sage: null = tp23.null_morphism(target = tp22, degree = 4)
1577
+ sage: null
1578
+ [K... Morphism (degree 4): K... -> K...]
1579
+ sage: idnt.composite((tp22, null))
1580
+ [K... Morphism (degree 3): K... -> K...]
1581
+ """
1582
+ if object is None:
1583
+ return self
1584
+ if isinstance(object, KenzoChainComplexMorphism):
1585
+ return KenzoChainComplexMorphism(__cmps__(self._kenzo, object._kenzo))
1586
+ elif isinstance(object, KenzoChainComplex):
1587
+ return KenzoChainComplexMorphism(__cmps__(self._kenzo, __dffr_aux__(object._kenzo)))
1588
+ elif isinstance(object, tuple):
1589
+ rslt = self._kenzo
1590
+ for mrph in object:
1591
+ rslt = __cmps__(rslt, mrph._kenzo)
1592
+ return KenzoChainComplexMorphism(rslt)
1593
+
1594
+ def sum(self, object=None):
1595
+ r"""
1596
+ Return a morphism, sum of the morphism ``self`` and the morphism(s) given
1597
+ by the parameter ``object``.
1598
+
1599
+ INPUT:
1600
+
1601
+ - ``object`` -- a KenzoChainComplexMorphism instance, a tuple of
1602
+ KenzoChainComplexMorphism instances or ``None`` (default)
1603
+
1604
+ OUTPUT:
1605
+
1606
+ A :class:`KenzoChainComplexMorphism`, sum of the morphism ``self``
1607
+ and the morphism(s given by ``object`` (if ``object`` is ``None``,
1608
+ ``self`` morphism is returned).
1609
+
1610
+ EXAMPLES::
1611
+
1612
+ sage: # optional - kenzo
1613
+ sage: from sage.interfaces.kenzo import KChainComplex
1614
+ sage: m1 = matrix(ZZ, 3, 2, [-1, 1, 3, -4, 5, 6])
1615
+ sage: m4 = matrix(ZZ, 2, 2, [1, 2, 3, 6])
1616
+ sage: m5 = matrix(ZZ, 2, 3, [2, 2, 2, -1, -1, -1])
1617
+ sage: sage_chcm = ChainComplex({1: m1, 4: m4, 5: m5}, degree = -1)
1618
+ sage: kenzo_chcm = KChainComplex(sage_chcm)
1619
+ sage: kenzo_chcm
1620
+ [K... Chain-Complex]
1621
+ sage: idnt = kenzo_chcm.identity_morphism()
1622
+ sage: idnt
1623
+ [K... Morphism (degree 0): K... -> K...]
1624
+ sage: opps_id = idnt.opposite()
1625
+ sage: opps_id
1626
+ [K... Morphism (degree 0): K... -> K...]
1627
+ sage: null = kenzo_chcm.null_morphism()
1628
+ sage: null
1629
+ [K... Morphism (degree 0): K... -> K...]
1630
+ sage: idx2 = idnt.sum(idnt)
1631
+ sage: idx5 = idx2.sum(
1632
+ ....: (opps_id, idnt, idnt, null, idx2.sum(idnt), opps_id))
1633
+ sage: kenzo_chcm.basis(4)
1634
+ ['G4G0', 'G4G1']
1635
+ sage: idx2.evaluation(4, [2, 'G4G0', -5, 'G4G1'])
1636
+ <BLANKLINE>
1637
+ ----------------------------------------------------------------------{CMBN 4}
1638
+ <4 * G4G0>
1639
+ <-10 * G4G1>
1640
+ ------------------------------------------------------------------------------
1641
+ <BLANKLINE>
1642
+ sage: idx5.evaluation(4, [2, 'G4G0', -5, 'G4G1'])
1643
+ <BLANKLINE>
1644
+ ----------------------------------------------------------------------{CMBN 4}
1645
+ <10 * G4G0>
1646
+ <-25 * G4G1>
1647
+ ------------------------------------------------------------------------------
1648
+ <BLANKLINE>
1649
+ """
1650
+ if object is None:
1651
+ return self
1652
+ if isinstance(object, KenzoChainComplexMorphism):
1653
+ return KenzoChainComplexMorphism(__add__(self._kenzo, object._kenzo))
1654
+ elif isinstance(object, tuple):
1655
+ rslt = self._kenzo
1656
+ for mrph in object:
1657
+ rslt = __add__(rslt, mrph._kenzo)
1658
+ return KenzoChainComplexMorphism(rslt)
1659
+
1660
+ def substract(self, object=None):
1661
+ r"""
1662
+ Return a morphism, difference of the morphism ``self`` and the
1663
+ morphism(s) given by the parameter ``object``.
1664
+
1665
+ INPUT:
1666
+
1667
+ - ``object`` -- a KenzoChainComplexMorphism instance, a tuple of
1668
+ KenzoChainComplexMorphism instances or ``None`` (default)
1669
+
1670
+ OUTPUT:
1671
+
1672
+ A :class:`KenzoChainComplexMorphism`, difference of the morphism
1673
+ ``self`` and the morphism(s) given by ``object`` (if ``object`` is
1674
+ ``None``, ``self`` morphism is returned). For example, if ``object`` =
1675
+ (mrph1, mrph2, mrph3) the result is ``self`` - mrph1 - mrph2 - mrph3.
1676
+
1677
+ EXAMPLES::
1678
+
1679
+ sage: # optional - kenzo
1680
+ sage: from sage.interfaces.kenzo import KChainComplex
1681
+ sage: m1 = matrix(ZZ, 3, 2, [-1, 1, 3, -4, 5, 6])
1682
+ sage: m4 = matrix(ZZ, 2, 2, [1, 2, 3, 6])
1683
+ sage: m5 = matrix(ZZ, 2, 3, [2, 2, 2, -1, -1, -1])
1684
+ sage: sage_chcm = ChainComplex({1: m1, 4: m4, 5: m5}, degree = -1)
1685
+ sage: kenzo_chcm = KChainComplex(sage_chcm)
1686
+ sage: kenzo_chcm
1687
+ [K... Chain-Complex]
1688
+ sage: idnt = kenzo_chcm.identity_morphism()
1689
+ sage: idnt
1690
+ [K... Morphism (degree 0): K... -> K...]
1691
+ sage: opps_id = idnt.opposite()
1692
+ sage: opps_id
1693
+ [K... Morphism (degree 0): K... -> K...]
1694
+ sage: null = kenzo_chcm.null_morphism()
1695
+ sage: null
1696
+ [K... Morphism (degree 0): K... -> K...]
1697
+ sage: idx2 = idnt.substract(opps_id)
1698
+ sage: opps_idx2 = idx2.substract(
1699
+ ....: (opps_id, idnt, idnt, null, idx2.substract(opps_id)))
1700
+ sage: kenzo_chcm.basis(4)
1701
+ ['G4G0', 'G4G1']
1702
+ sage: idx2.evaluation(4, [2, 'G4G0', -5, 'G4G1'])
1703
+ <BLANKLINE>
1704
+ ----------------------------------------------------------------------{CMBN 4}
1705
+ <4 * G4G0>
1706
+ <-10 * G4G1>
1707
+ ------------------------------------------------------------------------------
1708
+ <BLANKLINE>
1709
+ sage: opps_idx2.evaluation(4, [2, 'G4G0', -5, 'G4G1'])
1710
+ <BLANKLINE>
1711
+ ----------------------------------------------------------------------{CMBN 4}
1712
+ <-4 * G4G0>
1713
+ <10 * G4G1>
1714
+ ------------------------------------------------------------------------------
1715
+ <BLANKLINE>
1716
+ """
1717
+ if object is None:
1718
+ return self
1719
+ if isinstance(object, KenzoChainComplexMorphism):
1720
+ return KenzoChainComplexMorphism(__sbtr__(self._kenzo, object._kenzo))
1721
+ elif isinstance(object, tuple):
1722
+ rslt = self._kenzo
1723
+ for mrph in object:
1724
+ rslt = __sbtr__(rslt, mrph._kenzo)
1725
+ return KenzoChainComplexMorphism(rslt)
1726
+
1727
+ def change_source_target_complex(self, source=None, target=None):
1728
+ r"""
1729
+ Build, from the morphism ``self``, a new morphism with ``source``
1730
+ and ``target`` as source and target Kenzo chain complexes.
1731
+
1732
+ INPUT:
1733
+
1734
+ - ``source`` -- a KenzoChainComplex instance or ``None`` (default)
1735
+
1736
+ - ``target`` -- a KenzoChainComplex instance or ``None`` (default)
1737
+
1738
+ OUTPUT:
1739
+
1740
+ - A :class:`KenzoChainComplexMorphism` inheriting from ``self`` the
1741
+ degree (:degr slot in Kenzo), the algorithm (:intr slot in Kenzo)
1742
+ and the strategy (:strt slot in Kenzo). The source and target slots
1743
+ of this new morphism are given by the parameters ``source`` and
1744
+ ``target`` respectively; if any parameter is omitted,
1745
+ the corresponding slot is inherited from ``self``.
1746
+
1747
+ EXAMPLES::
1748
+
1749
+ sage: # optional - kenzo
1750
+ sage: from sage.interfaces.kenzo import Sphere, KenzoChainComplex
1751
+ sage: from sage.libs.ecl import ecl_eval
1752
+ sage: ZCC = KenzoChainComplex(ecl_eval("(z-chcm)"))
1753
+ sage: ZCC
1754
+ [K... Chain-Complex]
1755
+ sage: s2 = Sphere(2)
1756
+ sage: s3 = Sphere(3)
1757
+ sage: tp = s2.tensor_product(s3)
1758
+ sage: tp
1759
+ [K... Filtered-Chain-Complex]
1760
+ sage: null = ZCC.null_morphism(tp)
1761
+ sage: null
1762
+ [K... Morphism (degree 0): K... -> K...]
1763
+ sage: null.source_complex()
1764
+ [K... Chain-Complex]
1765
+ sage: null2 = null.change_source_target_complex(source = tp)
1766
+ sage: null2
1767
+ [K... Morphism (degree 0): K... -> K...]
1768
+ sage: null2.source_complex()
1769
+ [K... Filtered-Chain-Complex]
1770
+ """
1771
+ source = source or self.source_complex()
1772
+ target = target or self.target_complex()
1773
+ return KenzoChainComplexMorphism(
1774
+ __change_sorc_trgt_aux__(self._kenzo, source._kenzo, target._kenzo))
1775
+
1776
+ def destructive_change_source_target_complex(self, source=None, target=None):
1777
+ r"""
1778
+ Modify destructively the morphism ``self`` taking ``source``
1779
+ and ``target`` as source and target Kenzo chain complexes of ``self``.
1780
+
1781
+ INPUT:
1782
+
1783
+ - ``source`` -- a KenzoChainComplex instance or ``None`` (default)
1784
+
1785
+ - ``target`` -- a KenzoChainComplex instance or ``None`` (default)
1786
+
1787
+ OUTPUT:
1788
+
1789
+ - A :class:`KenzoChainComplexMorphism`. The source and target
1790
+ slots of ``self`` are replaced respectively by the
1791
+ parameters ``source`` and ``target``; if any parameter is
1792
+ omitted, the corresponding slot is inherited from ``self``.
1793
+
1794
+ EXAMPLES::
1795
+
1796
+ sage: # optional - kenzo
1797
+ sage: from sage.interfaces.kenzo import Sphere, KenzoChainComplex
1798
+ sage: from sage.libs.ecl import ecl_eval
1799
+ sage: ZCC = KenzoChainComplex(ecl_eval("(z-chcm)"))
1800
+ sage: ZCC
1801
+ [K... Chain-Complex]
1802
+ sage: s2 = Sphere(2)
1803
+ sage: s3 = Sphere(3)
1804
+ sage: tp = s2.tensor_product(s3)
1805
+ sage: tp
1806
+ [K... Filtered-Chain-Complex]
1807
+ sage: null = ZCC.null_morphism(tp)
1808
+ sage: null
1809
+ [K... Morphism (degree 0): K... -> K...]
1810
+ sage: null.target_complex()
1811
+ [K... Filtered-Chain-Complex]
1812
+ sage: null.destructive_change_source_target_complex(target = ZCC)
1813
+ [K... Cohomology-Class on K... of degree 0]
1814
+ sage: null.target_complex()
1815
+ [K... Chain-Complex]
1816
+ """
1817
+ source = source or self.source_complex()
1818
+ target = target or self.target_complex()
1819
+ return KenzoChainComplexMorphism(
1820
+ __dstr_change_sorc_trgt_aux__(self._kenzo, source._kenzo, target._kenzo))
1821
+
1822
+
1823
+ def build_morphism(source_complex, target_complex, degree, algorithm, strategy, orgn):
1824
+ r"""
1825
+ Build a morphism of chain complexes by means of the corresponding build-mrph Kenzo
1826
+ function.
1827
+
1828
+ INPUT:
1829
+
1830
+ - ``source_complex`` -- the source object as a KenzoChainComplex instance
1831
+
1832
+ - ``target_complex`` -- the target object as a KenzoChainComplex instance
1833
+
1834
+ - ``degree`` -- integer representing the degree of the morphism
1835
+
1836
+ - ``algorithm`` -- a Lisp function defining the mapping (:intr slot in Kenzo)
1837
+
1838
+ - ``strategy`` -- the strategy (:strt slot in Kenzo), which must be one of
1839
+ the two strings ``gnrt`` or ``cmbn``, depending if the ``algorithm`` (a Lisp
1840
+ function) uses as arguments a degree and a generator or a combination,
1841
+ respectively.
1842
+
1843
+ - ``orgn`` -- list containing a description about the origin of the morphism
1844
+
1845
+ OUTPUT: a :class:`KenzoChainComplexMorphism`
1846
+
1847
+ EXAMPLES::
1848
+
1849
+ sage: # optional - kenzo
1850
+ sage: from sage.interfaces.kenzo import (KenzoChainComplex,
1851
+ ....: build_morphism)
1852
+ sage: from sage.libs.ecl import ecl_eval
1853
+ sage: ZCC = KenzoChainComplex(ecl_eval("(z-chcm)"))
1854
+ sage: A = build_morphism(
1855
+ ....: ZCC, ZCC, -1,
1856
+ ....: ecl_eval("#'(lambda (comb) (cmbn (1- (degr comb))))"),
1857
+ ....: "cmbn", ["zero morphism on ZCC"])
1858
+ sage: A.target_complex()
1859
+ [K... Chain-Complex]
1860
+ sage: A.degree()
1861
+ -1
1862
+ sage: type(A)
1863
+ <class 'sage.interfaces.kenzo.KenzoChainComplexMorphism'>
1864
+ """
1865
+ return KenzoChainComplexMorphism(
1866
+ __build_mrph_aux__(source_complex._kenzo, target_complex._kenzo,
1867
+ degree, algorithm, ":" + strategy, orgn))
1868
+
1869
+
1870
+ def morphism_dictmat(morphism):
1871
+ r"""
1872
+ Compute a list of matrices in ECL associated to a morphism in Sage.
1873
+
1874
+ INPUT:
1875
+
1876
+ - ``morphism`` -- a morphism of chain complexes
1877
+
1878
+ OUTPUT: a :class:`EclObject`
1879
+
1880
+ EXAMPLES::
1881
+
1882
+ sage: from sage.interfaces.kenzo import morphism_dictmat # optional - kenzo
1883
+ sage: X = simplicial_complexes.Simplex(1)
1884
+ sage: Y = simplicial_complexes.Simplex(0)
1885
+ sage: g = Hom(X,Y)({0:0, 1:0})
1886
+ sage: f = g.associated_chain_complex_morphism()
1887
+ sage: morphism_dictmat(f) # optional - kenzo
1888
+ <ECL: ((2 . #2A()) (1 . #2A()) (0 . #2A((1 1))))>
1889
+ """
1890
+ rslt = EclObject([])
1891
+ source = morphism.domain()
1892
+ d = source.differential()
1893
+ for k in d.keys():
1894
+ rslt = EclObject(k).cons(s2k_matrix(morphism.in_degree(k))).cons(rslt)
1895
+ return rslt
1896
+
1897
+
1898
+ def KChainComplexMorphism(morphism):
1899
+ r"""
1900
+ Construct a KenzoChainComplexMorphism from a ChainComplexMorphism in Sage.
1901
+
1902
+ INPUT:
1903
+
1904
+ - ``morphism`` -- a morphism of chain complexes
1905
+
1906
+ OUTPUT: a :class:`KenzoChainComplexMorphism`
1907
+
1908
+ EXAMPLES::
1909
+
1910
+ sage: # optional - kenzo
1911
+ sage: from sage.interfaces.kenzo import KChainComplexMorphism
1912
+ sage: C = ChainComplex({0: identity_matrix(ZZ, 1)})
1913
+ sage: D = ChainComplex({0: zero_matrix(ZZ, 1), 1: zero_matrix(ZZ, 1)})
1914
+ sage: f = Hom(C,D)({0: identity_matrix(ZZ, 1), 1: zero_matrix(ZZ, 1)})
1915
+ sage: g = KChainComplexMorphism(f); g
1916
+ [K... Morphism (degree 0): K... -> K...]
1917
+ sage: g.source_complex()
1918
+ [K... Chain-Complex]
1919
+ sage: g.target_complex()
1920
+ [K... Chain-Complex]
1921
+ """
1922
+ source = KChainComplex(morphism.domain())
1923
+ target = KChainComplex(morphism.codomain())
1924
+ matrix_list = morphism_dictmat(morphism)
1925
+ return KenzoChainComplexMorphism(
1926
+ __kmorphismchaincomplex_aux1__(matrix_list, source._kenzo, target._kenzo))
1927
+
1928
+
1929
+ def s2k_listofmorphisms(l):
1930
+ r"""
1931
+ Compute a list of morphisms of chain complexes in Kenzo from a list of morphisms in Sage.
1932
+
1933
+ INPUT:
1934
+
1935
+ - ``l`` -- list of morphisms of chain complexes
1936
+
1937
+ OUTPUT: a :class:`EclObject`
1938
+
1939
+ EXAMPLES::
1940
+
1941
+ sage: from sage.interfaces.kenzo import s2k_listofmorphisms # optional - kenzo
1942
+ sage: C1 = ChainComplex({1: matrix(ZZ, 0, 2, [])}, degree_of_differential=-1)
1943
+ sage: C2 = ChainComplex({1: matrix(ZZ, 1, 2, [1, 0])},degree_of_differential=-1)
1944
+ sage: C3 = ChainComplex({0: matrix(ZZ, 0,2 , [])},degree_of_differential=-1)
1945
+ sage: M1 = Hom(C2,C1)({1: matrix(ZZ, 2, 2, [2, 0, 0, 2])})
1946
+ sage: M2 = Hom(C3,C2)({0: matrix(ZZ, 1, 2, [2, 0])})
1947
+ sage: l = [M1, M2]
1948
+ sage: s2k_listofmorphisms(l) # optional - kenzo
1949
+ <ECL: ([K... Morphism (degree 0): K... -> K...] [K... Morphism (degree 0): K... -> K...])>
1950
+ """
1951
+ rslt = EclObject([])
1952
+ for m in l:
1953
+ rslt = EclObject(KChainComplexMorphism(m)._kenzo).cons(rslt)
1954
+ return __nreverse__(rslt)
1955
+
1956
+
1957
+ def BicomplexSpectralSequence(l):
1958
+ r"""
1959
+ Construct the spectral sequence associated to the bicomplex given by a list of morphisms.
1960
+
1961
+ INPUT:
1962
+
1963
+ - ``l`` -- list of morphisms of chain complexes
1964
+
1965
+ OUTPUT: a :class:`KenzoSpectralSequence`
1966
+
1967
+ EXAMPLES::
1968
+
1969
+ sage: # optional - kenzo
1970
+ sage: from sage.interfaces.kenzo import BicomplexSpectralSequence
1971
+ sage: C1 = ChainComplex({1: matrix(ZZ, 0, 2, [])}, degree_of_differential=-1)
1972
+ sage: C2 = ChainComplex({1: matrix(ZZ, 1, 2, [1, 0])},degree_of_differential=-1)
1973
+ sage: C3 = ChainComplex({0: matrix(ZZ, 0,2 , [])},degree_of_differential=-1)
1974
+ sage: M1 = Hom(C2,C1)({1: matrix(ZZ, 2, 2, [2, 0, 0, 2])})
1975
+ sage: M2 = Hom(C3,C2)({0: matrix(ZZ, 1, 2, [2, 0])})
1976
+ sage: l = [M1, M2]
1977
+ sage: E = BicomplexSpectralSequence(l)
1978
+ sage: E.group(2,0,1)
1979
+ Additive abelian group isomorphic to Z/2 + Z
1980
+ sage: E.table(3,0,2,0,2)
1981
+ 0 0 0
1982
+ Z/2 + Z/4 0 0
1983
+ 0 0 Z
1984
+ sage: E.matrix(2,2,0)
1985
+ [ 0 0]
1986
+ [-4 0]
1987
+ """
1988
+ return KenzoSpectralSequence(__bicomplex_spectral_sequence__(s2k_listofmorphisms(l)))