passagemath-graphs 10.6.1rc1__cp310-cp310-musllinux_1_2_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.
- passagemath_graphs-10.6.1rc1.dist-info/METADATA +292 -0
- passagemath_graphs-10.6.1rc1.dist-info/RECORD +260 -0
- passagemath_graphs-10.6.1rc1.dist-info/WHEEL +5 -0
- passagemath_graphs-10.6.1rc1.dist-info/top_level.txt +2 -0
- passagemath_graphs.libs/libgcc_s-69c45f16.so.1 +0 -0
- passagemath_graphs.libs/libgmp-8e78bd9b.so.10.5.0 +0 -0
- passagemath_graphs.libs/libstdc++-1f1a71be.so.6.0.33 +0 -0
- sage/all__sagemath_graphs.py +39 -0
- sage/combinat/abstract_tree.py +2723 -0
- sage/combinat/all__sagemath_graphs.py +34 -0
- sage/combinat/binary_tree.py +5306 -0
- sage/combinat/cluster_algebra_quiver/all.py +22 -0
- sage/combinat/cluster_algebra_quiver/cluster_seed.py +5208 -0
- sage/combinat/cluster_algebra_quiver/interact.py +124 -0
- sage/combinat/cluster_algebra_quiver/mutation_class.py +625 -0
- sage/combinat/cluster_algebra_quiver/mutation_type.py +1555 -0
- sage/combinat/cluster_algebra_quiver/quiver.py +2290 -0
- sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py +2468 -0
- sage/combinat/designs/MOLS_handbook_data.py +570 -0
- sage/combinat/designs/all.py +58 -0
- sage/combinat/designs/bibd.py +1655 -0
- sage/combinat/designs/block_design.py +1071 -0
- sage/combinat/designs/covering_array.py +269 -0
- sage/combinat/designs/covering_design.py +530 -0
- sage/combinat/designs/database.py +5615 -0
- sage/combinat/designs/design_catalog.py +122 -0
- sage/combinat/designs/designs_pyx.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/designs/designs_pyx.pxd +21 -0
- sage/combinat/designs/designs_pyx.pyx +993 -0
- sage/combinat/designs/difference_family.py +3951 -0
- sage/combinat/designs/difference_matrices.py +279 -0
- sage/combinat/designs/evenly_distributed_sets.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/designs/evenly_distributed_sets.pyx +661 -0
- sage/combinat/designs/ext_rep.py +1064 -0
- sage/combinat/designs/gen_quadrangles_with_spread.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/designs/gen_quadrangles_with_spread.pyx +339 -0
- sage/combinat/designs/group_divisible_designs.py +361 -0
- sage/combinat/designs/incidence_structures.py +2357 -0
- sage/combinat/designs/latin_squares.py +581 -0
- sage/combinat/designs/orthogonal_arrays.py +2244 -0
- sage/combinat/designs/orthogonal_arrays_build_recursive.py +1780 -0
- sage/combinat/designs/orthogonal_arrays_find_recursive.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/designs/orthogonal_arrays_find_recursive.pyx +967 -0
- sage/combinat/designs/resolvable_bibd.py +815 -0
- sage/combinat/designs/steiner_quadruple_systems.py +1306 -0
- sage/combinat/designs/subhypergraph_search.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/designs/subhypergraph_search.pyx +530 -0
- sage/combinat/designs/twographs.py +306 -0
- sage/combinat/finite_state_machine.py +14874 -0
- sage/combinat/finite_state_machine_generators.py +2006 -0
- sage/combinat/graph_path.py +448 -0
- sage/combinat/interval_posets.py +3908 -0
- sage/combinat/nu_tamari_lattice.py +269 -0
- sage/combinat/ordered_tree.py +1446 -0
- sage/combinat/posets/all.py +46 -0
- sage/combinat/posets/bubble_shuffle.py +247 -0
- sage/combinat/posets/cartesian_product.py +493 -0
- sage/combinat/posets/d_complete.py +182 -0
- sage/combinat/posets/elements.py +273 -0
- sage/combinat/posets/forest.py +30 -0
- sage/combinat/posets/hasse_cython.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/posets/hasse_cython.pyx +174 -0
- sage/combinat/posets/hasse_diagram.py +3672 -0
- sage/combinat/posets/hochschild_lattice.py +158 -0
- sage/combinat/posets/incidence_algebras.py +794 -0
- sage/combinat/posets/lattices.py +5117 -0
- sage/combinat/posets/linear_extension_iterator.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/posets/linear_extension_iterator.pyx +292 -0
- sage/combinat/posets/linear_extensions.py +1037 -0
- sage/combinat/posets/mobile.py +275 -0
- sage/combinat/posets/moebius_algebra.py +776 -0
- sage/combinat/posets/poset_examples.py +2178 -0
- sage/combinat/posets/posets.py +9360 -0
- sage/combinat/rooted_tree.py +1070 -0
- sage/combinat/shard_order.py +239 -0
- sage/combinat/tamari_lattices.py +384 -0
- sage/combinat/yang_baxter_graph.py +923 -0
- sage/databases/all__sagemath_graphs.py +1 -0
- sage/databases/knotinfo_db.py +1231 -0
- sage/ext_data/all__sagemath_graphs.py +1 -0
- sage/ext_data/graphs/graph_plot_js.html +330 -0
- sage/ext_data/kenzo/CP2.txt +45 -0
- sage/ext_data/kenzo/CP3.txt +349 -0
- sage/ext_data/kenzo/CP4.txt +4774 -0
- sage/ext_data/kenzo/README.txt +49 -0
- sage/ext_data/kenzo/S4.txt +20 -0
- sage/graphs/all.py +42 -0
- sage/graphs/asteroidal_triples.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/asteroidal_triples.pyx +320 -0
- sage/graphs/base/all.py +1 -0
- sage/graphs/base/boost_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/boost_graph.pxd +106 -0
- sage/graphs/base/boost_graph.pyx +3045 -0
- sage/graphs/base/c_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/c_graph.pxd +106 -0
- sage/graphs/base/c_graph.pyx +5096 -0
- sage/graphs/base/dense_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/dense_graph.pxd +28 -0
- sage/graphs/base/dense_graph.pyx +801 -0
- sage/graphs/base/graph_backends.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/graph_backends.pxd +5 -0
- sage/graphs/base/graph_backends.pyx +797 -0
- sage/graphs/base/overview.py +85 -0
- sage/graphs/base/sparse_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/sparse_graph.pxd +90 -0
- sage/graphs/base/sparse_graph.pyx +1653 -0
- sage/graphs/base/static_dense_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/static_dense_graph.pxd +5 -0
- sage/graphs/base/static_dense_graph.pyx +1032 -0
- sage/graphs/base/static_sparse_backend.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/static_sparse_backend.pxd +27 -0
- sage/graphs/base/static_sparse_backend.pyx +1583 -0
- sage/graphs/base/static_sparse_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/static_sparse_graph.pxd +37 -0
- sage/graphs/base/static_sparse_graph.pyx +1375 -0
- sage/graphs/bipartite_graph.py +2732 -0
- sage/graphs/centrality.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/centrality.pyx +1038 -0
- sage/graphs/cographs.py +519 -0
- sage/graphs/comparability.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/comparability.pyx +851 -0
- sage/graphs/connectivity.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/connectivity.pxd +157 -0
- sage/graphs/connectivity.pyx +4813 -0
- sage/graphs/convexity_properties.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/convexity_properties.pxd +16 -0
- sage/graphs/convexity_properties.pyx +870 -0
- sage/graphs/digraph.py +4754 -0
- sage/graphs/digraph_generators.py +1993 -0
- sage/graphs/distances_all_pairs.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/distances_all_pairs.pxd +12 -0
- sage/graphs/distances_all_pairs.pyx +2938 -0
- sage/graphs/domination.py +1363 -0
- sage/graphs/dot2tex_utils.py +100 -0
- sage/graphs/edge_connectivity.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/edge_connectivity.pyx +1215 -0
- sage/graphs/generators/all.py +1 -0
- sage/graphs/generators/basic.py +1769 -0
- sage/graphs/generators/chessboard.py +538 -0
- sage/graphs/generators/classical_geometries.py +1611 -0
- sage/graphs/generators/degree_sequence.py +235 -0
- sage/graphs/generators/distance_regular.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/generators/distance_regular.pyx +2846 -0
- sage/graphs/generators/families.py +4759 -0
- sage/graphs/generators/intersection.py +565 -0
- sage/graphs/generators/platonic_solids.py +262 -0
- sage/graphs/generators/random.py +2623 -0
- sage/graphs/generators/smallgraphs.py +5741 -0
- sage/graphs/generators/world_map.py +724 -0
- sage/graphs/generic_graph.py +26867 -0
- sage/graphs/generic_graph_pyx.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/generic_graph_pyx.pxd +34 -0
- sage/graphs/generic_graph_pyx.pyx +1673 -0
- sage/graphs/genus.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/genus.pyx +622 -0
- sage/graphs/graph.py +9645 -0
- sage/graphs/graph_coloring.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_coloring.pyx +2284 -0
- sage/graphs/graph_database.py +1177 -0
- sage/graphs/graph_decompositions/all.py +1 -0
- sage/graphs/graph_decompositions/bandwidth.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/bandwidth.pyx +428 -0
- sage/graphs/graph_decompositions/clique_separators.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/clique_separators.pyx +616 -0
- sage/graphs/graph_decompositions/cutwidth.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/cutwidth.pyx +753 -0
- sage/graphs/graph_decompositions/fast_digraph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/fast_digraph.pxd +13 -0
- sage/graphs/graph_decompositions/fast_digraph.pyx +212 -0
- sage/graphs/graph_decompositions/graph_products.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/graph_products.pyx +508 -0
- sage/graphs/graph_decompositions/modular_decomposition.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/modular_decomposition.pxd +27 -0
- sage/graphs/graph_decompositions/modular_decomposition.pyx +1536 -0
- sage/graphs/graph_decompositions/slice_decomposition.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/slice_decomposition.pxd +18 -0
- sage/graphs/graph_decompositions/slice_decomposition.pyx +1106 -0
- sage/graphs/graph_decompositions/tree_decomposition.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/tree_decomposition.pxd +17 -0
- sage/graphs/graph_decompositions/tree_decomposition.pyx +1996 -0
- sage/graphs/graph_decompositions/vertex_separation.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/vertex_separation.pxd +5 -0
- sage/graphs/graph_decompositions/vertex_separation.pyx +1963 -0
- sage/graphs/graph_editor.py +82 -0
- sage/graphs/graph_generators.py +3314 -0
- sage/graphs/graph_generators_pyx.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_generators_pyx.pyx +95 -0
- sage/graphs/graph_input.py +812 -0
- sage/graphs/graph_latex.py +2064 -0
- sage/graphs/graph_list.py +410 -0
- sage/graphs/graph_plot.py +1756 -0
- sage/graphs/graph_plot_js.py +338 -0
- sage/graphs/hyperbolicity.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/hyperbolicity.pyx +1704 -0
- sage/graphs/hypergraph_generators.py +364 -0
- sage/graphs/independent_sets.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/independent_sets.pxd +13 -0
- sage/graphs/independent_sets.pyx +402 -0
- sage/graphs/isgci.py +1033 -0
- sage/graphs/isoperimetric_inequalities.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/isoperimetric_inequalities.pyx +489 -0
- sage/graphs/line_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/line_graph.pyx +743 -0
- sage/graphs/lovasz_theta.py +77 -0
- sage/graphs/matching.py +1633 -0
- sage/graphs/matching_covered_graph.py +3590 -0
- sage/graphs/orientations.py +1489 -0
- sage/graphs/partial_cube.py +459 -0
- sage/graphs/path_enumeration.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/path_enumeration.pyx +2040 -0
- sage/graphs/pq_trees.py +1129 -0
- sage/graphs/print_graphs.py +201 -0
- sage/graphs/schnyder.py +865 -0
- sage/graphs/spanning_tree.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/spanning_tree.pyx +1457 -0
- sage/graphs/strongly_regular_db.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/strongly_regular_db.pyx +3340 -0
- sage/graphs/traversals.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/traversals.pxd +9 -0
- sage/graphs/traversals.pyx +1872 -0
- sage/graphs/trees.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/trees.pxd +15 -0
- sage/graphs/trees.pyx +310 -0
- sage/graphs/tutte_polynomial.py +713 -0
- sage/graphs/views.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/views.pyx +794 -0
- sage/graphs/weakly_chordal.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/weakly_chordal.pyx +604 -0
- sage/groups/all__sagemath_graphs.py +1 -0
- sage/groups/perm_gps/all__sagemath_graphs.py +1 -0
- sage/groups/perm_gps/partn_ref/all__sagemath_graphs.py +1 -0
- sage/groups/perm_gps/partn_ref/refinement_graphs.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_graphs.pxd +38 -0
- sage/groups/perm_gps/partn_ref/refinement_graphs.pyx +1666 -0
- sage/knots/all.py +6 -0
- sage/knots/free_knotinfo_monoid.py +507 -0
- sage/knots/gauss_code.py +291 -0
- sage/knots/knot.py +682 -0
- sage/knots/knot_table.py +284 -0
- sage/knots/knotinfo.py +2900 -0
- sage/knots/link.py +4715 -0
- sage/sandpiles/all.py +13 -0
- sage/sandpiles/examples.py +225 -0
- sage/sandpiles/sandpile.py +6365 -0
- sage/topology/all.py +22 -0
- sage/topology/cell_complex.py +1214 -0
- sage/topology/cubical_complex.py +1976 -0
- sage/topology/delta_complex.py +1806 -0
- sage/topology/filtered_simplicial_complex.py +744 -0
- sage/topology/moment_angle_complex.py +823 -0
- sage/topology/simplicial_complex.py +5160 -0
- sage/topology/simplicial_complex_catalog.py +92 -0
- sage/topology/simplicial_complex_examples.py +1680 -0
- sage/topology/simplicial_complex_homset.py +205 -0
- sage/topology/simplicial_complex_morphism.py +836 -0
- sage/topology/simplicial_set.py +4102 -0
- sage/topology/simplicial_set_catalog.py +55 -0
- sage/topology/simplicial_set_constructions.py +2954 -0
- sage/topology/simplicial_set_examples.py +865 -0
- sage/topology/simplicial_set_morphism.py +1464 -0
@@ -0,0 +1,865 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-graphs
|
2
|
+
# sage.doctest: needs sage.graphs
|
3
|
+
r"""
|
4
|
+
Examples of simplicial sets.
|
5
|
+
|
6
|
+
These are accessible via ``simplicial_sets.Sphere(3)``,
|
7
|
+
``simplicial_sets.Torus()``, etc. Type ``simplicial_sets.[TAB]`` to
|
8
|
+
see a complete list.
|
9
|
+
|
10
|
+
AUTHORS:
|
11
|
+
|
12
|
+
- John H. Palmieri (2016-07)
|
13
|
+
|
14
|
+
- Miguel Marco (2022-12)
|
15
|
+
"""
|
16
|
+
# ****************************************************************************
|
17
|
+
# Copyright (C) 2016 John H. Palmieri <palmieri at math.washington.edu>
|
18
|
+
#
|
19
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
20
|
+
# https://www.gnu.org/licenses/
|
21
|
+
#
|
22
|
+
# This code is distributed in the hope that it will be useful,
|
23
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty
|
24
|
+
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
25
|
+
#
|
26
|
+
# See the GNU General Public License for more details; the full text
|
27
|
+
# is available at:
|
28
|
+
#
|
29
|
+
# https://www.gnu.org/licenses/
|
30
|
+
#
|
31
|
+
# ****************************************************************************
|
32
|
+
|
33
|
+
import re
|
34
|
+
from pathlib import Path
|
35
|
+
|
36
|
+
from sage.env import SAGE_ENV
|
37
|
+
from sage.misc.cachefunc import cached_method, cached_function
|
38
|
+
from sage.misc.latex import latex
|
39
|
+
from sage.rings.infinity import Infinity
|
40
|
+
from sage.rings.integer import Integer
|
41
|
+
from sage.structure.parent import Parent
|
42
|
+
|
43
|
+
from .delta_complex import delta_complexes
|
44
|
+
from .simplicial_set import AbstractSimplex, \
|
45
|
+
SimplicialSet_arbitrary, SimplicialSet_finite
|
46
|
+
|
47
|
+
import sage.topology.simplicial_complex_catalog as simplicial_complexes
|
48
|
+
|
49
|
+
from sage.misc.lazy_import import lazy_import
|
50
|
+
lazy_import('sage.categories.simplicial_sets', 'SimplicialSets')
|
51
|
+
|
52
|
+
kenzo_path = Path(SAGE_ENV['SAGE_EXTCODE']) / 'kenzo'
|
53
|
+
|
54
|
+
|
55
|
+
# ######################################################################
|
56
|
+
# The nerve of a finite monoid, used in sage.categories.finite_monoid.
|
57
|
+
|
58
|
+
class Nerve(SimplicialSet_arbitrary):
|
59
|
+
def __init__(self, monoid):
|
60
|
+
"""
|
61
|
+
The nerve of a multiplicative monoid.
|
62
|
+
|
63
|
+
INPUT:
|
64
|
+
|
65
|
+
- ``monoid`` -- a multiplicative monoid
|
66
|
+
|
67
|
+
See
|
68
|
+
:meth:`sage.categories.finite_monoids.FiniteMonoids.ParentMethods.nerve`
|
69
|
+
for full documentation.
|
70
|
+
|
71
|
+
EXAMPLES::
|
72
|
+
|
73
|
+
sage: M = FiniteMonoids().example()
|
74
|
+
sage: M
|
75
|
+
An example of a finite multiplicative monoid: the integers modulo 12
|
76
|
+
sage: X = M.nerve()
|
77
|
+
sage: list(M)
|
78
|
+
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
|
79
|
+
sage: X.n_cells(0)
|
80
|
+
[1]
|
81
|
+
sage: X.n_cells(1)
|
82
|
+
[0, 10, 11, 2, 3, 4, 5, 6, 7, 8, 9]
|
83
|
+
"""
|
84
|
+
category = SimplicialSets().Pointed()
|
85
|
+
Parent.__init__(self, category=category)
|
86
|
+
self.rename("Nerve of {}".format(str(monoid)))
|
87
|
+
self.rename_latex("B{}".format(latex(monoid)))
|
88
|
+
|
89
|
+
e = AbstractSimplex(0, name=str(monoid.one()),
|
90
|
+
latex_name=latex(monoid.one()))
|
91
|
+
self._basepoint = e
|
92
|
+
vertex = SimplicialSet_finite({e: None}, base_point=e)
|
93
|
+
# self._n_skeleton: cache the highest dimensional skeleton
|
94
|
+
# calculated so far for this simplicial set, along with its
|
95
|
+
# dimension.
|
96
|
+
self._n_skeleton = (0, vertex)
|
97
|
+
self._monoid = monoid
|
98
|
+
# self._simplex_data: a tuple whose elements are pairs (simplex, list
|
99
|
+
# of monoid elements). Omit the base point.
|
100
|
+
self._simplex_data = ()
|
101
|
+
|
102
|
+
def __eq__(self, other) -> bool:
|
103
|
+
"""
|
104
|
+
Return ``True`` if ``self`` and ``other`` are equal.
|
105
|
+
|
106
|
+
This checks that the underlying monoids and the underlying
|
107
|
+
base points are the same. Because the base points will be
|
108
|
+
different each time the nerve is constructed, different
|
109
|
+
instances will not be equal.
|
110
|
+
|
111
|
+
EXAMPLES::
|
112
|
+
|
113
|
+
sage: # needs sage.groups
|
114
|
+
sage: C3 = groups.misc.MultiplicativeAbelian([3])
|
115
|
+
sage: C3.nerve() == C3.nerve()
|
116
|
+
False
|
117
|
+
sage: BC3 = C3.nerve()
|
118
|
+
sage: BC3 == BC3
|
119
|
+
True
|
120
|
+
"""
|
121
|
+
return (isinstance(other, Nerve)
|
122
|
+
and self._monoid == other._monoid
|
123
|
+
and self.base_point() == other.base_point())
|
124
|
+
|
125
|
+
def __ne__(self, other) -> bool:
|
126
|
+
"""
|
127
|
+
Return the negation of ``__eq__``.
|
128
|
+
|
129
|
+
EXAMPLES::
|
130
|
+
|
131
|
+
sage: # needs sage.groups
|
132
|
+
sage: C3 = groups.misc.MultiplicativeAbelian([3])
|
133
|
+
sage: G3 = groups.permutation.Cyclic(3)
|
134
|
+
sage: C3.nerve() != G3.nerve()
|
135
|
+
True
|
136
|
+
sage: C3.nerve() != C3.nerve()
|
137
|
+
True
|
138
|
+
"""
|
139
|
+
return not self == other
|
140
|
+
|
141
|
+
@cached_method
|
142
|
+
def __hash__(self):
|
143
|
+
"""
|
144
|
+
The hash is formed from the monoid and the base point.
|
145
|
+
|
146
|
+
EXAMPLES::
|
147
|
+
|
148
|
+
sage: G3 = groups.permutation.Cyclic(3) # needs sage.groups
|
149
|
+
sage: hash(G3.nerve()) # random # needs sage.groups
|
150
|
+
17
|
151
|
+
|
152
|
+
Different instances yield different base points, hence different hashes::
|
153
|
+
|
154
|
+
sage: # needs sage.groups
|
155
|
+
sage: X = G3.nerve()
|
156
|
+
sage: Y = G3.nerve()
|
157
|
+
sage: X.base_point() != Y.base_point()
|
158
|
+
True
|
159
|
+
sage: hash(X) != hash(Y)
|
160
|
+
True
|
161
|
+
"""
|
162
|
+
return hash(self._monoid) ^ hash(self.base_point())
|
163
|
+
|
164
|
+
def n_skeleton(self, n):
|
165
|
+
"""
|
166
|
+
Return the `n`-skeleton of this simplicial set.
|
167
|
+
|
168
|
+
That is, the simplicial set generated by all nondegenerate
|
169
|
+
simplices of dimension at most `n`.
|
170
|
+
|
171
|
+
INPUT:
|
172
|
+
|
173
|
+
- ``n`` -- the dimension
|
174
|
+
|
175
|
+
EXAMPLES::
|
176
|
+
|
177
|
+
sage: # needs sage.groups
|
178
|
+
sage: K4 = groups.misc.MultiplicativeAbelian([2,2])
|
179
|
+
sage: BK4 = simplicial_sets.ClassifyingSpace(K4)
|
180
|
+
sage: BK4.n_skeleton(3)
|
181
|
+
Simplicial set with 40 non-degenerate simplices
|
182
|
+
sage: BK4.n_cells(1) == BK4.n_skeleton(3).n_cells(1)
|
183
|
+
True
|
184
|
+
sage: BK4.n_cells(3) == BK4.n_skeleton(1).n_cells(3)
|
185
|
+
False
|
186
|
+
"""
|
187
|
+
from .simplicial_set_constructions import SubSimplicialSet
|
188
|
+
monoid = self._monoid
|
189
|
+
one = monoid.one()
|
190
|
+
# Build up chains of elements inductively, from dimension d-1
|
191
|
+
# to dimension d. We start with the cached
|
192
|
+
# self._n_skeleton. If only the 0-skeleton has been
|
193
|
+
# constructed, we construct the 1-cells by hand.
|
194
|
+
start, skel = self._n_skeleton
|
195
|
+
if start == n:
|
196
|
+
return skel
|
197
|
+
elif start > n:
|
198
|
+
return skel.n_skeleton(n)
|
199
|
+
|
200
|
+
# There is a single vertex. Name it after the identity
|
201
|
+
# element of the monoid.
|
202
|
+
e = skel.n_cells(0)[0]
|
203
|
+
# Build the dictionary simplices, to be used for
|
204
|
+
# constructing the simplicial set.
|
205
|
+
simplices = skel.face_data()
|
206
|
+
|
207
|
+
# face_dict: dictionary of simplices: keys are
|
208
|
+
# composites of monoid elements (as tuples), values are
|
209
|
+
# the corresponding simplices.
|
210
|
+
face_dict = dict(self._simplex_data)
|
211
|
+
|
212
|
+
if start == 0:
|
213
|
+
for g in monoid:
|
214
|
+
if g != one:
|
215
|
+
x = AbstractSimplex(1, name=str(g), latex_name=latex(g))
|
216
|
+
simplices[x] = (e, e)
|
217
|
+
face_dict[(g,)] = x
|
218
|
+
start = 1
|
219
|
+
|
220
|
+
for d in range(start + 1, n + 1):
|
221
|
+
for g in monoid:
|
222
|
+
if g == one:
|
223
|
+
continue
|
224
|
+
new_faces = {}
|
225
|
+
for t in face_dict.keys():
|
226
|
+
if len(t) != d - 1:
|
227
|
+
continue
|
228
|
+
# chain: chain of group elements to multiply,
|
229
|
+
# as a tuple.
|
230
|
+
chain = t + (g,)
|
231
|
+
# bdries: the face maps applied to chain, in a
|
232
|
+
# format suitable for passing to the DeltaComplex
|
233
|
+
# constructor.
|
234
|
+
x = AbstractSimplex(d,
|
235
|
+
name=' * '.join(str(_) for _ in chain),
|
236
|
+
latex_name=' * '.join(latex(_) for _ in chain))
|
237
|
+
new_faces[chain] = x
|
238
|
+
|
239
|
+
# Compute faces of x.
|
240
|
+
faces = [face_dict[chain[1:]]]
|
241
|
+
for i in range(d - 1):
|
242
|
+
product = chain[i] * chain[i + 1]
|
243
|
+
if product == one:
|
244
|
+
# Degenerate.
|
245
|
+
if d == 2:
|
246
|
+
face = e.apply_degeneracies(i)
|
247
|
+
else:
|
248
|
+
face = (face_dict[chain[:i]
|
249
|
+
+ chain[i+2:]].apply_degeneracies(i))
|
250
|
+
else:
|
251
|
+
# Non-degenerate.
|
252
|
+
face = (face_dict[chain[:i]
|
253
|
+
+ (product,) + chain[i+2:]])
|
254
|
+
faces.append(face)
|
255
|
+
faces.append(face_dict[chain[:-1]])
|
256
|
+
simplices[x] = faces
|
257
|
+
face_dict.update(new_faces)
|
258
|
+
|
259
|
+
K = SubSimplicialSet(simplices, self)
|
260
|
+
self._n_skeleton = (n, K)
|
261
|
+
self._simplex_data = face_dict.items()
|
262
|
+
return K
|
263
|
+
|
264
|
+
|
265
|
+
########################################################################
|
266
|
+
# Catalog of examples. These are accessed via simplicial_set_catalog.py.
|
267
|
+
|
268
|
+
def Sphere(n):
|
269
|
+
r"""
|
270
|
+
Return the `n`-sphere as a simplicial set.
|
271
|
+
|
272
|
+
It is constructed with two non-degenerate simplices: a vertex
|
273
|
+
`v_0` (which is the base point) and an `n`-simplex `\sigma_n`.
|
274
|
+
|
275
|
+
INPUT:
|
276
|
+
|
277
|
+
- ``n`` -- integer
|
278
|
+
|
279
|
+
EXAMPLES::
|
280
|
+
|
281
|
+
sage: S0 = simplicial_sets.Sphere(0)
|
282
|
+
sage: S0
|
283
|
+
S^0
|
284
|
+
sage: S0.nondegenerate_simplices()
|
285
|
+
[v_0, w_0]
|
286
|
+
sage: S0.is_pointed()
|
287
|
+
True
|
288
|
+
sage: simplicial_sets.Sphere(4)
|
289
|
+
S^4
|
290
|
+
sage: latex(simplicial_sets.Sphere(4))
|
291
|
+
S^{4}
|
292
|
+
sage: simplicial_sets.Sphere(4).nondegenerate_simplices()
|
293
|
+
[v_0, sigma_4]
|
294
|
+
"""
|
295
|
+
v_0 = AbstractSimplex(0, name='v_0')
|
296
|
+
if n == 0:
|
297
|
+
w_0 = AbstractSimplex(0, name='w_0')
|
298
|
+
return SimplicialSet_finite({v_0: None, w_0: None}, base_point=v_0,
|
299
|
+
name='S^0')
|
300
|
+
degens = range(n - 2, -1, -1)
|
301
|
+
degen_v = v_0.apply_degeneracies(*degens)
|
302
|
+
sigma = AbstractSimplex(n, name='sigma_{}'.format(n),
|
303
|
+
latex_name='\\sigma_{}'.format(n))
|
304
|
+
return SimplicialSet_finite({sigma: [degen_v] * (n + 1)}, base_point=v_0,
|
305
|
+
name='S^{}'.format(n),
|
306
|
+
latex_name='S^{{{}}}'.format(n))
|
307
|
+
|
308
|
+
|
309
|
+
def ClassifyingSpace(group):
|
310
|
+
r"""
|
311
|
+
Return the classifying space of ``group``, as a simplicial set.
|
312
|
+
|
313
|
+
INPUT:
|
314
|
+
|
315
|
+
- ``group`` -- a finite group or finite monoid
|
316
|
+
|
317
|
+
See
|
318
|
+
:meth:`sage.categories.finite_monoids.FiniteMonoids.ParentMethods.nerve`
|
319
|
+
for more details and more examples.
|
320
|
+
|
321
|
+
EXAMPLES::
|
322
|
+
|
323
|
+
sage: # needs sage.groups
|
324
|
+
sage: C2 = groups.misc.MultiplicativeAbelian([2])
|
325
|
+
sage: BC2 = simplicial_sets.ClassifyingSpace(C2)
|
326
|
+
sage: H = BC2.homology(range(9), base_ring=GF(2)) # needs sage.modules
|
327
|
+
sage: [H[i].dimension() for i in range(9)] # needs sage.modules
|
328
|
+
[0, 1, 1, 1, 1, 1, 1, 1, 1]
|
329
|
+
|
330
|
+
sage: Klein4 = groups.misc.MultiplicativeAbelian([2, 2]) # needs sage.groups
|
331
|
+
sage: BK = simplicial_sets.ClassifyingSpace(Klein4); BK # needs sage.groups
|
332
|
+
Classifying space of Multiplicative Abelian group isomorphic to C2 x C2
|
333
|
+
sage: BK.homology(range(5), base_ring=GF(2)) # long time (1 second) # needs sage.groups sage.modules
|
334
|
+
{0: Vector space of dimension 0 over Finite Field of size 2,
|
335
|
+
1: Vector space of dimension 2 over Finite Field of size 2,
|
336
|
+
2: Vector space of dimension 3 over Finite Field of size 2,
|
337
|
+
3: Vector space of dimension 4 over Finite Field of size 2,
|
338
|
+
4: Vector space of dimension 5 over Finite Field of size 2}
|
339
|
+
"""
|
340
|
+
X = group.nerve()
|
341
|
+
X.rename('Classifying space of {}'.format(group))
|
342
|
+
return X
|
343
|
+
|
344
|
+
|
345
|
+
def RealProjectiveSpace(n):
|
346
|
+
r"""
|
347
|
+
Return real `n`-dimensional projective space, as a simplicial set.
|
348
|
+
|
349
|
+
This is constructed as the `n`-skeleton of the nerve of the group
|
350
|
+
of order 2, and therefore has a single non-degenerate simplex in
|
351
|
+
each dimension up to `n`.
|
352
|
+
|
353
|
+
EXAMPLES::
|
354
|
+
|
355
|
+
sage: # needs sage.groups
|
356
|
+
sage: simplicial_sets.RealProjectiveSpace(7)
|
357
|
+
RP^7
|
358
|
+
sage: RP5 = simplicial_sets.RealProjectiveSpace(5)
|
359
|
+
sage: RP5.homology()
|
360
|
+
{0: 0, 1: C2, 2: 0, 3: C2, 4: 0, 5: Z}
|
361
|
+
sage: RP5
|
362
|
+
RP^5
|
363
|
+
sage: latex(RP5)
|
364
|
+
RP^{5}
|
365
|
+
|
366
|
+
sage: BC2 = simplicial_sets.RealProjectiveSpace(Infinity) # needs sage.groups
|
367
|
+
sage: latex(BC2) # needs sage.groups
|
368
|
+
RP^{\infty}
|
369
|
+
"""
|
370
|
+
if n == Infinity:
|
371
|
+
from sage.groups.abelian_gps.abelian_group import AbelianGroup
|
372
|
+
|
373
|
+
X = AbelianGroup([2]).nerve()
|
374
|
+
X.rename('RP^oo')
|
375
|
+
X.rename_latex('RP^{\\infty}')
|
376
|
+
else:
|
377
|
+
X = RealProjectiveSpace(Infinity).n_skeleton(n)
|
378
|
+
X.rename('RP^{}'.format(n))
|
379
|
+
X.rename_latex('RP^{{{}}}'.format(n))
|
380
|
+
return X
|
381
|
+
|
382
|
+
|
383
|
+
def KleinBottle():
|
384
|
+
r"""
|
385
|
+
Return the Klein bottle as a simplicial set.
|
386
|
+
|
387
|
+
This converts the `\Delta`-complex version to a simplicial set. It
|
388
|
+
has one 0-simplex, three 1-simplices, and two 2-simplices.
|
389
|
+
|
390
|
+
EXAMPLES::
|
391
|
+
|
392
|
+
sage: K = simplicial_sets.KleinBottle()
|
393
|
+
sage: K.f_vector()
|
394
|
+
[1, 3, 2]
|
395
|
+
sage: K.homology(reduced=False) # needs sage.modules
|
396
|
+
{0: Z, 1: Z x C2, 2: 0}
|
397
|
+
sage: K
|
398
|
+
Klein bottle
|
399
|
+
"""
|
400
|
+
temp = SimplicialSet_finite(delta_complexes.KleinBottle())
|
401
|
+
pt = temp.n_cells(0)[0]
|
402
|
+
return SimplicialSet_finite(temp.face_data(), base_point=pt,
|
403
|
+
name='Klein bottle')
|
404
|
+
|
405
|
+
|
406
|
+
def Torus():
|
407
|
+
r"""
|
408
|
+
Return the torus as a simplicial set.
|
409
|
+
|
410
|
+
This computes the product of the circle with itself, where the
|
411
|
+
circle is represented using a single 0-simplex and a single
|
412
|
+
1-simplex. Thus it has one 0-simplex, three 1-simplices, and two
|
413
|
+
2-simplices.
|
414
|
+
|
415
|
+
EXAMPLES::
|
416
|
+
|
417
|
+
sage: T = simplicial_sets.Torus()
|
418
|
+
sage: T.f_vector()
|
419
|
+
[1, 3, 2]
|
420
|
+
sage: T.homology(reduced=False) # needs sage.modules
|
421
|
+
{0: Z, 1: Z x Z, 2: Z}
|
422
|
+
"""
|
423
|
+
S1 = Sphere(1)
|
424
|
+
T = S1.product(S1)
|
425
|
+
T.rename('Torus')
|
426
|
+
return T
|
427
|
+
|
428
|
+
|
429
|
+
def Simplex(n):
|
430
|
+
r"""
|
431
|
+
Return the `n`-simplex as a simplicial set.
|
432
|
+
|
433
|
+
EXAMPLES::
|
434
|
+
|
435
|
+
sage: K = simplicial_sets.Simplex(2)
|
436
|
+
sage: K
|
437
|
+
2-simplex
|
438
|
+
sage: latex(K)
|
439
|
+
\Delta^{2}
|
440
|
+
sage: K.n_cells(0)
|
441
|
+
[(0,), (1,), (2,)]
|
442
|
+
sage: K.n_cells(1)
|
443
|
+
[(0, 1), (0, 2), (1, 2)]
|
444
|
+
sage: K.n_cells(2)
|
445
|
+
[(0, 1, 2)]
|
446
|
+
"""
|
447
|
+
return SimplicialSet_finite(simplicial_complexes.Simplex(n),
|
448
|
+
name='{}-simplex'.format(n),
|
449
|
+
latex_name='\\Delta^{{{}}}'.format(n))
|
450
|
+
|
451
|
+
|
452
|
+
@cached_function
|
453
|
+
def Empty():
|
454
|
+
"""
|
455
|
+
Return the empty simplicial set.
|
456
|
+
|
457
|
+
This should return the same simplicial set each time it is called.
|
458
|
+
|
459
|
+
EXAMPLES::
|
460
|
+
|
461
|
+
sage: from sage.topology.simplicial_set_examples import Empty
|
462
|
+
sage: E = Empty()
|
463
|
+
sage: E
|
464
|
+
Empty simplicial set
|
465
|
+
sage: E.nondegenerate_simplices()
|
466
|
+
[]
|
467
|
+
sage: E is Empty()
|
468
|
+
True
|
469
|
+
"""
|
470
|
+
return SimplicialSet_finite({}, name='Empty simplicial set')
|
471
|
+
|
472
|
+
|
473
|
+
@cached_function
|
474
|
+
def Point():
|
475
|
+
"""
|
476
|
+
Return a single point called "*" as a simplicial set.
|
477
|
+
|
478
|
+
This should return the same simplicial set each time it is called.
|
479
|
+
|
480
|
+
EXAMPLES::
|
481
|
+
|
482
|
+
sage: P = simplicial_sets.Point()
|
483
|
+
sage: P.is_pointed()
|
484
|
+
True
|
485
|
+
sage: P.nondegenerate_simplices()
|
486
|
+
[*]
|
487
|
+
|
488
|
+
sage: Q = simplicial_sets.Point()
|
489
|
+
sage: P is Q
|
490
|
+
True
|
491
|
+
sage: P == Q
|
492
|
+
True
|
493
|
+
"""
|
494
|
+
star = AbstractSimplex(0, name='*')
|
495
|
+
return SimplicialSet_finite({star: None}, base_point=star,
|
496
|
+
name='Point',
|
497
|
+
latex_name='*')
|
498
|
+
|
499
|
+
|
500
|
+
def Horn(n, k):
|
501
|
+
r"""
|
502
|
+
Return the horn `\Lambda^n_k`.
|
503
|
+
|
504
|
+
This is the subsimplicial set of the `n`-simplex obtained by
|
505
|
+
removing its `k`-th face.
|
506
|
+
|
507
|
+
EXAMPLES::
|
508
|
+
|
509
|
+
sage: L = simplicial_sets.Horn(3, 0)
|
510
|
+
sage: L
|
511
|
+
(3, 0)-Horn
|
512
|
+
sage: L.n_cells(3)
|
513
|
+
[]
|
514
|
+
sage: L.n_cells(2)
|
515
|
+
[(0, 1, 2), (0, 1, 3), (0, 2, 3)]
|
516
|
+
|
517
|
+
sage: L20 = simplicial_sets.Horn(2, 0)
|
518
|
+
sage: latex(L20)
|
519
|
+
\Lambda^{2}_{0}
|
520
|
+
sage: L20.inclusion_map()
|
521
|
+
Simplicial set morphism:
|
522
|
+
From: (2, 0)-Horn
|
523
|
+
To: 2-simplex
|
524
|
+
Defn: [(0,), (1,), (2,), (0, 1), (0, 2)] --> [(0,), (1,), (2,), (0, 1), (0, 2)]
|
525
|
+
"""
|
526
|
+
K = Simplex(n)
|
527
|
+
sigma = K.n_cells(n)[0]
|
528
|
+
L = K.subsimplicial_set(K.faces(sigma)[:k] + K.faces(sigma)[k+1:])
|
529
|
+
L.rename('({}, {})-Horn'.format(n, k))
|
530
|
+
L.rename_latex('\\Lambda^{{{}}}_{{{}}}'.format(n, k))
|
531
|
+
return L
|
532
|
+
|
533
|
+
|
534
|
+
def ComplexProjectiveSpace(n):
|
535
|
+
r"""
|
536
|
+
Return complex `n`-dimensional projective space, as a simplicial set.
|
537
|
+
|
538
|
+
This is only defined when `n` is at most 4. It is constructed
|
539
|
+
using the simplicial set decomposition provided by Kenzo, as
|
540
|
+
described by Sergeraert [Ser2010]_
|
541
|
+
|
542
|
+
EXAMPLES::
|
543
|
+
|
544
|
+
sage: simplicial_sets.ComplexProjectiveSpace(2).homology(reduced=False) # needs sage.modules
|
545
|
+
{0: Z, 1: 0, 2: Z, 3: 0, 4: Z}
|
546
|
+
sage: CP3 = simplicial_sets.ComplexProjectiveSpace(3); CP3 # needs pyparsing
|
547
|
+
CP^3
|
548
|
+
sage: latex(CP3) # needs pyparsing
|
549
|
+
CP^{3}
|
550
|
+
sage: CP3.f_vector() # needs pyparsing
|
551
|
+
[1, 0, 3, 10, 25, 30, 15]
|
552
|
+
|
553
|
+
sage: # long time, needs pyparsing sage.modules
|
554
|
+
sage: K = CP3.suspension() # long time (1 second)
|
555
|
+
sage: R = K.cohomology_ring(GF(2))
|
556
|
+
sage: R.gens()
|
557
|
+
(h^{0,0}, h^{3,0}, h^{5,0}, h^{7,0})
|
558
|
+
sage: x = R.gens()[1]
|
559
|
+
sage: x.Sq(2)
|
560
|
+
h^{5,0}
|
561
|
+
|
562
|
+
sage: simplicial_sets.ComplexProjectiveSpace(4).f_vector() # needs pyparsing
|
563
|
+
[1, 0, 4, 22, 97, 255, 390, 315, 105]
|
564
|
+
|
565
|
+
sage: simplicial_sets.ComplexProjectiveSpace(5)
|
566
|
+
Traceback (most recent call last):
|
567
|
+
...
|
568
|
+
ValueError: complex projective spaces are only available in dimensions between 0 and 4
|
569
|
+
"""
|
570
|
+
if n < 0 or n > 4:
|
571
|
+
raise ValueError('complex projective spaces are only available in dimensions between 0 and 4')
|
572
|
+
if n == 0:
|
573
|
+
return Point()
|
574
|
+
if n == 1:
|
575
|
+
return Sphere(2)
|
576
|
+
if n == 2:
|
577
|
+
# v: Kenzo name <<GBar>>
|
578
|
+
v = AbstractSimplex(0, name='v')
|
579
|
+
# f_2_i: Kenzo name <<GBar<- (i)><- NIL>>> for i=1,2
|
580
|
+
f2_1 = AbstractSimplex(2, name='rho_0')
|
581
|
+
f2_2 = AbstractSimplex(2, name='rho_1')
|
582
|
+
# f3_110: Kenzo name <<GBar<- (1 1)><0 NIL><- NIL>>>
|
583
|
+
# f3_011: Kenzo name <<GBar<0 (1)><- (1)><- NIL>>>
|
584
|
+
# f3_111: Kenzo name <<GBar<1 (1)><- (1)><- NIL>>>
|
585
|
+
f3_110 = AbstractSimplex(3, name='sigma_0', latex_name='\\sigma_0')
|
586
|
+
f3_011 = AbstractSimplex(3, name='sigma_1', latex_name='\\sigma_1')
|
587
|
+
f3_111 = AbstractSimplex(3, name='sigma_2', latex_name='\\sigma_2')
|
588
|
+
# f4_101101: Kenzo name <<GBar<1-0 (1)><1-0 NIL><- (1)><- NIL>>>
|
589
|
+
# f4_201110: Kenzo name <<GBar<2-0 (1)><1 (1)><0 NIL><- NIL>>>
|
590
|
+
# f4_211010: Kenzo name <<GBar<2-1 (1)><0 (1)><0 NIL><- NIL>>>
|
591
|
+
f4_101101 = AbstractSimplex(4, name='tau_0', latex_name='\\tau_0')
|
592
|
+
f4_201110 = AbstractSimplex(4, name='tau_1', latex_name='\\tau_1')
|
593
|
+
f4_211010 = AbstractSimplex(4, name='tau_2', latex_name='\\tau_2')
|
594
|
+
K = SimplicialSet_finite({f2_1: (v.apply_degeneracies(0),
|
595
|
+
v.apply_degeneracies(0),
|
596
|
+
v.apply_degeneracies(0)),
|
597
|
+
f2_2: (v.apply_degeneracies(0),
|
598
|
+
v.apply_degeneracies(0),
|
599
|
+
v.apply_degeneracies(0)),
|
600
|
+
f3_110: (f2_1, f2_2, f2_1, v.apply_degeneracies(1, 0)),
|
601
|
+
f3_011: (f2_1, f2_1, f2_1, f2_1),
|
602
|
+
f3_111: (v.apply_degeneracies(1, 0), f2_1, f2_2, f2_1),
|
603
|
+
f4_101101: (f2_1.apply_degeneracies(0),
|
604
|
+
f2_1.apply_degeneracies(0),
|
605
|
+
f3_011,
|
606
|
+
f2_1.apply_degeneracies(2),
|
607
|
+
f2_1.apply_degeneracies(2)),
|
608
|
+
f4_201110: (f2_1.apply_degeneracies(1),
|
609
|
+
f3_111,
|
610
|
+
f3_011,
|
611
|
+
f3_110,
|
612
|
+
f2_1.apply_degeneracies(1)),
|
613
|
+
f4_211010: (f2_1.apply_degeneracies(2),
|
614
|
+
f3_111,
|
615
|
+
f2_1.apply_degeneracies(1),
|
616
|
+
f3_110,
|
617
|
+
f2_1.apply_degeneracies(0))},
|
618
|
+
base_point=v, name='CP^2',
|
619
|
+
latex_name='CP^{2}')
|
620
|
+
return K
|
621
|
+
if n == 3:
|
622
|
+
file = kenzo_path / 'CP3.txt'
|
623
|
+
data = simplicial_data_from_kenzo_output(file)
|
624
|
+
v = [sigma for sigma in data if sigma.dimension() == 0][0]
|
625
|
+
return SimplicialSet_finite(data, base_point=v, name='CP^3',
|
626
|
+
latex_name='CP^{3}')
|
627
|
+
if n == 4:
|
628
|
+
file = kenzo_path / 'CP4.txt'
|
629
|
+
data = simplicial_data_from_kenzo_output(file)
|
630
|
+
v = [sigma for sigma in data if sigma.dimension() == 0][0]
|
631
|
+
return SimplicialSet_finite(data, base_point=v, name='CP^4',
|
632
|
+
latex_name='CP^{4}')
|
633
|
+
|
634
|
+
|
635
|
+
def simplicial_data_from_kenzo_output(filename) -> dict:
|
636
|
+
"""
|
637
|
+
Return data to construct a simplicial set, given Kenzo output.
|
638
|
+
|
639
|
+
INPUT:
|
640
|
+
|
641
|
+
- ``filename`` -- name of file containing the output from Kenzo's
|
642
|
+
:func:`show-structure` function
|
643
|
+
|
644
|
+
OUTPUT: data to construct a simplicial set from the Kenzo output
|
645
|
+
|
646
|
+
Several files with Kenzo output are in the directory
|
647
|
+
:file:`SAGE_EXTCODE/kenzo/`.
|
648
|
+
|
649
|
+
EXAMPLES::
|
650
|
+
|
651
|
+
sage: from sage.topology.simplicial_set_examples import simplicial_data_from_kenzo_output
|
652
|
+
sage: from sage.topology.simplicial_set import SimplicialSet
|
653
|
+
sage: from pathlib import Path
|
654
|
+
sage: sphere = Path(SAGE_ENV['SAGE_EXTCODE']) / 'kenzo' /'S4.txt'
|
655
|
+
sage: S4 = SimplicialSet(simplicial_data_from_kenzo_output(sphere)) # needs pyparsing
|
656
|
+
sage: S4.homology(reduced=False) # needs pyparsing
|
657
|
+
{0: Z, 1: 0, 2: 0, 3: 0, 4: Z}
|
658
|
+
"""
|
659
|
+
from pyparsing import OneOrMore, nestedExpr
|
660
|
+
|
661
|
+
with open(filename) as f:
|
662
|
+
data = f.read()
|
663
|
+
dim = 0
|
664
|
+
start = 0
|
665
|
+
# simplex_data: data for constructing the simplicial set.
|
666
|
+
simplex_data = {}
|
667
|
+
# simplex_names: simplices indexed by their names
|
668
|
+
simplex_names = {}
|
669
|
+
dim_idx = data.find('Dimension = {}:'.format(dim), start)
|
670
|
+
while dim_idx != -1:
|
671
|
+
start = dim_idx + len('Dimension = {}:'.format(dim))
|
672
|
+
new_dim_idx = data.find('Dimension = {}:'.format(dim + 1), start)
|
673
|
+
if new_dim_idx == -1:
|
674
|
+
end = len(data)
|
675
|
+
else:
|
676
|
+
end = new_dim_idx
|
677
|
+
if dim == 0:
|
678
|
+
simplex_string = data[data.find('Vertices :') + len('Vertices :'):end]
|
679
|
+
vertices = OneOrMore(nestedExpr()).parseString(simplex_string).asList()[0]
|
680
|
+
for v in vertices:
|
681
|
+
vertex = AbstractSimplex(0, name=v)
|
682
|
+
simplex_data[vertex] = None
|
683
|
+
simplex_names[v] = vertex
|
684
|
+
else:
|
685
|
+
simplex_string = data[start:end].strip()
|
686
|
+
|
687
|
+
for s in [_.strip() for _ in simplex_string.split('Simplex : ')]:
|
688
|
+
if s:
|
689
|
+
name, face_str = (_.strip() for _ in s.split('Faces : '))
|
690
|
+
face_str = face_str.strip('()')
|
691
|
+
face_str = face_str.split('<AbSm ')
|
692
|
+
faces = []
|
693
|
+
for f in face_str[1:]:
|
694
|
+
# f has the form 'DEGENS NAME>', possibly with a trailing space.
|
695
|
+
# DEGENS is a hyphen-separated list, like
|
696
|
+
# '3-2-1-0' or '0' or '-'.
|
697
|
+
m = re.match('[-[0-9]+', f)
|
698
|
+
degen_str = m.group(0)
|
699
|
+
if degen_str.find('-') != -1:
|
700
|
+
if degen_str == '-':
|
701
|
+
degens = []
|
702
|
+
else:
|
703
|
+
degens = [Integer(_)
|
704
|
+
for _ in degen_str.split('-')]
|
705
|
+
else:
|
706
|
+
degens = [Integer(degen_str)]
|
707
|
+
|
708
|
+
face_name = f[m.end(0):].strip()[:-1]
|
709
|
+
nondegen = simplex_names[face_name]
|
710
|
+
faces.append(nondegen.apply_degeneracies(*degens))
|
711
|
+
|
712
|
+
simplex = AbstractSimplex(dim, name=name)
|
713
|
+
simplex_data[simplex] = faces
|
714
|
+
simplex_names[name] = simplex
|
715
|
+
dim += 1
|
716
|
+
dim_idx = new_dim_idx
|
717
|
+
return simplex_data
|
718
|
+
|
719
|
+
|
720
|
+
def HopfMap():
|
721
|
+
r"""
|
722
|
+
Return a simplicial model of the Hopf map `S^3 \to S^2`.
|
723
|
+
|
724
|
+
This is taken from Exemple II.1.19 in the thesis of Clemens Berger
|
725
|
+
[Ber1991]_.
|
726
|
+
|
727
|
+
The Hopf map is a fibration `S^3 \to S^2`. If it is viewed as
|
728
|
+
attaching a 4-cell to the 2-sphere, the resulting adjunction space
|
729
|
+
is 2-dimensional complex projective space. The resulting model is
|
730
|
+
a bit larger than the one obtained from
|
731
|
+
``simplicial_sets.ComplexProjectiveSpace(2)``.
|
732
|
+
|
733
|
+
EXAMPLES::
|
734
|
+
|
735
|
+
sage: g = simplicial_sets.HopfMap()
|
736
|
+
sage: g.domain()
|
737
|
+
Simplicial set with 20 non-degenerate simplices
|
738
|
+
sage: g.codomain()
|
739
|
+
S^2
|
740
|
+
|
741
|
+
Using the Hopf map to attach a cell::
|
742
|
+
|
743
|
+
sage: X = g.mapping_cone()
|
744
|
+
sage: CP2 = simplicial_sets.ComplexProjectiveSpace(2)
|
745
|
+
sage: X.homology() == CP2.homology() # needs sage.modules
|
746
|
+
True
|
747
|
+
|
748
|
+
sage: X.f_vector()
|
749
|
+
[1, 0, 5, 9, 6]
|
750
|
+
sage: CP2.f_vector()
|
751
|
+
[1, 0, 2, 3, 3]
|
752
|
+
"""
|
753
|
+
# The 2-sphere and its simplices.
|
754
|
+
S2 = Sphere(2)
|
755
|
+
sigma = S2.n_cells(2)[0]
|
756
|
+
s0_sigma = sigma.apply_degeneracies(0)
|
757
|
+
s1_sigma = sigma.apply_degeneracies(1)
|
758
|
+
s2_sigma = sigma.apply_degeneracies(2)
|
759
|
+
# The 3-sphere and its simplices.
|
760
|
+
w_0 = AbstractSimplex(0, name='w')
|
761
|
+
w_1 = w_0.apply_degeneracies(0)
|
762
|
+
w_2 = w_0.apply_degeneracies(0, 0)
|
763
|
+
beta_11 = AbstractSimplex(1, name='beta_11', latex_name='\\beta_{11}')
|
764
|
+
beta_22 = AbstractSimplex(1, name='beta_22', latex_name='\\beta_{22}')
|
765
|
+
beta_23 = AbstractSimplex(1, name='beta_23', latex_name='\\beta_{23}')
|
766
|
+
beta_44 = AbstractSimplex(1, name='beta_44', latex_name='\\beta_{44}')
|
767
|
+
beta_1 = AbstractSimplex(2, name='beta_1', latex_name='\\beta_1')
|
768
|
+
beta_2 = AbstractSimplex(2, name='beta_2', latex_name='\\beta_2')
|
769
|
+
beta_3 = AbstractSimplex(2, name='beta_3', latex_name='\\beta_3')
|
770
|
+
beta_4 = AbstractSimplex(2, name='beta_4', latex_name='\\beta_4')
|
771
|
+
alpha_12 = AbstractSimplex(2, name='alpha_12', latex_name='\\alpha_{12}')
|
772
|
+
alpha_23 = AbstractSimplex(2, name='alpha_23', latex_name='\\alpha_{23}')
|
773
|
+
alpha_34 = AbstractSimplex(2, name='alpha_34', latex_name='\\alpha_{34}')
|
774
|
+
alpha_45 = AbstractSimplex(2, name='alpha_45', latex_name='\\alpha_{45}')
|
775
|
+
alpha_56 = AbstractSimplex(2, name='alpha_56', latex_name='\\alpha_{56}')
|
776
|
+
alpha_1 = AbstractSimplex(3, name='alpha_1', latex_name='\\alpha_1')
|
777
|
+
alpha_2 = AbstractSimplex(3, name='alpha_2', latex_name='\\alpha_2')
|
778
|
+
alpha_3 = AbstractSimplex(3, name='alpha_3', latex_name='\\alpha_3')
|
779
|
+
alpha_4 = AbstractSimplex(3, name='alpha_4', latex_name='\\alpha_4')
|
780
|
+
alpha_5 = AbstractSimplex(3, name='alpha_5', latex_name='\\alpha_5')
|
781
|
+
alpha_6 = AbstractSimplex(3, name='alpha_6', latex_name='\\alpha_6')
|
782
|
+
S3 = SimplicialSet_finite({beta_11: (w_0, w_0), beta_22: (w_0, w_0),
|
783
|
+
beta_23: (w_0, w_0), beta_44: (w_0, w_0),
|
784
|
+
beta_1: (w_1, beta_11, w_1),
|
785
|
+
beta_2: (w_1, beta_22, beta_23),
|
786
|
+
beta_3: (w_1, beta_23, w_1),
|
787
|
+
beta_4: (w_1, beta_44, w_1),
|
788
|
+
alpha_12: (beta_11, beta_23, w_1),
|
789
|
+
alpha_23: (beta_11, beta_22, w_1),
|
790
|
+
alpha_34: (beta_11, beta_22, beta_44),
|
791
|
+
alpha_45: (w_1, beta_23, beta_44),
|
792
|
+
alpha_56: (w_1, beta_23, w_1),
|
793
|
+
alpha_1: (beta_1, beta_3, alpha_12, w_2),
|
794
|
+
alpha_2: (beta_11.apply_degeneracies(1), beta_2,
|
795
|
+
alpha_23, alpha_12),
|
796
|
+
alpha_3: (beta_11.apply_degeneracies(0), alpha_34,
|
797
|
+
alpha_23, beta_4),
|
798
|
+
alpha_4: (beta_1, beta_2, alpha_34, alpha_45),
|
799
|
+
alpha_5: (w_2, alpha_45, alpha_56, beta_4),
|
800
|
+
alpha_6: (w_2, beta_3, alpha_56, w_2)},
|
801
|
+
base_point=w_0)
|
802
|
+
return S3.Hom(S2)({alpha_1: s0_sigma, alpha_2: s1_sigma,
|
803
|
+
alpha_3: s2_sigma, alpha_4: s0_sigma,
|
804
|
+
alpha_5: s2_sigma, alpha_6: s1_sigma})
|
805
|
+
|
806
|
+
|
807
|
+
def PresentationComplex(G):
|
808
|
+
r"""
|
809
|
+
Return a simplicial set constructed from a group presentation.
|
810
|
+
The result is a subdivision of the presentation complex.
|
811
|
+
|
812
|
+
The presentation complex has a single vertex and it has one edge for
|
813
|
+
each generator. Then triangles (and eventually new edges
|
814
|
+
to glue them) are added to realize the relations.
|
815
|
+
|
816
|
+
INPUT:
|
817
|
+
|
818
|
+
- ``G`` -- a finitely presented group
|
819
|
+
|
820
|
+
EXAMPLES::
|
821
|
+
|
822
|
+
sage: # needs sage.groups
|
823
|
+
sage: G = SymmetricGroup(2).as_finitely_presented_group(); G
|
824
|
+
Finitely presented group < a | a^2 >
|
825
|
+
sage: S = simplicial_sets.PresentationComplex(G); S
|
826
|
+
Simplicial set with 5 non-degenerate simplices
|
827
|
+
sage: S.face_data()
|
828
|
+
{Delta^0: None,
|
829
|
+
a: (Delta^0, Delta^0),
|
830
|
+
a^-1: (Delta^0, Delta^0),
|
831
|
+
Ta: (a, s_0 Delta^0, a^-1),
|
832
|
+
a^2: (a, s_0 Delta^0, a)}
|
833
|
+
sage: S.fundamental_group()
|
834
|
+
Finitely presented group < e0 | e0^2 >
|
835
|
+
"""
|
836
|
+
O = AbstractSimplex(0)
|
837
|
+
SO = O.apply_degeneracies(0)
|
838
|
+
edges = {g: AbstractSimplex(1, name=str(g)) for g in G.gens()}
|
839
|
+
inverseedges = {g.inverse(): AbstractSimplex(1, name=str(g.inverse())) for g in G.gens()}
|
840
|
+
all_edges = {}
|
841
|
+
all_edges.update(edges)
|
842
|
+
all_edges.update(inverseedges)
|
843
|
+
triangles = {g: AbstractSimplex(2, name='T' + str(g)) for g in G.gens()}
|
844
|
+
face_maps = {g: [O, O] for g in all_edges.values()}
|
845
|
+
face_maps.update({triangles[t]: [all_edges[t], SO, all_edges[t.inverse()]] for t in triangles})
|
846
|
+
for r in G.relations():
|
847
|
+
if len(r.Tietze()) == 1:
|
848
|
+
pass
|
849
|
+
elif len(r.Tietze()) == 2:
|
850
|
+
a = all_edges[G([r.Tietze()[0]])]
|
851
|
+
b = all_edges[G([r.Tietze()[1]])]
|
852
|
+
T = AbstractSimplex(2, name=str(r))
|
853
|
+
face_maps[T] = [a, SO, b]
|
854
|
+
else:
|
855
|
+
words = [all_edges[G([a])] for a in r.Tietze()]
|
856
|
+
words[-1] = all_edges[G([-r.Tietze()[-1]])]
|
857
|
+
while len(words) > 3:
|
858
|
+
auxedge = AbstractSimplex(1)
|
859
|
+
face_maps[auxedge] = [O, O]
|
860
|
+
auxtring = AbstractSimplex(2)
|
861
|
+
face_maps[auxtring] = [words[1], auxedge, words[0]]
|
862
|
+
words = [auxedge] + words[2:]
|
863
|
+
auxtring = AbstractSimplex(2)
|
864
|
+
face_maps[auxtring] = [words[1], words[2], words[0]]
|
865
|
+
return SimplicialSet_finite(face_maps, base_point=O)
|