multipers 2.3.3b6__cp310-cp310-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.

Potentially problematic release.


This version of multipers might be problematic. Click here for more details.

Files changed (183) hide show
  1. multipers/.dylibs/libc++.1.0.dylib +0 -0
  2. multipers/.dylibs/libtbb.12.16.dylib +0 -0
  3. multipers/__init__.py +33 -0
  4. multipers/_signed_measure_meta.py +453 -0
  5. multipers/_slicer_meta.py +211 -0
  6. multipers/array_api/__init__.py +45 -0
  7. multipers/array_api/numpy.py +41 -0
  8. multipers/array_api/torch.py +58 -0
  9. multipers/data/MOL2.py +458 -0
  10. multipers/data/UCR.py +18 -0
  11. multipers/data/__init__.py +1 -0
  12. multipers/data/graphs.py +466 -0
  13. multipers/data/immuno_regions.py +27 -0
  14. multipers/data/minimal_presentation_to_st_bf.py +0 -0
  15. multipers/data/pytorch2simplextree.py +91 -0
  16. multipers/data/shape3d.py +101 -0
  17. multipers/data/synthetic.py +113 -0
  18. multipers/distances.py +202 -0
  19. multipers/filtration_conversions.pxd +229 -0
  20. multipers/filtration_conversions.pxd.tp +84 -0
  21. multipers/filtrations/__init__.py +18 -0
  22. multipers/filtrations/density.py +574 -0
  23. multipers/filtrations/filtrations.py +361 -0
  24. multipers/filtrations.pxd +224 -0
  25. multipers/function_rips.cpython-310-darwin.so +0 -0
  26. multipers/function_rips.pyx +105 -0
  27. multipers/grids.cpython-310-darwin.so +0 -0
  28. multipers/grids.pyx +433 -0
  29. multipers/gudhi/Persistence_slices_interface.h +132 -0
  30. multipers/gudhi/Simplex_tree_interface.h +239 -0
  31. multipers/gudhi/Simplex_tree_multi_interface.h +551 -0
  32. multipers/gudhi/cubical_to_boundary.h +59 -0
  33. multipers/gudhi/gudhi/Bitmap_cubical_complex.h +450 -0
  34. multipers/gudhi/gudhi/Bitmap_cubical_complex_base.h +1070 -0
  35. multipers/gudhi/gudhi/Bitmap_cubical_complex_periodic_boundary_conditions_base.h +579 -0
  36. multipers/gudhi/gudhi/Debug_utils.h +45 -0
  37. multipers/gudhi/gudhi/Fields/Multi_field.h +484 -0
  38. multipers/gudhi/gudhi/Fields/Multi_field_operators.h +455 -0
  39. multipers/gudhi/gudhi/Fields/Multi_field_shared.h +450 -0
  40. multipers/gudhi/gudhi/Fields/Multi_field_small.h +531 -0
  41. multipers/gudhi/gudhi/Fields/Multi_field_small_operators.h +507 -0
  42. multipers/gudhi/gudhi/Fields/Multi_field_small_shared.h +531 -0
  43. multipers/gudhi/gudhi/Fields/Z2_field.h +355 -0
  44. multipers/gudhi/gudhi/Fields/Z2_field_operators.h +376 -0
  45. multipers/gudhi/gudhi/Fields/Zp_field.h +420 -0
  46. multipers/gudhi/gudhi/Fields/Zp_field_operators.h +400 -0
  47. multipers/gudhi/gudhi/Fields/Zp_field_shared.h +418 -0
  48. multipers/gudhi/gudhi/Flag_complex_edge_collapser.h +337 -0
  49. multipers/gudhi/gudhi/Matrix.h +2107 -0
  50. multipers/gudhi/gudhi/Multi_critical_filtration.h +1038 -0
  51. multipers/gudhi/gudhi/Multi_persistence/Box.h +174 -0
  52. multipers/gudhi/gudhi/Multi_persistence/Line.h +282 -0
  53. multipers/gudhi/gudhi/Off_reader.h +173 -0
  54. multipers/gudhi/gudhi/One_critical_filtration.h +1441 -0
  55. multipers/gudhi/gudhi/Persistence_matrix/Base_matrix.h +769 -0
  56. multipers/gudhi/gudhi/Persistence_matrix/Base_matrix_with_column_compression.h +686 -0
  57. multipers/gudhi/gudhi/Persistence_matrix/Boundary_matrix.h +842 -0
  58. multipers/gudhi/gudhi/Persistence_matrix/Chain_matrix.h +1350 -0
  59. multipers/gudhi/gudhi/Persistence_matrix/Id_to_index_overlay.h +1105 -0
  60. multipers/gudhi/gudhi/Persistence_matrix/Position_to_index_overlay.h +859 -0
  61. multipers/gudhi/gudhi/Persistence_matrix/RU_matrix.h +910 -0
  62. multipers/gudhi/gudhi/Persistence_matrix/allocators/entry_constructors.h +139 -0
  63. multipers/gudhi/gudhi/Persistence_matrix/base_pairing.h +230 -0
  64. multipers/gudhi/gudhi/Persistence_matrix/base_swap.h +211 -0
  65. multipers/gudhi/gudhi/Persistence_matrix/boundary_cell_position_to_id_mapper.h +60 -0
  66. multipers/gudhi/gudhi/Persistence_matrix/boundary_face_position_to_id_mapper.h +60 -0
  67. multipers/gudhi/gudhi/Persistence_matrix/chain_pairing.h +136 -0
  68. multipers/gudhi/gudhi/Persistence_matrix/chain_rep_cycles.h +190 -0
  69. multipers/gudhi/gudhi/Persistence_matrix/chain_vine_swap.h +616 -0
  70. multipers/gudhi/gudhi/Persistence_matrix/columns/chain_column_extra_properties.h +150 -0
  71. multipers/gudhi/gudhi/Persistence_matrix/columns/column_dimension_holder.h +106 -0
  72. multipers/gudhi/gudhi/Persistence_matrix/columns/column_utilities.h +219 -0
  73. multipers/gudhi/gudhi/Persistence_matrix/columns/entry_types.h +327 -0
  74. multipers/gudhi/gudhi/Persistence_matrix/columns/heap_column.h +1140 -0
  75. multipers/gudhi/gudhi/Persistence_matrix/columns/intrusive_list_column.h +934 -0
  76. multipers/gudhi/gudhi/Persistence_matrix/columns/intrusive_set_column.h +934 -0
  77. multipers/gudhi/gudhi/Persistence_matrix/columns/list_column.h +980 -0
  78. multipers/gudhi/gudhi/Persistence_matrix/columns/naive_vector_column.h +1092 -0
  79. multipers/gudhi/gudhi/Persistence_matrix/columns/row_access.h +192 -0
  80. multipers/gudhi/gudhi/Persistence_matrix/columns/set_column.h +921 -0
  81. multipers/gudhi/gudhi/Persistence_matrix/columns/small_vector_column.h +1093 -0
  82. multipers/gudhi/gudhi/Persistence_matrix/columns/unordered_set_column.h +1012 -0
  83. multipers/gudhi/gudhi/Persistence_matrix/columns/vector_column.h +1244 -0
  84. multipers/gudhi/gudhi/Persistence_matrix/matrix_dimension_holders.h +186 -0
  85. multipers/gudhi/gudhi/Persistence_matrix/matrix_row_access.h +164 -0
  86. multipers/gudhi/gudhi/Persistence_matrix/ru_pairing.h +156 -0
  87. multipers/gudhi/gudhi/Persistence_matrix/ru_rep_cycles.h +376 -0
  88. multipers/gudhi/gudhi/Persistence_matrix/ru_vine_swap.h +540 -0
  89. multipers/gudhi/gudhi/Persistent_cohomology/Field_Zp.h +118 -0
  90. multipers/gudhi/gudhi/Persistent_cohomology/Multi_field.h +173 -0
  91. multipers/gudhi/gudhi/Persistent_cohomology/Persistent_cohomology_column.h +128 -0
  92. multipers/gudhi/gudhi/Persistent_cohomology.h +745 -0
  93. multipers/gudhi/gudhi/Points_off_io.h +171 -0
  94. multipers/gudhi/gudhi/Simple_object_pool.h +69 -0
  95. multipers/gudhi/gudhi/Simplex_tree/Simplex_tree_iterators.h +463 -0
  96. multipers/gudhi/gudhi/Simplex_tree/Simplex_tree_node_explicit_storage.h +83 -0
  97. multipers/gudhi/gudhi/Simplex_tree/Simplex_tree_siblings.h +106 -0
  98. multipers/gudhi/gudhi/Simplex_tree/Simplex_tree_star_simplex_iterators.h +277 -0
  99. multipers/gudhi/gudhi/Simplex_tree/hooks_simplex_base.h +62 -0
  100. multipers/gudhi/gudhi/Simplex_tree/indexing_tag.h +27 -0
  101. multipers/gudhi/gudhi/Simplex_tree/serialization_utils.h +62 -0
  102. multipers/gudhi/gudhi/Simplex_tree/simplex_tree_options.h +157 -0
  103. multipers/gudhi/gudhi/Simplex_tree.h +2794 -0
  104. multipers/gudhi/gudhi/Simplex_tree_multi.h +152 -0
  105. multipers/gudhi/gudhi/distance_functions.h +62 -0
  106. multipers/gudhi/gudhi/graph_simplicial_complex.h +104 -0
  107. multipers/gudhi/gudhi/persistence_interval.h +253 -0
  108. multipers/gudhi/gudhi/persistence_matrix_options.h +170 -0
  109. multipers/gudhi/gudhi/reader_utils.h +367 -0
  110. multipers/gudhi/mma_interface_coh.h +256 -0
  111. multipers/gudhi/mma_interface_h0.h +223 -0
  112. multipers/gudhi/mma_interface_matrix.h +293 -0
  113. multipers/gudhi/naive_merge_tree.h +536 -0
  114. multipers/gudhi/scc_io.h +310 -0
  115. multipers/gudhi/truc.h +1403 -0
  116. multipers/io.cpython-310-darwin.so +0 -0
  117. multipers/io.pyx +644 -0
  118. multipers/ml/__init__.py +0 -0
  119. multipers/ml/accuracies.py +90 -0
  120. multipers/ml/invariants_with_persistable.py +79 -0
  121. multipers/ml/kernels.py +176 -0
  122. multipers/ml/mma.py +713 -0
  123. multipers/ml/one.py +472 -0
  124. multipers/ml/point_clouds.py +352 -0
  125. multipers/ml/signed_measures.py +1589 -0
  126. multipers/ml/sliced_wasserstein.py +461 -0
  127. multipers/ml/tools.py +113 -0
  128. multipers/mma_structures.cpython-310-darwin.so +0 -0
  129. multipers/mma_structures.pxd +128 -0
  130. multipers/mma_structures.pyx +2786 -0
  131. multipers/mma_structures.pyx.tp +1094 -0
  132. multipers/multi_parameter_rank_invariant/diff_helpers.h +84 -0
  133. multipers/multi_parameter_rank_invariant/euler_characteristic.h +97 -0
  134. multipers/multi_parameter_rank_invariant/function_rips.h +322 -0
  135. multipers/multi_parameter_rank_invariant/hilbert_function.h +769 -0
  136. multipers/multi_parameter_rank_invariant/persistence_slices.h +148 -0
  137. multipers/multi_parameter_rank_invariant/rank_invariant.h +369 -0
  138. multipers/multiparameter_edge_collapse.py +41 -0
  139. multipers/multiparameter_module_approximation/approximation.h +2330 -0
  140. multipers/multiparameter_module_approximation/combinatory.h +129 -0
  141. multipers/multiparameter_module_approximation/debug.h +107 -0
  142. multipers/multiparameter_module_approximation/euler_curves.h +0 -0
  143. multipers/multiparameter_module_approximation/format_python-cpp.h +286 -0
  144. multipers/multiparameter_module_approximation/heap_column.h +238 -0
  145. multipers/multiparameter_module_approximation/images.h +79 -0
  146. multipers/multiparameter_module_approximation/list_column.h +174 -0
  147. multipers/multiparameter_module_approximation/list_column_2.h +232 -0
  148. multipers/multiparameter_module_approximation/ru_matrix.h +347 -0
  149. multipers/multiparameter_module_approximation/set_column.h +135 -0
  150. multipers/multiparameter_module_approximation/structure_higher_dim_barcode.h +36 -0
  151. multipers/multiparameter_module_approximation/unordered_set_column.h +166 -0
  152. multipers/multiparameter_module_approximation/utilities.h +403 -0
  153. multipers/multiparameter_module_approximation/vector_column.h +223 -0
  154. multipers/multiparameter_module_approximation/vector_matrix.h +331 -0
  155. multipers/multiparameter_module_approximation/vineyards.h +464 -0
  156. multipers/multiparameter_module_approximation/vineyards_trajectories.h +649 -0
  157. multipers/multiparameter_module_approximation.cpython-310-darwin.so +0 -0
  158. multipers/multiparameter_module_approximation.pyx +235 -0
  159. multipers/pickle.py +90 -0
  160. multipers/plots.py +456 -0
  161. multipers/point_measure.cpython-310-darwin.so +0 -0
  162. multipers/point_measure.pyx +395 -0
  163. multipers/simplex_tree_multi.cpython-310-darwin.so +0 -0
  164. multipers/simplex_tree_multi.pxd +134 -0
  165. multipers/simplex_tree_multi.pyx +10840 -0
  166. multipers/simplex_tree_multi.pyx.tp +2009 -0
  167. multipers/slicer.cpython-310-darwin.so +0 -0
  168. multipers/slicer.pxd +3034 -0
  169. multipers/slicer.pxd.tp +234 -0
  170. multipers/slicer.pyx +20481 -0
  171. multipers/slicer.pyx.tp +1088 -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 +62 -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-2.3.3b6.dist-info/METADATA +128 -0
  180. multipers-2.3.3b6.dist-info/RECORD +183 -0
  181. multipers-2.3.3b6.dist-info/WHEEL +6 -0
  182. multipers-2.3.3b6.dist-info/licenses/LICENSE +21 -0
  183. multipers-2.3.3b6.dist-info/top_level.txt +1 -0
@@ -0,0 +1,616 @@
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 <utility> //std::swap & std::move
24
+ #include <cassert>
25
+ #include <functional> //std::function
26
+ #include <stdexcept> //std::invalid_argument
27
+
28
+ #include "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
+ {
57
+ friend void swap([[maybe_unused]] Dummy_chain_vine_swap& d1, [[maybe_unused]] Dummy_chain_vine_swap& d2) {}
58
+
59
+ Dummy_chain_vine_swap() {}
60
+ template <typename BirthComparatorFunction, typename DeathComparatorFunction>
61
+ Dummy_chain_vine_swap([[maybe_unused]] const BirthComparatorFunction& birthComparator,
62
+ [[maybe_unused]] const DeathComparatorFunction& deathComparator) {}
63
+ };
64
+
65
+ /**
66
+ * @ingroup persistence_matrix
67
+ *
68
+ * @brief Empty structure.
69
+ * Inherited instead of @ref Chain_barcode_swap, when the barcode is not stored.
70
+ */
71
+ struct Dummy_chain_vine_pairing
72
+ {
73
+ friend void swap([[maybe_unused]] Dummy_chain_vine_pairing& d1, [[maybe_unused]] Dummy_chain_vine_pairing& d2) {}
74
+ };
75
+
76
+ /**
77
+ * @ingroup persistence_matrix
78
+ *
79
+ * @brief Class managing the barcode for @ref Chain_vine_swap.
80
+ *
81
+ * @tparam Master_matrix An instantiation of @ref Matrix from which all types and options are deduced.
82
+ */
83
+ template <typename Master_matrix>
84
+ class Chain_barcode_swap : public Chain_pairing<Master_matrix>
85
+ {
86
+ public:
87
+ using ID_index = typename Master_matrix::ID_index; /**< @ref IDIdx index type. */
88
+ using Pos_index = typename Master_matrix::Pos_index; /**< @ref PosIdx index type. */
89
+ //CP = Chain Pairing
90
+ using CP = Chain_pairing<Master_matrix>;
91
+
92
+ /**
93
+ * @brief Default constructor.
94
+ */
95
+ Chain_barcode_swap(){};
96
+ /**
97
+ * @brief Copy constructor.
98
+ *
99
+ * @param toCopy Matrix to copy.
100
+ */
101
+ Chain_barcode_swap(const Chain_barcode_swap& toCopy)
102
+ : CP(static_cast<const CP&>(toCopy)), pivotToPosition_(toCopy.pivotToPosition_){};
103
+ /**
104
+ * @brief Move constructor.
105
+ *
106
+ * @param other Matrix to move.
107
+ */
108
+ Chain_barcode_swap(Chain_barcode_swap&& other)
109
+ : CP(std::move(static_cast<CP&>(other))), pivotToPosition_(std::move(other.pivotToPosition_)){};
110
+
111
+ protected:
112
+ using Dictionary = typename Master_matrix::template Dictionary<Pos_index>;
113
+
114
+ Dictionary pivotToPosition_; // necessary to keep track of the barcode changes
115
+
116
+ void swap_positions(ID_index pivot1, ID_index pivot2) {
117
+ if constexpr (Master_matrix::Option_list::has_map_column_container) {
118
+ std::swap(pivotToPosition_.at(pivot1), pivotToPosition_.at(pivot2));
119
+ } else {
120
+ std::swap(pivotToPosition_[pivot1], pivotToPosition_[pivot2]);
121
+ }
122
+ }
123
+
124
+ bool is_negative_in_pair(ID_index pivot) const {
125
+ Pos_index pos = _get_pivot_position(pivot);
126
+ return death(pivot) == pos;
127
+ }
128
+
129
+ void positive_transpose(ID_index pivot1, ID_index pivot2) {
130
+ Pos_index pos1 = _get_pivot_position(pivot1);
131
+ Pos_index pos2 = _get_pivot_position(pivot2);
132
+
133
+ _birth(pos1) = pos2;
134
+ _birth(pos2) = pos1;
135
+ std::swap(CP::indexToBar_.at(pos1), CP::indexToBar_.at(pos2));
136
+ }
137
+
138
+ void negative_transpose(ID_index pivot1, ID_index pivot2) {
139
+ Pos_index pos1 = _get_pivot_position(pivot1);
140
+ Pos_index pos2 = _get_pivot_position(pivot2);
141
+
142
+ _death(pos1) = pos2;
143
+ _death(pos2) = pos1;
144
+ std::swap(CP::indexToBar_.at(pos1), CP::indexToBar_.at(pos2));
145
+ }
146
+
147
+ void positive_negative_transpose(ID_index pivot1, ID_index pivot2) {
148
+ Pos_index pos1 = _get_pivot_position(pivot1);
149
+ Pos_index pos2 = _get_pivot_position(pivot2);
150
+
151
+ _birth(pos1) = pos2;
152
+ _death(pos2) = pos1;
153
+ std::swap(CP::indexToBar_.at(pos1), CP::indexToBar_.at(pos2));
154
+ }
155
+
156
+ void negative_positive_transpose(ID_index pivot1, ID_index pivot2) {
157
+ Pos_index pos1 = _get_pivot_position(pivot1);
158
+ Pos_index pos2 = _get_pivot_position(pivot2);
159
+
160
+ _death(pos1) = pos2;
161
+ _birth(pos2) = pos1;
162
+ std::swap(CP::indexToBar_.at(pos1), CP::indexToBar_.at(pos2));
163
+ }
164
+
165
+ bool are_adjacent(ID_index pivot1, ID_index pivot2) const {
166
+ Pos_index pos1 = _get_pivot_position(pivot1);
167
+ Pos_index pos2 = _get_pivot_position(pivot2);
168
+ return pos1 < pos2 ? (pos2 - pos1) == 1 : (pos1 - pos2) == 1;
169
+ }
170
+
171
+ Chain_barcode_swap& operator=(Chain_barcode_swap other) {
172
+ Chain_pairing<Master_matrix>::operator=(other);
173
+ pivotToPosition_.swap(other.pivotToPosition_);
174
+ }
175
+ friend void swap(Chain_barcode_swap& swap1, Chain_barcode_swap& swap2) {
176
+ swap(static_cast<Chain_pairing<Master_matrix>&>(swap1), static_cast<Chain_pairing<Master_matrix>&>(swap2));
177
+ swap1.pivotToPosition_.swap(swap2.pivotToPosition_);
178
+ }
179
+
180
+ Pos_index death(ID_index pivot) const {
181
+ Pos_index simplexIndex = _get_pivot_position(pivot);
182
+
183
+ if constexpr (Master_matrix::Option_list::has_removable_columns) {
184
+ return CP::indexToBar_.at(simplexIndex)->death;
185
+ } else {
186
+ return CP::barcode_.at(CP::indexToBar_.at(simplexIndex)).death;
187
+ }
188
+ }
189
+
190
+ Pos_index birth(ID_index pivot) const {
191
+ Pos_index simplexIndex = _get_pivot_position(pivot);
192
+
193
+ if constexpr (Master_matrix::Option_list::has_removable_columns) {
194
+ return CP::indexToBar_.at(simplexIndex)->birth;
195
+ } else {
196
+ return CP::barcode_.at(CP::indexToBar_.at(simplexIndex)).birth;
197
+ }
198
+ }
199
+
200
+ private:
201
+ Pos_index _get_pivot_position(ID_index pivot) const {
202
+ if constexpr (Master_matrix::Option_list::has_map_column_container) {
203
+ return pivotToPosition_.at(
204
+ pivot); // quite often called, make public and pass position instead of pivot to avoid find() every time?
205
+ } else {
206
+ return pivotToPosition_[pivot];
207
+ }
208
+ }
209
+
210
+ Pos_index& _death(Pos_index simplexIndex) {
211
+ if constexpr (Master_matrix::Option_list::has_removable_columns) {
212
+ return CP::indexToBar_.at(simplexIndex)->death;
213
+ } else {
214
+ return CP::barcode_.at(CP::indexToBar_.at(simplexIndex)).death;
215
+ }
216
+ }
217
+
218
+ Pos_index& _birth(Pos_index simplexIndex) {
219
+ if constexpr (Master_matrix::Option_list::has_removable_columns) {
220
+ return CP::indexToBar_.at(simplexIndex)->birth;
221
+ } else {
222
+ return CP::barcode_.at(CP::indexToBar_.at(simplexIndex)).birth;
223
+ }
224
+ }
225
+ };
226
+
227
+ /**
228
+ * @class Chain_vine_swap chain_vine_swap.h gudhi/Persistence_matrix/chain_vine_swap.h
229
+ * @ingroup persistence_matrix
230
+ *
231
+ * @brief Class managing the vine swaps for @ref Chain_matrix.
232
+ *
233
+ * @tparam Master_matrix An instantiation of @ref Matrix from which all types and options are deduced.
234
+ */
235
+ template <class Master_matrix>
236
+ class Chain_vine_swap : public std::conditional<Master_matrix::Option_list::has_column_pairings,
237
+ Chain_barcode_swap<Master_matrix>,
238
+ Dummy_chain_vine_pairing
239
+ >::type
240
+ {
241
+ public:
242
+ using Index = typename Master_matrix::Index; /**< @ref MatIdx index type. */
243
+ using ID_index = typename Master_matrix::ID_index; /**< @ref IDIdx index type. */
244
+ using Pos_index = typename Master_matrix::Pos_index; /**< @ref PosIdx index type. */
245
+ using Column_container = typename Master_matrix::Column_container; /**< Column container type. */
246
+ using Column = typename Master_matrix::Column; /**< Column type. */
247
+ typedef bool (*EventCompFuncPointer)(Pos_index, Pos_index); /**< Pointer type for birth/death comparators. */
248
+
249
+ /**
250
+ * @brief Default constructor. Only available if @ref PersistenceMatrixOptions::has_column_pairings is true.
251
+ */
252
+ Chain_vine_swap();
253
+ /**
254
+ * @brief Constructor storing the given comparators.
255
+ *
256
+ * @param birthComparator Method taking two @ref PosIdx indices as input and returning true if and only if
257
+ * the birth associated to the first position is strictly less than birth associated to
258
+ * the second one with respect to some self defined order. It is used while swapping two unpaired or
259
+ * two negative columns.
260
+ * @param deathComparator Method taking two @ref PosIdx indices as input and returning true if and only if
261
+ * the death associated to the first position is strictly less than death associated to
262
+ * the second one with respect to some self defined order. It is used while swapping two positive but paired
263
+ * columns. Default value: @ref _no_G_death_comparator.
264
+ */
265
+ Chain_vine_swap(std::function<bool(Pos_index,Pos_index)> birthComparator,
266
+ std::function<bool(Pos_index,Pos_index)> deathComparator = _no_G_death_comparator);
267
+ /**
268
+ * @brief Copy constructor.
269
+ *
270
+ * @param matrixToCopy Matrix to copy.
271
+ */
272
+ Chain_vine_swap(const Chain_vine_swap& matrixToCopy);
273
+ /**
274
+ * @brief Move constructor.
275
+ *
276
+ * @param other Matrix to move.
277
+ */
278
+ Chain_vine_swap(Chain_vine_swap&& other) noexcept;
279
+
280
+ /**
281
+ * @brief Does the same than @ref vine_swap, but assumes that the swap is non trivial and
282
+ * therefore skips a part of the case study.
283
+ *
284
+ * @param columnIndex1 @ref MatIdx index of the first cell.
285
+ * @param columnIndex2 @ref MatIdx index of the second cell.
286
+ * @return Let \f$ pos1 \f$ be the @ref PosIdx index of @p columnIndex1 and \f$ pos2 \f$ be the @ref PosIdx index of
287
+ * @p columnIndex2. The method returns the @ref MatIdx of the column which has now, after the swap, the @ref PosIdx
288
+ * \f$ max(pos1, pos2) \f$.
289
+ */
290
+ Index vine_swap_with_z_eq_1_case(Index columnIndex1, Index columnIndex2);
291
+ /**
292
+ * @brief Does a vine swap between two cells which are consecutive in the filtration. Roughly, if \f$ F \f$ is
293
+ * the current filtration represented by the matrix, the method modifies the matrix such that the new state
294
+ * corresponds to a valid state for the filtration \f$ F' \f$ equal to \f$ F \f$ but with the two given cells
295
+ * at swapped positions. Of course, the two cells should not have a face/coface relation which each other ;
296
+ * \f$ F' \f$ has to be a valid filtration.
297
+ * See @cite vineyards for more information about vine and vineyards.
298
+ *
299
+ * @param columnIndex1 @ref MatIdx index of the first cell.
300
+ * @param columnIndex2 @ref MatIdx index of the second cell. It is assumed that the @ref PosIdx of both only differs
301
+ * by one if the barcode is maintained.
302
+ * @return Let \f$ pos1 \f$ be the @ref PosIdx index of @p columnIndex1 and \f$ pos2 \f$ be the @ref PosIdx index of
303
+ * @p columnIndex2. The method returns the @ref MatIdx of the column which has now, after the swap, the @ref PosIdx
304
+ * \f$ max(pos1, pos2) \f$.
305
+ */
306
+ Index vine_swap(Index columnIndex1, Index columnIndex2);
307
+
308
+ /**
309
+ * @brief Assign operator.
310
+ */
311
+ Chain_vine_swap& operator=(Chain_vine_swap other);
312
+ /**
313
+ * @brief Swap operator.
314
+ */
315
+ friend void swap(Chain_vine_swap& swap1, Chain_vine_swap& swap2) {
316
+ if constexpr (Master_matrix::Option_list::has_column_pairings) {
317
+ swap(static_cast<Chain_barcode_swap<Master_matrix>&>(swap1),
318
+ static_cast<Chain_barcode_swap<Master_matrix>&>(swap2));
319
+ }
320
+ std::swap(swap1.birthComp_, swap2.birthComp_);
321
+ std::swap(swap1.deathComp_, swap2.deathComp_);
322
+ }
323
+
324
+ protected:
325
+ using CP = typename std::conditional<Master_matrix::Option_list::has_column_pairings,
326
+ Chain_barcode_swap<Master_matrix>,
327
+ Dummy_chain_vine_pairing
328
+ >::type;
329
+
330
+ private:
331
+ using Master_chain_matrix = typename Master_matrix::Master_chain_matrix;
332
+
333
+ std::function<bool(Pos_index,Pos_index)> birthComp_; /**< for F x F & H x H. */
334
+ std::function<bool(Pos_index,Pos_index)> deathComp_; /**< for G x G. */
335
+
336
+ bool _is_negative_in_pair(Index columnIndex);
337
+
338
+ Index _positive_vine_swap(Index columnIndex1, Index columnIndex2);
339
+ Index _positive_negative_vine_swap(Index columnIndex1, Index columnIndex2);
340
+ Index _negative_positive_vine_swap(Index columnIndex1, Index columnIndex2);
341
+ Index _negative_vine_swap(Index columnIndex1, Index columnIndex2);
342
+
343
+ constexpr Master_chain_matrix* _matrix() { return static_cast<Master_chain_matrix*>(this); }
344
+ constexpr const Master_chain_matrix* _matrix() const { return static_cast<const Master_chain_matrix*>(this); }
345
+ };
346
+
347
+ template <class Master_matrix>
348
+ inline Chain_vine_swap<Master_matrix>::Chain_vine_swap() : CP(), birthComp_(), deathComp_()
349
+ {
350
+ static_assert(Master_matrix::Option_list::has_column_pairings,
351
+ "If barcode is not stored, at least a birth comparator has to be specified.");
352
+ }
353
+
354
+ template <class Master_matrix>
355
+ inline Chain_vine_swap<Master_matrix>::Chain_vine_swap(std::function<bool(Pos_index,Pos_index)> birthComparator,
356
+ std::function<bool(Pos_index,Pos_index)> deathComparator)
357
+ : CP(), birthComp_(std::move(birthComparator)), deathComp_(std::move(deathComparator))
358
+ {}
359
+
360
+ template <class Master_matrix>
361
+ inline Chain_vine_swap<Master_matrix>::Chain_vine_swap(const Chain_vine_swap& matrixToCopy)
362
+ : CP(static_cast<const CP&>(matrixToCopy)),
363
+ birthComp_(matrixToCopy.birthComp_),
364
+ deathComp_(matrixToCopy.deathComp_)
365
+ {}
366
+
367
+ template <class Master_matrix>
368
+ inline Chain_vine_swap<Master_matrix>::Chain_vine_swap(Chain_vine_swap<Master_matrix>&& other) noexcept
369
+ : CP(std::move(static_cast<CP&>(other))),
370
+ birthComp_(std::move(other.birthComp_)),
371
+ deathComp_(std::move(other.deathComp_))
372
+ {}
373
+
374
+ template <class Master_matrix>
375
+ inline typename Chain_vine_swap<Master_matrix>::Index Chain_vine_swap<Master_matrix>::vine_swap_with_z_eq_1_case(
376
+ Index columnIndex1, Index columnIndex2)
377
+ {
378
+ const bool col1IsNeg = _is_negative_in_pair(columnIndex1);
379
+ const bool col2IsNeg = _is_negative_in_pair(columnIndex2);
380
+
381
+ if (col1IsNeg && col2IsNeg) return _negative_vine_swap(columnIndex1, columnIndex2);
382
+
383
+ if (col1IsNeg) return _negative_positive_vine_swap(columnIndex1, columnIndex2);
384
+
385
+ if (col2IsNeg) return _positive_negative_vine_swap(columnIndex1, columnIndex2);
386
+
387
+ return _positive_vine_swap(columnIndex1, columnIndex2);
388
+ }
389
+
390
+ template <class Master_matrix>
391
+ inline typename Chain_vine_swap<Master_matrix>::Index Chain_vine_swap<Master_matrix>::vine_swap(Index columnIndex1,
392
+ Index columnIndex2)
393
+ {
394
+ if constexpr (Master_matrix::Option_list::has_column_pairings) {
395
+ GUDHI_CHECK(CP::are_adjacent(_matrix()->get_pivot(columnIndex1), _matrix()->get_pivot(columnIndex2)),
396
+ std::invalid_argument(
397
+ "Chain_vine_swap::vine_swap - Columns to be swapped need to be adjacent in the 'real' matrix."));
398
+ }
399
+
400
+ const bool col1IsNeg = _is_negative_in_pair(columnIndex1);
401
+ const bool col2IsNeg = _is_negative_in_pair(columnIndex2);
402
+
403
+ if (col1IsNeg && col2IsNeg) {
404
+ if (_matrix()->is_zero_entry(columnIndex2, _matrix()->get_pivot(columnIndex1))) {
405
+ if constexpr (Master_matrix::Option_list::has_column_pairings) {
406
+ ID_index pivot1 = _matrix()->get_pivot(columnIndex1);
407
+ ID_index pivot2 = _matrix()->get_pivot(columnIndex2);
408
+
409
+ CP::negative_transpose(pivot1, pivot2);
410
+ CP::swap_positions(pivot1, pivot2);
411
+ }
412
+ return columnIndex1;
413
+ }
414
+ return _negative_vine_swap(columnIndex1, columnIndex2);
415
+ }
416
+
417
+ if (col1IsNeg) {
418
+ if (_matrix()->is_zero_entry(columnIndex2, _matrix()->get_pivot(columnIndex1))) {
419
+ if constexpr (Master_matrix::Option_list::has_column_pairings) {
420
+ ID_index pivot1 = _matrix()->get_pivot(columnIndex1);
421
+ ID_index pivot2 = _matrix()->get_pivot(columnIndex2);
422
+
423
+ CP::negative_positive_transpose(pivot1, pivot2);
424
+ CP::swap_positions(pivot1, pivot2);
425
+ }
426
+ return columnIndex1;
427
+ }
428
+ return _negative_positive_vine_swap(columnIndex1, columnIndex2);
429
+ }
430
+
431
+ if (col2IsNeg) {
432
+ if (_matrix()->is_zero_entry(columnIndex2, _matrix()->get_pivot(columnIndex1))) {
433
+ if constexpr (Master_matrix::Option_list::has_column_pairings) {
434
+ ID_index pivot1 = _matrix()->get_pivot(columnIndex1);
435
+ ID_index pivot2 = _matrix()->get_pivot(columnIndex2);
436
+
437
+ CP::positive_negative_transpose(pivot1, pivot2);
438
+ CP::swap_positions(pivot1, pivot2);
439
+ }
440
+ return columnIndex1;
441
+ }
442
+ return _positive_negative_vine_swap(columnIndex1, columnIndex2);
443
+ }
444
+
445
+ if (_matrix()->is_zero_entry(columnIndex2, _matrix()->get_pivot(columnIndex1))) {
446
+ if constexpr (Master_matrix::Option_list::has_column_pairings) {
447
+ ID_index pivot1 = _matrix()->get_pivot(columnIndex1);
448
+ ID_index pivot2 = _matrix()->get_pivot(columnIndex2);
449
+
450
+ CP::positive_transpose(pivot1, pivot2);
451
+ CP::swap_positions(pivot1, pivot2);
452
+ }
453
+ return columnIndex1;
454
+ }
455
+ return _positive_vine_swap(columnIndex1, columnIndex2);
456
+ }
457
+
458
+ template <class Master_matrix>
459
+ inline Chain_vine_swap<Master_matrix>& Chain_vine_swap<Master_matrix>::operator=(Chain_vine_swap<Master_matrix> other)
460
+ {
461
+ CP::operator=(other);
462
+ std::swap(birthComp_, other.birthComp_);
463
+ std::swap(deathComp_, other.deathComp_);
464
+ return *this;
465
+ }
466
+
467
+ template <class Master_matrix>
468
+ inline bool Chain_vine_swap<Master_matrix>::_is_negative_in_pair(Index columnIndex)
469
+ {
470
+ if constexpr (Master_matrix::Option_list::has_column_pairings) {
471
+ return CP::is_negative_in_pair(_matrix()->get_pivot(columnIndex));
472
+ } else {
473
+ auto& col = _matrix()->get_column(columnIndex);
474
+ if (!col.is_paired()) return false;
475
+ return col.get_pivot() > _matrix()->get_pivot(col.get_paired_chain_index());
476
+ }
477
+ }
478
+
479
+ template <class Master_matrix>
480
+ inline typename Chain_vine_swap<Master_matrix>::Index Chain_vine_swap<Master_matrix>::_positive_vine_swap(
481
+ Index columnIndex1, Index columnIndex2)
482
+ {
483
+ auto& col1 = _matrix()->get_column(columnIndex1);
484
+ auto& col2 = _matrix()->get_column(columnIndex2);
485
+
486
+ if constexpr (Master_matrix::Option_list::has_column_pairings) {
487
+ CP::swap_positions(col1.get_pivot(), col2.get_pivot());
488
+ }
489
+ // TODO: factorize the cases. But for debug it is much more easier to understand what is happening splitted like this
490
+ if (!col1.is_paired()) { // F x *
491
+ bool hasSmallerBirth;
492
+ if constexpr (Master_matrix::Option_list::has_column_pairings) {
493
+ // this order because position were swapped with CP::swap_positions
494
+ hasSmallerBirth = (CP::birth(col2.get_pivot()) < CP::birth(col1.get_pivot()));
495
+ } else {
496
+ hasSmallerBirth = birthComp_(columnIndex1, columnIndex2);
497
+ }
498
+
499
+ if (!col2.is_paired() && hasSmallerBirth) {
500
+ _matrix()->add_to(columnIndex1, columnIndex2);
501
+ if constexpr (Master_matrix::Option_list::has_column_pairings) {
502
+ CP::positive_transpose(col1.get_pivot(), col2.get_pivot());
503
+ }
504
+ return columnIndex1;
505
+ }
506
+ _matrix()->add_to(columnIndex2, columnIndex1);
507
+
508
+ return columnIndex2;
509
+ }
510
+
511
+ if (!col2.is_paired()) { // G x F
512
+ static_cast<Master_chain_matrix*>(this)->add_to(columnIndex1, columnIndex2);
513
+ if constexpr (Master_matrix::Option_list::has_column_pairings) {
514
+ CP::positive_transpose(col1.get_pivot(), col2.get_pivot());
515
+ }
516
+ return columnIndex1;
517
+ }
518
+
519
+ bool hasSmallerDeath;
520
+ if constexpr (Master_matrix::Option_list::has_column_pairings) {
521
+ // this order because position were swapped with CP::swap_positions
522
+ hasSmallerDeath = (CP::death(col2.get_pivot()) < CP::death(col1.get_pivot()));
523
+ } else {
524
+ hasSmallerDeath = deathComp_(columnIndex1, columnIndex2);
525
+ }
526
+
527
+ // G x G
528
+ if (hasSmallerDeath)
529
+ {
530
+ _matrix()->add_to(col1.get_paired_chain_index(), col2.get_paired_chain_index());
531
+ _matrix()->add_to(columnIndex1, columnIndex2);
532
+ if constexpr (Master_matrix::Option_list::has_column_pairings) {
533
+ CP::positive_transpose(col1.get_pivot(), col2.get_pivot());
534
+ }
535
+ return columnIndex1;
536
+ }
537
+
538
+ _matrix()->add_to(col2.get_paired_chain_index(), col1.get_paired_chain_index());
539
+ _matrix()->add_to(columnIndex2, columnIndex1);
540
+
541
+ return columnIndex2;
542
+ }
543
+
544
+ template <class Master_matrix>
545
+ inline typename Chain_vine_swap<Master_matrix>::Index Chain_vine_swap<Master_matrix>::_positive_negative_vine_swap(
546
+ Index columnIndex1, Index columnIndex2)
547
+ {
548
+ _matrix()->add_to(columnIndex1, columnIndex2);
549
+
550
+ if constexpr (Master_matrix::Option_list::has_column_pairings) {
551
+ ID_index pivot1 = _matrix()->get_pivot(columnIndex1);
552
+ ID_index pivot2 = _matrix()->get_pivot(columnIndex2);
553
+
554
+ CP::positive_negative_transpose(pivot1, pivot2);
555
+ CP::swap_positions(pivot1, pivot2);
556
+ }
557
+
558
+ return columnIndex1;
559
+ }
560
+
561
+ template <class Master_matrix>
562
+ inline typename Chain_vine_swap<Master_matrix>::Index Chain_vine_swap<Master_matrix>::_negative_positive_vine_swap(
563
+ Index columnIndex1, Index columnIndex2)
564
+ {
565
+ _matrix()->add_to(columnIndex2, columnIndex1);
566
+
567
+ if constexpr (Master_matrix::Option_list::has_column_pairings) {
568
+ CP::swap_positions(_matrix()->get_pivot(columnIndex1), _matrix()->get_pivot(columnIndex2));
569
+ }
570
+
571
+ return columnIndex2;
572
+ }
573
+
574
+ template <class Master_matrix>
575
+ inline typename Chain_vine_swap<Master_matrix>::Index Chain_vine_swap<Master_matrix>::_negative_vine_swap(
576
+ Index columnIndex1, Index columnIndex2)
577
+ {
578
+ auto& col1 = _matrix()->get_column(columnIndex1);
579
+ auto& col2 = _matrix()->get_column(columnIndex2);
580
+
581
+ Index pairedIndex1 = col1.get_paired_chain_index();
582
+ Index pairedIndex2 = col2.get_paired_chain_index();
583
+
584
+ bool hasSmallerBirth;
585
+ if constexpr (Master_matrix::Option_list::has_column_pairings) {
586
+ hasSmallerBirth = (CP::birth(col1.get_pivot()) < CP::birth(col2.get_pivot()));
587
+ } else {
588
+ hasSmallerBirth = birthComp_(pairedIndex1, pairedIndex2);
589
+ }
590
+
591
+ if constexpr (Master_matrix::Option_list::has_column_pairings) {
592
+ CP::swap_positions(col1.get_pivot(), col2.get_pivot());
593
+ }
594
+
595
+ if (hasSmallerBirth)
596
+ {
597
+ _matrix()->add_to(pairedIndex1, pairedIndex2);
598
+ _matrix()->add_to(columnIndex1, columnIndex2);
599
+
600
+ if constexpr (Master_matrix::Option_list::has_column_pairings) {
601
+ CP::negative_transpose(col1.get_pivot(), col2.get_pivot());
602
+ }
603
+
604
+ return columnIndex1;
605
+ }
606
+
607
+ _matrix()->add_to(pairedIndex2, pairedIndex1);
608
+ _matrix()->add_to(columnIndex2, columnIndex1);
609
+
610
+ return columnIndex2;
611
+ }
612
+
613
+ } // namespace persistence_matrix
614
+ } // namespace Gudhi
615
+
616
+ #endif // PM_CHAIN_VINE_SWAP_H