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,571 @@
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): Hannah Schreiber
4
+ *
5
+ * Copyright (C) 2022-24 Inria
6
+ *
7
+ * Modification(s):
8
+ * - YYYY/MM Author: Description of the modification
9
+ */
10
+
11
+ /**
12
+ * @file chain_vine_swap.h
13
+ * @author Hannah Schreiber
14
+ * @brief Contains the @ref Gudhi::persistence_matrix::Chain_barcode_swap and
15
+ * @ref Gudhi::persistence_matrix::Chain_vine_swap classes, as well as the
16
+ * @ref Gudhi::persistence_matrix::Dummy_chain_vine_swap and
17
+ * @ref Gudhi::persistence_matrix::Dummy_chain_vine_pairing structures.
18
+ */
19
+
20
+ #ifndef PM_CHAIN_VINE_SWAP_H
21
+ #define PM_CHAIN_VINE_SWAP_H
22
+
23
+ #include <cassert>
24
+ #include <utility> //std::swap & std::move
25
+ #include <functional> //std::function
26
+ #include <stdexcept> //std::invalid_argument
27
+
28
+ #include <gudhi/Persistence_matrix/chain_pairing.h>
29
+
30
+ namespace Gudhi {
31
+ namespace persistence_matrix {
32
+
33
+ /**
34
+ * @ingroup persistence_matrix
35
+ *
36
+ * @brief Default death comparator. Simply assumes that two positive paired columns are never swapped. Which is true
37
+ * for the use case in zigzag persistence for example.
38
+ *
39
+ * @param columnIndex1 First column index.
40
+ * @param columnIndex2 Second column index.
41
+ * @return false
42
+ */
43
+ constexpr bool _no_G_death_comparator([[maybe_unused]] unsigned int columnIndex1,
44
+ [[maybe_unused]] unsigned int columnIndex2)
45
+ {
46
+ return false;
47
+ }
48
+
49
+ /**
50
+ * @ingroup persistence_matrix
51
+ *
52
+ * @brief Empty structure.
53
+ * Inherited instead of @ref Chain_vine_swap, when vine swaps are not enabled.
54
+ */
55
+ struct Dummy_chain_vine_swap {
56
+ using CP = void;
57
+
58
+ friend void swap([[maybe_unused]] Dummy_chain_vine_swap& d1, [[maybe_unused]] Dummy_chain_vine_swap& d2) noexcept {}
59
+
60
+ Dummy_chain_vine_swap() = default;
61
+
62
+ template <typename BirthComparatorFunction, typename DeathComparatorFunction>
63
+ Dummy_chain_vine_swap([[maybe_unused]] const BirthComparatorFunction& birthComparator,
64
+ [[maybe_unused]] const DeathComparatorFunction& deathComparator)
65
+ {}
66
+ };
67
+
68
+ /**
69
+ * @ingroup persistence_matrix
70
+ *
71
+ * @brief Empty structure.
72
+ * Inherited instead of @ref Chain_barcode_swap, when the barcode is not stored.
73
+ */
74
+ struct Dummy_chain_vine_pairing {
75
+ friend void swap([[maybe_unused]] Dummy_chain_vine_pairing& d1,
76
+ [[maybe_unused]] Dummy_chain_vine_pairing& d2) noexcept
77
+ {}
78
+ };
79
+
80
+ /**
81
+ * @ingroup persistence_matrix
82
+ *
83
+ * @brief Class managing the barcode for @ref Chain_vine_swap.
84
+ *
85
+ * @tparam Master_matrix An instantiation of @ref Matrix from which all types and options are deduced.
86
+ */
87
+ template <typename Master_matrix>
88
+ class Chain_barcode_swap : public Chain_pairing<Master_matrix>
89
+ {
90
+ public:
91
+ using ID_index = typename Master_matrix::ID_index; /**< @ref IDIdx index type. */
92
+ using Pos_index = typename Master_matrix::Pos_index; /**< @ref PosIdx index type. */
93
+ // CP = Chain Pairing
94
+ using CP = Chain_pairing<Master_matrix>;
95
+
96
+ /**
97
+ * @brief Default constructor.
98
+ */
99
+ Chain_barcode_swap() = default;
100
+ /**
101
+ * @brief Copy constructor.
102
+ *
103
+ * @param toCopy Matrix to copy.
104
+ */
105
+ Chain_barcode_swap(const Chain_barcode_swap& toCopy) : CP(static_cast<const CP&>(toCopy)) {};
106
+ /**
107
+ * @brief Move constructor.
108
+ *
109
+ * @param other Matrix to move.
110
+ */
111
+ Chain_barcode_swap(Chain_barcode_swap&& other) noexcept : CP(std::move(static_cast<CP&>(other))) {};
112
+
113
+ ~Chain_barcode_swap() = default;
114
+
115
+ Chain_barcode_swap& operator=(Chain_barcode_swap other)
116
+ {
117
+ CP::operator=(other);
118
+ return *this;
119
+ }
120
+
121
+ Chain_barcode_swap& operator=(Chain_barcode_swap&& other) noexcept
122
+ {
123
+ CP::operator=(std::move(other));
124
+ return *this;
125
+ }
126
+
127
+ friend void swap(Chain_barcode_swap& swap1, Chain_barcode_swap& swap2) noexcept
128
+ {
129
+ swap(static_cast<CP&>(swap1), static_cast<CP&>(swap2));
130
+ }
131
+
132
+ protected:
133
+ bool _is_negative_in_bar(ID_index pivot) const
134
+ {
135
+ Pos_index pos = _get_pivot_position(pivot);
136
+ return _death_val(pivot) == pos;
137
+ }
138
+
139
+ void _positive_transpose_barcode(ID_index pivot1, ID_index pivot2)
140
+ {
141
+ Pos_index pos1 = _get_pivot_position(pivot1);
142
+ Pos_index pos2 = _get_pivot_position(pivot2);
143
+
144
+ _birth(pos1) = pos2;
145
+ _birth(pos2) = pos1;
146
+ std::swap(CP::indexToBar_.at(pos1), CP::indexToBar_.at(pos2));
147
+ }
148
+
149
+ void _negative_transpose_barcode(ID_index pivot1, ID_index pivot2)
150
+ {
151
+ Pos_index pos1 = _get_pivot_position(pivot1);
152
+ Pos_index pos2 = _get_pivot_position(pivot2);
153
+
154
+ _death(pos1) = pos2;
155
+ _death(pos2) = pos1;
156
+ std::swap(CP::indexToBar_.at(pos1), CP::indexToBar_.at(pos2));
157
+ }
158
+
159
+ void _positive_negative_transpose_barcode(ID_index pivot1, ID_index pivot2)
160
+ {
161
+ Pos_index pos1 = _get_pivot_position(pivot1);
162
+ Pos_index pos2 = _get_pivot_position(pivot2);
163
+
164
+ _birth(pos1) = pos2;
165
+ _death(pos2) = pos1;
166
+ std::swap(CP::indexToBar_.at(pos1), CP::indexToBar_.at(pos2));
167
+ }
168
+
169
+ void _negative_positive_transpose_barcode(ID_index pivot1, ID_index pivot2)
170
+ {
171
+ Pos_index pos1 = _get_pivot_position(pivot1);
172
+ Pos_index pos2 = _get_pivot_position(pivot2);
173
+
174
+ _death(pos1) = pos2;
175
+ _birth(pos2) = pos1;
176
+ std::swap(CP::indexToBar_.at(pos1), CP::indexToBar_.at(pos2));
177
+ }
178
+
179
+ bool _are_adjacent(ID_index pivot1, ID_index pivot2) const
180
+ {
181
+ Pos_index pos1 = _get_pivot_position(pivot1);
182
+ Pos_index pos2 = _get_pivot_position(pivot2);
183
+ return pos1 < pos2 ? (pos2 - pos1) == 1 : (pos1 - pos2) == 1;
184
+ }
185
+
186
+ Pos_index _death_val(ID_index pivot) const { return CP::_death(_get_pivot_position(pivot)); }
187
+
188
+ Pos_index _birth_val(ID_index pivot) const { return CP::_birth(_get_pivot_position(pivot)); }
189
+
190
+ void _reset() { CP::_reset(); }
191
+
192
+ private:
193
+ using Master_chain_matrix = typename Master_matrix::Master_chain_matrix;
194
+
195
+ Pos_index _get_pivot_position(ID_index pivot) const
196
+ {
197
+ const auto& map = static_cast<const Master_chain_matrix*>(this)->map_;
198
+ if constexpr (Master_matrix::Option_list::has_map_column_container) {
199
+ // TODO: quite often called, make public and pass position instead of pivot to avoid find() every time?
200
+ return map.at(pivot);
201
+ } else {
202
+ return map[pivot];
203
+ }
204
+ }
205
+
206
+ Pos_index& _death(Pos_index index)
207
+ {
208
+ if constexpr (Master_matrix::Option_list::has_removable_columns) {
209
+ return CP::indexToBar_.at(index)->death;
210
+ } else {
211
+ return CP::barcode_.at(CP::indexToBar_.at(index)).death;
212
+ }
213
+ }
214
+
215
+ Pos_index& _birth(Pos_index index)
216
+ {
217
+ if constexpr (Master_matrix::Option_list::has_removable_columns) {
218
+ return CP::indexToBar_.at(index)->birth;
219
+ } else {
220
+ return CP::barcode_.at(CP::indexToBar_.at(index)).birth;
221
+ }
222
+ }
223
+ };
224
+
225
+ /**
226
+ * @class Chain_vine_swap chain_vine_swap.h gudhi/Persistence_matrix/chain_vine_swap.h
227
+ * @ingroup persistence_matrix
228
+ *
229
+ * @brief Class managing the vine swaps for @ref Chain_matrix.
230
+ *
231
+ * @tparam Master_matrix An instantiation of @ref Matrix from which all types and options are deduced.
232
+ */
233
+ template <class Master_matrix>
234
+ class Chain_vine_swap
235
+ {
236
+ public:
237
+ using Index = typename Master_matrix::Index; /**< @ref MatIdx index type. */
238
+ using ID_index = typename Master_matrix::ID_index; /**< @ref IDIdx index type. */
239
+ using Pos_index = typename Master_matrix::Pos_index; /**< @ref PosIdx index type. */
240
+ using Column_container = typename Master_matrix::Column_container; /**< Column container type. */
241
+ using Column = typename Master_matrix::Column; /**< Column type. */
242
+ using EventCompFuncPointer = bool (*)(Pos_index, Pos_index); /**< Pointer type for birth/death comparators. */
243
+
244
+ /**
245
+ * @brief Default constructor. Only available if @ref PersistenceMatrixOptions::has_column_pairings is true.
246
+ */
247
+ Chain_vine_swap();
248
+ /**
249
+ * @brief Constructor storing the given comparators.
250
+ *
251
+ * @param birthComparator Method taking two @ref PosIdx indices as input and returning true if and only if
252
+ * the birth associated to the first position is strictly less than birth associated to
253
+ * the second one with respect to some self defined order. It is used while swapping two unpaired or
254
+ * two negative columns.
255
+ * @param deathComparator Method taking two @ref PosIdx indices as input and returning true if and only if
256
+ * the death associated to the first position is strictly less than death associated to
257
+ * the second one with respect to some self defined order. It is used while swapping two positive but paired
258
+ * columns. Default value: @ref _no_G_death_comparator.
259
+ */
260
+ Chain_vine_swap(std::function<bool(Pos_index, Pos_index)> birthComparator,
261
+ std::function<bool(Pos_index, Pos_index)> deathComparator = _no_G_death_comparator);
262
+
263
+ /**
264
+ * @brief Does the same than @ref vine_swap, but assumes that the swap is non trivial and
265
+ * therefore skips a part of the case study.
266
+ *
267
+ * @param columnIndex1 @ref MatIdx index of the first cell.
268
+ * @param columnIndex2 @ref MatIdx index of the second cell.
269
+ * @return Let \f$ pos1 \f$ be the @ref PosIdx index of @p columnIndex1 and \f$ pos2 \f$ be the @ref PosIdx index of
270
+ * @p columnIndex2. The method returns the @ref MatIdx of the column which has now, after the swap, the @ref PosIdx
271
+ * \f$ max(pos1, pos2) \f$.
272
+ */
273
+ Index vine_swap_with_z_eq_1_case(Index columnIndex1, Index columnIndex2);
274
+ /**
275
+ * @brief Does a vine swap between two cells which are consecutive in the filtration. Roughly, if \f$ F \f$ is
276
+ * the current filtration represented by the matrix, the method modifies the matrix such that the new state
277
+ * corresponds to a valid state for the filtration \f$ F' \f$ equal to \f$ F \f$ but with the two given cells
278
+ * at swapped positions. Of course, the two cells should not have a face/coface relation which each other ;
279
+ * \f$ F' \f$ has to be a valid filtration.
280
+ * See @cite vineyards for more information about vine and vineyards.
281
+ *
282
+ * @param columnIndex1 @ref MatIdx index of the first cell.
283
+ * @param columnIndex2 @ref MatIdx index of the second cell. It is assumed that the @ref PosIdx of both only differs
284
+ * by one if the barcode is maintained.
285
+ * @return Let \f$ pos1 \f$ be the @ref PosIdx index of @p columnIndex1 and \f$ pos2 \f$ be the @ref PosIdx index of
286
+ * @p columnIndex2. The method returns the @ref MatIdx of the column which has now, after the swap, the @ref PosIdx
287
+ * \f$ max(pos1, pos2) \f$.
288
+ */
289
+ Index vine_swap(Index columnIndex1, Index columnIndex2);
290
+
291
+ /**
292
+ * @brief Swap operator.
293
+ */
294
+ friend void swap(Chain_vine_swap& swap1, Chain_vine_swap& swap2) noexcept
295
+ {
296
+ std::swap(swap1.birthComp_, swap2.birthComp_);
297
+ std::swap(swap1.deathComp_, swap2.deathComp_);
298
+ }
299
+
300
+ private:
301
+ using Master_chain_matrix = typename Master_matrix::Master_chain_matrix;
302
+
303
+ std::function<bool(Pos_index, Pos_index)> birthComp_; /**< for F x F & H x H. */
304
+ std::function<bool(Pos_index, Pos_index)> deathComp_; /**< for G x G. */
305
+
306
+ bool _is_negative_in_pair(Index columnIndex);
307
+ Index _positive_vine_swap(Index columnIndex1, Index columnIndex2);
308
+ Index _positive_negative_vine_swap(Index columnIndex1, Index columnIndex2);
309
+ Index _negative_positive_vine_swap(Index columnIndex1, Index columnIndex2);
310
+ Index _negative_vine_swap(Index columnIndex1, Index columnIndex2);
311
+ void _swap_positions(ID_index pivot1, ID_index pivot2);
312
+
313
+ constexpr Master_chain_matrix* _matrix() { return static_cast<Master_chain_matrix*>(this); }
314
+
315
+ constexpr const Master_chain_matrix* _matrix() const { return static_cast<const Master_chain_matrix*>(this); }
316
+ };
317
+
318
+ template <class Master_matrix>
319
+ inline Chain_vine_swap<Master_matrix>::Chain_vine_swap() : birthComp_(), deathComp_()
320
+ {
321
+ static_assert(Master_matrix::Option_list::has_column_pairings,
322
+ "If barcode is not stored, at least a birth comparator has to be specified.");
323
+ }
324
+
325
+ template <class Master_matrix>
326
+ inline Chain_vine_swap<Master_matrix>::Chain_vine_swap(std::function<bool(Pos_index, Pos_index)> birthComparator,
327
+ std::function<bool(Pos_index, Pos_index)> deathComparator)
328
+ : birthComp_(std::move(birthComparator)), deathComp_(std::move(deathComparator))
329
+ {}
330
+
331
+ template <class Master_matrix>
332
+ inline typename Chain_vine_swap<Master_matrix>::Index Chain_vine_swap<Master_matrix>::vine_swap_with_z_eq_1_case(
333
+ Index columnIndex1,
334
+ Index columnIndex2)
335
+ {
336
+ const bool col1IsNeg = _is_negative_in_pair(columnIndex1);
337
+ const bool col2IsNeg = _is_negative_in_pair(columnIndex2);
338
+
339
+ if (col1IsNeg && col2IsNeg) return _negative_vine_swap(columnIndex1, columnIndex2);
340
+
341
+ if (col1IsNeg) return _negative_positive_vine_swap(columnIndex1, columnIndex2);
342
+
343
+ if (col2IsNeg) return _positive_negative_vine_swap(columnIndex1, columnIndex2);
344
+
345
+ return _positive_vine_swap(columnIndex1, columnIndex2);
346
+ }
347
+
348
+ template <class Master_matrix>
349
+ inline typename Chain_vine_swap<Master_matrix>::Index Chain_vine_swap<Master_matrix>::vine_swap(Index columnIndex1,
350
+ Index columnIndex2)
351
+ {
352
+ if constexpr (Master_matrix::Option_list::has_column_pairings) {
353
+ GUDHI_CHECK(_matrix()->_are_adjacent(_matrix()->get_pivot(columnIndex1), _matrix()->get_pivot(columnIndex2)),
354
+ std::invalid_argument(
355
+ "Chain_vine_swap::vine_swap - Columns to be swapped need to be adjacent in the 'real' matrix."));
356
+ }
357
+
358
+ const bool col1IsNeg = _is_negative_in_pair(columnIndex1);
359
+ const bool col2IsNeg = _is_negative_in_pair(columnIndex2);
360
+
361
+ if (col1IsNeg && col2IsNeg) {
362
+ if (_matrix()->is_zero_entry(columnIndex2, _matrix()->get_pivot(columnIndex1))) {
363
+ ID_index pivot1 = _matrix()->get_pivot(columnIndex1);
364
+ ID_index pivot2 = _matrix()->get_pivot(columnIndex2);
365
+ if constexpr (Master_matrix::Option_list::has_column_pairings) {
366
+ _matrix()->_negative_transpose_barcode(pivot1, pivot2);
367
+ }
368
+ _swap_positions(pivot1, pivot2);
369
+ return columnIndex1;
370
+ }
371
+ return _negative_vine_swap(columnIndex1, columnIndex2);
372
+ }
373
+
374
+ if (col1IsNeg) {
375
+ if (_matrix()->is_zero_entry(columnIndex2, _matrix()->get_pivot(columnIndex1))) {
376
+ ID_index pivot1 = _matrix()->get_pivot(columnIndex1);
377
+ ID_index pivot2 = _matrix()->get_pivot(columnIndex2);
378
+ if constexpr (Master_matrix::Option_list::has_column_pairings) {
379
+ _matrix()->_negative_positive_transpose_barcode(pivot1, pivot2);
380
+ }
381
+ _swap_positions(pivot1, pivot2);
382
+ return columnIndex1;
383
+ }
384
+ return _negative_positive_vine_swap(columnIndex1, columnIndex2);
385
+ }
386
+
387
+ if (col2IsNeg) {
388
+ if (_matrix()->is_zero_entry(columnIndex2, _matrix()->get_pivot(columnIndex1))) {
389
+ ID_index pivot1 = _matrix()->get_pivot(columnIndex1);
390
+ ID_index pivot2 = _matrix()->get_pivot(columnIndex2);
391
+ if constexpr (Master_matrix::Option_list::has_column_pairings) {
392
+ _matrix()->_positive_negative_transpose_barcode(pivot1, pivot2);
393
+ }
394
+ _swap_positions(pivot1, pivot2);
395
+ return columnIndex1;
396
+ }
397
+ return _positive_negative_vine_swap(columnIndex1, columnIndex2);
398
+ }
399
+
400
+ if (_matrix()->is_zero_entry(columnIndex2, _matrix()->get_pivot(columnIndex1))) {
401
+ ID_index pivot1 = _matrix()->get_pivot(columnIndex1);
402
+ ID_index pivot2 = _matrix()->get_pivot(columnIndex2);
403
+ if constexpr (Master_matrix::Option_list::has_column_pairings) {
404
+ _matrix()->_positive_transpose_barcode(pivot1, pivot2);
405
+ }
406
+ _swap_positions(pivot1, pivot2);
407
+ return columnIndex1;
408
+ }
409
+ return _positive_vine_swap(columnIndex1, columnIndex2);
410
+ }
411
+
412
+ template <class Master_matrix>
413
+ inline bool Chain_vine_swap<Master_matrix>::_is_negative_in_pair(Index columnIndex)
414
+ {
415
+ if constexpr (Master_matrix::Option_list::has_column_pairings) {
416
+ return _matrix()->_is_negative_in_bar(_matrix()->get_pivot(columnIndex));
417
+ } else {
418
+ auto& col = _matrix()->get_column(columnIndex);
419
+ if (!col.is_paired()) return false;
420
+ return col.get_pivot() > _matrix()->get_pivot(col.get_paired_chain_index());
421
+ }
422
+ }
423
+
424
+ template <class Master_matrix>
425
+ inline typename Chain_vine_swap<Master_matrix>::Index Chain_vine_swap<Master_matrix>::_positive_vine_swap(
426
+ Index columnIndex1,
427
+ Index columnIndex2)
428
+ {
429
+ auto& col1 = _matrix()->get_column(columnIndex1);
430
+ auto& col2 = _matrix()->get_column(columnIndex2);
431
+
432
+ _swap_positions(col1.get_pivot(), col2.get_pivot());
433
+ // TODO: factorize the cases
434
+ // But for debug it is much more easier to understand what is happening when split like this
435
+ if (!col1.is_paired()) { // F x *
436
+ bool hasSmallerBirth;
437
+ if constexpr (Master_matrix::Option_list::has_column_pairings) {
438
+ // this order because position were swapped with swap_positions
439
+ hasSmallerBirth = (_matrix()->_birth_val(col2.get_pivot()) < _matrix()->_birth_val(col1.get_pivot()));
440
+ } else {
441
+ hasSmallerBirth = birthComp_(columnIndex1, columnIndex2);
442
+ }
443
+
444
+ if (!col2.is_paired() && hasSmallerBirth) {
445
+ _matrix()->add_to(columnIndex1, columnIndex2);
446
+ if constexpr (Master_matrix::Option_list::has_column_pairings) {
447
+ _matrix()->_positive_transpose_barcode(col1.get_pivot(), col2.get_pivot());
448
+ }
449
+ return columnIndex1;
450
+ }
451
+ _matrix()->add_to(columnIndex2, columnIndex1);
452
+
453
+ return columnIndex2;
454
+ }
455
+
456
+ if (!col2.is_paired()) { // G x F
457
+ static_cast<Master_chain_matrix*>(this)->add_to(columnIndex1, columnIndex2);
458
+ if constexpr (Master_matrix::Option_list::has_column_pairings) {
459
+ _matrix()->_positive_transpose_barcode(col1.get_pivot(), col2.get_pivot());
460
+ }
461
+ return columnIndex1;
462
+ }
463
+
464
+ bool hasSmallerDeath;
465
+ if constexpr (Master_matrix::Option_list::has_column_pairings) {
466
+ // this order because position were swapped with swap_positions
467
+ hasSmallerDeath = (_matrix()->_death_val(col2.get_pivot()) < _matrix()->_death_val(col1.get_pivot()));
468
+ } else {
469
+ hasSmallerDeath = deathComp_(columnIndex1, columnIndex2);
470
+ }
471
+
472
+ // G x G
473
+ if (hasSmallerDeath) {
474
+ _matrix()->add_to(col1.get_paired_chain_index(), col2.get_paired_chain_index());
475
+ _matrix()->add_to(columnIndex1, columnIndex2);
476
+ if constexpr (Master_matrix::Option_list::has_column_pairings) {
477
+ _matrix()->_positive_transpose_barcode(col1.get_pivot(), col2.get_pivot());
478
+ }
479
+ return columnIndex1;
480
+ }
481
+
482
+ _matrix()->add_to(col2.get_paired_chain_index(), col1.get_paired_chain_index());
483
+ _matrix()->add_to(columnIndex2, columnIndex1);
484
+
485
+ return columnIndex2;
486
+ }
487
+
488
+ template <class Master_matrix>
489
+ inline typename Chain_vine_swap<Master_matrix>::Index Chain_vine_swap<Master_matrix>::_positive_negative_vine_swap(
490
+ Index columnIndex1,
491
+ Index columnIndex2)
492
+ {
493
+ _matrix()->add_to(columnIndex1, columnIndex2);
494
+
495
+ ID_index pivot1 = _matrix()->get_pivot(columnIndex1);
496
+ ID_index pivot2 = _matrix()->get_pivot(columnIndex2);
497
+ if constexpr (Master_matrix::Option_list::has_column_pairings) {
498
+ _matrix()->_positive_negative_transpose_barcode(pivot1, pivot2);
499
+ }
500
+ _swap_positions(pivot1, pivot2);
501
+
502
+ return columnIndex1;
503
+ }
504
+
505
+ template <class Master_matrix>
506
+ inline typename Chain_vine_swap<Master_matrix>::Index Chain_vine_swap<Master_matrix>::_negative_positive_vine_swap(
507
+ Index columnIndex1,
508
+ Index columnIndex2)
509
+ {
510
+ _matrix()->add_to(columnIndex2, columnIndex1);
511
+
512
+ _swap_positions(_matrix()->get_pivot(columnIndex1), _matrix()->get_pivot(columnIndex2));
513
+
514
+ return columnIndex2;
515
+ }
516
+
517
+ template <class Master_matrix>
518
+ inline typename Chain_vine_swap<Master_matrix>::Index Chain_vine_swap<Master_matrix>::_negative_vine_swap(
519
+ Index columnIndex1,
520
+ Index columnIndex2)
521
+ {
522
+ auto& col1 = _matrix()->get_column(columnIndex1);
523
+ auto& col2 = _matrix()->get_column(columnIndex2);
524
+
525
+ Index pairedIndex1 = col1.get_paired_chain_index();
526
+ Index pairedIndex2 = col2.get_paired_chain_index();
527
+
528
+ bool hasSmallerBirth;
529
+ if constexpr (Master_matrix::Option_list::has_column_pairings) {
530
+ hasSmallerBirth = (_matrix()->_birth_val(col1.get_pivot()) < _matrix()->_birth_val(col2.get_pivot()));
531
+ } else {
532
+ hasSmallerBirth = birthComp_(pairedIndex1, pairedIndex2);
533
+ }
534
+
535
+ _swap_positions(col1.get_pivot(), col2.get_pivot());
536
+
537
+ if (hasSmallerBirth) {
538
+ _matrix()->add_to(pairedIndex1, pairedIndex2);
539
+ _matrix()->add_to(columnIndex1, columnIndex2);
540
+
541
+ if constexpr (Master_matrix::Option_list::has_column_pairings) {
542
+ _matrix()->_negative_transpose_barcode(col1.get_pivot(), col2.get_pivot());
543
+ }
544
+
545
+ return columnIndex1;
546
+ }
547
+
548
+ _matrix()->add_to(pairedIndex2, pairedIndex1);
549
+ _matrix()->add_to(columnIndex2, columnIndex1);
550
+
551
+ return columnIndex2;
552
+ }
553
+
554
+ template <class Master_matrix>
555
+ inline void Chain_vine_swap<Master_matrix>::_swap_positions(ID_index pivot1, ID_index pivot2)
556
+ {
557
+ if constexpr (Master_matrix::Option_list::has_column_pairings ||
558
+ Master_matrix::Option_list::can_retrieve_representative_cycles) {
559
+ auto& map = _matrix()->map_;
560
+ if constexpr (Master_matrix::Option_list::has_map_column_container) {
561
+ std::swap(map.at(pivot1), map.at(pivot2));
562
+ } else {
563
+ std::swap(map[pivot1], map[pivot2]);
564
+ }
565
+ }
566
+ }
567
+
568
+ } // namespace persistence_matrix
569
+ } // namespace Gudhi
570
+
571
+ #endif // PM_CHAIN_VINE_SWAP_H