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,1157 @@
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 Id_to_index_overlay.h
13
+ * @author Hannah Schreiber
14
+ * @brief Contains the @ref Gudhi::persistence_matrix::Id_to_index_overlay class.
15
+ */
16
+
17
+ #ifndef PM_ID_TO_POS_TRANSLATION_H
18
+ #define PM_ID_TO_POS_TRANSLATION_H
19
+
20
+ #include <cmath>
21
+ #include <vector>
22
+ #include <cassert>
23
+ #include <utility> //std::swap, std::move & std::exchange
24
+ #include <algorithm> //std::transform
25
+ #include <stdexcept> //std::invalid_argument
26
+
27
+ namespace Gudhi {
28
+ namespace persistence_matrix {
29
+
30
+ /**
31
+ * @class Id_to_index_overlay Id_to_index_overlay.h gudhi/Persistence_matrix/Id_to_index_overlay.h
32
+ * @ingroup persistence_matrix
33
+ *
34
+ * @brief Overlay for @ref mp_matrices "non-basic matrices" replacing all input and output @ref MatIdx indices of
35
+ * the original methods with @ref IDIdx indices.
36
+ *
37
+ * @tparam Underlying_matrix %Matrix type taking the overlay.
38
+ * @tparam Master_matrix An instantiation of @ref Matrix from which all types and options are deduced.
39
+ */
40
+ template <class Underlying_matrix, class Master_matrix>
41
+ class Id_to_index_overlay
42
+ {
43
+ public:
44
+ using Index = typename Master_matrix::Index; /**< @ref MatIdx index type. */
45
+ using ID_index = typename Master_matrix::ID_index; /**< @ref IDIdx index type. */
46
+ using Pos_index = typename Master_matrix::Pos_index; /**< @ref PosIdx index type. */
47
+ using Dimension = typename Master_matrix::Dimension; /**< Dimension value type. */
48
+ /**
49
+ * @brief Field operators class. Necessary only if @ref PersistenceMatrixOptions::is_z2 is false.
50
+ */
51
+ using Field_operators = typename Master_matrix::Field_operators;
52
+ using Field_element = typename Master_matrix::Element; /**< Type of an field element. */
53
+ using Boundary = typename Master_matrix::Boundary; /**< Type of an input column. */
54
+ using Column = typename Master_matrix::Column; /**< Column type. */
55
+ using Row = typename Master_matrix::Row; /**< Row type,
56
+ only necessary with row access option. */
57
+ using Bar = typename Master_matrix::Bar; /**< Bar type. */
58
+ using Barcode = typename Master_matrix::Barcode; /**< Barcode type. */
59
+ using Cycle = typename Master_matrix::Cycle; /**< Cycle type. */
60
+ using Entry_constructor = typename Master_matrix::Entry_constructor; /**< Factory of @ref Entry classes. */
61
+ using Column_settings = typename Master_matrix::Column_settings; /**< Structure giving access to the columns to
62
+ necessary external classes. */
63
+
64
+ /**
65
+ * @brief Constructs an empty matrix.
66
+ *
67
+ * @param colSettings Pointer to an existing setting structure for the columns. The structure should contain all
68
+ * the necessary external classes specifically necessary for the chosen column type, such as custom allocators.
69
+ */
70
+ Id_to_index_overlay(Column_settings* colSettings);
71
+ /**
72
+ * @brief Constructs a new matrix from the given ranges of @ref Matrix::Entry_representative. Each range corresponds
73
+ * to a column (the order of the ranges are preserved). The content of the ranges is assumed to be sorted by
74
+ * increasing IDs. The IDs of the simplices are also assumed to be consecutive, ordered by filtration value, starting
75
+ * with 0.
76
+ *
77
+ * @tparam Boundary_range Range type for @ref Matrix::Entry_representative ranges.
78
+ * Assumed to have a begin(), end() and size() method.
79
+ * @param orderedBoundaries Range of boundaries: @p orderedBoundaries is interpreted as a boundary matrix of a
80
+ * filtered **simplicial** complex, whose boundaries are ordered by filtration order.
81
+ * Therefore, `orderedBoundaries[i]` should store the boundary of the \f$ i^{th} \f$ simplex in the filtration,
82
+ * as an ordered list of indices of its facets (again those indices correspond to their respective position
83
+ * in the matrix). That is why the indices of the simplices are assumed to be consecutive and starting with 0
84
+ * (an empty boundary is interpreted as a vertex boundary and not as a non existing simplex).
85
+ * All dimensions up to the maximal dimension of interest have to be present. If only a higher dimension is of
86
+ * interest and not everything should be stored, then use the @ref insert_boundary method instead
87
+ * (after creating the matrix with the @ref Id_to_index_overlay(unsigned int, Column_settings*)
88
+ * constructor preferably).
89
+ * @param colSettings Pointer to an existing setting structure for the columns. The structure should contain all
90
+ * the necessary external classes specifically necessary for the chosen column type, such as custom allocators.
91
+ */
92
+ template <class Boundary_range = Boundary>
93
+ Id_to_index_overlay(const std::vector<Boundary_range>& orderedBoundaries, Column_settings* colSettings);
94
+ /**
95
+ * @brief Constructs a new empty matrix and reserves space for the given number of columns.
96
+ *
97
+ * @param numberOfColumns Number of columns to reserve space for.
98
+ * @param colSettings Pointer to an existing setting structure for the columns. The structure should contain all
99
+ * the necessary external classes specifically necessary for the chosen column type, such as custom allocators.
100
+ */
101
+ Id_to_index_overlay(unsigned int numberOfColumns, Column_settings* colSettings);
102
+ /**
103
+ * @brief Only available for @ref chainmatrix "chain matrices". Constructs an empty matrix and stores the given
104
+ * comparators.
105
+ *
106
+ * @warning If @ref PersistenceMatrixOptions::has_vine_update is false, the comparators are not used.
107
+ * And if @ref PersistenceMatrixOptions::has_vine_update is true, but
108
+ * @ref PersistenceMatrixOptions::has_column_pairings is also true, the comparators are ignored and
109
+ * the current barcode is used to compare birth and deaths. Therefore it is useless to provide them in those cases.
110
+ *
111
+ * @tparam BirthComparatorFunction Type of the birth comparator: (@ref Pos_index, @ref Pos_index) -> bool
112
+ * @tparam DeathComparatorFunction Type of the death comparator: (@ref Pos_index, @ref Pos_index) -> bool
113
+ * @param colSettings Pointer to an existing setting structure for the columns. The structure should contain all
114
+ * the necessary external classes specifically necessary for the chosen column type, such as custom allocators.
115
+ * @param birthComparator Method taking two @ref PosIdx indices as input and returning true if and only if
116
+ * the birth associated to the first position is strictly less than birth associated to
117
+ * the second one with respect to some self defined order. It is used while swapping two unpaired or
118
+ * two negative columns.
119
+ * @param deathComparator Method taking two @ref PosIdx indices as input and returning true if and only if
120
+ * the death associated to the first position is strictly less than death associated to
121
+ * the second one with respect to some self defined order. It is used while swapping two positive but paired
122
+ * columns.
123
+ */
124
+ template <typename BirthComparatorFunction, typename DeathComparatorFunction>
125
+ Id_to_index_overlay(Column_settings* colSettings,
126
+ const BirthComparatorFunction& birthComparator,
127
+ const DeathComparatorFunction& deathComparator);
128
+ /**
129
+ * @brief Only available for @ref chainmatrix "chain matrices".
130
+ * Constructs a new matrix from the given ranges of @ref Matrix::Entry_representative. Each range corresponds to a
131
+ * column (the order of the ranges are preserved). The content of the ranges is assumed to be sorted by increasing
132
+ * IDs. The IDs of the simplices are also assumed to be consecutive, ordered by filtration value, starting with 0.
133
+ *
134
+ * @warning If @ref PersistenceMatrixOptions::has_vine_update is false, the comparators are not used.
135
+ * And if @ref PersistenceMatrixOptions::has_vine_update is true, but
136
+ * @ref PersistenceMatrixOptions::has_column_pairings is also true, the comparators are ignored and
137
+ * the current barcode is used to compare birth and deaths. Therefore it is useless to provide them in those cases.
138
+ *
139
+ * @tparam BirthComparatorFunction Type of the birth comparator: (@ref Pos_index, @ref Pos_index) -> bool
140
+ * @tparam DeathComparatorFunction Type of the death comparator: (@ref Pos_index, @ref Pos_index) -> bool
141
+ * @tparam Boundary_range Range type for @ref Matrix::Entry_representative ranges.
142
+ * Assumed to have a begin(), end() and size() method.
143
+ * @param orderedBoundaries Range of boundaries: @p orderedBoundaries is interpreted as a boundary matrix of a
144
+ * filtered **simplicial** complex, whose boundaries are ordered by filtration order.
145
+ * Therefore, `orderedBoundaries[i]` should store the boundary of the \f$ i^{th} \f$ simplex in the filtration,
146
+ * as an ordered list of indices of its facets (again those indices correspond to their respective position
147
+ * in the matrix). That is why the indices of the simplices are assumed to be consecutive and starting with 0
148
+ * (an empty boundary is interpreted as a vertex boundary and not as a non existing simplex).
149
+ * All dimensions up to the maximal dimension of interest have to be present. If only a higher dimension is of
150
+ * interest and not everything should be stored, then use the @ref insert_boundary method instead
151
+ * (after creating the matrix with the @ref Id_to_index_overlay(unsigned int, Column_settings*,
152
+ * const BirthComparatorFunction&, const DeathComparatorFunction&) constructor preferably).
153
+ * @param colSettings Pointer to an existing setting structure for the columns. The structure should contain all
154
+ * the necessary external classes specifically necessary for the chosen column type, such as custom allocators.
155
+ * @param birthComparator Method taking two @ref PosIdx indices as input and returning true if and only if
156
+ * the birth associated to the first position is strictly less than birth associated to
157
+ * the second one with respect to some self defined order. It is used while swapping two unpaired or
158
+ * two negative columns.
159
+ * @param deathComparator Method taking two @ref PosIdx indices as input and returning true if and only if
160
+ * the death associated to the first position is strictly less than death associated to
161
+ * the second one with respect to some self defined order. It is used while swapping two positive but paired
162
+ * columns.
163
+ */
164
+ template <typename BirthComparatorFunction, typename DeathComparatorFunction, class Boundary_range>
165
+ Id_to_index_overlay(const std::vector<Boundary_range>& orderedBoundaries,
166
+ Column_settings* colSettings,
167
+ const BirthComparatorFunction& birthComparator,
168
+ const DeathComparatorFunction& deathComparator);
169
+ /**
170
+ * @brief Only available for @ref chainmatrix "chain matrices".
171
+ * Constructs a new empty matrix and reserves space for the given number of columns.
172
+ *
173
+ * @warning If @ref PersistenceMatrixOptions::has_vine_update is false, the comparators are not used.
174
+ * And if @ref PersistenceMatrixOptions::has_vine_update is true, but
175
+ * @ref PersistenceMatrixOptions::has_column_pairings is also true, the comparators are ignored and
176
+ * the current barcode is used to compare birth and deaths. Therefore it is useless to provide them in those cases.
177
+ *
178
+ * @tparam BirthComparatorFunction Type of the birth comparator: (@ref Pos_index, @ref Pos_index) -> bool
179
+ * @tparam DeathComparatorFunction Type of the death comparator: (@ref Pos_index, @ref Pos_index) -> bool
180
+ * @param numberOfColumns Number of columns to reserve space for.
181
+ * @param colSettings Pointer to an existing setting structure for the columns. The structure should contain all
182
+ * the necessary external classes specifically necessary for the chosen column type, such as custom allocators.
183
+ * @param birthComparator Method taking two @ref PosIdx indices as input and returning true if and only if
184
+ * the birth associated to the first position is strictly less than birth associated to
185
+ * the second one with respect to some self defined order. It is used while swapping two unpaired or
186
+ * two negative columns.
187
+ * @param deathComparator Method taking two @ref PosIdx indices as input and returning true if and only if
188
+ * the death associated to the first position is strictly less than death associated to
189
+ * the second one with respect to some self defined order. It is used while swapping two positive but paired
190
+ * columns.
191
+ */
192
+ template <typename BirthComparatorFunction, typename DeathComparatorFunction>
193
+ Id_to_index_overlay(unsigned int numberOfColumns,
194
+ Column_settings* colSettings,
195
+ const BirthComparatorFunction& birthComparator,
196
+ const DeathComparatorFunction& deathComparator);
197
+ /**
198
+ * @brief Copy constructor. If @p operators or @p entryConstructor is not a null pointer, its value is kept
199
+ * instead of the one in the copied matrix.
200
+ *
201
+ * @param matrixToCopy Matrix to copy.
202
+ * @param colSettings Either a pointer to an existing setting structure for the columns or a null pointer.
203
+ * The structure should contain all the necessary external classes specifically necessary for the chosen column type,
204
+ * such as custom allocators. If null pointer, the pointer stored in @p matrixToCopy is used instead.
205
+ */
206
+ Id_to_index_overlay(const Id_to_index_overlay& matrixToCopy, Column_settings* colSettings = nullptr);
207
+ /**
208
+ * @brief Move constructor.
209
+ *
210
+ * @param other Matrix to move.
211
+ */
212
+ Id_to_index_overlay(Id_to_index_overlay&& other) noexcept;
213
+ /**
214
+ * @brief Destructor.
215
+ */
216
+ ~Id_to_index_overlay();
217
+
218
+ /**
219
+ * @brief Inserts at the end of the matrix a new ordered column corresponding to the given boundary.
220
+ * This means that it is assumed that this method is called on boundaries in the order of the filtration.
221
+ * It also assumes that the cells in the given boundary are identified by their relative position in the filtration,
222
+ * starting at 0. If it is not the case, use the other
223
+ * @ref insert_boundary(ID_index, const Boundary_range&, Dimension) "insert_boundary" instead by indicating the
224
+ * cell ID used in the boundaries when the cell is inserted.
225
+ *
226
+ * Different to the constructor, the boundaries do not have to come from a simplicial complex, but also from
227
+ * a more general entry complex. This includes cubical complexes or Morse complexes for example.
228
+ *
229
+ * The content of the new column will vary depending on the underlying @ref mp_matrices "type of the matrix":
230
+ * - If it is a boundary type matrix and only \f$ R \f$ is stored, the boundary is just copied. The column will only
231
+ * be reduced later when the barcode is requested in order to apply some optimizations with the additional
232
+ * knowledge. Hence, the barcode will also not be updated.
233
+ * - If it is a boundary type matrix and both \f$ R \f$ and \f$ U \f$ are stored, the new boundary is stored in its
234
+ * reduced form and the barcode, if active, is also updated.
235
+ * - If it is a chain type matrix, the new column is of the form
236
+ * `IDIdx + linear combination of older column IDIdxs`, where the combination is deduced while reducing the
237
+ * given boundary. If the barcode is stored, it will also be updated.
238
+ *
239
+ * @tparam Boundary_range Range of @ref Matrix::Entry_representative. Assumed to have a begin(), end() and size()
240
+ * method.
241
+ * @param boundary Boundary generating the new column. The content should be ordered by ID.
242
+ * @param dim Dimension of the cell whose boundary is given. If the complex is simplicial,
243
+ * this parameter can be omitted as it can be deduced from the size of the boundary.
244
+ */
245
+ template <class Boundary_range = Boundary>
246
+ void insert_boundary(const Boundary_range& boundary,
247
+ Dimension dim = Master_matrix::template get_null_value<Dimension>());
248
+ /**
249
+ * @brief It does the same as the other version, but allows the boundary cells to be identified without restrictions
250
+ * except that all IDs have to be strictly increasing in the order of filtration. Note that you should avoid then
251
+ * to use the other insertion method to avoid overwriting IDs.
252
+ *
253
+ * As a cell has to be inserted before one of its cofaces in a valid filtration (recall that it is assumed that
254
+ * the cells are inserted by order of filtration), it is sufficient to indicate the ID of the cell being inserted.
255
+ *
256
+ * @tparam Boundary_range Range of @ref Matrix::Entry_representative. Assumed to have a begin(), end() and size()
257
+ * method.
258
+ * @param cellIndex @ref IDIdx index to use to identify the new cell.
259
+ * @param boundary Boundary generating the new column. The indices of the boundary have to correspond to the
260
+ * @p cellIndex values of precedent calls of the method for the corresponding cells and should be ordered in
261
+ * increasing order.
262
+ * @param dim Dimension of the cell whose boundary is given. If the complex is simplicial,
263
+ * this parameter can be omitted as it can be deduced from the size of the boundary.
264
+ */
265
+ template <class Boundary_range = Boundary>
266
+ void insert_boundary(ID_index cellIndex,
267
+ const Boundary_range& boundary,
268
+ Dimension dim = Master_matrix::template get_null_value<Dimension>());
269
+ /**
270
+ * @brief Returns the column at the given @ref IDIdx index.
271
+ * For @ref boundarymatrix "RU matrices", the returned column is from \f$ R \f$.
272
+ * The type of the column depends on the chosen options, see @ref PersistenceMatrixOptions::column_type.
273
+ *
274
+ * @param cellID @ref IDIdx index of the column to return.
275
+ * @return Reference to the column.
276
+ */
277
+ Column& get_column(ID_index cellID);
278
+ /**
279
+ * @brief Only available if @ref PersistenceMatrixOptions::has_row_access is true.
280
+ * Returns the row at the given @ref rowindex "row index".
281
+ * For @ref boundarymatrix "RU matrices", the returned row is from \f$ R \f$.
282
+ * The type of the row depends on the chosen options, see @ref PersistenceMatrixOptions::has_intrusive_rows.
283
+ *
284
+ * @warning The @ref Entry_column_index::get_column_index "get_column_index" method of the row entries returns the
285
+ * original @ref PosIdx indices (before any swaps) for @ref boundarymatrix "boundary matrices" and
286
+ * @ref MatIdx indices for @ref chainmatrix "chain matrices".
287
+ *
288
+ * @param rowIndex @ref rowindex "Row index" of the row to return: @ref IDIdx for @ref chainmatrix "chain matrices"
289
+ * or updated @ref IDIdx for @ref boundarymatrix "boundary matrices" if swaps occurred.
290
+ * @return Reference to the row.
291
+ */
292
+ Row& get_row(ID_index rowIndex);
293
+ /**
294
+ * @brief The effect varies depending on the matrices and the options:
295
+ * - @ref boundarymatrix "boundary matrix" with only \f$ R \f$ stored:
296
+ * - @ref PersistenceMatrixOptions::has_map_column_container and
297
+ * @ref PersistenceMatrixOptions::has_column_and_row_swaps are true:
298
+ * cleans up maps used for the lazy row swaps.
299
+ * - @ref PersistenceMatrixOptions::has_row_access and @ref PersistenceMatrixOptions::has_removable_rows are true:
300
+ * assumes that the row is empty and removes it.
301
+ * - Otherwise, does nothing.
302
+ * - @ref boundarymatrix "boundary matrix" with \f$ U \f$ stored: only \f$ R \f$ is affected by the above.
303
+ * If properly used, \f$ U \f$ will never have empty rows.
304
+ * - @ref chainmatrix "chain matrix": only available if @ref PersistenceMatrixOptions::has_row_access and
305
+ * @ref PersistenceMatrixOptions::has_removable_rows are true.
306
+ * Assumes that the row is empty and removes it.
307
+ *
308
+ * @warning The removed rows are always assumed to be empty. If it is not the case, the deleted row entries are not
309
+ * removed from their columns. And in the case of intrusive rows, this will generate a segmentation fault when
310
+ * the column entries are destroyed later. The row access is just meant as a "read only" access to the rows and the
311
+ * @ref erase_empty_row method just as a way to specify that a row is empty and can therefore be removed from
312
+ * dictionaries. This allows to avoid testing the emptiness of a row at each column entry removal, what can be
313
+ * quite frequent.
314
+ *
315
+ * @param rowIndex @ref rowindex "Row index" of the empty row to remove.
316
+ */
317
+ void erase_empty_row(ID_index rowIndex);
318
+ /**
319
+ * @brief Only available for RU and @ref chainmatrix "chain matrices" and if
320
+ * @ref PersistenceMatrixOptions::has_removable_columns and @ref PersistenceMatrixOptions::has_vine_update are true.
321
+ * For @ref chainmatrix "chain matrices", @ref PersistenceMatrixOptions::has_map_column_container and
322
+ * @ref PersistenceMatrixOptions::has_column_pairings also need to be true.
323
+ * Assumes that the cell is maximal in the current complex and removes it such that the matrix remains consistent
324
+ * (i.e., RU is still an upper triangular decomposition of the @ref boundarymatrix "boundary matrix" and chain is
325
+ * still a compatible bases of the chain complex in the sense of @cite zigzag).
326
+ * The maximality of the cell is not verified.
327
+ * Also updates the barcode if it was computed.
328
+ *
329
+ * For @ref chainmatrix "chain matrices", using the other version of the method could perform better depending on
330
+ * how the data is maintained on the side of the user. Then, @ref PersistenceMatrixOptions::has_column_pairings also
331
+ * do not need to be true.
332
+ *
333
+ * See also @ref remove_last.
334
+ *
335
+ * @param cellID @ref IDIdx index of the cell to remove.
336
+ */
337
+ void remove_maximal_cell(ID_index cellID);
338
+ /**
339
+ * @brief Only available for @ref chainmatrix "chain matrices" and if
340
+ * @ref PersistenceMatrixOptions::has_removable_columns, @ref PersistenceMatrixOptions::has_vine_update
341
+ * and @ref PersistenceMatrixOptions::has_map_column_container are true.
342
+ * Assumes that the cell is maximal in the current complex and removes it such that the matrix remains consistent
343
+ * (i.e., it is still a compatible bases of the chain complex in the sense of @cite zigzag).
344
+ * The maximality of the cell is not verified.
345
+ * Also updates the barcode if it was computed.
346
+ *
347
+ * To maintain the compatibility, vine swaps are done to move the cell up to the end of the filtration. Once at
348
+ * the end, the removal is trivial. But for @ref chainmatrix "chain matrices", swaps do not actually swap the position
349
+ * of the column every time, so the cells appearing after @p cellIndex in the filtration have to be searched first
350
+ * within the matrix. If the user has an easy access to the @ref IDIdx of the cells in the order of filtration,
351
+ * passing them by argument with @p columnsToSwap allows to skip a linear search process. Typically, if the user knows
352
+ * that the cell he wants to remove is already the last cell of the filtration, calling
353
+ * @ref remove_maximal_cell(ID_index, const std::vector<ID_index>&) "remove_maximal_cell(cellID, {})"
354
+ * will be faster than @ref remove_last().
355
+ *
356
+ * See also @ref remove_last.
357
+ *
358
+ * @param cellID @ref IDIdx index of the cell to remove.
359
+ * @param columnsToSwap Vector of @ref IDIdx indices of the cells coming after @p cellID in the filtration.
360
+ */
361
+ void remove_maximal_cell(ID_index cellID, const std::vector<ID_index>& columnsToSwap);
362
+ /**
363
+ * @brief Only available if @ref PersistenceMatrixOptions::has_removable_columns is true. Additionally, if the
364
+ * matrix is a @ref chainmatrix "chain matrix", either @ref PersistenceMatrixOptions::has_map_column_container has to
365
+ * be true or @ref PersistenceMatrixOptions::has_vine_update has to be false.
366
+ * Removes the last cell in the filtration from the matrix and updates the barcode if it is stored.
367
+ *
368
+ * See also @ref remove_maximal_cell.
369
+ *
370
+ * For @ref chainmatrix "chain matrices", if @ref PersistenceMatrixOptions::has_vine_update is true, the last cell
371
+ * does not have to be at the end of the matrix and therefore has to be searched first. In this case, if the user
372
+ * already knows the @ref IDIdx of the last cell, calling
373
+ * @ref remove_maximal_cell(ID_index, const std::vector<ID_index>&) "remove_maximal_cell(cellID, {})"
374
+ * instead allows to skip the search.
375
+ */
376
+ void remove_last();
377
+
378
+ /**
379
+ * @brief Returns the maximal dimension of a cell stored in the matrix. Only available
380
+ * if @ref PersistenceMatrixOptions::has_matrix_maximal_dimension_access is true.
381
+ *
382
+ * @return The maximal dimension.
383
+ */
384
+ Dimension get_max_dimension() const;
385
+ /**
386
+ * @brief Returns the current number of columns in the matrix.
387
+ *
388
+ * @return The number of columns.
389
+ */
390
+ Index get_number_of_columns() const;
391
+ /**
392
+ * @brief Returns the dimension of the given cell. Only available for @ref mp_matrices "non-basic matrices".
393
+ *
394
+ * @param cellID @ref IDIdx index of the cell.
395
+ * @return Dimension of the cell.
396
+ */
397
+ Dimension get_column_dimension(ID_index cellID) const;
398
+
399
+ /**
400
+ * @brief Adds column corresponding to @p sourceCellID onto the column corresponding to @p targetCellID.
401
+ *
402
+ * @warning They will be no verification to ensure that the addition makes sense for the validity of the matrix.
403
+ * For example, a right-to-left addition could corrupt the computation of the barcode if done blindly.
404
+ * So should be used with care.
405
+ *
406
+ * @param sourceCellID @ref IDIdx index of the source column.
407
+ * @param targetCellID @ref IDIdx index of the target column.
408
+ */
409
+ void add_to(ID_index sourceCellID, ID_index targetCellID);
410
+ /**
411
+ * @brief Multiplies the target column with the coefficient and then adds the source column to it.
412
+ * That is: `targetColumn = (targetColumn * coefficient) + sourceColumn`.
413
+ *
414
+ * @warning They will be no verification to ensure that the addition makes sense for the validity of the matrix.
415
+ * For example, a right-to-left addition could corrupt the computation of the barcode if done blindly.
416
+ * So should be used with care.
417
+ *
418
+ * @param sourceCellID @ref IDIdx index of the source column.
419
+ * @param coefficient Value to multiply.
420
+ * @param targetCellID @ref IDIdx index of the target column.
421
+ */
422
+ void multiply_target_and_add_to(ID_index sourceCellID, const Field_element& coefficient, ID_index targetCellID);
423
+ /**
424
+ * @brief Multiplies the source column with the coefficient before adding it to the target column.
425
+ * That is: `targetColumn += (coefficient * sourceColumn)`. The source column will **not** be modified.
426
+ *
427
+ * @warning They will be no verification to ensure that the addition makes sense for the validity of the matrix.
428
+ * For example, a right-to-left addition could corrupt the computation of the barcode if done blindly.
429
+ * So should be used with care.
430
+ *
431
+ * @param coefficient Value to multiply.
432
+ * @param sourceCellID @ref IDIdx index of the source column.
433
+ * @param targetCellID @ref IDIdx index of the target column.
434
+ */
435
+ void multiply_source_and_add_to(const Field_element& coefficient, ID_index sourceCellID, ID_index targetCellID);
436
+
437
+ /**
438
+ * @brief Zeroes the entry at the given coordinates. Not available for @ref chainmatrix "chain matrices".
439
+ * In general, should be used with care to not destroy the validity
440
+ * of the persistence related properties of the matrix.
441
+ *
442
+ * For @ref boundarymatrix "RU matrices", zeros only the entry in \f$ R \f$.
443
+ *
444
+ * @param cellID @ref IDIdx index of the cell corresponding to the column of the entry.
445
+ * @param rowIndex @ref rowindex "Row index" of the row of the entry.
446
+ */
447
+ void zero_entry(ID_index cellID, ID_index rowIndex);
448
+ /**
449
+ * @brief Zeroes the column at the given index. Not available for @ref chainmatrix "chain matrices".
450
+ * In general, should be used with care to not destroy the validity
451
+ * of the persistence related properties of the matrix.
452
+ *
453
+ * For @ref boundarymatrix "RU matrices", zeros only the column in \f$ R \f$.
454
+ *
455
+ * @param cellID @ref IDIdx index of the cell corresponding to the column.
456
+ */
457
+ void zero_column(ID_index cellID);
458
+ /**
459
+ * @brief Indicates if the entry at given coordinates has value zero.
460
+ *
461
+ * For @ref boundarymatrix "RU matrices", looks into \f$ R \f$.
462
+ *
463
+ * @param cellID @ref IDIdx index of the cell corresponding to the column of the entry.
464
+ * @param rowIndex @ref rowindex "Row index" of the row of the entry.
465
+ * @return true If the entry has value zero.
466
+ * @return false Otherwise.
467
+ */
468
+ bool is_zero_entry(ID_index cellID, ID_index rowIndex) const;
469
+ /**
470
+ * @brief Indicates if the column at given index has value zero.
471
+ *
472
+ * For @ref boundarymatrix "RU matrices", looks into \f$ R \f$.
473
+ *
474
+ * Note that for @ref chainmatrix "chain matrices", this method should always return false, as a valid
475
+ * @ref chainmatrix "chain matrix" never has empty columns.
476
+ *
477
+ * @param cellID @ref IDIdx index of the cell corresponding to the column.
478
+ * @return true If the column has value zero.
479
+ * @return false Otherwise.
480
+ */
481
+ bool is_zero_column(ID_index cellID);
482
+
483
+ /**
484
+ * @brief Returns the @ref IDIdx index of the column which has the given @ref rowindex "row index" as pivot.
485
+ * Assumes that the pivot exists. For @ref boundarymatrix "RU matrices", the column is returned from \f$ R \f$.
486
+ *
487
+ * Recall that the row indices for @ref chainmatrix "chain matrices" correspond to the @ref IDIdx indices and that
488
+ * the row indices for a @ref boundarymatrix "RU matrix" correspond to the updated @ref IDIdx indices which got
489
+ * potentially swapped by a vine swap.
490
+ *
491
+ * @param cellIndex @ref rowindex "Row index" of the pivot.
492
+ * @return @ref IDIdx index of the column with the given pivot.
493
+ */
494
+ ID_index get_column_with_pivot(ID_index cellIndex) const;
495
+ /**
496
+ * @brief Returns the @ref rowindex "row index" of the pivot of the given column.
497
+ *
498
+ * @param cellID @ref IDIdx index of the cell corresponding to the column.
499
+ * @return The @ref rowindex "row index" of the pivot.
500
+ */
501
+ ID_index get_pivot(ID_index cellID);
502
+
503
+ /**
504
+ * @brief Resets the matrix to an empty matrix.
505
+ *
506
+ * @param colSettings Pointer to an existing setting structure for the columns. The structure should contain all
507
+ * the necessary external classes specifically necessary for the chosen column type, such as custom allocators.
508
+ */
509
+ void reset(Column_settings* colSettings)
510
+ {
511
+ matrix_.reset(colSettings);
512
+ if constexpr (Master_matrix::Option_list::is_of_boundary_type)
513
+ if (idToIndex_ != nullptr) idToIndex_->clear();
514
+ nextIndex_ = 0;
515
+ }
516
+
517
+ /**
518
+ * @brief Assign operator.
519
+ */
520
+ Id_to_index_overlay& operator=(const Id_to_index_overlay& other);
521
+ /**
522
+ * @brief Assign operator.
523
+ */
524
+ Id_to_index_overlay& operator=(Id_to_index_overlay&& other) noexcept;
525
+
526
+ /**
527
+ * @brief Swap operator.
528
+ */
529
+ friend void swap(Id_to_index_overlay& matrix1, Id_to_index_overlay& matrix2) noexcept
530
+ {
531
+ swap(matrix1.matrix_, matrix2.matrix_);
532
+ std::swap(matrix1.idToIndex_, matrix2.idToIndex_);
533
+ std::swap(matrix1.nextIndex_, matrix2.nextIndex_);
534
+ }
535
+
536
+ void print(); // for debug
537
+
538
+ // access to optional methods
539
+
540
+ /**
541
+ * @brief Returns the current barcode of the matrix.
542
+ * Available only if @ref PersistenceMatrixOptions::has_column_pairings is true.
543
+ *
544
+ * Recall that we assume that the boundaries were inserted in the order of filtration for the barcode to be valid.
545
+ *
546
+ * @warning For simple @ref boundarymatrix "boundary matrices" (only storing \f$ R \f$), we assume that
547
+ * @ref get_current_barcode is only called once, when the matrix is completed.
548
+ *
549
+ * @return A reference to the barcode. The barcode is a vector of @ref Matrix::Bar. A bar stores three attributes:
550
+ * the @ref PosIdx birth index, the @ref PosIdx death index and the dimension of the bar.
551
+ */
552
+ const Barcode& get_current_barcode();
553
+
554
+ /**
555
+ * @brief Only available for simple @ref boundarymatrix "boundary matrices" (only storing \f$ R \f$) and if
556
+ * @ref PersistenceMatrixOptions::has_column_and_row_swaps is true.
557
+ * Swaps the two given columns. Note that it really just swaps two columns and do not updates
558
+ * anything else, nor performs additions to maintain some properties on the matrix.
559
+ *
560
+ * @param cellID1 First column @ref IDIdx index to swap.
561
+ * @param cellID2 Second column @ref IDIdx index to swap.
562
+ */
563
+ void swap_columns(ID_index cellID1, ID_index cellID2);
564
+ /**
565
+ * @brief Only available for simple @ref boundarymatrix "boundary matrices" (only storing R)
566
+ * and if @ref PersistenceMatrixOptions::has_column_and_row_swaps is true.
567
+ * Swaps the two given rows. Note that it really just swaps two rows and do not updates
568
+ * anything else, nor performs additions to maintain some properties on the matrix.
569
+ *
570
+ * @param rowIndex1 First @ref rowindex "row index" to swap.
571
+ * @param rowIndex2 Second @ref rowindex "row index" to swap.
572
+ */
573
+ void swap_rows(Index rowIndex1, Index rowIndex2);
574
+ /**
575
+ * @brief Only available if @ref PersistenceMatrixOptions::has_vine_update is true.
576
+ * Does the same than @ref vine_swap, but assumes that the swap is non trivial and
577
+ * therefore skips a part of the case study.
578
+ *
579
+ * @param cellID1 @ref IDIdx index of the first cell.
580
+ * @param cellID2 @ref IDIdx index of the second cell. It is assumed that the @ref PosIdx of both only differs by one.
581
+ * @return Let \f$ pos1 \f$ be the @ref PosIdx index of @p columnIndex1 and \f$ pos2 \f$ be the @ref PosIdx index of
582
+ * @p columnIndex2. The method returns the @ref MatIdx of the column which has now, after the swap, the @ref PosIdx
583
+ * \f$ max(pos1, pos2) \f$.
584
+ */
585
+ ID_index vine_swap_with_z_eq_1_case(ID_index cellID1, ID_index cellID2);
586
+ /**
587
+ * @brief Only available if @ref PersistenceMatrixOptions::has_vine_update is true.
588
+ * Does a vine swap between two cells which are consecutive in the filtration. Roughly, if \f$ F \f$ is
589
+ * the current filtration represented by the matrix, the method modifies the matrix such that the new state
590
+ * corresponds to a valid state for the filtration \f$ F' \f$ equal to \f$ F \f$ but with the two given cells
591
+ * at swapped positions. Of course, the two cells should not have a face/coface relation which each other ;
592
+ * \f$ F' \f$ has to be a valid filtration.
593
+ * See @cite vineyards for more information about vine and vineyards.
594
+ *
595
+ * @param cellID1 @ref IDIdx index of the first cell.
596
+ * @param cellID2 @ref IDIdx index of the second cell. It is assumed that the @ref PosIdx of both only differs by one.
597
+ * @return Let \f$ pos1 \f$ be the @ref PosIdx index of @p columnIndex1 and \f$ pos2 \f$ be the @ref PosIdx index of
598
+ * @p columnIndex2. The method returns the @ref MatIdx of the column which has now, after the swap, the @ref PosIdx
599
+ * \f$ max(pos1, pos2) \f$.
600
+ */
601
+ ID_index vine_swap(ID_index cellID1, ID_index cellID2);
602
+
603
+ /**
604
+ * @brief Only available if @ref PersistenceMatrixOptions::can_retrieve_representative_cycles is true. Pre-computes
605
+ * the representative cycles of the current state of the filtration represented by the matrix. It needs to be called
606
+ * before calling @ref get_representative_cycles if the matrix was modified since last call. Otherwise the old cycles
607
+ * will be returned.
608
+ *
609
+ * @param dim If different from default value, only the cycles of the given dimension are updated.
610
+ * All others are erased.
611
+ */
612
+ void update_representative_cycles(Dimension dim = Master_matrix::template get_null_value<Dimension>());
613
+ /**
614
+ * @brief Only available if @ref PersistenceMatrixOptions::can_retrieve_representative_cycles is true. Pre-computes
615
+ * the representative cycle in the current matrix state of the given bar. It needs to be called
616
+ * before calling @ref get_representative_cycle if the matrix was modified since last call. Otherwise the old cycle
617
+ * will be returned.
618
+ *
619
+ * @param bar Bar corresponding to the wanted representative cycle.
620
+ */
621
+ void update_representative_cycle(const Bar& bar);
622
+ /**
623
+ * @brief Only available if @ref PersistenceMatrixOptions::can_retrieve_representative_cycles is true.
624
+ * Returns all representative cycles of the current filtration.
625
+ *
626
+ * @return A const reference to the vector of representative cycles.
627
+ */
628
+ const std::vector<Cycle>& get_representative_cycles();
629
+ /**
630
+ * @brief Only available if @ref PersistenceMatrixOptions::can_retrieve_representative_cycles is true.
631
+ * Returns the cycle representing the given bar.
632
+ *
633
+ * @param bar A bar from the current barcode.
634
+ * @return A const reference to the cycle representing @p bar.
635
+ */
636
+ const Cycle& get_representative_cycle(const Bar& bar);
637
+
638
+ private:
639
+ using Dictionary = typename Master_matrix::template Dictionary<Index>;
640
+
641
+ Underlying_matrix matrix_; /**< Interfaced matrix. */
642
+ Dictionary* idToIndex_; /**< Map from @ref IDIdx index to @ref MatIdx index. */
643
+ Index nextIndex_; /**< Next unused index. */
644
+
645
+ void _initialize_map(unsigned int size);
646
+ Index _id_to_index(ID_index id) const;
647
+ Index& _id_to_index(ID_index id);
648
+ };
649
+
650
+ template <class Underlying_matrix, class Master_matrix>
651
+ inline Id_to_index_overlay<Underlying_matrix, Master_matrix>::Id_to_index_overlay(Column_settings* colSettings)
652
+ : matrix_(colSettings), idToIndex_(nullptr), nextIndex_(0)
653
+ {
654
+ _initialize_map(0);
655
+ }
656
+
657
+ template <class Underlying_matrix, class Master_matrix>
658
+ template <class Boundary_range>
659
+ inline Id_to_index_overlay<Underlying_matrix, Master_matrix>::Id_to_index_overlay(
660
+ const std::vector<Boundary_range>& orderedBoundaries,
661
+ Column_settings* colSettings)
662
+ : matrix_(orderedBoundaries, colSettings), idToIndex_(nullptr), nextIndex_(orderedBoundaries.size())
663
+ {
664
+ _initialize_map(orderedBoundaries.size());
665
+ if constexpr (Master_matrix::Option_list::is_of_boundary_type) {
666
+ for (unsigned int i = 0; i < orderedBoundaries.size(); i++) {
667
+ _id_to_index(i) = i;
668
+ }
669
+ }
670
+ }
671
+
672
+ template <class Underlying_matrix, class Master_matrix>
673
+ inline Id_to_index_overlay<Underlying_matrix, Master_matrix>::Id_to_index_overlay(unsigned int numberOfColumns,
674
+ Column_settings* colSettings)
675
+ : matrix_(numberOfColumns, colSettings), idToIndex_(nullptr), nextIndex_(0)
676
+ {
677
+ _initialize_map(numberOfColumns);
678
+ }
679
+
680
+ template <class Underlying_matrix, class Master_matrix>
681
+ template <typename BirthComparatorFunction, typename DeathComparatorFunction>
682
+ inline Id_to_index_overlay<Underlying_matrix, Master_matrix>::Id_to_index_overlay(
683
+ Column_settings* colSettings,
684
+ const BirthComparatorFunction& birthComparator,
685
+ const DeathComparatorFunction& deathComparator)
686
+ : matrix_(colSettings, birthComparator, deathComparator), idToIndex_(nullptr), nextIndex_(0)
687
+ {
688
+ _initialize_map(0);
689
+ }
690
+
691
+ template <class Underlying_matrix, class Master_matrix>
692
+ template <typename BirthComparatorFunction, typename DeathComparatorFunction, class Boundary_range>
693
+ inline Id_to_index_overlay<Underlying_matrix, Master_matrix>::Id_to_index_overlay(
694
+ const std::vector<Boundary_range>& orderedBoundaries,
695
+ Column_settings* colSettings,
696
+ const BirthComparatorFunction& birthComparator,
697
+ const DeathComparatorFunction& deathComparator)
698
+ : matrix_(orderedBoundaries, colSettings, birthComparator, deathComparator),
699
+ idToIndex_(nullptr),
700
+ nextIndex_(orderedBoundaries.size())
701
+ {
702
+ _initialize_map(orderedBoundaries.size());
703
+ if constexpr (Master_matrix::Option_list::is_of_boundary_type) {
704
+ for (unsigned int i = 0; i < orderedBoundaries.size(); i++) {
705
+ _id_to_index(i) = i;
706
+ }
707
+ }
708
+ }
709
+
710
+ template <class Underlying_matrix, class Master_matrix>
711
+ template <typename BirthComparatorFunction, typename DeathComparatorFunction>
712
+ inline Id_to_index_overlay<Underlying_matrix, Master_matrix>::Id_to_index_overlay(
713
+ unsigned int numberOfColumns,
714
+ Column_settings* colSettings,
715
+ const BirthComparatorFunction& birthComparator,
716
+ const DeathComparatorFunction& deathComparator)
717
+ : matrix_(numberOfColumns, colSettings, birthComparator, deathComparator), idToIndex_(nullptr), nextIndex_(0)
718
+ {
719
+ _initialize_map(numberOfColumns);
720
+ }
721
+
722
+ template <class Underlying_matrix, class Master_matrix>
723
+ inline Id_to_index_overlay<Underlying_matrix, Master_matrix>::Id_to_index_overlay(
724
+ const Id_to_index_overlay& matrixToCopy,
725
+ Column_settings* colSettings)
726
+ : matrix_(matrixToCopy.matrix_, colSettings), idToIndex_(nullptr), nextIndex_(matrixToCopy.nextIndex_)
727
+ {
728
+ if constexpr (Master_matrix::Option_list::is_of_boundary_type) {
729
+ idToIndex_ = new Dictionary(*matrixToCopy.idToIndex_);
730
+ } else {
731
+ idToIndex_ = &matrix_.pivotToColumnIndex_;
732
+ }
733
+ }
734
+
735
+ template <class Underlying_matrix, class Master_matrix>
736
+ inline Id_to_index_overlay<Underlying_matrix, Master_matrix>::Id_to_index_overlay(Id_to_index_overlay&& other) noexcept
737
+ : matrix_(std::move(other.matrix_)),
738
+ idToIndex_(std::exchange(other.idToIndex_, nullptr)),
739
+ nextIndex_(std::exchange(other.nextIndex_, 0))
740
+ {
741
+ }
742
+
743
+ template <class Underlying_matrix, class Master_matrix>
744
+ inline Id_to_index_overlay<Underlying_matrix, Master_matrix>::~Id_to_index_overlay()
745
+ {
746
+ if constexpr (Master_matrix::Option_list::is_of_boundary_type) {
747
+ delete idToIndex_;
748
+ }
749
+ }
750
+
751
+ template <class Underlying_matrix, class Master_matrix>
752
+ template <class Boundary_range>
753
+ inline void Id_to_index_overlay<Underlying_matrix, Master_matrix>::insert_boundary(const Boundary_range& boundary,
754
+ Dimension dim)
755
+ {
756
+ matrix_.insert_boundary(boundary, dim);
757
+ if constexpr (Master_matrix::Option_list::is_of_boundary_type) {
758
+ if constexpr (Master_matrix::Option_list::has_map_column_container) {
759
+ idToIndex_->emplace(nextIndex_, nextIndex_);
760
+ } else {
761
+ if (idToIndex_->size() == nextIndex_) {
762
+ idToIndex_->push_back(nextIndex_);
763
+ } else {
764
+ _id_to_index(nextIndex_) = nextIndex_;
765
+ }
766
+ }
767
+ ++nextIndex_;
768
+ }
769
+ }
770
+
771
+ template <class Underlying_matrix, class Master_matrix>
772
+ template <class Boundary_range>
773
+ inline void Id_to_index_overlay<Underlying_matrix, Master_matrix>::insert_boundary(ID_index cellIndex,
774
+ const Boundary_range& boundary,
775
+ Dimension dim)
776
+ {
777
+ if constexpr (Master_matrix::Option_list::has_map_column_container) {
778
+ GUDHI_CHECK(idToIndex_->find(cellIndex) == idToIndex_->end(),
779
+ std::invalid_argument("Id_to_index_overlay::insert_boundary - Index for simplex already chosen!"));
780
+ } else {
781
+ GUDHI_CHECK(
782
+ (idToIndex_->size() <= cellIndex || _id_to_index(cellIndex) == Master_matrix::template get_null_value<Index>()),
783
+ std::invalid_argument("Id_to_index_overlay::insert_boundary - Index for simplex already chosen!"));
784
+ }
785
+ matrix_.insert_boundary(cellIndex, boundary, dim);
786
+ if constexpr (Master_matrix::Option_list::is_of_boundary_type) {
787
+ if constexpr (Master_matrix::Option_list::has_map_column_container) {
788
+ idToIndex_->emplace(cellIndex, nextIndex_);
789
+ } else {
790
+ if (idToIndex_->size() <= cellIndex) {
791
+ idToIndex_->resize(cellIndex + 1, Master_matrix::template get_null_value<Index>());
792
+ }
793
+ _id_to_index(cellIndex) = nextIndex_;
794
+ }
795
+ ++nextIndex_;
796
+ }
797
+ }
798
+
799
+ template <class Underlying_matrix, class Master_matrix>
800
+ inline typename Id_to_index_overlay<Underlying_matrix, Master_matrix>::Column&
801
+ Id_to_index_overlay<Underlying_matrix, Master_matrix>::get_column(ID_index cellID)
802
+ {
803
+ return matrix_.get_column(_id_to_index(cellID));
804
+ }
805
+
806
+ template <class Underlying_matrix, class Master_matrix>
807
+ inline typename Id_to_index_overlay<Underlying_matrix, Master_matrix>::Row&
808
+ Id_to_index_overlay<Underlying_matrix, Master_matrix>::get_row(ID_index rowIndex)
809
+ {
810
+ return matrix_.get_row(rowIndex);
811
+ }
812
+
813
+ template <class Underlying_matrix, class Master_matrix>
814
+ inline void Id_to_index_overlay<Underlying_matrix, Master_matrix>::erase_empty_row(ID_index rowIndex)
815
+ {
816
+ return matrix_.erase_empty_row(rowIndex);
817
+ }
818
+
819
+ template <class Underlying_matrix, class Master_matrix>
820
+ inline void Id_to_index_overlay<Underlying_matrix, Master_matrix>::remove_maximal_cell(ID_index cellID)
821
+ {
822
+ if constexpr (Master_matrix::Option_list::is_of_boundary_type) {
823
+ std::vector<ID_index> indexToID(nextIndex_);
824
+ if constexpr (Master_matrix::Option_list::has_map_column_container) {
825
+ for (auto& p : *idToIndex_) {
826
+ indexToID[p.second] = p.first;
827
+ }
828
+ } else {
829
+ for (ID_index i = 0; i < idToIndex_->size(); ++i) {
830
+ if (_id_to_index(i) != Master_matrix::template get_null_value<Index>()) indexToID[_id_to_index(i)] = i;
831
+ }
832
+ }
833
+ --nextIndex_;
834
+ for (Index curr = _id_to_index(cellID); curr < nextIndex_; ++curr) {
835
+ matrix_.vine_swap(curr);
836
+ std::swap(idToIndex_->at(indexToID[curr]), idToIndex_->at(indexToID[curr + 1]));
837
+ }
838
+ matrix_.remove_last();
839
+ GUDHI_CHECK(_id_to_index(cellID) == nextIndex_,
840
+ std::logic_error("Id_to_index_overlay::remove_maximal_cell - Indexation problem."));
841
+
842
+ if constexpr (Master_matrix::Option_list::has_map_column_container) {
843
+ idToIndex_->erase(cellID);
844
+ } else {
845
+ _id_to_index(cellID) = Master_matrix::template get_null_value<Index>();
846
+ }
847
+ } else {
848
+ matrix_.remove_maximal_cell(cellID);
849
+ }
850
+ }
851
+
852
+ template <class Underlying_matrix, class Master_matrix>
853
+ inline void Id_to_index_overlay<Underlying_matrix, Master_matrix>::remove_maximal_cell(
854
+ ID_index cellID,
855
+ const std::vector<ID_index>& columnsToSwap)
856
+ {
857
+ static_assert(!Master_matrix::Option_list::is_of_boundary_type,
858
+ "'remove_maximal_cell(ID_index,const std::vector<Index>&)' is not available for the chosen options.");
859
+ std::vector<Index> translatedIndices;
860
+ std::transform(columnsToSwap.cbegin(), columnsToSwap.cend(), std::back_inserter(translatedIndices), [&](ID_index id) {
861
+ return _id_to_index(id);
862
+ });
863
+ matrix_.remove_maximal_cell(cellID, translatedIndices);
864
+ }
865
+
866
+ template <class Underlying_matrix, class Master_matrix>
867
+ inline void Id_to_index_overlay<Underlying_matrix, Master_matrix>::remove_last()
868
+ {
869
+ if (idToIndex_->empty()) return; // empty matrix
870
+
871
+ matrix_.remove_last();
872
+
873
+ if constexpr (Master_matrix::Option_list::is_of_boundary_type) {
874
+ --nextIndex_;
875
+ if constexpr (Master_matrix::Option_list::has_map_column_container) {
876
+ auto it = idToIndex_->begin();
877
+ while (it->second != nextIndex_) ++it; // should never reach idToIndex_->end()
878
+ idToIndex_->erase(it);
879
+ } else {
880
+ Index id = idToIndex_->size() - 1;
881
+ // should always stop before reaching -1
882
+ while (_id_to_index(id) == Master_matrix::template get_null_value<Index>()) --id;
883
+ GUDHI_CHECK(_id_to_index(id) == nextIndex_,
884
+ std::logic_error("Id_to_index_overlay::remove_last - Indexation problem."));
885
+ _id_to_index(id) = Master_matrix::template get_null_value<Index>();
886
+ }
887
+ }
888
+ }
889
+
890
+ template <class Underlying_matrix, class Master_matrix>
891
+ inline typename Id_to_index_overlay<Underlying_matrix, Master_matrix>::Dimension
892
+ Id_to_index_overlay<Underlying_matrix, Master_matrix>::get_max_dimension() const
893
+ {
894
+ return matrix_.get_max_dimension();
895
+ }
896
+
897
+ template <class Underlying_matrix, class Master_matrix>
898
+ inline typename Id_to_index_overlay<Underlying_matrix, Master_matrix>::Index
899
+ Id_to_index_overlay<Underlying_matrix, Master_matrix>::get_number_of_columns() const
900
+ {
901
+ return matrix_.get_number_of_columns();
902
+ }
903
+
904
+ template <class Underlying_matrix, class Master_matrix>
905
+ inline typename Id_to_index_overlay<Underlying_matrix, Master_matrix>::Dimension
906
+ Id_to_index_overlay<Underlying_matrix, Master_matrix>::get_column_dimension(ID_index cellID) const
907
+ {
908
+ return matrix_.get_column_dimension(_id_to_index(cellID));
909
+ }
910
+
911
+ template <class Underlying_matrix, class Master_matrix>
912
+ inline void Id_to_index_overlay<Underlying_matrix, Master_matrix>::add_to(ID_index sourceCellID, ID_index targetCellID)
913
+ {
914
+ return matrix_.add_to(_id_to_index(sourceCellID), _id_to_index(targetCellID));
915
+ }
916
+
917
+ template <class Underlying_matrix, class Master_matrix>
918
+ inline void Id_to_index_overlay<Underlying_matrix, Master_matrix>::multiply_target_and_add_to(
919
+ ID_index sourceCellID,
920
+ const Field_element& coefficient,
921
+ ID_index targetCellID)
922
+ {
923
+ return matrix_.multiply_target_and_add_to(_id_to_index(sourceCellID), coefficient, _id_to_index(targetCellID));
924
+ }
925
+
926
+ template <class Underlying_matrix, class Master_matrix>
927
+ inline void Id_to_index_overlay<Underlying_matrix, Master_matrix>::multiply_source_and_add_to(
928
+ const Field_element& coefficient,
929
+ ID_index sourceCellID,
930
+ ID_index targetCellID)
931
+ {
932
+ return matrix_.multiply_source_and_add_to(coefficient, _id_to_index(sourceCellID), _id_to_index(targetCellID));
933
+ }
934
+
935
+ template <class Underlying_matrix, class Master_matrix>
936
+ inline void Id_to_index_overlay<Underlying_matrix, Master_matrix>::zero_entry(ID_index cellID, ID_index rowIndex)
937
+ {
938
+ return matrix_.zero_entry(_id_to_index(cellID), rowIndex);
939
+ }
940
+
941
+ template <class Underlying_matrix, class Master_matrix>
942
+ inline void Id_to_index_overlay<Underlying_matrix, Master_matrix>::zero_column(ID_index cellID)
943
+ {
944
+ return matrix_.zero_column(_id_to_index(cellID));
945
+ }
946
+
947
+ template <class Underlying_matrix, class Master_matrix>
948
+ inline bool Id_to_index_overlay<Underlying_matrix, Master_matrix>::is_zero_entry(ID_index cellID,
949
+ ID_index rowIndex) const
950
+ {
951
+ return matrix_.is_zero_entry(_id_to_index(cellID), rowIndex);
952
+ }
953
+
954
+ template <class Underlying_matrix, class Master_matrix>
955
+ inline bool Id_to_index_overlay<Underlying_matrix, Master_matrix>::is_zero_column(ID_index cellID)
956
+ {
957
+ return matrix_.is_zero_column(_id_to_index(cellID));
958
+ }
959
+
960
+ template <class Underlying_matrix, class Master_matrix>
961
+ inline typename Id_to_index_overlay<Underlying_matrix, Master_matrix>::ID_index
962
+ Id_to_index_overlay<Underlying_matrix, Master_matrix>::get_column_with_pivot(ID_index cellIndex) const
963
+ {
964
+ if constexpr (Master_matrix::Option_list::is_of_boundary_type) {
965
+ Index pos = matrix_.get_column_with_pivot(cellIndex);
966
+ ID_index i = 0;
967
+ while (_id_to_index(i) != pos) ++i;
968
+ return i;
969
+ } else {
970
+ return cellIndex;
971
+ }
972
+ }
973
+
974
+ template <class Underlying_matrix, class Master_matrix>
975
+ inline typename Id_to_index_overlay<Underlying_matrix, Master_matrix>::ID_index
976
+ Id_to_index_overlay<Underlying_matrix, Master_matrix>::get_pivot(ID_index cellID)
977
+ {
978
+ if constexpr (Master_matrix::Option_list::is_of_boundary_type) {
979
+ return matrix_.get_pivot(_id_to_index(cellID));
980
+ } else {
981
+ return cellID;
982
+ }
983
+ }
984
+
985
+ template <class Underlying_matrix, class Master_matrix>
986
+ inline Id_to_index_overlay<Underlying_matrix, Master_matrix>&
987
+ Id_to_index_overlay<Underlying_matrix, Master_matrix>::operator=(const Id_to_index_overlay& other)
988
+ {
989
+ if (this == &other) return *this;
990
+
991
+ matrix_ = other.matrix_;
992
+ if constexpr (Master_matrix::Option_list::is_of_boundary_type) {
993
+ delete idToIndex_;
994
+ idToIndex_ = other.idToIndex_;
995
+ } else {
996
+ idToIndex_ = &matrix_.pivotToColumnIndex_;
997
+ }
998
+ nextIndex_ = other.nextIndex_;
999
+
1000
+ return *this;
1001
+ }
1002
+
1003
+ template <class Underlying_matrix, class Master_matrix>
1004
+ inline Id_to_index_overlay<Underlying_matrix, Master_matrix>&
1005
+ Id_to_index_overlay<Underlying_matrix, Master_matrix>::operator=(Id_to_index_overlay&& other) noexcept
1006
+ {
1007
+ if (this == &other) return *this;
1008
+
1009
+ matrix_ = std::move(other.matrix_);
1010
+ if constexpr (Master_matrix::Option_list::is_of_boundary_type) {
1011
+ delete idToIndex_;
1012
+ }
1013
+ idToIndex_ = std::exchange(other.idToIndex_, nullptr);
1014
+ nextIndex_ = std::exchange(other.nextIndex_, 0);
1015
+
1016
+ return *this;
1017
+ }
1018
+
1019
+ template <class Underlying_matrix, class Master_matrix>
1020
+ inline void Id_to_index_overlay<Underlying_matrix, Master_matrix>::print()
1021
+ {
1022
+ return matrix_.print();
1023
+ }
1024
+
1025
+ template <class Underlying_matrix, class Master_matrix>
1026
+ inline const typename Id_to_index_overlay<Underlying_matrix, Master_matrix>::Barcode&
1027
+ Id_to_index_overlay<Underlying_matrix, Master_matrix>::get_current_barcode()
1028
+ {
1029
+ return matrix_.get_current_barcode();
1030
+ }
1031
+
1032
+ template <class Underlying_matrix, class Master_matrix>
1033
+ inline void Id_to_index_overlay<Underlying_matrix, Master_matrix>::update_representative_cycles(Dimension dim)
1034
+ {
1035
+ matrix_.update_representative_cycles(dim);
1036
+ }
1037
+
1038
+ template <class Underlying_matrix, class Master_matrix>
1039
+ inline void Id_to_index_overlay<Underlying_matrix, Master_matrix>::update_representative_cycle(const Bar& bar)
1040
+ {
1041
+ matrix_.update_representative_cycle(bar);
1042
+ }
1043
+
1044
+ template <class Underlying_matrix, class Master_matrix>
1045
+ inline const std::vector<typename Id_to_index_overlay<Underlying_matrix, Master_matrix>::Cycle>&
1046
+ Id_to_index_overlay<Underlying_matrix, Master_matrix>::get_representative_cycles()
1047
+ {
1048
+ return matrix_.get_representative_cycles();
1049
+ }
1050
+
1051
+ template <class Underlying_matrix, class Master_matrix>
1052
+ inline const typename Id_to_index_overlay<Underlying_matrix, Master_matrix>::Cycle&
1053
+ Id_to_index_overlay<Underlying_matrix, Master_matrix>::get_representative_cycle(const Bar& bar)
1054
+ {
1055
+ return matrix_.get_representative_cycle(bar);
1056
+ }
1057
+
1058
+ template <class Underlying_matrix, class Master_matrix>
1059
+ inline void Id_to_index_overlay<Underlying_matrix, Master_matrix>::swap_columns(ID_index cellID1, ID_index cellID2)
1060
+ {
1061
+ matrix_.swap_columns(_id_to_index(cellID1), _id_to_index(cellID2));
1062
+ std::swap(idToIndex_->at(cellID1), idToIndex_->at(cellID2));
1063
+ }
1064
+
1065
+ template <class Underlying_matrix, class Master_matrix>
1066
+ inline void Id_to_index_overlay<Underlying_matrix, Master_matrix>::swap_rows(Index rowIndex1, Index rowIndex2)
1067
+ {
1068
+ matrix_.swap_rows(rowIndex1, rowIndex2);
1069
+ }
1070
+
1071
+ template <class Underlying_matrix, class Master_matrix>
1072
+ inline typename Id_to_index_overlay<Underlying_matrix, Master_matrix>::ID_index
1073
+ Id_to_index_overlay<Underlying_matrix, Master_matrix>::vine_swap_with_z_eq_1_case(ID_index cellID1, ID_index cellID2)
1074
+ {
1075
+ Index first = _id_to_index(cellID1);
1076
+ Index second = _id_to_index(cellID2);
1077
+ if (first > second) std::swap(first, second);
1078
+
1079
+ if constexpr (Master_matrix::Option_list::is_of_boundary_type) {
1080
+ GUDHI_CHECK(second - first == 1,
1081
+ std::invalid_argument(
1082
+ "Id_to_index_overlay::vine_swap_with_z_eq_1_case - The columns to swap are not contiguous."));
1083
+
1084
+ bool change = matrix_.vine_swap_with_z_eq_1_case(first);
1085
+
1086
+ std::swap(idToIndex_->at(cellID1), idToIndex_->at(cellID2));
1087
+
1088
+ if (change) {
1089
+ return cellID1;
1090
+ }
1091
+ return cellID2;
1092
+ } else {
1093
+ return matrix_.vine_swap_with_z_eq_1_case(first, second);
1094
+ }
1095
+ }
1096
+
1097
+ template <class Underlying_matrix, class Master_matrix>
1098
+ inline typename Id_to_index_overlay<Underlying_matrix, Master_matrix>::ID_index
1099
+ Id_to_index_overlay<Underlying_matrix, Master_matrix>::vine_swap(ID_index cellID1, ID_index cellID2)
1100
+ {
1101
+ Index first = _id_to_index(cellID1);
1102
+ Index second = _id_to_index(cellID2);
1103
+ if (first > second) std::swap(first, second);
1104
+
1105
+ if constexpr (Master_matrix::Option_list::is_of_boundary_type) {
1106
+ GUDHI_CHECK(second - first == 1,
1107
+ std::invalid_argument("Id_to_index_overlay::vine_swap - The columns to swap are not contiguous."));
1108
+
1109
+ bool change = matrix_.vine_swap(first);
1110
+
1111
+ std::swap(idToIndex_->at(cellID1), idToIndex_->at(cellID2));
1112
+
1113
+ if (change) {
1114
+ return cellID1;
1115
+ }
1116
+ return cellID2;
1117
+ } else {
1118
+ return matrix_.vine_swap(first, second);
1119
+ }
1120
+ }
1121
+
1122
+ template <class Underlying_matrix, class Master_matrix>
1123
+ inline void Id_to_index_overlay<Underlying_matrix, Master_matrix>::_initialize_map([[maybe_unused]] unsigned int size)
1124
+ {
1125
+ if constexpr (Master_matrix::Option_list::is_of_boundary_type) {
1126
+ if constexpr (Master_matrix::Option_list::has_map_column_container) {
1127
+ idToIndex_ = new Dictionary(size);
1128
+ } else {
1129
+ idToIndex_ = new Dictionary(size, Master_matrix::template get_null_value<Index>());
1130
+ }
1131
+ } else {
1132
+ idToIndex_ = &matrix_.pivotToColumnIndex_;
1133
+ }
1134
+ }
1135
+
1136
+ template <class Underlying_matrix, class Master_matrix>
1137
+ inline typename Id_to_index_overlay<Underlying_matrix, Master_matrix>::Index
1138
+ Id_to_index_overlay<Underlying_matrix, Master_matrix>::_id_to_index(ID_index id) const
1139
+ {
1140
+ if constexpr (Master_matrix::Option_list::has_map_column_container) {
1141
+ return idToIndex_->at(id);
1142
+ } else {
1143
+ return idToIndex_->operator[](id);
1144
+ }
1145
+ }
1146
+
1147
+ template <class Underlying_matrix, class Master_matrix>
1148
+ inline typename Id_to_index_overlay<Underlying_matrix, Master_matrix>::Index&
1149
+ Id_to_index_overlay<Underlying_matrix, Master_matrix>::_id_to_index(ID_index id)
1150
+ {
1151
+ return idToIndex_->operator[](id); // for maps, the entry is created if not existing as needed in the constructors
1152
+ }
1153
+
1154
+ } // namespace persistence_matrix
1155
+ } // namespace Gudhi
1156
+
1157
+ #endif // PM_ID_TO_POS_TRANSLATION_H