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,744 @@
1
+ # sage_setup: distribution = sagemath-graphs
2
+ # sage.doctest: needs sage.graphs
3
+ r"""
4
+ Finite filtered complexes
5
+
6
+ AUTHORS:
7
+
8
+ - Guillaume Rousseau (2021-05)
9
+
10
+ This module implements the basic structures of finite filtered complexes.
11
+ A filtered complex is a simplicial complex, where each simplex is given
12
+ a weight, or "filtration value", such that the weight of a simplex is
13
+ greater than the weight of each of its faces.
14
+
15
+ The algorithm used in this module comes from [ZC2005]_.
16
+
17
+ EXAMPLES::
18
+
19
+ sage: FilteredSimplicialComplex([([0], 0), ([1], 0), ([0, 1], 1)])
20
+ Filtered complex on vertex set (0, 1) and
21
+ with simplices ((0,) : 0), ((1,) : 0), ((0, 1) : 1)
22
+
23
+ Sage can compute persistent homology of simplicial complexes::
24
+
25
+ sage: X = FilteredSimplicialComplex([([0], 0), ([1], 0), ([0, 1], 1)])
26
+ sage: X.persistence_intervals(0) # needs sage.modules
27
+ [(0, 1), (0, +Infinity)]
28
+
29
+ FilteredSimplicialComplex objects are mutable. Filtration values can be
30
+ set with the ``filtration`` method as follows::
31
+
32
+ sage: X = FilteredSimplicialComplex() # returns an empty complex
33
+ sage: X.persistence_intervals(1) # needs sage.modules
34
+ []
35
+ sage: X.filtration(Simplex([0, 2]), 0) # recursively adds faces
36
+ sage: X.filtration(Simplex([0, 1]), 0)
37
+ sage: X.filtration(Simplex([1, 2]), 0)
38
+ sage: X.filtration(Simplex([0, 1, 2]), 1) # closes the circle
39
+ sage: X.persistence_intervals(1) # needs sage.modules
40
+ [(0, 1)]
41
+
42
+ The filtration value of a simplex can be accessed as well with the
43
+ ``filtration`` method, by not specifying a filtration value in
44
+ the arguments. If the simplex is not in the complex, this returns
45
+ ``None``::
46
+
47
+ sage: X = FilteredSimplicialComplex([([0], 0), ([1], 0), ([0,1], 1)])
48
+ sage: X.filtration(Simplex([0]))
49
+ 0
50
+ sage: X.filtration(Simplex([1,2])) is None
51
+ True
52
+
53
+ Filtration values can be accessed with function call and list
54
+ syntax as follows::
55
+
56
+ sage: X = FilteredSimplicialComplex([([0], 0), ([1], 0), ([0,1], 1)])
57
+ sage: s_1 = Simplex([0])
58
+ sage: X[s_1]
59
+ 0
60
+ sage: X(Simplex([0,1]))
61
+ 1
62
+ sage: X(Simplex(['baba']))
63
+ <BLANKLINE>
64
+
65
+ It is also possible to set the filtration value of a simplex with
66
+ the ``insert`` method, which takes as argument a list of vertices
67
+ rather than a ``Simplex``. This can make code more readable / clear::
68
+
69
+ sage: X = FilteredSimplicialComplex()
70
+ sage: X.insert(['a'], 0)
71
+ sage: X.insert(['b', 'c'], 1)
72
+ sage: X
73
+ Filtered complex on vertex set ('a', 'b', 'c') and with simplices
74
+ (('a',) : 0), (('c',) : 1), (('b',) : 1), (('b', 'c') : 1)
75
+ """
76
+
77
+ # ****************************************************************************
78
+ # Copyright (C) 2013 GUILLAUME ROUSSEAU <guillaume.rousseau@ens-lyon.fr>
79
+ #
80
+ # This program is free software: you can redistribute it and/or modify
81
+ # it under the terms of the GNU General Public License as published by
82
+ # the Free Software Foundation, either version 2 of the License, or
83
+ # (at your option) any later version.
84
+ # https://www.gnu.org/licenses/
85
+ # ****************************************************************************
86
+
87
+ from sage.misc.cachefunc import cached_method
88
+ from sage.misc.lazy_import import lazy_import
89
+ from sage.rings.integer import Integer
90
+ from sage.rings.infinity import infinity
91
+ from sage.structure.sage_object import SageObject
92
+ from sage.topology.simplicial_complex import Simplex, SimplicialComplex
93
+
94
+ lazy_import('sage.modules.free_module', 'FreeModule')
95
+ lazy_import('sage.rings.finite_rings.finite_field_constructor', 'GF')
96
+
97
+
98
+ class FilteredSimplicialComplex(SageObject):
99
+ r"""
100
+ Define a filtered complex.
101
+
102
+ INPUT:
103
+
104
+ - ``simplices`` -- list of simplices and filtration values
105
+ - ``verbose`` -- boolean (default: ``False``); if ``True``, any change to
106
+ the filtration value of a simplex will be printed
107
+
108
+ ``simplices`` should be a list of tuples ``(l, v)``, where
109
+ ``l`` is a list of vertices and ``v`` is the corresponding
110
+ filtration value.
111
+
112
+ EXAMPLES::
113
+
114
+ sage: FilteredSimplicialComplex([([0], 0), ([1], 0), ([2], 1), ([0,1], 2.27)])
115
+ Filtered complex on vertex set (0, 1, 2) and with simplices
116
+ ((0,) : 0), ((1,) : 0), ((2,) : 1), ((0, 1) : 2.27000000000000)
117
+ """
118
+ def __init__(self, simplices=[], verbose=False):
119
+ """
120
+ Initialize ``self``.
121
+
122
+ EXAMPLES::
123
+
124
+ sage: X = FilteredSimplicialComplex([([0], 0), ([1], 0), ([2], 1), ([0,1], 2.27)])
125
+ sage: TestSuite(X).run()
126
+ """
127
+ # _vertices is the set of vertices on which the complex
128
+ # is constructed
129
+ self._vertices = set()
130
+
131
+ # _filtration_dict has simplices as keys
132
+ # and entries are corresponding filtration values
133
+ self._filtration_dict = {}
134
+ self._dimension = 0
135
+ self._max_value = 0
136
+
137
+ # when _verbose is set to True, insertion
138
+ # will warn the user when something non-trivial
139
+ # happens.
140
+ self._verbose = verbose
141
+
142
+ # Insert all simplices in the initial list
143
+ for l, v in simplices:
144
+ self.insert(l, v)
145
+
146
+ def __eq__(self, other):
147
+ """
148
+ Check equality.
149
+
150
+ EXAMPLES::
151
+
152
+ sage: X = FilteredSimplicialComplex([([0], 0), ([1], 0), ([2], 1), ([0,1], 2.27)])
153
+ sage: Y = FilteredSimplicialComplex()
154
+ sage: Y.insert([0], 0)
155
+ sage: Y.insert([1], 0)
156
+ sage: Y.insert([2], 1)
157
+ sage: Y.insert([0,1], 2.27)
158
+ sage: X == Y
159
+ True
160
+ sage: Y.filtration([1,2], 2)
161
+ sage: X == Y
162
+ False
163
+
164
+ sage: Y = FilteredSimplicialComplex([([0], 0), ([1], 0), ([2], 1), ([0,1], 2)])
165
+ sage: X == Y
166
+ False
167
+ """
168
+ return (isinstance(other, FilteredSimplicialComplex)
169
+ and self._vertices == other._vertices
170
+ and self._filtration_dict == other._filtration_dict)
171
+
172
+ def __ne__(self, other):
173
+ """
174
+ Check inequality.
175
+
176
+ EXAMPLES::
177
+
178
+ sage: X = FilteredSimplicialComplex([([0], 0), ([1], 0), ([2], 1), ([0,1], 2.27)])
179
+ sage: Y = FilteredSimplicialComplex([([0], 0), ([1], 0), ([2], 1), ([0,1], 3)])
180
+ sage: X != Y
181
+ True
182
+ sage: Y.filtration([0,1], 2.27)
183
+ sage: X != Y
184
+ False
185
+ """
186
+ return not (self == other)
187
+
188
+ def _get_value(self, s):
189
+ r"""
190
+ Return the filtration value of a simplex ``s`` in the complex.
191
+
192
+ EXAMPLES::
193
+
194
+ sage: X = FilteredSimplicialComplex([([0], 1), ([1], 2)])
195
+ sage: X._get_value(Simplex([0]))
196
+ 1
197
+
198
+ This also works for the call and getitem syntax as a shorthand::
199
+
200
+ sage: X(Simplex([0]))
201
+ 1
202
+ sage: X[Simplex([0])]
203
+ 1
204
+ """
205
+ if s in self._filtration_dict:
206
+ return self._filtration_dict[s]
207
+ else:
208
+ return None
209
+
210
+ __call__ = _get_value
211
+ __getitem__ = _get_value
212
+
213
+ def _insert(self, simplex, filtration_value):
214
+ r"""
215
+ Add a simplex to the complex.
216
+
217
+ All faces of the simplex are added recursively if they are
218
+ not already present, with the same value.
219
+ If the simplex is already present, and the new value is lower
220
+ than its current value in the complex, the value gets updated,
221
+ otherwise it does not change. This propagates recursively to faces.
222
+
223
+ If verbose has been enabled, this method will describe what it
224
+ is doing during an insertion.
225
+
226
+ INPUT:
227
+
228
+ - ``simplex`` -- :class:`Simplex`; simplex to be inserted
229
+ - ``filtration_value`` -- value of the simplex
230
+
231
+ EXAMPLES::
232
+
233
+ sage: X = FilteredSimplicialComplex()
234
+ sage: X._insert(Simplex([0]), 3)
235
+ sage: X
236
+ Filtered complex on vertex set (0,) and with simplices ((0,) : 3)
237
+ """
238
+ # Keep track of whether the simplex is already in the complex
239
+ # and if it should be updated or not
240
+ curr_value = self[simplex]
241
+ if curr_value is not None:
242
+ if self._verbose:
243
+ print("Face {} is already in the complex.".format(simplex))
244
+ if curr_value > filtration_value:
245
+ if self._verbose:
246
+ verbose_string = "However its value is {}".format(curr_value)
247
+ verbose_string += ": updating it to {}".format(filtration_value)
248
+ print(verbose_string)
249
+ self._filtration_dict.pop(simplex)
250
+ else:
251
+ if self._verbose:
252
+ print("Its value is {}: keeping it that way".format(curr_value))
253
+ return
254
+
255
+ # check that all faces are in the complex already.
256
+ # If not, warn the user and add faces (recursively)
257
+ faces = simplex.faces()
258
+ if simplex.dimension() > 0:
259
+ for f in faces:
260
+ if self._verbose:
261
+ print("Also inserting face {} with value {}".format(f, filtration_value))
262
+ self._insert(f, filtration_value)
263
+
264
+ self._filtration_dict[simplex] = filtration_value
265
+ self._dimension = max(self._dimension, simplex.dimension())
266
+ self._max_value = max(self._max_value, filtration_value)
267
+ self._vertices.update(simplex.set())
268
+ self._persistent_homology.clear_cache()
269
+
270
+ def insert(self, vertex_list, filtration_value):
271
+ r"""
272
+ Add a simplex to the complex.
273
+
274
+ All faces of the simplex are added recursively if they are
275
+ not already present, with the same value.
276
+ If the simplex is already present, and the new value is lower
277
+ than its current value in the complex, the value gets updated,
278
+ otherwise it does not change. This propagates recursively to faces.
279
+
280
+ If verbose has been enabled, this method will describe what it
281
+ is doing during an insertion.
282
+
283
+ INPUT:
284
+
285
+ - ``vertex_list`` -- list of vertices
286
+ - ``filtration_value`` -- desired value of the simplex to be added
287
+
288
+ EXAMPLES::
289
+
290
+ sage: X = FilteredSimplicialComplex()
291
+ sage: X.insert(Simplex([0]),3)
292
+ sage: X
293
+ Filtered complex on vertex set (0,) and with simplices ((0,) : 3)
294
+
295
+ If the verbose parameter was set to true, this method will print
296
+ some info::
297
+
298
+ sage: X = FilteredSimplicialComplex(verbose=True)
299
+ sage: X.insert(Simplex([0, 1]), 2)
300
+ Also inserting face (1,) with value 2
301
+ Also inserting face (0,) with value 2
302
+ sage: X.insert(Simplex([0]),1)
303
+ Face (0,) is already in the complex.
304
+ However its value is 2: updating it to 1
305
+ sage: X.insert(Simplex([0]), 77)
306
+ Face (0,) is already in the complex.
307
+ Its value is 1: keeping it that way
308
+ """
309
+ self._insert(Simplex(vertex_list), filtration_value)
310
+
311
+ def filtration(self, s, filtration_value=None):
312
+ r"""
313
+ Set filtration value of a simplex, or return value
314
+ of existing simplex.
315
+
316
+ INPUT:
317
+
318
+ - ``s`` -- :class:`Simplex` for which to set or obtain the
319
+ value of
320
+ - ``filtration_value`` -- (optional) filtration value
321
+ for the simplex
322
+
323
+ If no filtration value is specified, this returns the value of
324
+ the simplex in the complex. If the simplex is not in the complex,
325
+ this returns ``None``.
326
+
327
+ If ``filtration_value`` is set, this function inserts the
328
+ simplex into the complex with the specified value.
329
+ See documentation of :meth:`insert` for more details.
330
+
331
+ EXAMPLES::
332
+
333
+ sage: X = FilteredSimplicialComplex([([0], 0), ([1], 1)])
334
+ sage: X.filtration(Simplex([0, 1])) is None
335
+ True
336
+ sage: X.filtration(Simplex([0, 1]), 2)
337
+ sage: X.filtration([0, 1])
338
+ 2
339
+ """
340
+ s = Simplex(s)
341
+ if filtration_value is None:
342
+ return self._get_value(s)
343
+ else:
344
+ self._insert(s, filtration_value)
345
+
346
+ def prune(self, threshold):
347
+ r"""
348
+ Return a copy of the filtered complex, where simplices above
349
+ the threshold value have been removed.
350
+
351
+ INPUT:
352
+
353
+ - ``threshold`` -- a real value, above which simplices are discarded
354
+
355
+ Simplices with filtration value exactly equal to ``threshold``
356
+ are kept in the result.
357
+
358
+ EXAMPLES::
359
+
360
+ sage: a = FilteredSimplicialComplex()
361
+ sage: a.insert([0], 0)
362
+ sage: a.insert([0, 1], 1)
363
+ sage: a.insert([0, 2], 2)
364
+ sage: b = a.prune(1)
365
+ sage: b
366
+ Filtered complex on vertex set (0, 1) and
367
+ with simplices ((0,) : 0), ((1,) : 1), ((0, 1) : 1)
368
+ """
369
+ result_complex = FilteredSimplicialComplex()
370
+ for s in self._filtration_dict:
371
+ if self[s] <= threshold:
372
+ result_complex._insert(s, self[s])
373
+
374
+ return result_complex
375
+
376
+ @cached_method(key=lambda self, f, s, v: (f, s))
377
+ def _persistent_homology(self, field=2, strict=True, verbose=False):
378
+ """
379
+ Compute the homology intervals of the complex.
380
+
381
+ INPUT:
382
+
383
+ - ``field`` -- (default: 2) prime number modulo which the homology
384
+ is computed
385
+ - ``strict`` -- boolean (default: ``True``); if ``False``, takes into account
386
+ intervals of persistence 0
387
+ - ``verbose`` -- boolean (default: ``False``); if ``True``, prints the
388
+ progress of computation
389
+
390
+ This method is called whenever Betti numbers or intervals are
391
+ computed, and the result is cached. It returns the list of
392
+ intervals.
393
+
394
+ ALGORITHM:
395
+
396
+ The computation behind persistent homology is a matrix reduction.
397
+ The algorithm implemented is described in [ZC2005]_.
398
+
399
+ EXAMPLES::
400
+
401
+ sage: X = FilteredSimplicialComplex([([0], 0), ([1], 0), ([0,1], 2)])
402
+ sage: X._persistent_homology()[0] # needs sage.modules
403
+ [(0, 2), (0, +Infinity)]
404
+
405
+ Some homology elements may have a lifespan or persistence of 0.
406
+ They are usually discarded, but can be kept if necessary::
407
+
408
+ sage: X = FilteredSimplicialComplex()
409
+ sage: X.insert([0,1],1) # opens a hole and closes it instantly
410
+ sage: X._persistent_homology(strict=False)[0] # needs sage.modules
411
+ [(1, 1), (1, +Infinity)]
412
+
413
+ REFERENCES:
414
+
415
+ - [ZC2005]_
416
+
417
+ TESTS:
418
+
419
+ This complex is used as a running example in [ZC2005]_::
420
+
421
+ sage: l = [([0], 0), ([1], 0), ([2], 1), ([3], 1), ([0, 1], 1),
422
+ ....: ([1, 2], 1), ([0, 3], 2), ([2, 3], 2), ([0, 2], 3),
423
+ ....: ([0, 1, 2], 4), ([0, 2, 3], 5)]
424
+ sage: X = FilteredSimplicialComplex(l)
425
+ sage: X.persistence_intervals(0) # needs sage.modules
426
+ [(0, 1), (1, 2), (0, +Infinity)]
427
+ sage: X.persistence_intervals(1) # needs sage.modules
428
+ [(3, 4), (2, 5)]
429
+ sage: X.persistence_intervals(0, strict=False) # needs sage.modules
430
+ [(0, 1), (1, 1), (1, 2), (0, +Infinity)]
431
+ """
432
+ # first, order the simplices in lexico order
433
+ # on dimension, value and then arbitrary order
434
+ # defined by the Simplex class.
435
+ def key(s):
436
+ d = self._get_value(s)
437
+ return (s.dimension(), d, s)
438
+ simplices = list(self._filtration_dict)
439
+ simplices.sort(key=key)
440
+
441
+ # remember the index of each simplex in a dict
442
+ self._index_of_simplex = {}
443
+ n = len(simplices)
444
+ for i in range(n):
445
+ self._index_of_simplex[simplices[i]] = i
446
+
447
+ self._field_int = field
448
+ self._field = GF(field)
449
+ self._chaingroup = FreeModule(self._field, rank_or_basis_keys=simplices)
450
+
451
+ # Initialize data structures for the algo
452
+ self._marked = [False] * n
453
+ self._T = [None] * n
454
+ intervals = [[] for i in range(self._dimension + 1)]
455
+ self.pairs = []
456
+
457
+ self._strict = strict
458
+ self._verbose = verbose
459
+
460
+ if self._verbose:
461
+ print("Beginning first pass")
462
+
463
+ for j in range(n):
464
+ # if being verbose, print progress
465
+ # every 1000 simplices.
466
+ if self._verbose and j % 1000 == 0:
467
+ print('{}/{}'.format(j, n))
468
+
469
+ s = simplices[j]
470
+ d = self._remove_pivot_rows(s, simplices)
471
+
472
+ if d == 0:
473
+ self._marked[j] = True
474
+ else:
475
+ max_index = self._max_index(d)
476
+ t = simplices[max_index]
477
+ self._T[max_index] = (s, d)
478
+ self._add_interval(t, s, intervals)
479
+
480
+ if self._verbose:
481
+ print("First pass over, beginning second pass")
482
+
483
+ for j in range(n):
484
+ if self._verbose and j % 1000 == 0:
485
+ print('{}/{}'.format(j, n))
486
+
487
+ s = simplices[j]
488
+ if self._marked[j] and not self._T[j]:
489
+ self._add_interval(s, None, intervals)
490
+
491
+ if self._verbose:
492
+ print("Second pass over")
493
+ return intervals
494
+
495
+ def _add_interval(self, s, t, intervals):
496
+ r"""
497
+ Add a new interval (i.e. homology element).
498
+
499
+ This method should not be called by users, it is used in
500
+ the :meth:`_persistent_homology` method. The simplex of
501
+ death may be ``None``, in which case the interval is infinite.
502
+
503
+ INPUT:
504
+
505
+ - ``s`` -- birth simplex
506
+ - ``t`` -- death simplex
507
+ - ``intervals`` -- list of current intervals
508
+
509
+ If ``t`` is not ``None``, its dimension should be
510
+ one more than the dimension of ``s``.
511
+
512
+ TESTS::
513
+
514
+ sage: # needs sage.modules
515
+ sage: X = FilteredSimplicialComplex([([0], 0), ([1, 2], 10)])
516
+ sage: int_list = X._persistent_homology()
517
+ sage: int_list[0]
518
+ [(0, +Infinity), (10, +Infinity)]
519
+ sage: X._add_interval(Simplex([0]), Simplex([1, 2]), int_list)
520
+ sage: int_list[0]
521
+ [(0, +Infinity), (10, +Infinity), (0, 10)]
522
+
523
+ Infinite interval::
524
+
525
+ sage: int_list2 = [[],[]]
526
+ sage: X._add_interval(Simplex([1, 2]), None, int_list2) # needs sage.modules
527
+ sage: int_list2[1]
528
+ [(10, +Infinity)]
529
+ """
530
+ # figure out dimension of homology element
531
+ # and indices of the two simplices. If the
532
+ # closing simplex is None, then the interval
533
+ # is infinite.
534
+ k = s.dimension()
535
+ i = self._filtration_dict[s]
536
+ if not t:
537
+ j = infinity
538
+ else:
539
+ j = self._filtration_dict[t]
540
+
541
+ # Only add intervals of length 0 if
542
+ # strict mode is not enabled.
543
+ if i != j or (not self._strict):
544
+ intervals[k].append((i, j))
545
+ self.pairs.append((s, t))
546
+
547
+ def _remove_pivot_rows(self, s, simplices):
548
+ r"""
549
+ Return the boundary chain of a simplex,
550
+ from which pivot elements have been removed.
551
+
552
+ This method implements the subroutine of the same name
553
+ in [ZC2005]_. This method should not be called by users,
554
+ it is used in the :meth:`_persistent_homology` method.
555
+
556
+ TESTS::
557
+
558
+ sage: l = [([0], 0), ([1], 0), ([2], 1), ([3], 1), ([0, 1], 1), ([1, 2], 1),
559
+ ....: ([0, 3], 2), ([2, 3], 2), ([0, 2], 3), ([0, 1, 2], 4)]
560
+ sage: X = FilteredSimplicialComplex(l)
561
+ sage: X._persistent_homology() # needs sage.modules
562
+ [[(0, 1), (1, 2), (0, +Infinity)], [(3, 4), (2, +Infinity)], []]
563
+ sage: X._remove_pivot_rows(Simplex([0,1,2]), list(X._filtration_dict)) # needs sage.modules
564
+ 0
565
+ sage: X.insert([0,2,3],5)
566
+ sage: X._remove_pivot_rows(Simplex([0,2,3]), list(X._filtration_dict)) # needs sage.modules
567
+ B[(2, 3)]
568
+ """
569
+ d = self._chaingroup()
570
+ # Handle the case when the simplex is a vertex
571
+ if s.dimension() == 0:
572
+ return d
573
+
574
+ # Initialize the boundary chain
575
+ for i, f in enumerate(s.faces()):
576
+ d += (-1)**i * self._chaingroup(f)
577
+
578
+ # Remove all unmarked elements
579
+ for s, x_s in d:
580
+ j = self._index_of_simplex[s]
581
+ if not self._marked[j]:
582
+ d = d - x_s * self._chaingroup(s)
583
+
584
+ # Reduce d until it is empty or until the simplex
585
+ # with maximum index in the complex among all
586
+ # nonzero terms is not in T.
587
+ while d != 0:
588
+ max_index = self._max_index(d)
589
+ t = simplices[max_index]
590
+
591
+ if not self._T[max_index]:
592
+ break
593
+
594
+ c = self._T[max_index][1]
595
+ q = c[t]
596
+ d = d - ((q**(-1)) * c)
597
+
598
+ return d
599
+
600
+ def _max_index(self, d):
601
+ r"""
602
+ Return the maximal index of all simplices with nonzero
603
+ coefficient in ``d``.
604
+
605
+ This method is called in :meth:`_remove_pivot_rows` and
606
+ :meth:`_persistent_homology`. It should not be called by users
607
+ outside of those methods.
608
+
609
+ TESTS::
610
+
611
+ sage: # needs sage.modules
612
+ sage: X = FilteredSimplicialComplex([([0], 0), ([1], 5), ([0, 1], 18), ([0, 2, 3], 32)])
613
+ sage: X._persistent_homology()
614
+ [[(5, 18), (0, +Infinity)], [], []]
615
+ sage: a = X._chaingroup(Simplex([0, 1]))
616
+ sage: b = X._chaingroup(Simplex([0, 3]))
617
+ sage: d = a + b
618
+ sage: X._max_index(d)
619
+ 6
620
+ """
621
+ currmax = -1
622
+ for s, x_s in d:
623
+ j = self._index_of_simplex[s]
624
+ currmax = max(j, currmax)
625
+ return currmax
626
+
627
+ def persistence_intervals(self, dimension, field=2, strict=True, verbose=None):
628
+ r"""
629
+ Return the list of `d`-dimensional homology elements.
630
+
631
+ INPUT:
632
+
633
+ - ``dimension`` -- integer; dimension `d` for which to
634
+ return intervals
635
+ - ``field`` -- prime number (default: 2); modulo which persistent
636
+ homology is computed
637
+ - ``strict`` -- boolean (default: ``True``); if ``False``, takes into account
638
+ intervals of persistence 0
639
+ - ``verbose`` -- (optional) if ``True``, print the steps of the
640
+ persistent homology computation; the default is the verbosity
641
+ of ``self``
642
+
643
+ EXAMPLES::
644
+
645
+ sage: X = FilteredSimplicialComplex([([0], 0), ([1], 1), ([0,1], 2)])
646
+ sage: X.persistence_intervals(0) # needs sage.modules
647
+ [(1, 2), (0, +Infinity)]
648
+ """
649
+ if verbose is None:
650
+ verbose = self._verbose
651
+ intervals = self._persistent_homology(field, strict, verbose=verbose)
652
+ if dimension < len(intervals):
653
+ return intervals[dimension][:]
654
+ else:
655
+ return []
656
+
657
+ def betti_number(self, k, a, b, field=2, strict=True, verbose=None):
658
+ r"""
659
+ Return the ``k``-dimensional Betti number from ``a`` to ``a + b``.
660
+
661
+ INPUT:
662
+
663
+ - ``k`` -- the dimension for the Betti number
664
+ - ``a`` -- the lower filtration value
665
+ - ``b`` -- the size of the interval
666
+ - ``field`` -- prime number (default: 2); modulo which persistent
667
+ homology is computed
668
+ - ``strict`` -- boolean (default: ``True``); if ``False``, takes into account
669
+ intervals of persistence 0
670
+ - ``verbose`` -- (optional) if ``True``, print the steps of the
671
+ persistent homology computation; the default is the verbosity
672
+ of ``self``
673
+
674
+ The Betti number `\beta_k^{a,a+b}` counts the number of
675
+ homology elements which are alive throughout the whole
676
+ duration ``[a, a+b]``.
677
+
678
+ EXAMPLES::
679
+
680
+ sage: X = FilteredSimplicialComplex([([0], 0), ([1], 0), ([0,1], 2)])
681
+ sage: X.betti_number(0, 0.5, 1) # needs sage.modules
682
+ 2
683
+ sage: X.betti_number(0, 1.5, 1) # needs sage.modules
684
+ 1
685
+
686
+ If an element vanishes at time ``a + b`` exactly,
687
+ it does not count towards the Betti number::
688
+
689
+ sage: X = FilteredSimplicialComplex([([0], 0), ([1], 0), ([0,1], 2)])
690
+ sage: X.betti_number(0, 1.5, 0.5) # needs sage.modules
691
+ 1
692
+ """
693
+ if verbose is None:
694
+ verbose = self._verbose
695
+ intervals = self._persistent_homology(field, strict, verbose=verbose)
696
+ return Integer(sum(1 for i, j in intervals[k]
697
+ if (i <= a and a + b < j) and a >= 0))
698
+
699
+ def _repr_(self):
700
+ """
701
+ Print representation.
702
+
703
+ If there are more than 10 simplices or vertices, only prints the
704
+ count for each.
705
+
706
+ EXAMPLES::
707
+
708
+ sage: X = FilteredSimplicialComplex([([0], 0), ([1], 0), ([0, 1], 1)])
709
+ sage: X
710
+ Filtered complex on vertex set (0, 1) and with simplices ((0,) : 0), ((1,) : 0), ((0, 1) : 1)
711
+ sage: X.insert([0, 1, 2, 3, 4], 8)
712
+ sage: X
713
+ Filtered complex on 5 vertices and with 31 simplices
714
+ """
715
+ vert_count = len(self._vertices)
716
+ simp_count = len(self._filtration_dict)
717
+ if simp_count > 10 or vert_count > 10:
718
+ vertex_string = "on {} vertices".format(vert_count)
719
+ simplex_string = "with {} simplices".format(simp_count)
720
+ else:
721
+ vertex_string = "on vertex set {}".format(tuple(sorted(self._vertices)))
722
+ simplex_string = "with simplices "
723
+ simplex_list = ["({} : {})".format(s, self._filtration_dict[s]) for s in self._filtration_dict]
724
+ simplex_string += ", ".join(simplex_list)
725
+
726
+ return "Filtered complex " + vertex_string + " and " + simplex_string
727
+
728
+ def _simplicial_(self):
729
+ """
730
+ Return the associated simplicial complex.
731
+
732
+ All simplices of the filtered simplicial complex are
733
+ included in the resulting simplicial complex.
734
+
735
+ EXAMPLES::
736
+
737
+ sage: l = [([0],0), ([1],0), ([2],1), ([3],1), ([0, 1],1), ([1, 2],1), ([0, 3],2),
738
+ ....: ([2, 3],2), ([0, 2],3), ([0, 1, 2],4), ([0, 2, 3],5)]
739
+ sage: a = FilteredSimplicialComplex(l)
740
+ sage: b = SimplicialComplex(a)
741
+ sage: b
742
+ Simplicial complex with vertex set (0, 1, 2, 3) and facets {(0, 1, 2), (0, 2, 3)}
743
+ """
744
+ return SimplicialComplex(self._filtration_dict)