multipers 2.4.0b1__cp312-cp312-macosx_11_0_arm64.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 (184) hide show
  1. multipers/.dylibs/libboost_timer.dylib +0 -0
  2. multipers/.dylibs/libc++.1.0.dylib +0 -0
  3. multipers/.dylibs/libtbb.12.17.dylib +0 -0
  4. multipers/__init__.py +33 -0
  5. multipers/_signed_measure_meta.py +426 -0
  6. multipers/_slicer_meta.py +231 -0
  7. multipers/array_api/__init__.py +62 -0
  8. multipers/array_api/numpy.py +124 -0
  9. multipers/array_api/torch.py +133 -0
  10. multipers/data/MOL2.py +458 -0
  11. multipers/data/UCR.py +18 -0
  12. multipers/data/__init__.py +1 -0
  13. multipers/data/graphs.py +466 -0
  14. multipers/data/immuno_regions.py +27 -0
  15. multipers/data/minimal_presentation_to_st_bf.py +0 -0
  16. multipers/data/pytorch2simplextree.py +91 -0
  17. multipers/data/shape3d.py +101 -0
  18. multipers/data/synthetic.py +113 -0
  19. multipers/distances.py +202 -0
  20. multipers/filtration_conversions.pxd +736 -0
  21. multipers/filtration_conversions.pxd.tp +226 -0
  22. multipers/filtrations/__init__.py +21 -0
  23. multipers/filtrations/density.py +529 -0
  24. multipers/filtrations/filtrations.py +480 -0
  25. multipers/filtrations.pxd +534 -0
  26. multipers/filtrations.pxd.tp +332 -0
  27. multipers/function_rips.cpython-312-darwin.so +0 -0
  28. multipers/function_rips.pyx +104 -0
  29. multipers/grids.cpython-312-darwin.so +0 -0
  30. multipers/grids.pyx +538 -0
  31. multipers/gudhi/Persistence_slices_interface.h +213 -0
  32. multipers/gudhi/Simplex_tree_interface.h +274 -0
  33. multipers/gudhi/Simplex_tree_multi_interface.h +648 -0
  34. multipers/gudhi/gudhi/Bitmap_cubical_complex.h +450 -0
  35. multipers/gudhi/gudhi/Bitmap_cubical_complex_base.h +1070 -0
  36. multipers/gudhi/gudhi/Bitmap_cubical_complex_periodic_boundary_conditions_base.h +579 -0
  37. multipers/gudhi/gudhi/Debug_utils.h +52 -0
  38. multipers/gudhi/gudhi/Degree_rips_bifiltration.h +2307 -0
  39. multipers/gudhi/gudhi/Dynamic_multi_parameter_filtration.h +2524 -0
  40. multipers/gudhi/gudhi/Fields/Multi_field.h +453 -0
  41. multipers/gudhi/gudhi/Fields/Multi_field_operators.h +460 -0
  42. multipers/gudhi/gudhi/Fields/Multi_field_shared.h +444 -0
  43. multipers/gudhi/gudhi/Fields/Multi_field_small.h +584 -0
  44. multipers/gudhi/gudhi/Fields/Multi_field_small_operators.h +490 -0
  45. multipers/gudhi/gudhi/Fields/Multi_field_small_shared.h +580 -0
  46. multipers/gudhi/gudhi/Fields/Z2_field.h +391 -0
  47. multipers/gudhi/gudhi/Fields/Z2_field_operators.h +389 -0
  48. multipers/gudhi/gudhi/Fields/Zp_field.h +493 -0
  49. multipers/gudhi/gudhi/Fields/Zp_field_operators.h +384 -0
  50. multipers/gudhi/gudhi/Fields/Zp_field_shared.h +492 -0
  51. multipers/gudhi/gudhi/Flag_complex_edge_collapser.h +337 -0
  52. multipers/gudhi/gudhi/Matrix.h +2200 -0
  53. multipers/gudhi/gudhi/Multi_filtration/Multi_parameter_generator.h +1712 -0
  54. multipers/gudhi/gudhi/Multi_filtration/multi_filtration_conversions.h +237 -0
  55. multipers/gudhi/gudhi/Multi_filtration/multi_filtration_utils.h +225 -0
  56. multipers/gudhi/gudhi/Multi_parameter_filtered_complex.h +485 -0
  57. multipers/gudhi/gudhi/Multi_parameter_filtration.h +2643 -0
  58. multipers/gudhi/gudhi/Multi_persistence/Box.h +233 -0
  59. multipers/gudhi/gudhi/Multi_persistence/Line.h +309 -0
  60. multipers/gudhi/gudhi/Multi_persistence/Multi_parameter_filtered_complex_pcoh_interface.h +268 -0
  61. multipers/gudhi/gudhi/Multi_persistence/Persistence_interface_cohomology.h +159 -0
  62. multipers/gudhi/gudhi/Multi_persistence/Persistence_interface_matrix.h +463 -0
  63. multipers/gudhi/gudhi/Multi_persistence/Point.h +853 -0
  64. multipers/gudhi/gudhi/Off_reader.h +173 -0
  65. multipers/gudhi/gudhi/Persistence_matrix/Base_matrix.h +834 -0
  66. multipers/gudhi/gudhi/Persistence_matrix/Base_matrix_with_column_compression.h +838 -0
  67. multipers/gudhi/gudhi/Persistence_matrix/Boundary_matrix.h +833 -0
  68. multipers/gudhi/gudhi/Persistence_matrix/Chain_matrix.h +1367 -0
  69. multipers/gudhi/gudhi/Persistence_matrix/Id_to_index_overlay.h +1157 -0
  70. multipers/gudhi/gudhi/Persistence_matrix/Position_to_index_overlay.h +869 -0
  71. multipers/gudhi/gudhi/Persistence_matrix/RU_matrix.h +905 -0
  72. multipers/gudhi/gudhi/Persistence_matrix/allocators/entry_constructors.h +122 -0
  73. multipers/gudhi/gudhi/Persistence_matrix/base_pairing.h +260 -0
  74. multipers/gudhi/gudhi/Persistence_matrix/base_swap.h +288 -0
  75. multipers/gudhi/gudhi/Persistence_matrix/chain_pairing.h +170 -0
  76. multipers/gudhi/gudhi/Persistence_matrix/chain_rep_cycles.h +247 -0
  77. multipers/gudhi/gudhi/Persistence_matrix/chain_vine_swap.h +571 -0
  78. multipers/gudhi/gudhi/Persistence_matrix/columns/chain_column_extra_properties.h +182 -0
  79. multipers/gudhi/gudhi/Persistence_matrix/columns/column_dimension_holder.h +130 -0
  80. multipers/gudhi/gudhi/Persistence_matrix/columns/column_utilities.h +235 -0
  81. multipers/gudhi/gudhi/Persistence_matrix/columns/entry_types.h +312 -0
  82. multipers/gudhi/gudhi/Persistence_matrix/columns/heap_column.h +1092 -0
  83. multipers/gudhi/gudhi/Persistence_matrix/columns/intrusive_list_column.h +923 -0
  84. multipers/gudhi/gudhi/Persistence_matrix/columns/intrusive_set_column.h +914 -0
  85. multipers/gudhi/gudhi/Persistence_matrix/columns/list_column.h +930 -0
  86. multipers/gudhi/gudhi/Persistence_matrix/columns/naive_vector_column.h +1071 -0
  87. multipers/gudhi/gudhi/Persistence_matrix/columns/row_access.h +203 -0
  88. multipers/gudhi/gudhi/Persistence_matrix/columns/set_column.h +886 -0
  89. multipers/gudhi/gudhi/Persistence_matrix/columns/unordered_set_column.h +984 -0
  90. multipers/gudhi/gudhi/Persistence_matrix/columns/vector_column.h +1213 -0
  91. multipers/gudhi/gudhi/Persistence_matrix/index_mapper.h +58 -0
  92. multipers/gudhi/gudhi/Persistence_matrix/matrix_dimension_holders.h +227 -0
  93. multipers/gudhi/gudhi/Persistence_matrix/matrix_row_access.h +200 -0
  94. multipers/gudhi/gudhi/Persistence_matrix/ru_pairing.h +166 -0
  95. multipers/gudhi/gudhi/Persistence_matrix/ru_rep_cycles.h +319 -0
  96. multipers/gudhi/gudhi/Persistence_matrix/ru_vine_swap.h +562 -0
  97. multipers/gudhi/gudhi/Persistence_on_a_line.h +152 -0
  98. multipers/gudhi/gudhi/Persistence_on_rectangle.h +617 -0
  99. multipers/gudhi/gudhi/Persistent_cohomology/Field_Zp.h +118 -0
  100. multipers/gudhi/gudhi/Persistent_cohomology/Multi_field.h +173 -0
  101. multipers/gudhi/gudhi/Persistent_cohomology/Persistent_cohomology_column.h +128 -0
  102. multipers/gudhi/gudhi/Persistent_cohomology.h +769 -0
  103. multipers/gudhi/gudhi/Points_off_io.h +171 -0
  104. multipers/gudhi/gudhi/Projective_cover_kernel.h +379 -0
  105. multipers/gudhi/gudhi/Simple_object_pool.h +69 -0
  106. multipers/gudhi/gudhi/Simplex_tree/Simplex_tree_iterators.h +559 -0
  107. multipers/gudhi/gudhi/Simplex_tree/Simplex_tree_node_explicit_storage.h +83 -0
  108. multipers/gudhi/gudhi/Simplex_tree/Simplex_tree_siblings.h +121 -0
  109. multipers/gudhi/gudhi/Simplex_tree/Simplex_tree_star_simplex_iterators.h +277 -0
  110. multipers/gudhi/gudhi/Simplex_tree/filtration_value_utils.h +155 -0
  111. multipers/gudhi/gudhi/Simplex_tree/hooks_simplex_base.h +62 -0
  112. multipers/gudhi/gudhi/Simplex_tree/indexing_tag.h +27 -0
  113. multipers/gudhi/gudhi/Simplex_tree/serialization_utils.h +60 -0
  114. multipers/gudhi/gudhi/Simplex_tree/simplex_tree_options.h +105 -0
  115. multipers/gudhi/gudhi/Simplex_tree.h +3170 -0
  116. multipers/gudhi/gudhi/Slicer.h +848 -0
  117. multipers/gudhi/gudhi/Thread_safe_slicer.h +393 -0
  118. multipers/gudhi/gudhi/distance_functions.h +62 -0
  119. multipers/gudhi/gudhi/graph_simplicial_complex.h +104 -0
  120. multipers/gudhi/gudhi/multi_simplex_tree_helpers.h +147 -0
  121. multipers/gudhi/gudhi/persistence_interval.h +263 -0
  122. multipers/gudhi/gudhi/persistence_matrix_options.h +188 -0
  123. multipers/gudhi/gudhi/reader_utils.h +367 -0
  124. multipers/gudhi/gudhi/simple_mdspan.h +484 -0
  125. multipers/gudhi/gudhi/slicer_helpers.h +779 -0
  126. multipers/gudhi/tmp_h0_pers/mma_interface_h0.h +223 -0
  127. multipers/gudhi/tmp_h0_pers/naive_merge_tree.h +536 -0
  128. multipers/io.cpython-312-darwin.so +0 -0
  129. multipers/io.pyx +472 -0
  130. multipers/ml/__init__.py +0 -0
  131. multipers/ml/accuracies.py +90 -0
  132. multipers/ml/invariants_with_persistable.py +79 -0
  133. multipers/ml/kernels.py +176 -0
  134. multipers/ml/mma.py +713 -0
  135. multipers/ml/one.py +472 -0
  136. multipers/ml/point_clouds.py +352 -0
  137. multipers/ml/signed_measures.py +1667 -0
  138. multipers/ml/sliced_wasserstein.py +461 -0
  139. multipers/ml/tools.py +113 -0
  140. multipers/mma_structures.cpython-312-darwin.so +0 -0
  141. multipers/mma_structures.pxd +134 -0
  142. multipers/mma_structures.pyx +1483 -0
  143. multipers/mma_structures.pyx.tp +1126 -0
  144. multipers/multi_parameter_rank_invariant/diff_helpers.h +85 -0
  145. multipers/multi_parameter_rank_invariant/euler_characteristic.h +95 -0
  146. multipers/multi_parameter_rank_invariant/function_rips.h +317 -0
  147. multipers/multi_parameter_rank_invariant/hilbert_function.h +761 -0
  148. multipers/multi_parameter_rank_invariant/persistence_slices.h +149 -0
  149. multipers/multi_parameter_rank_invariant/rank_invariant.h +350 -0
  150. multipers/multiparameter_edge_collapse.py +41 -0
  151. multipers/multiparameter_module_approximation/approximation.h +2541 -0
  152. multipers/multiparameter_module_approximation/debug.h +107 -0
  153. multipers/multiparameter_module_approximation/format_python-cpp.h +292 -0
  154. multipers/multiparameter_module_approximation/utilities.h +428 -0
  155. multipers/multiparameter_module_approximation.cpython-312-darwin.so +0 -0
  156. multipers/multiparameter_module_approximation.pyx +286 -0
  157. multipers/ops.cpython-312-darwin.so +0 -0
  158. multipers/ops.pyx +231 -0
  159. multipers/pickle.py +89 -0
  160. multipers/plots.py +550 -0
  161. multipers/point_measure.cpython-312-darwin.so +0 -0
  162. multipers/point_measure.pyx +409 -0
  163. multipers/simplex_tree_multi.cpython-312-darwin.so +0 -0
  164. multipers/simplex_tree_multi.pxd +136 -0
  165. multipers/simplex_tree_multi.pyx +11719 -0
  166. multipers/simplex_tree_multi.pyx.tp +2102 -0
  167. multipers/slicer.cpython-312-darwin.so +0 -0
  168. multipers/slicer.pxd +2097 -0
  169. multipers/slicer.pxd.tp +263 -0
  170. multipers/slicer.pyx +13042 -0
  171. multipers/slicer.pyx.tp +1259 -0
  172. multipers/tensor/tensor.h +672 -0
  173. multipers/tensor.pxd +13 -0
  174. multipers/test.pyx +44 -0
  175. multipers/tests/__init__.py +70 -0
  176. multipers/torch/__init__.py +1 -0
  177. multipers/torch/diff_grids.py +240 -0
  178. multipers/torch/rips_density.py +310 -0
  179. multipers/vector_interface.pxd +46 -0
  180. multipers-2.4.0b1.dist-info/METADATA +131 -0
  181. multipers-2.4.0b1.dist-info/RECORD +184 -0
  182. multipers-2.4.0b1.dist-info/WHEEL +6 -0
  183. multipers-2.4.0b1.dist-info/licenses/LICENSE +21 -0
  184. multipers-2.4.0b1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,485 @@
1
+ /* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT.
2
+ * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details.
3
+ * Author(s): David Loiseaux
4
+ *
5
+ * Copyright (C) 2023 Inria
6
+ *
7
+ * Modification(s):
8
+ * - 2025/04 Hannah Schreiber: Reorganization + documentation.
9
+ * - YYYY/MM Author: Description of the modification
10
+ */
11
+
12
+ /**
13
+ * @file Multi_parameter_filtered_complex.h
14
+ * @author David Loiseaux
15
+ * @brief Contains the @ref Gudhi::multi_persistence::Multi_parameter_filtered_complex class.
16
+ */
17
+
18
+ #ifndef MP_FILTERED_COMPLEX_H_INCLUDED
19
+ #define MP_FILTERED_COMPLEX_H_INCLUDED
20
+
21
+ #include <cstdint> //std::uint32_t
22
+ #include <algorithm>
23
+ #include <numeric>
24
+ #include <ostream>
25
+ #include <stdexcept>
26
+ #include <utility>
27
+ #include <vector>
28
+
29
+ #include <gudhi/Debug_utils.h>
30
+ #include <gudhi/Multi_parameter_filtration.h> //for lex order
31
+ #include <gudhi/Multi_filtration/multi_filtration_conversions.h>
32
+ #include <oneapi/tbb/parallel_for.h>
33
+
34
+ namespace Gudhi {
35
+ namespace multi_persistence {
36
+
37
+ // TODO: better name
38
+ /**
39
+ * @class Multi_parameter_filtered_complex Multi_parameter_filtered_complex.h gudhi/Multi_parameter_filtered_complex.h
40
+ * @ingroup multi_persistence
41
+ *
42
+ * @brief Class storing the boundaries, the dimensions and the filtration values of all cells composing a complex.
43
+ *
44
+ * @tparam MultiFiltrationValue Filtration value class respecting the @ref MultiFiltrationValue concept.
45
+ */
46
+ template <class MultiFiltrationValue>
47
+ class Multi_parameter_filtered_complex
48
+ {
49
+ public:
50
+ using Index = std::uint32_t; /**< Complex index type. */
51
+ using Filtration_value = MultiFiltrationValue; /**< Filtration value type. */
52
+ using T = typename Filtration_value::value_type; /**< Numerical type of an element in a filtration value. */
53
+ using Filtration_value_container = std::vector<Filtration_value>; /**< Filtration value container type. */
54
+ using Boundary = std::vector<Index>; /**< Cell boundary type, represented by the complex indices of its faces. */
55
+ using Boundary_container = std::vector<Boundary>; /**< Boundary container type. */
56
+ using Dimension = int; /**< Dimension type. */
57
+ using Dimension_container = std::vector<Dimension>; /**< Dimension container type. */
58
+
59
+ /**
60
+ * @brief Default constructor. Constructs an empty complex.
61
+ */
62
+ Multi_parameter_filtered_complex() : filtrationValues_(), maxDimension_(-1), isOrderedByDimension_(true) {}
63
+
64
+ /**
65
+ * @brief Constructs the complex by copying all three given containers into the class.
66
+ *
67
+ * @param boundaries Container of boundaries. A boundary has to be described by the indices of its faces in this
68
+ * container. E.g., if a vertex \f$ v \f$ is stored at index \f$ i \f$ and another vertex at index \f$ j \f$, then
69
+ * `boundaries[i]` and `boundaries[j]` are both empty and if the edge \f$ (v,u) \f$ is at index \f$ k \f$, then
70
+ * `boundaries[k]` is equal to `{i, j}`. All boundaries are expected to be ordered by increasing index value.
71
+ * @param dimensions Dimension container. The value at index \f$ i \f$ has to correspond to the dimension of the
72
+ * cell at index \f$ i \f$ in `boundaries`.
73
+ * @param filtrationValues Filtration value container. The value at index \f$ i \f$ has to correspond to the
74
+ * filtration value of the cell at index \f$ i \f$ in `boundaries`.
75
+ */
76
+ Multi_parameter_filtered_complex(const Boundary_container& boundaries,
77
+ const Dimension_container& dimensions,
78
+ const Filtration_value_container& filtrationValues)
79
+ : boundaries_(boundaries),
80
+ dimensions_(dimensions),
81
+ filtrationValues_(filtrationValues),
82
+ maxDimension_(-1),
83
+ isOrderedByDimension_(false)
84
+ {
85
+ _initialize_dimension_utils();
86
+ }
87
+
88
+ /**
89
+ * @brief Constructs the complex by moving all three given containers to the class.
90
+ *
91
+ * @param boundaries Container of boundaries. A boundary has to be described by the indices of its faces in this
92
+ * container. E.g., if a vertex \f$ v \f$ is stored at index \f$ i \f$ and another vertex at index \f$ j \f$, then
93
+ * `boundaries[i]` and `boundaries[j]` are both empty and if the edge \f$ (v,u) \f$ is at index \f$ k \f$, then
94
+ * `boundaries[k]` is equal to `{i, j}`. All boundaries are expected to be ordered by increasing index value.
95
+ * @param dimensions Dimension container. The value at index \f$ i \f$ has to correspond to the dimension of the
96
+ * cell at index \f$ i \f$ in `boundaries`.
97
+ * @param filtrationValues Filtration value container. The value at index \f$ i \f$ has to correspond to the
98
+ * filtration value of the cell at index \f$ i \f$ in `boundaries`.
99
+ */
100
+ Multi_parameter_filtered_complex(Boundary_container&& boundaries,
101
+ Dimension_container&& dimensions,
102
+ Filtration_value_container&& filtrationValues)
103
+ : boundaries_(std::move(boundaries)),
104
+ dimensions_(std::move(dimensions)),
105
+ filtrationValues_(std::move(filtrationValues)),
106
+ maxDimension_(0),
107
+ isOrderedByDimension_(false)
108
+ {
109
+ _initialize_dimension_utils();
110
+ }
111
+
112
+ /**
113
+ * @brief Copy constructor.
114
+ */
115
+ Multi_parameter_filtered_complex(const Multi_parameter_filtered_complex& complex) = default;
116
+
117
+ /**
118
+ * @brief Copy constructor.
119
+ */
120
+ template <class OtherFiltrationValue>
121
+ Multi_parameter_filtered_complex(const Multi_parameter_filtered_complex<OtherFiltrationValue>& complex)
122
+ : boundaries_(complex.get_boundaries()),
123
+ dimensions_(complex.get_dimensions()),
124
+ filtrationValues_(complex.get_filtration_values().size()),
125
+ maxDimension_(complex.get_max_dimension()),
126
+ isOrderedByDimension_(complex.is_ordered_by_dimension())
127
+ {
128
+ const auto& fils = complex.get_filtration_values();
129
+ for (Index i = 0; i < filtrationValues_.size(); ++i) {
130
+ filtrationValues_[i] = multi_filtration::as_type<MultiFiltrationValue>(fils[i]);
131
+ }
132
+ }
133
+
134
+ /**
135
+ * @brief Move constructor.
136
+ */
137
+ Multi_parameter_filtered_complex(Multi_parameter_filtered_complex&& complex) noexcept = default;
138
+
139
+ /**
140
+ * @brief Destructor.
141
+ */
142
+ ~Multi_parameter_filtered_complex() = default;
143
+
144
+ /**
145
+ * @brief Assign operator.
146
+ */
147
+ Multi_parameter_filtered_complex& operator=(const Multi_parameter_filtered_complex& other) = default;
148
+
149
+ /**
150
+ * @brief Assign operator.
151
+ */
152
+ template <class OtherFiltrationValue>
153
+ Multi_parameter_filtered_complex& operator=(const Multi_parameter_filtered_complex<OtherFiltrationValue>& other)
154
+ {
155
+ boundaries_ = other.get_boundaries();
156
+ dimensions_ = other.get_dimensions();
157
+ const auto& fils = other.get_filtration_values();
158
+ filtrationValues_ = Filtration_value_container(fils.size());
159
+ for (Index i = 0; i < filtrationValues_.size(); ++i) {
160
+ filtrationValues_[i] = multi_filtration::as_type<MultiFiltrationValue>(fils[i]);
161
+ }
162
+ maxDimension_ = other.get_max_dimension();
163
+ isOrderedByDimension_ = other.is_ordered_by_dimension();
164
+
165
+ return *this;
166
+ }
167
+
168
+ /**
169
+ * @brief Move assign operator.
170
+ */
171
+ Multi_parameter_filtered_complex& operator=(Multi_parameter_filtered_complex&& other) noexcept = default;
172
+
173
+ /**
174
+ * @brief Returns the number of cells in the complex.
175
+ */
176
+ [[nodiscard]] Index get_number_of_cycle_generators() const { return boundaries_.size(); }
177
+
178
+ /**
179
+ * @brief Returns the number of parameters in the filtration.
180
+ */
181
+ [[nodiscard]] Index get_number_of_parameters() const
182
+ {
183
+ if (filtrationValues_.empty()) return 0;
184
+ return filtrationValues_[0].num_parameters();
185
+ }
186
+
187
+ /**
188
+ * @brief Returns true if and only if the boundaries are ordered by dimension. That is, if an index increases,
189
+ * the represented cell at the new index can only have same or higher dimension than the cell at the index before.
190
+ */
191
+ [[nodiscard]] bool is_ordered_by_dimension() const { return isOrderedByDimension_; }
192
+
193
+ /**
194
+ * @brief Returns a const reference to the filtration value container.
195
+ */
196
+ const Filtration_value_container& get_filtration_values() const { return filtrationValues_; }
197
+
198
+ /**
199
+ * @brief Returns a reference to the filtration value container.
200
+ * @warning The container is not const such that the user can easily modify/update a filtration value. But do not
201
+ * modify the size of the container, its indices have still to correspond to the indices in the other containers.
202
+ */
203
+ Filtration_value_container& get_filtration_values() { return filtrationValues_; }
204
+
205
+ /**
206
+ * @brief Returns a const reference to the dimension container.
207
+ */
208
+ [[nodiscard]] const Dimension_container& get_dimensions() const { return dimensions_; }
209
+
210
+ /**
211
+ * @brief Returns a const reference to the boundary container.
212
+ */
213
+ [[nodiscard]] const Boundary_container& get_boundaries() const { return boundaries_; }
214
+
215
+ /**
216
+ * @brief Returns the maximal dimension of a cell in the complex.
217
+ */
218
+ [[nodiscard]] Dimension get_max_dimension() const { return maxDimension_; }
219
+
220
+ /**
221
+ * @brief Sorts the container internally such that the cells are ordered first by dimension and then
222
+ * co-lexicographically by filtration values. If two cells have same dimension and same filtration value, they are
223
+ * considered equal (i.e., they relative position from each other does not matter).
224
+ * Note that the indices of the cells changes therefore.
225
+ */
226
+ void sort_by_dimension_co_lexicographically()
227
+ {
228
+ using namespace Gudhi::multi_filtration;
229
+
230
+ sort([&](Index i, Index j) -> bool {
231
+ if (dimensions_[i] == dimensions_[j]) {
232
+ return is_strict_less_than_lexicographically<true>(filtrationValues_[i], filtrationValues_[j]);
233
+ }
234
+ return dimensions_[i] < dimensions_[j];
235
+ });
236
+ }
237
+
238
+ /**
239
+ * @brief Sorts the internal containers using the given comparaison method.
240
+ * Note that the indices of the cells changes therefore.
241
+ *
242
+ * @tparam Comp Method type with signature (Index, Index)->bool.
243
+ * @param comparaison Method taking two complex indices (those before the sort) as input and returns true if and
244
+ * only if the cell at the first index is supposed to be placed before the cell at the second index.
245
+ */
246
+ template <typename Comp>
247
+ void sort(Comp&& comparaison)
248
+ {
249
+ // TODO: test if it is not faster to just reconstruct everything instead of swapping
250
+ // Note: perm and inv have to be build in any case
251
+ // if we reconstruct, we additionally build three containers of vector of Index, of Index
252
+ // and of Filtration_value, which will be swapped respectively with boundaries_, dimensions_
253
+ // and filtrationValues_
254
+ // in this version (swapping), we additionally build two containers of Index instead
255
+ // so should theoretically be better, but not so sure if we replace the containers with
256
+ // completely flat containers one day, i.e. with no cheap swap method
257
+ std::vector<Index> perm(boundaries_.size());
258
+ std::iota(perm.begin(), perm.end(), 0);
259
+ std::vector<Index> pos = perm;
260
+ std::vector<Index> invPos = perm;
261
+ std::sort(perm.begin(), perm.end(), std::forward<Comp>(comparaison));
262
+ std::vector<Index> invPerm(boundaries_.size());
263
+ for (Index i = 0; i < perm.size(); ++i) invPerm[perm[i]] = i;
264
+
265
+ Dimension lastDim = -1;
266
+ isOrderedByDimension_ = true;
267
+
268
+ for (Index curr = 0; curr < perm.size(); ++curr) {
269
+ Index p = perm[curr];
270
+ Index i = pos[p];
271
+ if (i != curr) {
272
+ GUDHI_CHECK(curr < i, std::runtime_error("Got curr " + std::to_string(curr) + " >= i " + std::to_string(i)));
273
+ std::swap(boundaries_[curr], boundaries_[i]);
274
+ std::swap(dimensions_[curr], dimensions_[i]);
275
+ swap(filtrationValues_[curr], filtrationValues_[i]);
276
+ std::swap(pos[invPos[curr]], pos[p]);
277
+ std::swap(invPos[curr], invPos[pos[invPos[curr]]]);
278
+ }
279
+ for (Index& b : boundaries_[curr]) b = invPerm[b];
280
+ std::sort(boundaries_[curr].begin(), boundaries_[curr].end());
281
+ if (lastDim > dimensions_[curr]) isOrderedByDimension_ = false;
282
+ lastDim = dimensions_[curr];
283
+ }
284
+ }
285
+
286
+ /**
287
+ * @brief Removes completely from the complex all cells of dimension strictly higher than given.
288
+ *
289
+ * @warning If @ref is_ordered_by_dimension does not return true, the complex is sorted by dimension before pruning.
290
+ * So, the indexing changes afterwards.
291
+ *
292
+ * @param maxDim Maximal dimension to keep.
293
+ * @return Number of remaining cells in the complex.
294
+ */
295
+ Index prune_above_dimension(int maxDim)
296
+ {
297
+ if (!isOrderedByDimension_) sort_by_dimension_co_lexicographically();
298
+ Index i = 0;
299
+ while (i < dimensions_.size() && dimensions_[i] < maxDim + 1) ++i;
300
+ boundaries_.resize(i);
301
+ dimensions_.resize(i);
302
+ filtrationValues_.resize(i);
303
+ maxDimension_ = dimensions_.empty() ? -1 : dimensions_.back();
304
+ return i;
305
+ }
306
+
307
+ /**
308
+ * @brief Projects all filtration values into the given grid. If @p coordinate is false, the entries are set to
309
+ * the nearest upper bound value with the same parameter in the grid. Otherwise, the entries are set to the indices
310
+ * of those nearest upper bound values.
311
+ * An index \f$ i \f$ of the grid corresponds to the same parameter as the index \f$ i \f$ in a generator of the
312
+ * filtration value. The internal vectors correspond to the possible values of the parameters, ordered by increasing
313
+ * value, forming therefore all together a 2D grid.
314
+ *
315
+ * @param grid Vector of vector with size at least number of filtration parameters.
316
+ * @param coordinate If true, the values are set to the coordinates of the projection in the grid. If false,
317
+ * the values are set to the values at the coordinates of the projection.
318
+ */
319
+ void coarsen_on_grid(const std::vector<std::vector<T> >& grid, bool coordinate = true)
320
+ {
321
+ // for (auto gen = 0U; gen < filtrationValues_.size(); ++gen) {
322
+ // filtrationValues_[gen].project_onto_grid(grid, coordinate);
323
+ // }
324
+ tbb::parallel_for(Index(0), Index(filtrationValues_.size()), [&](Index gen) {
325
+ // TODO : preallocate for tbb
326
+ filtrationValues_[gen].project_onto_grid(grid, coordinate);
327
+ });
328
+
329
+ }
330
+
331
+ /**
332
+ * @brief Builds a new complex by reordering the cells in the given complex with the given permutation map.
333
+ */
334
+ friend Multi_parameter_filtered_complex build_permuted_complex(const Multi_parameter_filtered_complex& complex,
335
+ const std::vector<Index>& permutation)
336
+ {
337
+ if (permutation.size() > complex.get_number_of_cycle_generators())
338
+ throw std::invalid_argument("Invalid permutation size.");
339
+
340
+ const Index nullIndex = -1;
341
+ std::vector<Index> inv(complex.get_number_of_cycle_generators(), nullIndex);
342
+ for (Index i = 0; i < permutation.size(); ++i) inv[permutation[i]] = i;
343
+
344
+ Boundary_container newBoundaries;
345
+ newBoundaries.reserve(permutation.size());
346
+ Dimension_container newDimensions;
347
+ newDimensions.reserve(permutation.size());
348
+ Filtration_value_container newFiltrationValues;
349
+ newBoundaries.reserve(permutation.size());
350
+
351
+ for (Index i : permutation) {
352
+ Boundary boundary;
353
+ for (Index b : complex.boundaries_[i]) {
354
+ if (inv[b] != nullIndex) boundary.push_back(inv[b]);
355
+ }
356
+ std::sort(boundary.begin(), boundary.end());
357
+ newBoundaries.emplace_back(std::move(boundary));
358
+ newDimensions.push_back(complex.dimensions_[i]);
359
+ newFiltrationValues.emplace_back(complex.filtrationValues_[i]);
360
+ }
361
+
362
+ return Multi_parameter_filtered_complex(
363
+ std::move(newBoundaries), std::move(newDimensions), std::move(newFiltrationValues));
364
+ }
365
+
366
+ /**
367
+ * @brief Builds a new complex by reordering the cells in the given complex the same way than
368
+ * @ref sort_by_dimension_co_lexicographically. Returns a pair with the new complex as first element and the
369
+ * permutation map used as second element.
370
+ */
371
+ friend std::pair<Multi_parameter_filtered_complex, std::vector<Index> > build_permuted_complex(
372
+ const Multi_parameter_filtered_complex& complex)
373
+ {
374
+ using namespace Gudhi::multi_filtration;
375
+
376
+ std::vector<Index> perm(complex.get_number_of_cycle_generators());
377
+ std::iota(perm.begin(), perm.end(), 0);
378
+ std::sort(perm.begin(), perm.end(), [&](Index i, Index j) -> bool {
379
+ if (complex.dimensions_[i] == complex.dimensions_[j]) {
380
+ return is_strict_less_than_lexicographically<true>(complex.filtrationValues_[i], complex.filtrationValues_[j]);
381
+ }
382
+ return complex.dimensions_[i] < complex.dimensions_[j];
383
+ });
384
+ auto out = build_permuted_complex(complex, perm);
385
+ return std::make_pair(std::move(out), std::move(perm));
386
+ }
387
+
388
+ /**
389
+ * @brief Builds a new complex from the given one by projecting its filtration values on a grid.
390
+ * See @ref coarsen_on_grid with the paramater `coordinate` at true.
391
+ */
392
+ friend auto build_complex_coarsen_on_grid(const Multi_parameter_filtered_complex& complex,
393
+ const std::vector<std::vector<T> >& grid)
394
+ {
395
+ using namespace Gudhi::multi_filtration;
396
+ using Return_filtration_value = decltype(std::declval<Filtration_value>().template as_type<std::int32_t>());
397
+ using Return_complex = Multi_parameter_filtered_complex<Return_filtration_value>;
398
+
399
+ typename Return_complex::Filtration_value_container coords(complex.get_number_of_cycle_generators());
400
+ for (Index gen = 0U; gen < coords.size(); ++gen) {
401
+ coords[gen] = compute_coordinates_in_grid<std::int32_t>(complex.filtrationValues_[gen], grid);
402
+ }
403
+ return Return_complex(complex.boundaries_, complex.dimensions_, coords);
404
+ }
405
+
406
+ // /**
407
+ // * @brief Compares two boundaries and returns true if and only if the size of the first is strictly smaller than
408
+ // the
409
+ // * second, or, if the two sizes are the same, the first is lexicographically strictly smaller than the second.
410
+ // * The boundaries are assumed to be ordered by increasing values.
411
+ // */
412
+ // static bool boundary_is_strictly_smaller_than(const Boundary& b1, const Boundary& b2) {
413
+ // // we want faces to be smaller than proper cofaces
414
+ // if (b1.size() < b2.size()) return true;
415
+ // if (b1.size() > b2.size()) return false;
416
+
417
+ // // lexico for others
418
+ // for (Index i = 0; i < b2.size(); ++i){
419
+ // if (b1[i] < b2[i]) return true;
420
+ // if (b1[i] > b2[i]) return false;
421
+ // }
422
+
423
+ // // equal
424
+ // return false;
425
+ // }
426
+
427
+ /**
428
+ * @brief Outstream operator.
429
+ */
430
+ friend std::ostream& operator<<(std::ostream& stream, const Multi_parameter_filtered_complex& complex)
431
+ {
432
+ stream << "Boundary:\n";
433
+ stream << "{\n";
434
+ for (Index i = 0; i < complex.boundaries_.size(); ++i) {
435
+ const auto& boundary = complex.boundaries_[i];
436
+ stream << i << ": {";
437
+ for (auto b : boundary) stream << b << ", ";
438
+ if (!boundary.empty()) stream << "\b" << "\b ";
439
+ stream << "},\n";
440
+ }
441
+ stream << "}\n";
442
+
443
+ stream << "Dimensions: (max " << complex.get_max_dimension() << ")\n";
444
+ stream << "{";
445
+ for (auto d : complex.dimensions_) stream << d << ", ";
446
+ if (!complex.dimensions_.empty()) {
447
+ stream << "\b" << "\b";
448
+ }
449
+ stream << "}\n";
450
+
451
+ stream << "Filtration values:\n";
452
+ stream << "{\n";
453
+ for (auto f : complex.filtrationValues_) stream << f << "\n";
454
+ stream << "}\n";
455
+
456
+ return stream;
457
+ }
458
+
459
+ private:
460
+ Boundary_container boundaries_; /**< Boundary container. */
461
+ Dimension_container dimensions_; /**< Dimension container. */
462
+ Filtration_value_container filtrationValues_; /**< Filtration value container. */
463
+ Dimension maxDimension_; /**< Maximal dimension of a cell. */
464
+ bool isOrderedByDimension_; /**< True if and only if the containers are ordered by dimension. */
465
+
466
+ /**
467
+ * @brief Initializes maxDimension_ and isOrderedByDimension_
468
+ */
469
+ void _initialize_dimension_utils()
470
+ {
471
+ isOrderedByDimension_ = true;
472
+ if (dimensions_.empty()) return;
473
+
474
+ for (Index i = 0; i < dimensions_.size() - 1; ++i) {
475
+ maxDimension_ = std::max(dimensions_[i], maxDimension_);
476
+ if (dimensions_[i] > dimensions_[i + 1]) isOrderedByDimension_ = false;
477
+ }
478
+ maxDimension_ = std::max(dimensions_.back(), maxDimension_);
479
+ }
480
+ };
481
+
482
+ } // namespace multi_persistence
483
+ } // namespace Gudhi
484
+
485
+ #endif // MP_FILTERED_COMPLEX_H_INCLUDED