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