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,1214 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-graphs
|
2
|
+
# sage.doctest: needs sage.graphs
|
3
|
+
r"""
|
4
|
+
Generic cell complexes
|
5
|
+
|
6
|
+
AUTHORS:
|
7
|
+
|
8
|
+
- John H. Palmieri (2009-08)
|
9
|
+
|
10
|
+
This module defines a class of abstract finite cell complexes. This
|
11
|
+
is meant as a base class from which other classes (like
|
12
|
+
:class:`~sage.homology.simplicial_complex.SimplicialComplex`,
|
13
|
+
:class:`~sage.homology.cubical_complex.CubicalComplex`, and
|
14
|
+
:class:`~sage.homology.delta_complex.DeltaComplex`) should derive. As
|
15
|
+
such, most of its properties are not implemented. It is meant for use
|
16
|
+
by developers producing new classes, not casual users.
|
17
|
+
|
18
|
+
.. NOTE::
|
19
|
+
|
20
|
+
Keywords for :meth:`~GenericCellComplex.chain_complex`,
|
21
|
+
:meth:`~GenericCellComplex.homology`, etc.: any keywords given to
|
22
|
+
the :meth:`~GenericCellComplex.homology` method get passed on to
|
23
|
+
the :meth:`~GenericCellComplex.chain_complex` method and also to
|
24
|
+
the constructor for chain complexes in
|
25
|
+
:class:`sage.homology.chain_complex.ChainComplex_class <ChainComplex>`,
|
26
|
+
as well as its associated
|
27
|
+
:meth:`~sage.homology.chain_complex.ChainComplex_class.homology` method.
|
28
|
+
This means that those keywords should have consistent meaning in
|
29
|
+
all of those situations. It also means that it is easy to
|
30
|
+
implement new keywords: for example, if you implement a new
|
31
|
+
keyword for the
|
32
|
+
:meth:`sage.homology.chain_complex.ChainComplex_class.homology` method,
|
33
|
+
then it will be automatically accessible through the
|
34
|
+
:meth:`~GenericCellComplex.homology` method for cell complexes --
|
35
|
+
just make sure it gets documented.
|
36
|
+
"""
|
37
|
+
|
38
|
+
########################################################################
|
39
|
+
# Copyright (C) 2009 John H. Palmieri <palmieri@math.washington.edu>
|
40
|
+
#
|
41
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
42
|
+
# as published by the Free Software Foundation; either version 2 of
|
43
|
+
# the License, or (at your option) any later version.
|
44
|
+
#
|
45
|
+
# https://www.gnu.org/licenses/
|
46
|
+
########################################################################
|
47
|
+
|
48
|
+
from sage.structure.sage_object import SageObject
|
49
|
+
from sage.rings.integer_ring import ZZ
|
50
|
+
from sage.rings.rational_field import QQ
|
51
|
+
from sage.misc.abstract_method import abstract_method
|
52
|
+
|
53
|
+
|
54
|
+
class GenericCellComplex(SageObject):
|
55
|
+
r"""
|
56
|
+
Class of abstract cell complexes.
|
57
|
+
|
58
|
+
This is meant to be used by developers to produce new classes, not
|
59
|
+
by casual users. Classes which derive from this are
|
60
|
+
:class:`~sage.homology.simplicial_complex.SimplicialComplex`,
|
61
|
+
:class:`~sage.homology.delta_complex.DeltaComplex`, and
|
62
|
+
:class:`~sage.homology.cubical_complex.CubicalComplex`.
|
63
|
+
|
64
|
+
Most of the methods here are not implemented, but probably should
|
65
|
+
be implemented in a derived class. Most of the other methods call
|
66
|
+
a non-implemented one; their docstrings contain examples from
|
67
|
+
derived classes in which the various methods have been defined.
|
68
|
+
For example, :meth:`homology` calls :meth:`chain_complex`; the
|
69
|
+
class :class:`~sage.homology.delta_complex.DeltaComplex`
|
70
|
+
implements
|
71
|
+
:meth:`~sage.homology.delta_complex.DeltaComplex.chain_complex`,
|
72
|
+
and so the :meth:`homology` method here is illustrated with
|
73
|
+
examples involving `\Delta`-complexes.
|
74
|
+
|
75
|
+
EXAMPLES:
|
76
|
+
|
77
|
+
It's hard to give informative examples of the base class, since
|
78
|
+
essentially nothing is implemented. ::
|
79
|
+
|
80
|
+
sage: from sage.topology.cell_complex import GenericCellComplex
|
81
|
+
sage: A = GenericCellComplex()
|
82
|
+
"""
|
83
|
+
def __eq__(self, right):
|
84
|
+
"""
|
85
|
+
Comparisons of cell complexes are not implemented.
|
86
|
+
|
87
|
+
EXAMPLES::
|
88
|
+
|
89
|
+
sage: from sage.topology.cell_complex import GenericCellComplex
|
90
|
+
sage: A = GenericCellComplex(); B = GenericCellComplex()
|
91
|
+
sage: A == B # indirect doctest
|
92
|
+
Traceback (most recent call last):
|
93
|
+
...
|
94
|
+
NotImplementedError
|
95
|
+
"""
|
96
|
+
raise NotImplementedError
|
97
|
+
|
98
|
+
def __ne__(self, right):
|
99
|
+
"""
|
100
|
+
Comparisons of cell complexes are not implemented.
|
101
|
+
|
102
|
+
EXAMPLES::
|
103
|
+
|
104
|
+
sage: from sage.topology.cell_complex import GenericCellComplex
|
105
|
+
sage: A = GenericCellComplex(); B = GenericCellComplex()
|
106
|
+
sage: A != B # indirect doctest
|
107
|
+
Traceback (most recent call last):
|
108
|
+
...
|
109
|
+
NotImplementedError
|
110
|
+
"""
|
111
|
+
raise NotImplementedError
|
112
|
+
|
113
|
+
############################################################
|
114
|
+
# self.cells() and related methods
|
115
|
+
############################################################
|
116
|
+
|
117
|
+
@abstract_method
|
118
|
+
def cells(self, subcomplex=None):
|
119
|
+
"""
|
120
|
+
The cells of this cell complex, in the form of a dictionary:
|
121
|
+
the keys are integers, representing dimension, and the value
|
122
|
+
associated to an integer `d` is the set of `d`-cells. If the
|
123
|
+
optional argument ``subcomplex`` is present, then return only
|
124
|
+
the cells which are *not* in the subcomplex.
|
125
|
+
|
126
|
+
INPUT:
|
127
|
+
|
128
|
+
- ``subcomplex`` -- subcomplex (default: ``None``); a subcomplex of
|
129
|
+
this cell complex; return the cells which are not in this subcomplex
|
130
|
+
|
131
|
+
This is not implemented in general; it should be implemented
|
132
|
+
in any derived class. When implementing, see the warning in
|
133
|
+
the :meth:`dimension` method.
|
134
|
+
|
135
|
+
This method is used by various other methods, such as
|
136
|
+
:meth:`n_cells` and :meth:`f_vector`.
|
137
|
+
|
138
|
+
EXAMPLES::
|
139
|
+
|
140
|
+
sage: from sage.topology.cell_complex import GenericCellComplex
|
141
|
+
sage: A = GenericCellComplex()
|
142
|
+
sage: A.cells()
|
143
|
+
Traceback (most recent call last):
|
144
|
+
...
|
145
|
+
NotImplementedError: <abstract method cells at ...>
|
146
|
+
"""
|
147
|
+
|
148
|
+
def dimension(self):
|
149
|
+
"""
|
150
|
+
The dimension of this cell complex: the maximum
|
151
|
+
dimension of its cells.
|
152
|
+
|
153
|
+
.. WARNING::
|
154
|
+
|
155
|
+
If the :meth:`cells` method calls :meth:`dimension`,
|
156
|
+
then you'll get an infinite loop. So either don't use
|
157
|
+
:meth:`dimension` or override :meth:`dimension`.
|
158
|
+
|
159
|
+
EXAMPLES::
|
160
|
+
|
161
|
+
sage: simplicial_complexes.RandomComplex(d=5, n=8).dimension()
|
162
|
+
5
|
163
|
+
sage: delta_complexes.Sphere(3).dimension()
|
164
|
+
3
|
165
|
+
sage: T = cubical_complexes.Torus()
|
166
|
+
sage: T.product(T).dimension()
|
167
|
+
4
|
168
|
+
"""
|
169
|
+
try:
|
170
|
+
return max([x.dimension() for x in self._facets])
|
171
|
+
except AttributeError:
|
172
|
+
if len(self.cells()) == 0:
|
173
|
+
# The empty cell complex has dimension -1.
|
174
|
+
return -1
|
175
|
+
return max(self.cells())
|
176
|
+
|
177
|
+
def n_cells(self, n, subcomplex=None):
|
178
|
+
"""
|
179
|
+
List of cells of dimension `n` of this cell complex.
|
180
|
+
If the optional argument ``subcomplex`` is present, then
|
181
|
+
return the `n`-dimensional cells which are *not* in the
|
182
|
+
subcomplex.
|
183
|
+
|
184
|
+
INPUT:
|
185
|
+
|
186
|
+
- ``n`` -- nonnegative integer; the dimension
|
187
|
+
- ``subcomplex`` -- (optional) a subcomplex of this cell complex;
|
188
|
+
return the cells which are not in this subcomplex
|
189
|
+
|
190
|
+
.. NOTE::
|
191
|
+
|
192
|
+
The resulting list need not be sorted. If you want a sorted
|
193
|
+
list of `n`-cells, use :meth:`_n_cells_sorted`.
|
194
|
+
|
195
|
+
EXAMPLES::
|
196
|
+
|
197
|
+
sage: delta_complexes.Torus().n_cells(1)
|
198
|
+
[(0, 0), (0, 0), (0, 0)]
|
199
|
+
sage: cubical_complexes.Cube(1).n_cells(0)
|
200
|
+
[[1,1], [0,0]]
|
201
|
+
"""
|
202
|
+
if n in self.cells(subcomplex):
|
203
|
+
return list(self.cells(subcomplex)[n])
|
204
|
+
else:
|
205
|
+
# don't barf if someone asks for n_cells in a dimension where there are none
|
206
|
+
return []
|
207
|
+
|
208
|
+
def _n_cells_sorted(self, n, subcomplex=None):
|
209
|
+
"""
|
210
|
+
Sorted list of cells of dimension `n` of this cell complex.
|
211
|
+
If the optional argument ``subcomplex`` is present, then
|
212
|
+
return the `n`-dimensional cells which are *not* in the
|
213
|
+
subcomplex.
|
214
|
+
|
215
|
+
INPUT:
|
216
|
+
|
217
|
+
- ``n`` -- the dimension
|
218
|
+
- ``subcomplex`` -- (default: ``None``) a subcomplex of this cell
|
219
|
+
complex; return the cells which are not in this subcomplex
|
220
|
+
|
221
|
+
EXAMPLES::
|
222
|
+
|
223
|
+
sage: S = Set(range(1,5))
|
224
|
+
sage: Z = SimplicialComplex(S.subsets())
|
225
|
+
sage: Z
|
226
|
+
Simplicial complex with vertex set (1, 2, 3, 4) and facets {(1, 2, 3, 4)}
|
227
|
+
sage: Z._n_cells_sorted(2)
|
228
|
+
[(1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4)]
|
229
|
+
sage: K = SimplicialComplex([[1,2,3], [2,3,4]])
|
230
|
+
sage: Z._n_cells_sorted(2, subcomplex=K)
|
231
|
+
[(1, 2, 4), (1, 3, 4)]
|
232
|
+
|
233
|
+
sage: # needs sage.symbolic
|
234
|
+
sage: S = SimplicialComplex([[complex(i), complex(1)]])
|
235
|
+
sage: S._n_cells_sorted(0)
|
236
|
+
[((1+0j),), (1j,)]
|
237
|
+
"""
|
238
|
+
n_cells = self.n_cells(n, subcomplex)
|
239
|
+
try:
|
240
|
+
return sorted(n_cells)
|
241
|
+
except TypeError:
|
242
|
+
return sorted(n_cells, key=str)
|
243
|
+
|
244
|
+
def f_vector(self):
|
245
|
+
"""
|
246
|
+
The `f`-vector of this cell complex: a list whose `n`-th
|
247
|
+
item is the number of `(n-1)`-cells. Note that, like all
|
248
|
+
lists in Sage, this is indexed starting at 0: the 0th element
|
249
|
+
in this list is the number of `(-1)`-cells (which is 1: the
|
250
|
+
empty cell is the only `(-1)`-cell).
|
251
|
+
|
252
|
+
EXAMPLES::
|
253
|
+
|
254
|
+
sage: simplicial_complexes.KleinBottle().f_vector()
|
255
|
+
[1, 8, 24, 16]
|
256
|
+
sage: delta_complexes.KleinBottle().f_vector()
|
257
|
+
[1, 1, 3, 2]
|
258
|
+
sage: cubical_complexes.KleinBottle().f_vector()
|
259
|
+
[1, 42, 84, 42]
|
260
|
+
"""
|
261
|
+
return [self._f_dict()[n] for n in range(-1, self.dimension() + 1)]
|
262
|
+
|
263
|
+
def _f_dict(self):
|
264
|
+
"""
|
265
|
+
The `f`-vector of this cell complex as a dictionary: the
|
266
|
+
item associated to an integer `n` is the number of the
|
267
|
+
`n`-cells.
|
268
|
+
|
269
|
+
EXAMPLES::
|
270
|
+
|
271
|
+
sage: simplicial_complexes.KleinBottle()._f_dict()[1]
|
272
|
+
24
|
273
|
+
sage: delta_complexes.KleinBottle()._f_dict()[1]
|
274
|
+
3
|
275
|
+
"""
|
276
|
+
answer = {}
|
277
|
+
answer[-1] = 1
|
278
|
+
for n in range(self.dimension() + 1):
|
279
|
+
answer[n] = len(self.cells()[n])
|
280
|
+
return answer
|
281
|
+
|
282
|
+
def euler_characteristic(self):
|
283
|
+
r"""
|
284
|
+
The Euler characteristic of this cell complex: the
|
285
|
+
alternating sum over `n \geq 0` of the number of
|
286
|
+
`n`-cells.
|
287
|
+
|
288
|
+
EXAMPLES::
|
289
|
+
|
290
|
+
sage: simplicial_complexes.Simplex(5).euler_characteristic()
|
291
|
+
1
|
292
|
+
sage: delta_complexes.Sphere(6).euler_characteristic()
|
293
|
+
2
|
294
|
+
sage: cubical_complexes.KleinBottle().euler_characteristic()
|
295
|
+
0
|
296
|
+
"""
|
297
|
+
return sum((-1)**n * self.f_vector()[n + 1] for n in range(self.dimension() + 1))
|
298
|
+
|
299
|
+
############################################################
|
300
|
+
# end of methods using self.cells()
|
301
|
+
############################################################
|
302
|
+
|
303
|
+
@abstract_method
|
304
|
+
def product(self, right, rename_vertices=True):
|
305
|
+
"""
|
306
|
+
The (Cartesian) product of this cell complex with another one.
|
307
|
+
|
308
|
+
Products are not implemented for general cell complexes. They
|
309
|
+
may be implemented in some derived classes (like simplicial
|
310
|
+
complexes).
|
311
|
+
|
312
|
+
EXAMPLES::
|
313
|
+
|
314
|
+
sage: from sage.topology.cell_complex import GenericCellComplex
|
315
|
+
sage: A = GenericCellComplex(); B = GenericCellComplex()
|
316
|
+
sage: A.product(B)
|
317
|
+
Traceback (most recent call last):
|
318
|
+
...
|
319
|
+
NotImplementedError: <abstract method product at ...>
|
320
|
+
"""
|
321
|
+
|
322
|
+
@abstract_method
|
323
|
+
def disjoint_union(self, right):
|
324
|
+
"""
|
325
|
+
The disjoint union of this cell complex with another one.
|
326
|
+
|
327
|
+
INPUT:
|
328
|
+
|
329
|
+
- ``right`` -- the other cell complex (the right-hand factor)
|
330
|
+
|
331
|
+
Disjoint unions are not implemented for general cell complexes.
|
332
|
+
|
333
|
+
EXAMPLES::
|
334
|
+
|
335
|
+
sage: from sage.topology.cell_complex import GenericCellComplex
|
336
|
+
sage: A = GenericCellComplex(); B = GenericCellComplex()
|
337
|
+
sage: A.disjoint_union(B)
|
338
|
+
Traceback (most recent call last):
|
339
|
+
...
|
340
|
+
NotImplementedError: <abstract method disjoint_union at ...>
|
341
|
+
"""
|
342
|
+
|
343
|
+
@abstract_method
|
344
|
+
def wedge(self, right):
|
345
|
+
"""
|
346
|
+
The wedge (one-point union) of this cell complex with
|
347
|
+
another one.
|
348
|
+
|
349
|
+
INPUT:
|
350
|
+
|
351
|
+
- ``right`` -- the other cell complex (the right-hand factor)
|
352
|
+
|
353
|
+
Wedges are not implemented for general cell complexes.
|
354
|
+
|
355
|
+
EXAMPLES::
|
356
|
+
|
357
|
+
sage: from sage.topology.cell_complex import GenericCellComplex
|
358
|
+
sage: A = GenericCellComplex(); B = GenericCellComplex()
|
359
|
+
sage: A.wedge(B)
|
360
|
+
Traceback (most recent call last):
|
361
|
+
...
|
362
|
+
NotImplementedError: <abstract method wedge at ...>
|
363
|
+
"""
|
364
|
+
|
365
|
+
############################################################
|
366
|
+
# self.join() and related methods
|
367
|
+
############################################################
|
368
|
+
|
369
|
+
@abstract_method
|
370
|
+
def join(self, right):
|
371
|
+
"""
|
372
|
+
The join of this cell complex with another one.
|
373
|
+
|
374
|
+
INPUT:
|
375
|
+
|
376
|
+
- ``right`` -- the other cell complex (the right-hand factor)
|
377
|
+
|
378
|
+
Joins are not implemented for general cell complexes. They
|
379
|
+
may be implemented in some derived classes (like simplicial
|
380
|
+
complexes).
|
381
|
+
|
382
|
+
EXAMPLES::
|
383
|
+
|
384
|
+
sage: from sage.topology.cell_complex import GenericCellComplex
|
385
|
+
sage: A = GenericCellComplex(); B = GenericCellComplex()
|
386
|
+
sage: A.join(B)
|
387
|
+
Traceback (most recent call last):
|
388
|
+
...
|
389
|
+
NotImplementedError: <abstract method join at ...>
|
390
|
+
"""
|
391
|
+
|
392
|
+
# for some classes, you may want * to mean join:
|
393
|
+
###
|
394
|
+
# __mul__ = join
|
395
|
+
|
396
|
+
# the cone on X is the join of X with a point. See
|
397
|
+
# simplicial_complex.py for one implementation.
|
398
|
+
###
|
399
|
+
# def cone(self):
|
400
|
+
# return self.join(POINT)
|
401
|
+
|
402
|
+
# the suspension of X is the join of X with the 0-sphere (two
|
403
|
+
# points). See simplicial_complex.py for one implementation.
|
404
|
+
###
|
405
|
+
# def suspension(self, n=1):
|
406
|
+
# """
|
407
|
+
# The suspension of this cell complex.
|
408
|
+
#
|
409
|
+
# INPUT:
|
410
|
+
#
|
411
|
+
# - ``n`` -- positive integer (default: 1); suspend this many times.
|
412
|
+
# """
|
413
|
+
# raise NotImplementedError
|
414
|
+
|
415
|
+
############################################################
|
416
|
+
# end of methods using self.join()
|
417
|
+
############################################################
|
418
|
+
|
419
|
+
############################################################
|
420
|
+
# chain complexes, homology
|
421
|
+
############################################################
|
422
|
+
|
423
|
+
@abstract_method
|
424
|
+
def chain_complex(self, subcomplex=None, augmented=False,
|
425
|
+
verbose=False, check=True, dimensions=None,
|
426
|
+
base_ring=ZZ, cochain=False):
|
427
|
+
"""
|
428
|
+
This is not implemented for general cell complexes.
|
429
|
+
|
430
|
+
Some keywords to possibly implement in a derived class:
|
431
|
+
|
432
|
+
- ``subcomplex`` -- a subcomplex: compute the relative chain complex
|
433
|
+
- ``augmented`` -- a bool: whether to return the augmented complex
|
434
|
+
- ``verbose`` -- a bool: whether to print informational messages as
|
435
|
+
the chain complex is being computed
|
436
|
+
- ``check`` -- a bool: whether to check that the each
|
437
|
+
composite of two consecutive differentials is zero
|
438
|
+
- ``dimensions`` -- if ``None``, compute the chain complex in all
|
439
|
+
dimensions. If a list or tuple of integers, compute the
|
440
|
+
chain complex in those dimensions, setting the chain groups
|
441
|
+
in all other dimensions to zero.
|
442
|
+
|
443
|
+
Definitely implement the following:
|
444
|
+
|
445
|
+
- ``base_ring`` -- commutative ring (default: ZZ)
|
446
|
+
- ``cochain`` -- a bool: whether to return the cochain complex
|
447
|
+
|
448
|
+
EXAMPLES::
|
449
|
+
|
450
|
+
sage: from sage.topology.cell_complex import GenericCellComplex
|
451
|
+
sage: A = GenericCellComplex()
|
452
|
+
sage: A.chain_complex()
|
453
|
+
Traceback (most recent call last):
|
454
|
+
...
|
455
|
+
NotImplementedError: <abstract method chain_complex at ...>
|
456
|
+
"""
|
457
|
+
|
458
|
+
def homology(self, dim=None, base_ring=ZZ, subcomplex=None,
|
459
|
+
generators=False, cohomology=False, algorithm='pari',
|
460
|
+
verbose=False, reduced=True, **kwds):
|
461
|
+
r"""
|
462
|
+
The (reduced) homology of this cell complex.
|
463
|
+
|
464
|
+
INPUT:
|
465
|
+
|
466
|
+
- ``dim`` -- integer or list of integers or ``None`` (default:
|
467
|
+
``None``); if ``None``, then return the homology in every
|
468
|
+
dimension. If ``dim`` is an integer or list, return the
|
469
|
+
homology in the given dimensions. (Actually, if ``dim`` is
|
470
|
+
a list, return the homology in the range from ``min(dim)``
|
471
|
+
to ``max(dim)``.)
|
472
|
+
- ``base_ring`` -- commutative ring (default: ``ZZ``); must be `\ZZ` or
|
473
|
+
a field
|
474
|
+
- ``subcomplex`` -- (default: empty) a subcomplex of this simplicial
|
475
|
+
complex. Compute the homology relative to this subcomplex.
|
476
|
+
- ``generators`` -- boolean (default: ``False``); if ``True``, return
|
477
|
+
generators for the homology groups along with the groups.
|
478
|
+
- ``cohomology`` -- boolean (default: ``False``); if ``True``, compute
|
479
|
+
cohomology rather than homology
|
480
|
+
- ``algorithm`` -- string (default: ``'pari'``); the algorithm options
|
481
|
+
are 'auto', 'dhsw', or 'pari'. See below for a description of what
|
482
|
+
they mean.
|
483
|
+
- ``verbose`` -- boolean (default: ``False``); if True, print some
|
484
|
+
messages as the homology is computed
|
485
|
+
- ``reduced`` -- boolean (default: ``True``); if ``True``, return the
|
486
|
+
reduced homology
|
487
|
+
|
488
|
+
ALGORITHM:
|
489
|
+
|
490
|
+
Compute the chain complex of ``self`` and compute its homology
|
491
|
+
groups. To do this: over a field, just compute ranks and
|
492
|
+
nullities, thus obtaining dimensions of the homology groups as
|
493
|
+
vector spaces. Over the integers, compute Smith normal form
|
494
|
+
of the boundary matrices defining the chain complex according
|
495
|
+
to the value of ``algorithm``. If ``algorithm`` is
|
496
|
+
``'auto'``, then for each relatively small matrix, use the
|
497
|
+
standard Sage method, which calls the Pari package. For any
|
498
|
+
large matrix, reduce it using the Dumas, Heckenbach, Saunders,
|
499
|
+
and Welker elimination algorithm [DHSW2003]_: see
|
500
|
+
:func:`~sage.homology.matrix_utils.dhsw_snf` for details.
|
501
|
+
|
502
|
+
``'no_chomp'`` is a synonym for ``'auto'``, maintained for
|
503
|
+
backward-compatibility.
|
504
|
+
|
505
|
+
``algorithm`` may also be ``'pari'`` or ``'dhsw'``, which
|
506
|
+
forces the named algorithm to be used regardless of the size
|
507
|
+
of the matrices.
|
508
|
+
|
509
|
+
As of this writing, ``'pari'`` is the fastest standard option.
|
510
|
+
|
511
|
+
EXAMPLES::
|
512
|
+
|
513
|
+
sage: # needs sage.modules
|
514
|
+
sage: P = delta_complexes.RealProjectivePlane()
|
515
|
+
sage: P.homology()
|
516
|
+
{0: 0, 1: C2, 2: 0}
|
517
|
+
sage: P.homology(reduced=False)
|
518
|
+
{0: Z, 1: C2, 2: 0}
|
519
|
+
sage: P.homology(base_ring=GF(2))
|
520
|
+
{0: Vector space of dimension 0 over Finite Field of size 2,
|
521
|
+
1: Vector space of dimension 1 over Finite Field of size 2,
|
522
|
+
2: Vector space of dimension 1 over Finite Field of size 2}
|
523
|
+
sage: S7 = delta_complexes.Sphere(7)
|
524
|
+
sage: S7.homology(7)
|
525
|
+
Z
|
526
|
+
sage: cubical_complexes.KleinBottle().homology(1, base_ring=GF(2))
|
527
|
+
Vector space of dimension 2 over Finite Field of size 2
|
528
|
+
|
529
|
+
Sage can compute generators of homology groups::
|
530
|
+
|
531
|
+
sage: S2 = simplicial_complexes.Sphere(2)
|
532
|
+
sage: S2.homology(dim=2, generators=True, base_ring=GF(2)) # needs sage.modules
|
533
|
+
[(Vector space of dimension 1 over Finite Field of size 2,
|
534
|
+
(0, 1, 2) + (0, 1, 3) + (0, 2, 3) + (1, 2, 3))]
|
535
|
+
|
536
|
+
When generators are computed, Sage returns a pair for each
|
537
|
+
dimension: the group and the list of generators. For
|
538
|
+
simplicial complexes, each generator is represented as a
|
539
|
+
linear combination of simplices, as above, and for cubical
|
540
|
+
complexes, each generator is a linear combination of cubes::
|
541
|
+
|
542
|
+
sage: S2_cub = cubical_complexes.Sphere(2)
|
543
|
+
sage: S2_cub.homology(dim=2, generators=True) # needs sage.modules
|
544
|
+
[(Z,
|
545
|
+
[0,0] x [0,1] x [0,1] - [0,1] x [0,0] x [0,1] + [0,1] x [0,1] x [0,0]
|
546
|
+
- [0,1] x [0,1] x [1,1] + [0,1] x [1,1] x [0,1] - [1,1] x [0,1] x [0,1])]
|
547
|
+
|
548
|
+
Similarly for simplicial sets::
|
549
|
+
|
550
|
+
sage: S = simplicial_sets.Sphere(2)
|
551
|
+
sage: S.homology(generators=True) # needs sage.modules
|
552
|
+
{0: [], 1: 0, 2: [(Z, sigma_2)]}
|
553
|
+
"""
|
554
|
+
from sage.homology.homology_group import HomologyGroup
|
555
|
+
|
556
|
+
if dim is not None:
|
557
|
+
if isinstance(dim, (list, tuple, range)):
|
558
|
+
low = min(dim) - 1
|
559
|
+
high = max(dim) + 2
|
560
|
+
else:
|
561
|
+
low = dim - 1
|
562
|
+
high = dim + 2
|
563
|
+
dims = range(low, high)
|
564
|
+
else:
|
565
|
+
dims = None
|
566
|
+
|
567
|
+
# Derived classes can implement specialized algorithms using a
|
568
|
+
# _homology_ method. See SimplicialComplex for one example.
|
569
|
+
# Those may allow for other arguments, so we pass **kwds.
|
570
|
+
if hasattr(self, '_homology_'):
|
571
|
+
return self._homology_(dim, subcomplex=subcomplex,
|
572
|
+
cohomology=cohomology, base_ring=base_ring,
|
573
|
+
verbose=verbose, algorithm=algorithm,
|
574
|
+
reduced=reduced, generators=generators,
|
575
|
+
**kwds)
|
576
|
+
|
577
|
+
C = self.chain_complex(cochain=cohomology, augmented=reduced,
|
578
|
+
dimensions=dims, subcomplex=subcomplex,
|
579
|
+
base_ring=base_ring, verbose=verbose)
|
580
|
+
answer = C.homology(base_ring=base_ring, generators=generators,
|
581
|
+
verbose=verbose, algorithm=algorithm)
|
582
|
+
|
583
|
+
if generators:
|
584
|
+
# Try to convert chain complex information to topological
|
585
|
+
# chain information.
|
586
|
+
for i in answer:
|
587
|
+
H_with_gens = answer[i]
|
588
|
+
if H_with_gens:
|
589
|
+
chains = self.n_chains(i, base_ring=base_ring)
|
590
|
+
new_H = []
|
591
|
+
for (H, gen) in H_with_gens:
|
592
|
+
v = gen.vector(i)
|
593
|
+
new_gen = chains.zero()
|
594
|
+
for (coeff, chain) in zip(v, chains.gens()):
|
595
|
+
new_gen += coeff * chain
|
596
|
+
new_H.append((H, new_gen))
|
597
|
+
answer[i] = new_H
|
598
|
+
|
599
|
+
if dim is None:
|
600
|
+
dim = range(self.dimension() + 1)
|
601
|
+
zero = HomologyGroup(0, base_ring)
|
602
|
+
if isinstance(dim, (list, tuple, range)):
|
603
|
+
return dict([d, answer.get(d, zero)] for d in dim)
|
604
|
+
return answer.get(dim, zero)
|
605
|
+
|
606
|
+
def cohomology(self, dim=None, base_ring=ZZ, subcomplex=None,
|
607
|
+
generators=False, algorithm='pari',
|
608
|
+
verbose=False, reduced=True):
|
609
|
+
r"""
|
610
|
+
The reduced cohomology of this cell complex.
|
611
|
+
|
612
|
+
The arguments are the same as for the :meth:`homology` method,
|
613
|
+
except that :meth:`homology` accepts a ``cohomology`` key
|
614
|
+
word, while this function does not: ``cohomology`` is
|
615
|
+
automatically true here. Indeed, this function just calls
|
616
|
+
:meth:`homology` with ``cohomology`` set to ``True``.
|
617
|
+
|
618
|
+
INPUT:
|
619
|
+
|
620
|
+
- ``dim``
|
621
|
+
- ``base_ring``
|
622
|
+
- ``subcomplex``
|
623
|
+
- ``algorithm``
|
624
|
+
- ``verbose``
|
625
|
+
- ``reduced``
|
626
|
+
|
627
|
+
EXAMPLES::
|
628
|
+
|
629
|
+
sage: circle = SimplicialComplex([[0,1], [1,2], [0, 2]])
|
630
|
+
sage: circle.cohomology(0) # needs sage.modules
|
631
|
+
0
|
632
|
+
sage: circle.cohomology(1) # needs sage.modules
|
633
|
+
Z
|
634
|
+
|
635
|
+
Projective plane::
|
636
|
+
|
637
|
+
sage: # needs sage.modules
|
638
|
+
sage: P2 = SimplicialComplex([[0,1,2], [0,2,3], [0,1,5], [0,4,5], [0,3,4],
|
639
|
+
....: [1,2,4], [1,3,4], [1,3,5], [2,3,5], [2,4,5]])
|
640
|
+
sage: P2.cohomology(2)
|
641
|
+
C2
|
642
|
+
sage: P2.cohomology(2, base_ring=GF(2))
|
643
|
+
Vector space of dimension 1 over Finite Field of size 2
|
644
|
+
sage: P2.cohomology(2, base_ring=GF(3))
|
645
|
+
Vector space of dimension 0 over Finite Field of size 3
|
646
|
+
|
647
|
+
sage: cubical_complexes.KleinBottle().cohomology(2) # needs sage.modules
|
648
|
+
C2
|
649
|
+
|
650
|
+
Relative cohomology::
|
651
|
+
|
652
|
+
sage: T = SimplicialComplex([[0,1]])
|
653
|
+
sage: U = SimplicialComplex([[0], [1]])
|
654
|
+
sage: T.cohomology(1, subcomplex=U) # needs sage.modules
|
655
|
+
Z
|
656
|
+
|
657
|
+
A `\Delta`-complex example::
|
658
|
+
|
659
|
+
sage: s5 = delta_complexes.Sphere(5)
|
660
|
+
sage: s5.cohomology(base_ring=GF(7))[5] # needs sage.modules
|
661
|
+
Vector space of dimension 1 over Finite Field of size 7
|
662
|
+
"""
|
663
|
+
return self.homology(dim=dim, cohomology=True, base_ring=base_ring,
|
664
|
+
subcomplex=subcomplex, generators=generators,
|
665
|
+
algorithm=algorithm, verbose=verbose,
|
666
|
+
reduced=reduced)
|
667
|
+
|
668
|
+
def betti(self, dim=None, subcomplex=None):
|
669
|
+
r"""
|
670
|
+
The Betti numbers of this simplicial complex as a dictionary
|
671
|
+
(or a single Betti number, if only one dimension is given):
|
672
|
+
the `i`-th Betti number is the rank of the `i`-th homology group.
|
673
|
+
|
674
|
+
INPUT:
|
675
|
+
|
676
|
+
- ``dim`` -- integer or list of integers or ``None`` (default:
|
677
|
+
``None``); if ``None``, then return every Betti number, as
|
678
|
+
a dictionary with keys the non-negative integers. If
|
679
|
+
``dim`` is an integer or list, return the Betti number for
|
680
|
+
each given dimension. (Actually, if ``dim`` is a list,
|
681
|
+
return the Betti numbers, as a dictionary, in the range
|
682
|
+
from ``min(dim)`` to ``max(dim)``. If ``dim`` is a number,
|
683
|
+
return the Betti number in that dimension.)
|
684
|
+
- ``subcomplex`` -- a subcomplex (default: ``None``) of this cell
|
685
|
+
complex; compute the Betti numbers of the homology relative to this
|
686
|
+
subcomplex
|
687
|
+
|
688
|
+
EXAMPLES:
|
689
|
+
|
690
|
+
Build the two-sphere as a three-fold join of a
|
691
|
+
two-point space with itself::
|
692
|
+
|
693
|
+
sage: S = SimplicialComplex([[0], [1]])
|
694
|
+
sage: (S*S*S).betti() # needs sage.modules
|
695
|
+
{0: 1, 1: 0, 2: 1}
|
696
|
+
sage: (S*S*S).betti([1,2]) # needs sage.modules
|
697
|
+
{1: 0, 2: 1}
|
698
|
+
sage: (S*S*S).betti(2) # needs sage.modules
|
699
|
+
1
|
700
|
+
|
701
|
+
Or build the two-sphere as a `\Delta`-complex::
|
702
|
+
|
703
|
+
sage: S2 = delta_complexes.Sphere(2)
|
704
|
+
sage: S2.betti([1,2]) # needs sage.modules
|
705
|
+
{1: 0, 2: 1}
|
706
|
+
|
707
|
+
Or as a cubical complex::
|
708
|
+
|
709
|
+
sage: S2c = cubical_complexes.Sphere(2)
|
710
|
+
sage: S2c.betti(2) # needs sage.modules
|
711
|
+
1
|
712
|
+
"""
|
713
|
+
dic = {}
|
714
|
+
H = self.homology(dim, base_ring=QQ, subcomplex=subcomplex)
|
715
|
+
try:
|
716
|
+
for n in H.keys():
|
717
|
+
dic[n] = H[n].dimension()
|
718
|
+
if n == 0:
|
719
|
+
dic[n] += 1
|
720
|
+
except AttributeError:
|
721
|
+
return H.dimension()
|
722
|
+
else:
|
723
|
+
return dic
|
724
|
+
|
725
|
+
def is_acyclic(self, base_ring=ZZ):
|
726
|
+
"""
|
727
|
+
Return ``True`` if the reduced homology with coefficients in
|
728
|
+
``base_ring`` of this cell complex is zero.
|
729
|
+
|
730
|
+
INPUT:
|
731
|
+
|
732
|
+
- ``base_ring`` -- (default: ``ZZ``) compute homology
|
733
|
+
with coefficients in this ring
|
734
|
+
|
735
|
+
EXAMPLES::
|
736
|
+
|
737
|
+
sage: RP2 = simplicial_complexes.RealProjectivePlane()
|
738
|
+
sage: RP2.is_acyclic() # needs sage.modules
|
739
|
+
False
|
740
|
+
sage: RP2.is_acyclic(QQ) # needs sage.modules
|
741
|
+
True
|
742
|
+
|
743
|
+
This first computes the Euler characteristic: if it is not 1,
|
744
|
+
the complex cannot be acyclic. So this should return ``False``
|
745
|
+
reasonably quickly on complexes with Euler characteristic not
|
746
|
+
equal to 1::
|
747
|
+
|
748
|
+
sage: K = cubical_complexes.KleinBottle()
|
749
|
+
sage: C = cubical_complexes.Cube(2)
|
750
|
+
sage: P = K.product(C); P
|
751
|
+
Cubical complex with 168 vertices and 1512 cubes
|
752
|
+
sage: P.euler_characteristic()
|
753
|
+
0
|
754
|
+
sage: P.is_acyclic()
|
755
|
+
False
|
756
|
+
"""
|
757
|
+
if self.euler_characteristic() != 1:
|
758
|
+
return False
|
759
|
+
H = self.homology(base_ring=base_ring)
|
760
|
+
if base_ring == ZZ:
|
761
|
+
return all(len(x.invariants()) == 0 for x in H.values())
|
762
|
+
else:
|
763
|
+
# base_ring is a field.
|
764
|
+
return all(x.dimension() == 0 for x in H.values())
|
765
|
+
|
766
|
+
def n_chains(self, n, base_ring=ZZ, cochains=False):
|
767
|
+
r"""
|
768
|
+
Return the free module of chains in degree ``n`` over ``base_ring``.
|
769
|
+
|
770
|
+
INPUT:
|
771
|
+
|
772
|
+
- ``n`` -- integer
|
773
|
+
- ``base_ring`` -- ring (default: `\ZZ`)
|
774
|
+
- ``cochains`` -- boolean (default: ``False``); if
|
775
|
+
``True``, return cochains instead
|
776
|
+
|
777
|
+
The only difference between chains and cochains is
|
778
|
+
notation. In a simplicial complex, for example, a simplex
|
779
|
+
``(0,1,2)`` is written as "(0,1,2)" in the group of chains but
|
780
|
+
as "\chi_(0,1,2)" in the group of cochains.
|
781
|
+
|
782
|
+
EXAMPLES::
|
783
|
+
|
784
|
+
sage: S2 = simplicial_complexes.Sphere(2)
|
785
|
+
sage: S2.n_chains(1, QQ) # needs sage.modules
|
786
|
+
Free module generated by {(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)}
|
787
|
+
over Rational Field
|
788
|
+
sage: list(S2.n_chains(1, QQ, cochains=False).basis()) # needs sage.modules
|
789
|
+
[(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)]
|
790
|
+
sage: list(S2.n_chains(1, QQ, cochains=True).basis()) # needs sage.modules
|
791
|
+
[\chi_(0, 1), \chi_(0, 2), \chi_(0, 3), \chi_(1, 2), \chi_(1, 3), \chi_(2, 3)]
|
792
|
+
"""
|
793
|
+
from sage.homology.chains import Chains, Cochains
|
794
|
+
|
795
|
+
n_cells = tuple(self._n_cells_sorted(n))
|
796
|
+
if cochains:
|
797
|
+
return Cochains(self, n, n_cells, base_ring)
|
798
|
+
else:
|
799
|
+
return Chains(self, n, n_cells, base_ring)
|
800
|
+
|
801
|
+
def algebraic_topological_model(self, base_ring=QQ):
|
802
|
+
r"""
|
803
|
+
Algebraic topological model for this cell complex with
|
804
|
+
coefficients in ``base_ring``.
|
805
|
+
|
806
|
+
The term "algebraic topological model" is defined by Pilarczyk
|
807
|
+
and Réal [PR2015]_.
|
808
|
+
|
809
|
+
This is not implemented for generic cell complexes. For any
|
810
|
+
classes deriving from this one, when this method is
|
811
|
+
implemented, it should essentially just call either
|
812
|
+
:func:`~sage.homology.algebraic_topological_model.algebraic_topological_model`
|
813
|
+
or
|
814
|
+
:func:`~sage.homology.algebraic_topological_model.algebraic_topological_model_delta_complex`.
|
815
|
+
|
816
|
+
EXAMPLES::
|
817
|
+
|
818
|
+
sage: from sage.topology.cell_complex import GenericCellComplex
|
819
|
+
sage: A = GenericCellComplex()
|
820
|
+
sage: A.algebraic_topological_model(QQ)
|
821
|
+
Traceback (most recent call last):
|
822
|
+
...
|
823
|
+
NotImplementedError
|
824
|
+
"""
|
825
|
+
raise NotImplementedError
|
826
|
+
|
827
|
+
def homology_with_basis(self, base_ring=QQ, cohomology=False):
|
828
|
+
r"""
|
829
|
+
Return the unreduced homology of this complex with
|
830
|
+
coefficients in ``base_ring`` with a chosen basis.
|
831
|
+
|
832
|
+
This is implemented for simplicial, cubical, and
|
833
|
+
`\Delta`-complexes, not for arbitrary generic cell complexes.
|
834
|
+
|
835
|
+
INPUT:
|
836
|
+
|
837
|
+
- ``base_ring`` -- coefficient ring (default:
|
838
|
+
``QQ``); must be a field
|
839
|
+
- ``cohomology`` -- boolean (default: ``False``); if
|
840
|
+
``True``, return cohomology instead of homology
|
841
|
+
|
842
|
+
Homology basis elements are named 'h_{dim,i}' where i ranges
|
843
|
+
between 0 and `r-1`, if `r` is the rank of the homology
|
844
|
+
group. Cohomology basis elements are denoted `h^{dim,i}`
|
845
|
+
instead.
|
846
|
+
|
847
|
+
.. SEEALSO::
|
848
|
+
|
849
|
+
If ``cohomology`` is ``True``, this returns the cohomology
|
850
|
+
as a ring: it calls :meth:`cohomology_ring`.
|
851
|
+
|
852
|
+
EXAMPLES::
|
853
|
+
|
854
|
+
sage: # needs sage.modules
|
855
|
+
sage: K = simplicial_complexes.KleinBottle()
|
856
|
+
sage: H = K.homology_with_basis(QQ); H
|
857
|
+
Homology module of Minimal triangulation of the Klein bottle
|
858
|
+
over Rational Field
|
859
|
+
sage: sorted(H.basis(), key=str)
|
860
|
+
[h_{0,0}, h_{1,0}]
|
861
|
+
sage: H = K.homology_with_basis(GF(2)); H
|
862
|
+
Homology module of Minimal triangulation of the Klein bottle
|
863
|
+
over Finite Field of size 2
|
864
|
+
sage: sorted(H.basis(), key=str)
|
865
|
+
[h_{0,0}, h_{1,0}, h_{1,1}, h_{2,0}]
|
866
|
+
|
867
|
+
The homology is constructed as a graded object, so for
|
868
|
+
example, you can ask for the basis in a single degree::
|
869
|
+
|
870
|
+
sage: H.basis(1) # needs sage.modules
|
871
|
+
Finite family {(1, 0): h_{1,0}, (1, 1): h_{1,1}}
|
872
|
+
|
873
|
+
sage: S3 = delta_complexes.Sphere(3)
|
874
|
+
sage: H = S3.homology_with_basis(QQ, cohomology=True) # needs sage.modules
|
875
|
+
sage: list(H.basis(3)) # needs sage.modules
|
876
|
+
[h^{3,0}]
|
877
|
+
"""
|
878
|
+
from sage.homology.homology_vector_space_with_basis import \
|
879
|
+
HomologyVectorSpaceWithBasis, HomologyVectorSpaceWithBasis_mod2, \
|
880
|
+
is_GF2
|
881
|
+
|
882
|
+
if cohomology:
|
883
|
+
return self.cohomology_ring(base_ring)
|
884
|
+
if is_GF2(base_ring):
|
885
|
+
return HomologyVectorSpaceWithBasis_mod2(base_ring, self)
|
886
|
+
return HomologyVectorSpaceWithBasis(base_ring, self, cohomology)
|
887
|
+
|
888
|
+
def cohomology_ring(self, base_ring=QQ):
|
889
|
+
r"""
|
890
|
+
Return the unreduced cohomology with coefficients in
|
891
|
+
``base_ring`` with a chosen basis.
|
892
|
+
|
893
|
+
This is implemented for simplicial, cubical, and
|
894
|
+
`\Delta`-complexes, not for arbitrary generic cell complexes.
|
895
|
+
The resulting elements are suitable for computing cup
|
896
|
+
products. For simplicial complexes, they should be suitable
|
897
|
+
for computing cohomology operations; so far, only mod 2
|
898
|
+
cohomology operations have been implemented.
|
899
|
+
|
900
|
+
INPUT:
|
901
|
+
|
902
|
+
- ``base_ring`` -- coefficient ring (default:
|
903
|
+
``QQ``); must be a field
|
904
|
+
|
905
|
+
The basis elements in dimension ``dim`` are named 'h^{dim,i}'
|
906
|
+
where `i` ranges between 0 and `r-1`, if `r` is the rank of
|
907
|
+
the cohomology group.
|
908
|
+
|
909
|
+
.. NOTE::
|
910
|
+
|
911
|
+
For all but the smallest complexes, this is likely to be
|
912
|
+
slower than :meth:`cohomology` (with field coefficients),
|
913
|
+
possibly by several orders of magnitude. This and its
|
914
|
+
companion :meth:`homology_with_basis` carry extra
|
915
|
+
information which allows computation of cup products, for
|
916
|
+
example, but because of speed issues, you may only wish to
|
917
|
+
use these if you need that extra information.
|
918
|
+
|
919
|
+
EXAMPLES::
|
920
|
+
|
921
|
+
sage: # needs sage.modules
|
922
|
+
sage: K = simplicial_complexes.KleinBottle()
|
923
|
+
sage: H = K.cohomology_ring(QQ); H
|
924
|
+
Cohomology ring of Minimal triangulation of the Klein bottle
|
925
|
+
over Rational Field
|
926
|
+
sage: sorted(H.basis(), key=str)
|
927
|
+
[h^{0,0}, h^{1,0}]
|
928
|
+
sage: H = K.cohomology_ring(GF(2)); H
|
929
|
+
Cohomology ring of Minimal triangulation of the Klein bottle
|
930
|
+
over Finite Field of size 2
|
931
|
+
sage: sorted(H.basis(), key=str)
|
932
|
+
[h^{0,0}, h^{1,0}, h^{1,1}, h^{2,0}]
|
933
|
+
|
934
|
+
sage: X = delta_complexes.SurfaceOfGenus(2)
|
935
|
+
sage: H = X.cohomology_ring(QQ); H # needs sage.modules
|
936
|
+
Cohomology ring of Delta complex with 3 vertices and 29 simplices
|
937
|
+
over Rational Field
|
938
|
+
sage: sorted(H.basis(1), key=str) # needs sage.modules
|
939
|
+
[h^{1,0}, h^{1,1}, h^{1,2}, h^{1,3}]
|
940
|
+
|
941
|
+
sage: H = simplicial_complexes.Torus().cohomology_ring(QQ); H # needs sage.modules
|
942
|
+
Cohomology ring of Minimal triangulation of the torus
|
943
|
+
over Rational Field
|
944
|
+
sage: x = H.basis()[1,0]; x # needs sage.modules
|
945
|
+
h^{1,0}
|
946
|
+
sage: y = H.basis()[1,1]; y # needs sage.modules
|
947
|
+
h^{1,1}
|
948
|
+
|
949
|
+
You can compute cup products of cohomology classes::
|
950
|
+
|
951
|
+
sage: # needs sage.modules
|
952
|
+
sage: x.cup_product(y)
|
953
|
+
-h^{2,0}
|
954
|
+
sage: x * y # alternate notation
|
955
|
+
-h^{2,0}
|
956
|
+
sage: y.cup_product(x)
|
957
|
+
h^{2,0}
|
958
|
+
sage: x.cup_product(x)
|
959
|
+
0
|
960
|
+
|
961
|
+
Cohomology operations::
|
962
|
+
|
963
|
+
sage: # needs sage.groups
|
964
|
+
sage: RP2 = simplicial_complexes.RealProjectivePlane()
|
965
|
+
sage: K = RP2.suspension()
|
966
|
+
sage: K.set_immutable()
|
967
|
+
sage: y = K.cohomology_ring(GF(2)).basis()[2,0]; y # needs sage.modules
|
968
|
+
h^{2,0}
|
969
|
+
sage: y.Sq(1) # needs sage.modules
|
970
|
+
h^{3,0}
|
971
|
+
|
972
|
+
To compute the cohomology ring, the complex must be
|
973
|
+
"immutable". This is only relevant for simplicial complexes,
|
974
|
+
and most simplicial complexes are immutable, but certain
|
975
|
+
constructions make them mutable. The suspension is one
|
976
|
+
example, and this is the reason for calling
|
977
|
+
``K.set_immutable()`` above. Another example::
|
978
|
+
|
979
|
+
sage: S1 = simplicial_complexes.Sphere(1)
|
980
|
+
sage: T = S1.product(S1)
|
981
|
+
sage: T.is_immutable()
|
982
|
+
False
|
983
|
+
sage: T.cohomology_ring() # needs sage.modules
|
984
|
+
Traceback (most recent call last):
|
985
|
+
...
|
986
|
+
ValueError: this simplicial complex must be immutable; call set_immutable()
|
987
|
+
sage: T.set_immutable()
|
988
|
+
sage: T.cohomology_ring() # needs sage.modules
|
989
|
+
Cohomology ring of Simplicial complex with 9 vertices and
|
990
|
+
18 facets over Rational Field
|
991
|
+
"""
|
992
|
+
from sage.homology.homology_vector_space_with_basis import CohomologyRing, \
|
993
|
+
CohomologyRing_mod2, is_GF2
|
994
|
+
|
995
|
+
if is_GF2(base_ring):
|
996
|
+
return CohomologyRing_mod2(base_ring, self)
|
997
|
+
return CohomologyRing(base_ring, self)
|
998
|
+
|
999
|
+
@abstract_method
|
1000
|
+
def alexander_whitney(self, cell, dim_left):
|
1001
|
+
r"""
|
1002
|
+
The decomposition of ``cell`` in this complex into left and right
|
1003
|
+
factors, suitable for computing cup products. This should
|
1004
|
+
provide a cellular approximation for the diagonal map `K \to K
|
1005
|
+
\times K`.
|
1006
|
+
|
1007
|
+
This method is not implemented for generic cell complexes, but
|
1008
|
+
must be implemented for any derived class to make cup products
|
1009
|
+
work in ``self.cohomology_ring()``.
|
1010
|
+
|
1011
|
+
INPUT:
|
1012
|
+
|
1013
|
+
- ``cell`` -- a cell in this complex
|
1014
|
+
- ``dim_left`` -- the dimension of the left-hand factors in
|
1015
|
+
the decomposition
|
1016
|
+
|
1017
|
+
OUTPUT: list containing triples ``(c, left, right)``.
|
1018
|
+
``left`` and ``right`` should be cells in this complex, and
|
1019
|
+
``c`` an integer. In the cellular approximation of the
|
1020
|
+
diagonal map, the chain represented by ``cell`` should get
|
1021
|
+
sent to the sum of terms `c (left \otimes right)` in the
|
1022
|
+
tensor product `C(K) \otimes C(K)` of the chain complex for
|
1023
|
+
this complex with itself.
|
1024
|
+
|
1025
|
+
This gets used in the method
|
1026
|
+
:meth:`~sage.homology.homology_vector_space_with_basis.CohomologyRing.product_on_basis`
|
1027
|
+
for the class of cohomology rings.
|
1028
|
+
|
1029
|
+
For simplicial and cubical complexes, the decomposition can be
|
1030
|
+
done at the level of individual cells: see
|
1031
|
+
:meth:`~sage.homology.simplicial_complex.Simplex.alexander_whitney`
|
1032
|
+
and
|
1033
|
+
:meth:`~sage.homology.cubical_complex.Cube.alexander_whitney`. Then
|
1034
|
+
the method for simplicial complexes just calls the method for
|
1035
|
+
individual simplices, and similarly for cubical complexes. For
|
1036
|
+
`\Delta`-complexes and simplicial sets, the method is instead
|
1037
|
+
defined at the level of the cell complex.
|
1038
|
+
|
1039
|
+
EXAMPLES::
|
1040
|
+
|
1041
|
+
sage: from sage.topology.cell_complex import GenericCellComplex
|
1042
|
+
sage: A = GenericCellComplex()
|
1043
|
+
sage: A.alexander_whitney(None, 2)
|
1044
|
+
Traceback (most recent call last):
|
1045
|
+
...
|
1046
|
+
NotImplementedError: <abstract method alexander_whitney at ...>
|
1047
|
+
"""
|
1048
|
+
|
1049
|
+
############################################################
|
1050
|
+
# end of chain complexes, homology
|
1051
|
+
############################################################
|
1052
|
+
|
1053
|
+
def face_poset(self):
|
1054
|
+
r"""
|
1055
|
+
The face poset of this cell complex, the poset of
|
1056
|
+
nonempty cells, ordered by inclusion.
|
1057
|
+
|
1058
|
+
This uses the :meth:`cells` method, and also assumes that for
|
1059
|
+
each cell ``f``, all of ``f.faces()``, ``tuple(f)``, and
|
1060
|
+
``f.dimension()`` make sense. (If this is not the case in
|
1061
|
+
some derived class, as happens with `\Delta`-complexes, then
|
1062
|
+
override this method.)
|
1063
|
+
|
1064
|
+
EXAMPLES::
|
1065
|
+
|
1066
|
+
sage: P = SimplicialComplex([[0, 1], [1,2], [2,3]]).face_poset(); P
|
1067
|
+
Finite poset containing 7 elements
|
1068
|
+
sage: sorted(P.list())
|
1069
|
+
[(0,), (0, 1), (1,), (1, 2), (2,), (2, 3), (3,)]
|
1070
|
+
|
1071
|
+
sage: S2 = cubical_complexes.Sphere(2)
|
1072
|
+
sage: S2.face_poset()
|
1073
|
+
Finite poset containing 26 elements
|
1074
|
+
"""
|
1075
|
+
from sage.combinat.posets.posets import Poset
|
1076
|
+
from sage.misc.flatten import flatten
|
1077
|
+
covers = {}
|
1078
|
+
# The code for posets seems to work better if each cell is
|
1079
|
+
# converted to a tuple.
|
1080
|
+
all_cells = flatten([list(f) for f in self.cells().values()])
|
1081
|
+
|
1082
|
+
for C in all_cells:
|
1083
|
+
if C.dimension() >= 0:
|
1084
|
+
covers[tuple(C)] = []
|
1085
|
+
for C in all_cells:
|
1086
|
+
for face in C.faces():
|
1087
|
+
if face.dimension() >= 0:
|
1088
|
+
covers[tuple(face)].append(tuple(C))
|
1089
|
+
return Poset(covers)
|
1090
|
+
|
1091
|
+
def graph(self):
|
1092
|
+
"""
|
1093
|
+
The 1-skeleton of this cell complex, as a graph.
|
1094
|
+
|
1095
|
+
This is not implemented for general cell complexes.
|
1096
|
+
|
1097
|
+
EXAMPLES::
|
1098
|
+
|
1099
|
+
sage: from sage.topology.cell_complex import GenericCellComplex
|
1100
|
+
sage: A = GenericCellComplex()
|
1101
|
+
sage: A.graph()
|
1102
|
+
Traceback (most recent call last):
|
1103
|
+
...
|
1104
|
+
NotImplementedError
|
1105
|
+
"""
|
1106
|
+
raise NotImplementedError
|
1107
|
+
|
1108
|
+
def is_connected(self):
|
1109
|
+
"""
|
1110
|
+
Return ``True`` if this cell complex is connected.
|
1111
|
+
|
1112
|
+
EXAMPLES::
|
1113
|
+
|
1114
|
+
sage: V = SimplicialComplex([[0,1,2],[3]]); V
|
1115
|
+
Simplicial complex with vertex set (0, 1, 2, 3) and facets {(3,), (0, 1, 2)}
|
1116
|
+
sage: V.is_connected()
|
1117
|
+
False
|
1118
|
+
sage: X = SimplicialComplex([[0,1,2]])
|
1119
|
+
sage: X.is_connected()
|
1120
|
+
True
|
1121
|
+
sage: U = simplicial_complexes.ChessboardComplex(3,3)
|
1122
|
+
sage: U.is_connected()
|
1123
|
+
True
|
1124
|
+
sage: W = simplicial_complexes.Sphere(3)
|
1125
|
+
sage: W.is_connected()
|
1126
|
+
True
|
1127
|
+
sage: S = SimplicialComplex([[0,1],[2,3]])
|
1128
|
+
sage: S.is_connected()
|
1129
|
+
False
|
1130
|
+
|
1131
|
+
sage: cubical_complexes.Sphere(0).is_connected()
|
1132
|
+
False
|
1133
|
+
sage: cubical_complexes.Sphere(2).is_connected()
|
1134
|
+
True
|
1135
|
+
"""
|
1136
|
+
return self.graph().is_connected()
|
1137
|
+
|
1138
|
+
@abstract_method
|
1139
|
+
def n_skeleton(self, n):
|
1140
|
+
"""
|
1141
|
+
The `n`-skeleton of this cell complex: the cell
|
1142
|
+
complex obtained by discarding all of the simplices in
|
1143
|
+
dimensions larger than `n`.
|
1144
|
+
|
1145
|
+
INPUT:
|
1146
|
+
|
1147
|
+
- ``n`` -- nonnegative integer
|
1148
|
+
|
1149
|
+
This is not implemented for general cell complexes.
|
1150
|
+
|
1151
|
+
EXAMPLES::
|
1152
|
+
|
1153
|
+
sage: from sage.topology.cell_complex import GenericCellComplex
|
1154
|
+
sage: A = GenericCellComplex()
|
1155
|
+
sage: A.n_skeleton(3)
|
1156
|
+
Traceback (most recent call last):
|
1157
|
+
...
|
1158
|
+
NotImplementedError: <abstract method n_skeleton at ...>
|
1159
|
+
"""
|
1160
|
+
|
1161
|
+
def _string_constants(self):
|
1162
|
+
"""
|
1163
|
+
Tuple containing the name of the type of complex, and the
|
1164
|
+
singular and plural of the name of the cells from which it is
|
1165
|
+
built. This is used in constructing the string representation.
|
1166
|
+
|
1167
|
+
OUTPUT: tuple of strings
|
1168
|
+
|
1169
|
+
This returns ``('Cell', 'cell', 'cells')``, as in "Cell
|
1170
|
+
complex", "1 cell", and "24 cells", but in other classes it
|
1171
|
+
could be overridden, as for example with ``('Cubical', 'cube',
|
1172
|
+
'cubes')`` or ``('Delta', 'simplex', 'simplices')``. If for a
|
1173
|
+
derived class, the basic form of the print representation is
|
1174
|
+
acceptable, you can just modify these strings.
|
1175
|
+
|
1176
|
+
EXAMPLES::
|
1177
|
+
|
1178
|
+
sage: from sage.topology.cell_complex import GenericCellComplex
|
1179
|
+
sage: GenericCellComplex()._string_constants()
|
1180
|
+
('Cell', 'cell', 'cells')
|
1181
|
+
sage: delta_complexes.Sphere(0)._string_constants()
|
1182
|
+
('Delta', 'simplex', 'simplices')
|
1183
|
+
sage: cubical_complexes.Sphere(0)._string_constants()
|
1184
|
+
('Cubical', 'cube', 'cubes')
|
1185
|
+
"""
|
1186
|
+
return ('Cell', 'cell', 'cells')
|
1187
|
+
|
1188
|
+
def _repr_(self):
|
1189
|
+
"""
|
1190
|
+
Print representation.
|
1191
|
+
|
1192
|
+
OUTPUT: string
|
1193
|
+
|
1194
|
+
EXAMPLES::
|
1195
|
+
|
1196
|
+
sage: delta_complexes.Sphere(7) # indirect doctest
|
1197
|
+
Delta complex with 8 vertices and 257 simplices
|
1198
|
+
sage: delta_complexes.Torus()._repr_()
|
1199
|
+
'Delta complex with 1 vertex and 7 simplices'
|
1200
|
+
"""
|
1201
|
+
vertices = len(self.n_cells(0))
|
1202
|
+
Name, cell_name, cells_name = self._string_constants()
|
1203
|
+
if vertices != 1:
|
1204
|
+
vertex_string = "with %s vertices" % vertices
|
1205
|
+
else:
|
1206
|
+
vertex_string = "with 1 vertex"
|
1207
|
+
cells = 0
|
1208
|
+
for dim in self.cells():
|
1209
|
+
cells += len(self.cells()[dim])
|
1210
|
+
if cells != 1:
|
1211
|
+
cells_string = " and {} {}".format(cells, cells_name)
|
1212
|
+
else:
|
1213
|
+
cells_string = " and 1 %s" % cell_name
|
1214
|
+
return Name + " complex " + vertex_string + cells_string
|