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.
Files changed (260) hide show
  1. passagemath_graphs-10.6.1rc1.dist-info/METADATA +292 -0
  2. passagemath_graphs-10.6.1rc1.dist-info/RECORD +260 -0
  3. passagemath_graphs-10.6.1rc1.dist-info/WHEEL +5 -0
  4. passagemath_graphs-10.6.1rc1.dist-info/top_level.txt +2 -0
  5. passagemath_graphs.libs/libgcc_s-69c45f16.so.1 +0 -0
  6. passagemath_graphs.libs/libgmp-8e78bd9b.so.10.5.0 +0 -0
  7. passagemath_graphs.libs/libstdc++-1f1a71be.so.6.0.33 +0 -0
  8. sage/all__sagemath_graphs.py +39 -0
  9. sage/combinat/abstract_tree.py +2723 -0
  10. sage/combinat/all__sagemath_graphs.py +34 -0
  11. sage/combinat/binary_tree.py +5306 -0
  12. sage/combinat/cluster_algebra_quiver/all.py +22 -0
  13. sage/combinat/cluster_algebra_quiver/cluster_seed.py +5208 -0
  14. sage/combinat/cluster_algebra_quiver/interact.py +124 -0
  15. sage/combinat/cluster_algebra_quiver/mutation_class.py +625 -0
  16. sage/combinat/cluster_algebra_quiver/mutation_type.py +1555 -0
  17. sage/combinat/cluster_algebra_quiver/quiver.py +2290 -0
  18. sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py +2468 -0
  19. sage/combinat/designs/MOLS_handbook_data.py +570 -0
  20. sage/combinat/designs/all.py +58 -0
  21. sage/combinat/designs/bibd.py +1655 -0
  22. sage/combinat/designs/block_design.py +1071 -0
  23. sage/combinat/designs/covering_array.py +269 -0
  24. sage/combinat/designs/covering_design.py +530 -0
  25. sage/combinat/designs/database.py +5615 -0
  26. sage/combinat/designs/design_catalog.py +122 -0
  27. sage/combinat/designs/designs_pyx.cpython-310-aarch64-linux-gnu.so +0 -0
  28. sage/combinat/designs/designs_pyx.pxd +21 -0
  29. sage/combinat/designs/designs_pyx.pyx +993 -0
  30. sage/combinat/designs/difference_family.py +3951 -0
  31. sage/combinat/designs/difference_matrices.py +279 -0
  32. sage/combinat/designs/evenly_distributed_sets.cpython-310-aarch64-linux-gnu.so +0 -0
  33. sage/combinat/designs/evenly_distributed_sets.pyx +661 -0
  34. sage/combinat/designs/ext_rep.py +1064 -0
  35. sage/combinat/designs/gen_quadrangles_with_spread.cpython-310-aarch64-linux-gnu.so +0 -0
  36. sage/combinat/designs/gen_quadrangles_with_spread.pyx +339 -0
  37. sage/combinat/designs/group_divisible_designs.py +361 -0
  38. sage/combinat/designs/incidence_structures.py +2357 -0
  39. sage/combinat/designs/latin_squares.py +581 -0
  40. sage/combinat/designs/orthogonal_arrays.py +2244 -0
  41. sage/combinat/designs/orthogonal_arrays_build_recursive.py +1780 -0
  42. sage/combinat/designs/orthogonal_arrays_find_recursive.cpython-310-aarch64-linux-gnu.so +0 -0
  43. sage/combinat/designs/orthogonal_arrays_find_recursive.pyx +967 -0
  44. sage/combinat/designs/resolvable_bibd.py +815 -0
  45. sage/combinat/designs/steiner_quadruple_systems.py +1306 -0
  46. sage/combinat/designs/subhypergraph_search.cpython-310-aarch64-linux-gnu.so +0 -0
  47. sage/combinat/designs/subhypergraph_search.pyx +530 -0
  48. sage/combinat/designs/twographs.py +306 -0
  49. sage/combinat/finite_state_machine.py +14874 -0
  50. sage/combinat/finite_state_machine_generators.py +2006 -0
  51. sage/combinat/graph_path.py +448 -0
  52. sage/combinat/interval_posets.py +3908 -0
  53. sage/combinat/nu_tamari_lattice.py +269 -0
  54. sage/combinat/ordered_tree.py +1446 -0
  55. sage/combinat/posets/all.py +46 -0
  56. sage/combinat/posets/bubble_shuffle.py +247 -0
  57. sage/combinat/posets/cartesian_product.py +493 -0
  58. sage/combinat/posets/d_complete.py +182 -0
  59. sage/combinat/posets/elements.py +273 -0
  60. sage/combinat/posets/forest.py +30 -0
  61. sage/combinat/posets/hasse_cython.cpython-310-aarch64-linux-gnu.so +0 -0
  62. sage/combinat/posets/hasse_cython.pyx +174 -0
  63. sage/combinat/posets/hasse_diagram.py +3672 -0
  64. sage/combinat/posets/hochschild_lattice.py +158 -0
  65. sage/combinat/posets/incidence_algebras.py +794 -0
  66. sage/combinat/posets/lattices.py +5117 -0
  67. sage/combinat/posets/linear_extension_iterator.cpython-310-aarch64-linux-gnu.so +0 -0
  68. sage/combinat/posets/linear_extension_iterator.pyx +292 -0
  69. sage/combinat/posets/linear_extensions.py +1037 -0
  70. sage/combinat/posets/mobile.py +275 -0
  71. sage/combinat/posets/moebius_algebra.py +776 -0
  72. sage/combinat/posets/poset_examples.py +2178 -0
  73. sage/combinat/posets/posets.py +9360 -0
  74. sage/combinat/rooted_tree.py +1070 -0
  75. sage/combinat/shard_order.py +239 -0
  76. sage/combinat/tamari_lattices.py +384 -0
  77. sage/combinat/yang_baxter_graph.py +923 -0
  78. sage/databases/all__sagemath_graphs.py +1 -0
  79. sage/databases/knotinfo_db.py +1231 -0
  80. sage/ext_data/all__sagemath_graphs.py +1 -0
  81. sage/ext_data/graphs/graph_plot_js.html +330 -0
  82. sage/ext_data/kenzo/CP2.txt +45 -0
  83. sage/ext_data/kenzo/CP3.txt +349 -0
  84. sage/ext_data/kenzo/CP4.txt +4774 -0
  85. sage/ext_data/kenzo/README.txt +49 -0
  86. sage/ext_data/kenzo/S4.txt +20 -0
  87. sage/graphs/all.py +42 -0
  88. sage/graphs/asteroidal_triples.cpython-310-aarch64-linux-gnu.so +0 -0
  89. sage/graphs/asteroidal_triples.pyx +320 -0
  90. sage/graphs/base/all.py +1 -0
  91. sage/graphs/base/boost_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  92. sage/graphs/base/boost_graph.pxd +106 -0
  93. sage/graphs/base/boost_graph.pyx +3045 -0
  94. sage/graphs/base/c_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  95. sage/graphs/base/c_graph.pxd +106 -0
  96. sage/graphs/base/c_graph.pyx +5096 -0
  97. sage/graphs/base/dense_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  98. sage/graphs/base/dense_graph.pxd +28 -0
  99. sage/graphs/base/dense_graph.pyx +801 -0
  100. sage/graphs/base/graph_backends.cpython-310-aarch64-linux-gnu.so +0 -0
  101. sage/graphs/base/graph_backends.pxd +5 -0
  102. sage/graphs/base/graph_backends.pyx +797 -0
  103. sage/graphs/base/overview.py +85 -0
  104. sage/graphs/base/sparse_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  105. sage/graphs/base/sparse_graph.pxd +90 -0
  106. sage/graphs/base/sparse_graph.pyx +1653 -0
  107. sage/graphs/base/static_dense_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  108. sage/graphs/base/static_dense_graph.pxd +5 -0
  109. sage/graphs/base/static_dense_graph.pyx +1032 -0
  110. sage/graphs/base/static_sparse_backend.cpython-310-aarch64-linux-gnu.so +0 -0
  111. sage/graphs/base/static_sparse_backend.pxd +27 -0
  112. sage/graphs/base/static_sparse_backend.pyx +1583 -0
  113. sage/graphs/base/static_sparse_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  114. sage/graphs/base/static_sparse_graph.pxd +37 -0
  115. sage/graphs/base/static_sparse_graph.pyx +1375 -0
  116. sage/graphs/bipartite_graph.py +2732 -0
  117. sage/graphs/centrality.cpython-310-aarch64-linux-gnu.so +0 -0
  118. sage/graphs/centrality.pyx +1038 -0
  119. sage/graphs/cographs.py +519 -0
  120. sage/graphs/comparability.cpython-310-aarch64-linux-gnu.so +0 -0
  121. sage/graphs/comparability.pyx +851 -0
  122. sage/graphs/connectivity.cpython-310-aarch64-linux-gnu.so +0 -0
  123. sage/graphs/connectivity.pxd +157 -0
  124. sage/graphs/connectivity.pyx +4813 -0
  125. sage/graphs/convexity_properties.cpython-310-aarch64-linux-gnu.so +0 -0
  126. sage/graphs/convexity_properties.pxd +16 -0
  127. sage/graphs/convexity_properties.pyx +870 -0
  128. sage/graphs/digraph.py +4754 -0
  129. sage/graphs/digraph_generators.py +1993 -0
  130. sage/graphs/distances_all_pairs.cpython-310-aarch64-linux-gnu.so +0 -0
  131. sage/graphs/distances_all_pairs.pxd +12 -0
  132. sage/graphs/distances_all_pairs.pyx +2938 -0
  133. sage/graphs/domination.py +1363 -0
  134. sage/graphs/dot2tex_utils.py +100 -0
  135. sage/graphs/edge_connectivity.cpython-310-aarch64-linux-gnu.so +0 -0
  136. sage/graphs/edge_connectivity.pyx +1215 -0
  137. sage/graphs/generators/all.py +1 -0
  138. sage/graphs/generators/basic.py +1769 -0
  139. sage/graphs/generators/chessboard.py +538 -0
  140. sage/graphs/generators/classical_geometries.py +1611 -0
  141. sage/graphs/generators/degree_sequence.py +235 -0
  142. sage/graphs/generators/distance_regular.cpython-310-aarch64-linux-gnu.so +0 -0
  143. sage/graphs/generators/distance_regular.pyx +2846 -0
  144. sage/graphs/generators/families.py +4759 -0
  145. sage/graphs/generators/intersection.py +565 -0
  146. sage/graphs/generators/platonic_solids.py +262 -0
  147. sage/graphs/generators/random.py +2623 -0
  148. sage/graphs/generators/smallgraphs.py +5741 -0
  149. sage/graphs/generators/world_map.py +724 -0
  150. sage/graphs/generic_graph.py +26867 -0
  151. sage/graphs/generic_graph_pyx.cpython-310-aarch64-linux-gnu.so +0 -0
  152. sage/graphs/generic_graph_pyx.pxd +34 -0
  153. sage/graphs/generic_graph_pyx.pyx +1673 -0
  154. sage/graphs/genus.cpython-310-aarch64-linux-gnu.so +0 -0
  155. sage/graphs/genus.pyx +622 -0
  156. sage/graphs/graph.py +9645 -0
  157. sage/graphs/graph_coloring.cpython-310-aarch64-linux-gnu.so +0 -0
  158. sage/graphs/graph_coloring.pyx +2284 -0
  159. sage/graphs/graph_database.py +1177 -0
  160. sage/graphs/graph_decompositions/all.py +1 -0
  161. sage/graphs/graph_decompositions/bandwidth.cpython-310-aarch64-linux-gnu.so +0 -0
  162. sage/graphs/graph_decompositions/bandwidth.pyx +428 -0
  163. sage/graphs/graph_decompositions/clique_separators.cpython-310-aarch64-linux-gnu.so +0 -0
  164. sage/graphs/graph_decompositions/clique_separators.pyx +616 -0
  165. sage/graphs/graph_decompositions/cutwidth.cpython-310-aarch64-linux-gnu.so +0 -0
  166. sage/graphs/graph_decompositions/cutwidth.pyx +753 -0
  167. sage/graphs/graph_decompositions/fast_digraph.cpython-310-aarch64-linux-gnu.so +0 -0
  168. sage/graphs/graph_decompositions/fast_digraph.pxd +13 -0
  169. sage/graphs/graph_decompositions/fast_digraph.pyx +212 -0
  170. sage/graphs/graph_decompositions/graph_products.cpython-310-aarch64-linux-gnu.so +0 -0
  171. sage/graphs/graph_decompositions/graph_products.pyx +508 -0
  172. sage/graphs/graph_decompositions/modular_decomposition.cpython-310-aarch64-linux-gnu.so +0 -0
  173. sage/graphs/graph_decompositions/modular_decomposition.pxd +27 -0
  174. sage/graphs/graph_decompositions/modular_decomposition.pyx +1536 -0
  175. sage/graphs/graph_decompositions/slice_decomposition.cpython-310-aarch64-linux-gnu.so +0 -0
  176. sage/graphs/graph_decompositions/slice_decomposition.pxd +18 -0
  177. sage/graphs/graph_decompositions/slice_decomposition.pyx +1106 -0
  178. sage/graphs/graph_decompositions/tree_decomposition.cpython-310-aarch64-linux-gnu.so +0 -0
  179. sage/graphs/graph_decompositions/tree_decomposition.pxd +17 -0
  180. sage/graphs/graph_decompositions/tree_decomposition.pyx +1996 -0
  181. sage/graphs/graph_decompositions/vertex_separation.cpython-310-aarch64-linux-gnu.so +0 -0
  182. sage/graphs/graph_decompositions/vertex_separation.pxd +5 -0
  183. sage/graphs/graph_decompositions/vertex_separation.pyx +1963 -0
  184. sage/graphs/graph_editor.py +82 -0
  185. sage/graphs/graph_generators.py +3314 -0
  186. sage/graphs/graph_generators_pyx.cpython-310-aarch64-linux-gnu.so +0 -0
  187. sage/graphs/graph_generators_pyx.pyx +95 -0
  188. sage/graphs/graph_input.py +812 -0
  189. sage/graphs/graph_latex.py +2064 -0
  190. sage/graphs/graph_list.py +410 -0
  191. sage/graphs/graph_plot.py +1756 -0
  192. sage/graphs/graph_plot_js.py +338 -0
  193. sage/graphs/hyperbolicity.cpython-310-aarch64-linux-gnu.so +0 -0
  194. sage/graphs/hyperbolicity.pyx +1704 -0
  195. sage/graphs/hypergraph_generators.py +364 -0
  196. sage/graphs/independent_sets.cpython-310-aarch64-linux-gnu.so +0 -0
  197. sage/graphs/independent_sets.pxd +13 -0
  198. sage/graphs/independent_sets.pyx +402 -0
  199. sage/graphs/isgci.py +1033 -0
  200. sage/graphs/isoperimetric_inequalities.cpython-310-aarch64-linux-gnu.so +0 -0
  201. sage/graphs/isoperimetric_inequalities.pyx +489 -0
  202. sage/graphs/line_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  203. sage/graphs/line_graph.pyx +743 -0
  204. sage/graphs/lovasz_theta.py +77 -0
  205. sage/graphs/matching.py +1633 -0
  206. sage/graphs/matching_covered_graph.py +3590 -0
  207. sage/graphs/orientations.py +1489 -0
  208. sage/graphs/partial_cube.py +459 -0
  209. sage/graphs/path_enumeration.cpython-310-aarch64-linux-gnu.so +0 -0
  210. sage/graphs/path_enumeration.pyx +2040 -0
  211. sage/graphs/pq_trees.py +1129 -0
  212. sage/graphs/print_graphs.py +201 -0
  213. sage/graphs/schnyder.py +865 -0
  214. sage/graphs/spanning_tree.cpython-310-aarch64-linux-gnu.so +0 -0
  215. sage/graphs/spanning_tree.pyx +1457 -0
  216. sage/graphs/strongly_regular_db.cpython-310-aarch64-linux-gnu.so +0 -0
  217. sage/graphs/strongly_regular_db.pyx +3340 -0
  218. sage/graphs/traversals.cpython-310-aarch64-linux-gnu.so +0 -0
  219. sage/graphs/traversals.pxd +9 -0
  220. sage/graphs/traversals.pyx +1872 -0
  221. sage/graphs/trees.cpython-310-aarch64-linux-gnu.so +0 -0
  222. sage/graphs/trees.pxd +15 -0
  223. sage/graphs/trees.pyx +310 -0
  224. sage/graphs/tutte_polynomial.py +713 -0
  225. sage/graphs/views.cpython-310-aarch64-linux-gnu.so +0 -0
  226. sage/graphs/views.pyx +794 -0
  227. sage/graphs/weakly_chordal.cpython-310-aarch64-linux-gnu.so +0 -0
  228. sage/graphs/weakly_chordal.pyx +604 -0
  229. sage/groups/all__sagemath_graphs.py +1 -0
  230. sage/groups/perm_gps/all__sagemath_graphs.py +1 -0
  231. sage/groups/perm_gps/partn_ref/all__sagemath_graphs.py +1 -0
  232. sage/groups/perm_gps/partn_ref/refinement_graphs.cpython-310-aarch64-linux-gnu.so +0 -0
  233. sage/groups/perm_gps/partn_ref/refinement_graphs.pxd +38 -0
  234. sage/groups/perm_gps/partn_ref/refinement_graphs.pyx +1666 -0
  235. sage/knots/all.py +6 -0
  236. sage/knots/free_knotinfo_monoid.py +507 -0
  237. sage/knots/gauss_code.py +291 -0
  238. sage/knots/knot.py +682 -0
  239. sage/knots/knot_table.py +284 -0
  240. sage/knots/knotinfo.py +2900 -0
  241. sage/knots/link.py +4715 -0
  242. sage/sandpiles/all.py +13 -0
  243. sage/sandpiles/examples.py +225 -0
  244. sage/sandpiles/sandpile.py +6365 -0
  245. sage/topology/all.py +22 -0
  246. sage/topology/cell_complex.py +1214 -0
  247. sage/topology/cubical_complex.py +1976 -0
  248. sage/topology/delta_complex.py +1806 -0
  249. sage/topology/filtered_simplicial_complex.py +744 -0
  250. sage/topology/moment_angle_complex.py +823 -0
  251. sage/topology/simplicial_complex.py +5160 -0
  252. sage/topology/simplicial_complex_catalog.py +92 -0
  253. sage/topology/simplicial_complex_examples.py +1680 -0
  254. sage/topology/simplicial_complex_homset.py +205 -0
  255. sage/topology/simplicial_complex_morphism.py +836 -0
  256. sage/topology/simplicial_set.py +4102 -0
  257. sage/topology/simplicial_set_catalog.py +55 -0
  258. sage/topology/simplicial_set_constructions.py +2954 -0
  259. sage/topology/simplicial_set_examples.py +865 -0
  260. 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