multipers 2.3.3b6__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.

Potentially problematic release.


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

Files changed (183) hide show
  1. multipers/.dylibs/libc++.1.0.dylib +0 -0
  2. multipers/.dylibs/libtbb.12.16.dylib +0 -0
  3. multipers/__init__.py +33 -0
  4. multipers/_signed_measure_meta.py +453 -0
  5. multipers/_slicer_meta.py +211 -0
  6. multipers/array_api/__init__.py +45 -0
  7. multipers/array_api/numpy.py +41 -0
  8. multipers/array_api/torch.py +58 -0
  9. multipers/data/MOL2.py +458 -0
  10. multipers/data/UCR.py +18 -0
  11. multipers/data/__init__.py +1 -0
  12. multipers/data/graphs.py +466 -0
  13. multipers/data/immuno_regions.py +27 -0
  14. multipers/data/minimal_presentation_to_st_bf.py +0 -0
  15. multipers/data/pytorch2simplextree.py +91 -0
  16. multipers/data/shape3d.py +101 -0
  17. multipers/data/synthetic.py +113 -0
  18. multipers/distances.py +202 -0
  19. multipers/filtration_conversions.pxd +229 -0
  20. multipers/filtration_conversions.pxd.tp +84 -0
  21. multipers/filtrations/__init__.py +18 -0
  22. multipers/filtrations/density.py +574 -0
  23. multipers/filtrations/filtrations.py +361 -0
  24. multipers/filtrations.pxd +224 -0
  25. multipers/function_rips.cpython-312-darwin.so +0 -0
  26. multipers/function_rips.pyx +105 -0
  27. multipers/grids.cpython-312-darwin.so +0 -0
  28. multipers/grids.pyx +433 -0
  29. multipers/gudhi/Persistence_slices_interface.h +132 -0
  30. multipers/gudhi/Simplex_tree_interface.h +239 -0
  31. multipers/gudhi/Simplex_tree_multi_interface.h +551 -0
  32. multipers/gudhi/cubical_to_boundary.h +59 -0
  33. multipers/gudhi/gudhi/Bitmap_cubical_complex.h +450 -0
  34. multipers/gudhi/gudhi/Bitmap_cubical_complex_base.h +1070 -0
  35. multipers/gudhi/gudhi/Bitmap_cubical_complex_periodic_boundary_conditions_base.h +579 -0
  36. multipers/gudhi/gudhi/Debug_utils.h +45 -0
  37. multipers/gudhi/gudhi/Fields/Multi_field.h +484 -0
  38. multipers/gudhi/gudhi/Fields/Multi_field_operators.h +455 -0
  39. multipers/gudhi/gudhi/Fields/Multi_field_shared.h +450 -0
  40. multipers/gudhi/gudhi/Fields/Multi_field_small.h +531 -0
  41. multipers/gudhi/gudhi/Fields/Multi_field_small_operators.h +507 -0
  42. multipers/gudhi/gudhi/Fields/Multi_field_small_shared.h +531 -0
  43. multipers/gudhi/gudhi/Fields/Z2_field.h +355 -0
  44. multipers/gudhi/gudhi/Fields/Z2_field_operators.h +376 -0
  45. multipers/gudhi/gudhi/Fields/Zp_field.h +420 -0
  46. multipers/gudhi/gudhi/Fields/Zp_field_operators.h +400 -0
  47. multipers/gudhi/gudhi/Fields/Zp_field_shared.h +418 -0
  48. multipers/gudhi/gudhi/Flag_complex_edge_collapser.h +337 -0
  49. multipers/gudhi/gudhi/Matrix.h +2107 -0
  50. multipers/gudhi/gudhi/Multi_critical_filtration.h +1038 -0
  51. multipers/gudhi/gudhi/Multi_persistence/Box.h +174 -0
  52. multipers/gudhi/gudhi/Multi_persistence/Line.h +282 -0
  53. multipers/gudhi/gudhi/Off_reader.h +173 -0
  54. multipers/gudhi/gudhi/One_critical_filtration.h +1441 -0
  55. multipers/gudhi/gudhi/Persistence_matrix/Base_matrix.h +769 -0
  56. multipers/gudhi/gudhi/Persistence_matrix/Base_matrix_with_column_compression.h +686 -0
  57. multipers/gudhi/gudhi/Persistence_matrix/Boundary_matrix.h +842 -0
  58. multipers/gudhi/gudhi/Persistence_matrix/Chain_matrix.h +1350 -0
  59. multipers/gudhi/gudhi/Persistence_matrix/Id_to_index_overlay.h +1105 -0
  60. multipers/gudhi/gudhi/Persistence_matrix/Position_to_index_overlay.h +859 -0
  61. multipers/gudhi/gudhi/Persistence_matrix/RU_matrix.h +910 -0
  62. multipers/gudhi/gudhi/Persistence_matrix/allocators/entry_constructors.h +139 -0
  63. multipers/gudhi/gudhi/Persistence_matrix/base_pairing.h +230 -0
  64. multipers/gudhi/gudhi/Persistence_matrix/base_swap.h +211 -0
  65. multipers/gudhi/gudhi/Persistence_matrix/boundary_cell_position_to_id_mapper.h +60 -0
  66. multipers/gudhi/gudhi/Persistence_matrix/boundary_face_position_to_id_mapper.h +60 -0
  67. multipers/gudhi/gudhi/Persistence_matrix/chain_pairing.h +136 -0
  68. multipers/gudhi/gudhi/Persistence_matrix/chain_rep_cycles.h +190 -0
  69. multipers/gudhi/gudhi/Persistence_matrix/chain_vine_swap.h +616 -0
  70. multipers/gudhi/gudhi/Persistence_matrix/columns/chain_column_extra_properties.h +150 -0
  71. multipers/gudhi/gudhi/Persistence_matrix/columns/column_dimension_holder.h +106 -0
  72. multipers/gudhi/gudhi/Persistence_matrix/columns/column_utilities.h +219 -0
  73. multipers/gudhi/gudhi/Persistence_matrix/columns/entry_types.h +327 -0
  74. multipers/gudhi/gudhi/Persistence_matrix/columns/heap_column.h +1140 -0
  75. multipers/gudhi/gudhi/Persistence_matrix/columns/intrusive_list_column.h +934 -0
  76. multipers/gudhi/gudhi/Persistence_matrix/columns/intrusive_set_column.h +934 -0
  77. multipers/gudhi/gudhi/Persistence_matrix/columns/list_column.h +980 -0
  78. multipers/gudhi/gudhi/Persistence_matrix/columns/naive_vector_column.h +1092 -0
  79. multipers/gudhi/gudhi/Persistence_matrix/columns/row_access.h +192 -0
  80. multipers/gudhi/gudhi/Persistence_matrix/columns/set_column.h +921 -0
  81. multipers/gudhi/gudhi/Persistence_matrix/columns/small_vector_column.h +1093 -0
  82. multipers/gudhi/gudhi/Persistence_matrix/columns/unordered_set_column.h +1012 -0
  83. multipers/gudhi/gudhi/Persistence_matrix/columns/vector_column.h +1244 -0
  84. multipers/gudhi/gudhi/Persistence_matrix/matrix_dimension_holders.h +186 -0
  85. multipers/gudhi/gudhi/Persistence_matrix/matrix_row_access.h +164 -0
  86. multipers/gudhi/gudhi/Persistence_matrix/ru_pairing.h +156 -0
  87. multipers/gudhi/gudhi/Persistence_matrix/ru_rep_cycles.h +376 -0
  88. multipers/gudhi/gudhi/Persistence_matrix/ru_vine_swap.h +540 -0
  89. multipers/gudhi/gudhi/Persistent_cohomology/Field_Zp.h +118 -0
  90. multipers/gudhi/gudhi/Persistent_cohomology/Multi_field.h +173 -0
  91. multipers/gudhi/gudhi/Persistent_cohomology/Persistent_cohomology_column.h +128 -0
  92. multipers/gudhi/gudhi/Persistent_cohomology.h +745 -0
  93. multipers/gudhi/gudhi/Points_off_io.h +171 -0
  94. multipers/gudhi/gudhi/Simple_object_pool.h +69 -0
  95. multipers/gudhi/gudhi/Simplex_tree/Simplex_tree_iterators.h +463 -0
  96. multipers/gudhi/gudhi/Simplex_tree/Simplex_tree_node_explicit_storage.h +83 -0
  97. multipers/gudhi/gudhi/Simplex_tree/Simplex_tree_siblings.h +106 -0
  98. multipers/gudhi/gudhi/Simplex_tree/Simplex_tree_star_simplex_iterators.h +277 -0
  99. multipers/gudhi/gudhi/Simplex_tree/hooks_simplex_base.h +62 -0
  100. multipers/gudhi/gudhi/Simplex_tree/indexing_tag.h +27 -0
  101. multipers/gudhi/gudhi/Simplex_tree/serialization_utils.h +62 -0
  102. multipers/gudhi/gudhi/Simplex_tree/simplex_tree_options.h +157 -0
  103. multipers/gudhi/gudhi/Simplex_tree.h +2794 -0
  104. multipers/gudhi/gudhi/Simplex_tree_multi.h +152 -0
  105. multipers/gudhi/gudhi/distance_functions.h +62 -0
  106. multipers/gudhi/gudhi/graph_simplicial_complex.h +104 -0
  107. multipers/gudhi/gudhi/persistence_interval.h +253 -0
  108. multipers/gudhi/gudhi/persistence_matrix_options.h +170 -0
  109. multipers/gudhi/gudhi/reader_utils.h +367 -0
  110. multipers/gudhi/mma_interface_coh.h +256 -0
  111. multipers/gudhi/mma_interface_h0.h +223 -0
  112. multipers/gudhi/mma_interface_matrix.h +293 -0
  113. multipers/gudhi/naive_merge_tree.h +536 -0
  114. multipers/gudhi/scc_io.h +310 -0
  115. multipers/gudhi/truc.h +1403 -0
  116. multipers/io.cpython-312-darwin.so +0 -0
  117. multipers/io.pyx +644 -0
  118. multipers/ml/__init__.py +0 -0
  119. multipers/ml/accuracies.py +90 -0
  120. multipers/ml/invariants_with_persistable.py +79 -0
  121. multipers/ml/kernels.py +176 -0
  122. multipers/ml/mma.py +713 -0
  123. multipers/ml/one.py +472 -0
  124. multipers/ml/point_clouds.py +352 -0
  125. multipers/ml/signed_measures.py +1589 -0
  126. multipers/ml/sliced_wasserstein.py +461 -0
  127. multipers/ml/tools.py +113 -0
  128. multipers/mma_structures.cpython-312-darwin.so +0 -0
  129. multipers/mma_structures.pxd +128 -0
  130. multipers/mma_structures.pyx +2786 -0
  131. multipers/mma_structures.pyx.tp +1094 -0
  132. multipers/multi_parameter_rank_invariant/diff_helpers.h +84 -0
  133. multipers/multi_parameter_rank_invariant/euler_characteristic.h +97 -0
  134. multipers/multi_parameter_rank_invariant/function_rips.h +322 -0
  135. multipers/multi_parameter_rank_invariant/hilbert_function.h +769 -0
  136. multipers/multi_parameter_rank_invariant/persistence_slices.h +148 -0
  137. multipers/multi_parameter_rank_invariant/rank_invariant.h +369 -0
  138. multipers/multiparameter_edge_collapse.py +41 -0
  139. multipers/multiparameter_module_approximation/approximation.h +2330 -0
  140. multipers/multiparameter_module_approximation/combinatory.h +129 -0
  141. multipers/multiparameter_module_approximation/debug.h +107 -0
  142. multipers/multiparameter_module_approximation/euler_curves.h +0 -0
  143. multipers/multiparameter_module_approximation/format_python-cpp.h +286 -0
  144. multipers/multiparameter_module_approximation/heap_column.h +238 -0
  145. multipers/multiparameter_module_approximation/images.h +79 -0
  146. multipers/multiparameter_module_approximation/list_column.h +174 -0
  147. multipers/multiparameter_module_approximation/list_column_2.h +232 -0
  148. multipers/multiparameter_module_approximation/ru_matrix.h +347 -0
  149. multipers/multiparameter_module_approximation/set_column.h +135 -0
  150. multipers/multiparameter_module_approximation/structure_higher_dim_barcode.h +36 -0
  151. multipers/multiparameter_module_approximation/unordered_set_column.h +166 -0
  152. multipers/multiparameter_module_approximation/utilities.h +403 -0
  153. multipers/multiparameter_module_approximation/vector_column.h +223 -0
  154. multipers/multiparameter_module_approximation/vector_matrix.h +331 -0
  155. multipers/multiparameter_module_approximation/vineyards.h +464 -0
  156. multipers/multiparameter_module_approximation/vineyards_trajectories.h +649 -0
  157. multipers/multiparameter_module_approximation.cpython-312-darwin.so +0 -0
  158. multipers/multiparameter_module_approximation.pyx +235 -0
  159. multipers/pickle.py +90 -0
  160. multipers/plots.py +456 -0
  161. multipers/point_measure.cpython-312-darwin.so +0 -0
  162. multipers/point_measure.pyx +395 -0
  163. multipers/simplex_tree_multi.cpython-312-darwin.so +0 -0
  164. multipers/simplex_tree_multi.pxd +134 -0
  165. multipers/simplex_tree_multi.pyx +10840 -0
  166. multipers/simplex_tree_multi.pyx.tp +2009 -0
  167. multipers/slicer.cpython-312-darwin.so +0 -0
  168. multipers/slicer.pxd +3034 -0
  169. multipers/slicer.pxd.tp +234 -0
  170. multipers/slicer.pyx +20481 -0
  171. multipers/slicer.pyx.tp +1088 -0
  172. multipers/tensor/tensor.h +672 -0
  173. multipers/tensor.pxd +13 -0
  174. multipers/test.pyx +44 -0
  175. multipers/tests/__init__.py +62 -0
  176. multipers/torch/__init__.py +1 -0
  177. multipers/torch/diff_grids.py +240 -0
  178. multipers/torch/rips_density.py +310 -0
  179. multipers-2.3.3b6.dist-info/METADATA +128 -0
  180. multipers-2.3.3b6.dist-info/RECORD +183 -0
  181. multipers-2.3.3b6.dist-info/WHEEL +6 -0
  182. multipers-2.3.3b6.dist-info/licenses/LICENSE +21 -0
  183. multipers-2.3.3b6.dist-info/top_level.txt +1 -0
@@ -0,0 +1,842 @@
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 Boundary_matrix.h
13
+ * @author Hannah Schreiber
14
+ * @brief Contains the @ref Gudhi::persistence_matrix::Boundary_matrix class.
15
+ */
16
+
17
+ #ifndef PM_BOUNDARY_MATRIX_H
18
+ #define PM_BOUNDARY_MATRIX_H
19
+
20
+ #include <cassert>
21
+ #include <iostream> //print() only
22
+ #include <iterator>
23
+ #include <vector>
24
+ #include <utility> //std::swap, std::move & std::exchange
25
+
26
+ namespace Gudhi {
27
+ namespace persistence_matrix {
28
+
29
+ // TODO: factorize/inherit/compose with Base_matrix?
30
+ /**
31
+ * @class Boundary_matrix Boundary_matrix.h gudhi/Persistence_matrix/Boundary_matrix.h
32
+ * @ingroup persistence_matrix
33
+ *
34
+ * @brief %Matrix structure to store the ordered @ref boundarymatrix "boundary matrix" \f$ R \f$ of a filtered complex
35
+ * in order to compute its persistent homology. Provides an access to its columns and rows as well as the possibility
36
+ * to remove the last cells of the filtration while maintaining a valid barcode.
37
+ *
38
+ * @tparam Master_matrix An instantiation of @ref Matrix from which all types and options are deduced.
39
+ */
40
+ template <class Master_matrix>
41
+ class Boundary_matrix : public Master_matrix::Matrix_dimension_option,
42
+ public Master_matrix::template Base_swap_option<Boundary_matrix<Master_matrix> >,
43
+ public Master_matrix::Base_pairing_option,
44
+ public Master_matrix::Matrix_row_access_option
45
+ {
46
+ public:
47
+ using Index = typename Master_matrix::Index; /**< Container index type. */
48
+ using ID_index = typename Master_matrix::ID_index; /**< @ref IDIdx index type. */
49
+ using Dimension = typename Master_matrix::Dimension; /**< Dimension value type. */
50
+ /**
51
+ * @brief Field operators class. Necessary only if @ref PersistenceMatrixOptions::is_z2 is false.
52
+ */
53
+ using Field_operators = typename Master_matrix::Field_operators;
54
+ using Field_element = typename Master_matrix::Element; /**< Type of an field element. */
55
+ using Column = typename Master_matrix::Column; /**< Column type. */
56
+ using Boundary = typename Master_matrix::Boundary; /**< Type of an input column. */
57
+ using Row = typename Master_matrix::Row; /**< Row type,
58
+ only necessary with row access option. */
59
+ using Entry_constructor = typename Master_matrix::Entry_constructor; /**< Factory of @ref Entry classes. */
60
+ using Column_settings = typename Master_matrix::Column_settings; /**< Structure giving access to the columns to
61
+ necessary external classes. */
62
+
63
+ /**
64
+ * @brief Constructs an empty matrix.
65
+ *
66
+ * @param colSettings Pointer to an existing setting structure for the columns. The structure should contain all
67
+ * the necessary external classes specifically necessary for the choosen column type, such as custom allocators.
68
+ */
69
+ Boundary_matrix(Column_settings* colSettings);
70
+ /**
71
+ * @brief Constructs a new matrix from the given ranges of @ref Matrix::Entry_representative. Each range corresponds
72
+ * to a column (the order of the ranges are preserved). The content of the ranges is assumed to be sorted by
73
+ * increasing IDs. The IDs of the simplices are also assumed to be consecutive, ordered by filtration value, starting
74
+ * with 0.
75
+ *
76
+ * @tparam Boundary_range Range type for @ref Matrix::Entry_representative ranges.
77
+ * Assumed to have a begin(), end() and size() method.
78
+ * @param orderedBoundaries Range of boundaries: @p orderedBoundaries is interpreted as a boundary matrix of a
79
+ * filtered **simplicial** complex, whose boundaries are ordered by filtration order.
80
+ * Therefore, `orderedBoundaries[i]` should store the boundary of the \f$ i^{th} \f$ simplex in the filtration,
81
+ * as an ordered list of indices of its facets (again those indices correspond to their respective position
82
+ * in the matrix). That is why the indices of the simplices are assumed to be consecutive and starting with 0
83
+ * (an empty boundary is interpreted as a vertex boundary and not as a non existing simplex).
84
+ * All dimensions up to the maximal dimension of interest have to be present. If only a higher dimension is of
85
+ * interest and not everything should be stored, then use the @ref insert_boundary method instead
86
+ * (after creating the matrix with the
87
+ * @ref Boundary_matrix(unsigned int numberOfColumns, Column_settings* colSettings)
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
+ Boundary_matrix(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
+ Boundary_matrix(unsigned int numberOfColumns, Column_settings* colSettings);
103
+ /**
104
+ * @brief Copy constructor. If @p colSettings is not a null pointer, its value is kept
105
+ * instead of the one in the copied matrix.
106
+ *
107
+ * @param matrixToCopy Matrix to copy.
108
+ * @param colSettings Either a pointer to an existing setting structure for the columns or a null pointer.
109
+ * The structure should contain all the necessary external classes specifically necessary for the choosen column type,
110
+ * such as custom allocators. If null pointer, the pointer stored in @p matrixToCopy is used instead.
111
+ */
112
+ Boundary_matrix(const Boundary_matrix& matrixToCopy,
113
+ Column_settings* colSettings = nullptr);
114
+ /**
115
+ * @brief Move constructor.
116
+ *
117
+ * @param other Matrix to move.
118
+ */
119
+ Boundary_matrix(Boundary_matrix&& other) noexcept;
120
+
121
+ /**
122
+ * @brief Inserts at the end of the matrix a new ordered column corresponding to the given boundary.
123
+ * This means that it is assumed that this method is called on boundaries in the order of the filtration.
124
+ * It also assumes that the cells in the given boundary are identified by their relative position in the filtration,
125
+ * starting at 0. If it is not the case, use the other
126
+ * @ref insert_boundary(ID_index cellIndex, const Boundary_range& boundary, Dimension dim) "insert_boundary"
127
+ * instead by indicating the cell ID used in the boundaries when the cell is inserted.
128
+ *
129
+ * Different to the constructor, the boundaries do not have to come from a simplicial complex, but also from
130
+ * a more general entry complex. This includes cubical complexes or Morse complexes for example.
131
+ *
132
+ * At the insertion, the boundary will be copied as is. The column will only be reduced later when the barcode
133
+ * is requested in order to apply some optimizations with the additional knowledge. Hence, the barcode will also
134
+ * not be updated, so call @ref Base_pairing::get_current_barcode "get_current_barcode" only when the matrix is
135
+ * complete.
136
+ *
137
+ * @tparam Boundary_range Range of @ref Matrix::Entry_representative. Assumed to have a begin(), end() and size()
138
+ * method.
139
+ * @param boundary Boundary generating the new column. The content should be ordered by ID.
140
+ * @param dim Dimension of the cell whose boundary is given. If the complex is simplicial,
141
+ * this parameter can be omitted as it can be deduced from the size of the boundary.
142
+ * @return The @ref MatIdx index of the inserted boundary.
143
+ */
144
+ template <class Boundary_range = Boundary>
145
+ Index insert_boundary(const Boundary_range& boundary, Dimension dim = -1);
146
+ /**
147
+ * @brief It does the same as the other version, but allows the boundary cells to be identified without restrictions
148
+ * except that all IDs have to be strictly increasing in the order of filtration. Note that you should avoid then
149
+ * to use the other insertion method to avoid overwriting IDs.
150
+ *
151
+ * As a cell has to be inserted before one of its cofaces in a valid filtration (recall that it is assumed that
152
+ * the cells are inserted by order of filtration), it is sufficient to indicate the ID of the cell being inserted.
153
+ *
154
+ * @tparam Boundary_range Range of @ref Matrix::Entry_representative. Assumed to have a begin(), end() and size()
155
+ * method.
156
+ * @param cellIndex @ref IDIdx index to use to identify the new cell.
157
+ * @param boundary Boundary generating the new column. The indices of the boundary have to correspond to the
158
+ * @p cellIndex values of precedent calls of the method for the corresponding cells and should be ordered in
159
+ * increasing order.
160
+ * @param dim Dimension of the cell whose boundary is given. If the complex is simplicial,
161
+ * this parameter can be omitted as it can be deduced from the size of the boundary.
162
+ * @return The @ref MatIdx index of the inserted boundary.
163
+ */
164
+ template <class Boundary_range = Boundary>
165
+ Index insert_boundary(ID_index cellIndex, const Boundary_range& boundary, Dimension dim = -1);
166
+ /**
167
+ * @brief Returns the column at the given @ref MatIdx index.
168
+ * The type of the column depends on the choosen options, see @ref PersistenceMatrixOptions::column_type.
169
+ *
170
+ * Note that before returning the column, all column entries can eventually be reordered, if lazy swaps occurred.
171
+ * It is therefore recommended to avoid calling @ref get_column between column or row swaps, otherwise the benefits
172
+ * of the the laziness is lost.
173
+ *
174
+ * @param columnIndex @ref MatIdx index of the column to return.
175
+ * @return Reference to the column.
176
+ */
177
+ Column& get_column(Index columnIndex);
178
+ /**
179
+ * @brief Only available if @ref PersistenceMatrixOptions::has_row_access is true.
180
+ * Returns the row at the given @ref rowindex "row index" of the matrix.
181
+ * The type of the row depends on the choosen options, see @ref PersistenceMatrixOptions::has_intrusive_rows.
182
+ *
183
+ * Note that before returning the row, all column entries can eventually be reordered, if lazy swaps occurred.
184
+ * It is therefore recommended to avoid calling @ref get_row between column or row swaps, otherwise the benefits
185
+ * of the the laziness is lost.
186
+ *
187
+ * @param rowIndex @ref rowindex "Row index" of the row to return.
188
+ * @return Reference to the row.
189
+ */
190
+ Row& get_row(Index rowIndex);
191
+ /**
192
+ * @brief Only available if @ref PersistenceMatrixOptions::has_removable_columns is true.
193
+ * Removes the last cell in the filtration from the matrix and updates the barcode if this one was already computed.
194
+ *
195
+ * @return The pivot of the removed cell.
196
+ */
197
+ Index remove_last();
198
+ /**
199
+ * @brief If @ref PersistenceMatrixOptions::has_row_access and @ref PersistenceMatrixOptions::has_removable_rows
200
+ * are true: assumes that the row is empty and removes it. If @ref PersistenceMatrixOptions::has_map_column_container
201
+ * and @ref PersistenceMatrixOptions::has_column_and_row_swaps are true: cleans up maps used for the lazy row swaps.
202
+ * Otherwise, does nothing.
203
+ *
204
+ * @warning The removed rows are always assumed to be empty. If it is not the case, the deleted row entries are not
205
+ * removed from their columns. And in the case of intrusive rows, this will generate a segmentation fault when
206
+ * the column entries are destroyed later. The row access is just meant as a "read only" access to the rows and the
207
+ * @ref erase_empty_row method just as a way to specify that a row is empty and can therefore be removed from
208
+ * dictionaries. This allows to avoid testing the emptiness of a row at each column entry removal, what can be
209
+ * quite frequent.
210
+ *
211
+ * @param rowIndex @ref rowindex "Row index" of the empty row.
212
+ */
213
+ void erase_empty_row(Index rowIndex);
214
+
215
+ /**
216
+ * @brief Returns the current number of columns in the matrix.
217
+ *
218
+ * @return The number of columns.
219
+ */
220
+ Index get_number_of_columns() const;
221
+
222
+ /**
223
+ * @brief Returns the dimension of the given column.
224
+ *
225
+ * @param columnIndex @ref MatIdx index of the column representing the cell.
226
+ * @return Dimension of the cell.
227
+ */
228
+ Dimension get_column_dimension(Index columnIndex) const;
229
+
230
+ /**
231
+ * @brief Adds column at @p sourceColumnIndex onto the column at @p targetColumnIndex in the matrix.
232
+ *
233
+ * @warning They will be no verification to ensure that the addition makes sense for the validity of a
234
+ * boundary matrix of a filtered complex. For example, a right-to-left addition could corrupt the computation
235
+ * of the barcode if done blindly. So should be used with care.
236
+ *
237
+ * @param sourceColumnIndex @ref MatIdx index of the source column.
238
+ * @param targetColumnIndex @ref MatIdx index of the target column.
239
+ */
240
+ void add_to(Index sourceColumnIndex, Index targetColumnIndex);
241
+ /**
242
+ * @brief Multiplies the target column with the coefficient and then adds the source column to it.
243
+ * That is: `targetColumn = (targetColumn * coefficient) + sourceColumn`.
244
+ *
245
+ * @warning They will be no verification to ensure that the addition makes sense for the validity of a
246
+ * boundary matrix of a filtered complex. For example, a right-to-left addition could corrupt the computation
247
+ * of the barcode if done blindly. So should be used with care.
248
+ *
249
+ * @param sourceColumnIndex @ref MatIdx index of the source column.
250
+ * @param coefficient Value to multiply.
251
+ * @param targetColumnIndex @ref MatIdx index of the target column.
252
+ */
253
+ void multiply_target_and_add_to(Index sourceColumnIndex,
254
+ const Field_element& coefficient,
255
+ Index targetColumnIndex);
256
+ /**
257
+ * @brief Multiplies the source column with the coefficient before adding it to the target column.
258
+ * That is: `targetColumn += (coefficient * sourceColumn)`. The source column will **not** be modified.
259
+ *
260
+ * @warning They will be no verification to ensure that the addition makes sense for the validity of a
261
+ * boundary matrix of a filtered complex. For example, a right-to-left addition could corrupt the computation
262
+ * of the barcode if done blindly. So should be used with care.
263
+ *
264
+ * @param coefficient Value to multiply.
265
+ * @param sourceColumnIndex @ref MatIdx index of the source column.
266
+ * @param targetColumnIndex @ref MatIdx index of the target column.
267
+ */
268
+ void multiply_source_and_add_to(const Field_element& coefficient,
269
+ Index sourceColumnIndex,
270
+ Index targetColumnIndex);
271
+
272
+ /**
273
+ * @brief Zeroes the entry at the given coordinates.
274
+ *
275
+ * @warning They will be no verification to ensure that the zeroing makes sense for the validity of a
276
+ * boundary matrix of a filtered complex. So should be used while knowing what one is doing.
277
+ *
278
+ * @param columnIndex @ref MatIdx index of the column of the entry.
279
+ * @param rowIndex @ref rowindex "Row index" of the row of the entry.
280
+ */
281
+ void zero_entry(Index columnIndex, Index rowIndex);
282
+ /**
283
+ * @brief Zeroes the column at the given index.
284
+ *
285
+ * @warning They will be no verification to ensure that the zeroing makes sense for the validity of a
286
+ * boundary matrix of a filtered complex. So should be used while knowing what one is doing.
287
+ *
288
+ * @param columnIndex @ref MatIdx index of the column to zero.
289
+ */
290
+ void zero_column(Index columnIndex);
291
+ /**
292
+ * @brief Indicates if the entry at given coordinates has value zero.
293
+ *
294
+ * @param columnIndex @ref MatIdx index of the column of the entry.
295
+ * @param rowIndex @ref rowindex "Row index" of the row of the entry.
296
+ * @return true If the entry has value zero.
297
+ * @return false Otherwise.
298
+ */
299
+ bool is_zero_entry(Index columnIndex, Index rowIndex) const;
300
+ /**
301
+ * @brief Indicates if the column at given index has value zero.
302
+ *
303
+ * @param columnIndex @ref MatIdx index of the column.
304
+ * @return true If the column has value zero.
305
+ * @return false Otherwise.
306
+ */
307
+ bool is_zero_column(Index columnIndex);
308
+
309
+ /**
310
+ * @brief Returns the pivot of the given column.
311
+ *
312
+ * @param columnIndex @ref MatIdx index of the column.
313
+ * @return Pivot of the column at @p columnIndex.
314
+ */
315
+ Index get_pivot(Index columnIndex);
316
+
317
+ /**
318
+ * @brief Resets the matrix to an empty matrix.
319
+ *
320
+ * @param colSettings Pointer to an existing setting structure for the columns. The structure should contain all
321
+ * the necessary external classes specifically necessary for the choosen column type, such as custom allocators.
322
+ */
323
+ void reset(Column_settings* colSettings) {
324
+ matrix_.clear();
325
+ nextInsertIndex_ = 0;
326
+ colSettings_ = colSettings;
327
+ }
328
+
329
+ /**
330
+ * @brief Assign operator.
331
+ */
332
+ Boundary_matrix& operator=(const Boundary_matrix& other);
333
+ /**
334
+ * @brief Swap operator.
335
+ */
336
+ friend void swap(Boundary_matrix& matrix1, Boundary_matrix& matrix2) {
337
+ swap(static_cast<typename Master_matrix::Matrix_dimension_option&>(matrix1),
338
+ static_cast<typename Master_matrix::Matrix_dimension_option&>(matrix2));
339
+ swap(static_cast<typename Master_matrix::template Base_swap_option<Boundary_matrix<Master_matrix> >&>(matrix1),
340
+ static_cast<typename Master_matrix::template Base_swap_option<Boundary_matrix<Master_matrix> >&>(matrix2));
341
+ swap(static_cast<typename Master_matrix::Base_pairing_option&>(matrix1),
342
+ static_cast<typename Master_matrix::Base_pairing_option&>(matrix2));
343
+ matrix1.matrix_.swap(matrix2.matrix_);
344
+ std::swap(matrix1.nextInsertIndex_, matrix2.nextInsertIndex_);
345
+ std::swap(matrix1.colSettings_, matrix2.colSettings_);
346
+
347
+ if constexpr (Master_matrix::Option_list::has_row_access) {
348
+ swap(static_cast<typename Master_matrix::Matrix_row_access_option&>(matrix1),
349
+ static_cast<typename Master_matrix::Matrix_row_access_option&>(matrix2));
350
+ }
351
+ }
352
+
353
+ void print(Index startCol = 0, Index endCol = -1, Index startRow = 0, Index endRow = -1); // for debug
354
+
355
+ private:
356
+ using Dim_opt = typename Master_matrix::Matrix_dimension_option;
357
+ using Swap_opt = typename Master_matrix::template Base_swap_option<Boundary_matrix<Master_matrix> >;
358
+ using Pair_opt = typename Master_matrix::Base_pairing_option;
359
+ using RA_opt = typename Master_matrix::Matrix_row_access_option;
360
+ using Column_container = typename Master_matrix::Column_container;
361
+
362
+ friend Swap_opt;
363
+ friend Pair_opt;
364
+
365
+ Column_container matrix_; /**< Column container. */
366
+ Index nextInsertIndex_; /**< Next unused column index. */
367
+ Column_settings* colSettings_; /**< Entry factory. */
368
+
369
+ static constexpr bool activeDimOption =
370
+ Master_matrix::Option_list::has_matrix_maximal_dimension_access || Master_matrix::maxDimensionIsNeeded;
371
+ static constexpr bool activeSwapOption =
372
+ Master_matrix::Option_list::has_column_and_row_swaps || Master_matrix::Option_list::has_vine_update;
373
+ static constexpr bool activePairingOption = Master_matrix::Option_list::has_column_pairings &&
374
+ !Master_matrix::Option_list::has_vine_update &&
375
+ !Master_matrix::Option_list::can_retrieve_representative_cycles;
376
+
377
+ void _orderRowsIfNecessary();
378
+ const Column& _get_column(Index columnIndex) const;
379
+ Column& _get_column(Index columnIndex);
380
+ Index _get_real_row_index(Index rowIndex) const;
381
+ template <class Container>
382
+ void _container_insert(const Container& column, Index pos, Dimension dim);
383
+ void _container_insert(const Column& column, [[maybe_unused]] Index pos = 0);
384
+ };
385
+
386
+ template <class Master_matrix>
387
+ inline Boundary_matrix<Master_matrix>::Boundary_matrix(Column_settings* colSettings)
388
+ : Dim_opt(-1),
389
+ Swap_opt(),
390
+ Pair_opt(),
391
+ RA_opt(),
392
+ nextInsertIndex_(0),
393
+ colSettings_(colSettings)
394
+ {}
395
+
396
+ template <class Master_matrix>
397
+ template <class Boundary_range>
398
+ inline Boundary_matrix<Master_matrix>::Boundary_matrix(const std::vector<Boundary_range>& orderedBoundaries,
399
+ Column_settings* colSettings)
400
+ : Dim_opt(-1),
401
+ Swap_opt(orderedBoundaries.size()),
402
+ Pair_opt(),
403
+ RA_opt(orderedBoundaries.size()),
404
+ nextInsertIndex_(orderedBoundaries.size()),
405
+ colSettings_(colSettings)
406
+ {
407
+ matrix_.reserve(orderedBoundaries.size());
408
+
409
+ for (Index i = 0; i < orderedBoundaries.size(); i++) {
410
+ _container_insert(orderedBoundaries[i], i, orderedBoundaries[i].size() == 0 ? 0 : orderedBoundaries[i].size() - 1);
411
+ }
412
+ }
413
+
414
+ template <class Master_matrix>
415
+ inline Boundary_matrix<Master_matrix>::Boundary_matrix(unsigned int numberOfColumns,
416
+ Column_settings* colSettings)
417
+ : Dim_opt(-1),
418
+ Swap_opt(numberOfColumns),
419
+ Pair_opt(),
420
+ RA_opt(numberOfColumns),
421
+ matrix_(!Master_matrix::Option_list::has_map_column_container && Master_matrix::Option_list::has_row_access
422
+ ? 0
423
+ : numberOfColumns),
424
+ nextInsertIndex_(0),
425
+ colSettings_(colSettings)
426
+ {
427
+ if constexpr (!Master_matrix::Option_list::has_map_column_container && Master_matrix::Option_list::has_row_access)
428
+ matrix_.reserve(numberOfColumns);
429
+ }
430
+
431
+ template <class Master_matrix>
432
+ inline Boundary_matrix<Master_matrix>::Boundary_matrix(const Boundary_matrix& matrixToCopy,
433
+ Column_settings* colSettings)
434
+ : Dim_opt(static_cast<const Dim_opt&>(matrixToCopy)),
435
+ Swap_opt(static_cast<const Swap_opt&>(matrixToCopy)),
436
+ Pair_opt(static_cast<const Pair_opt&>(matrixToCopy)),
437
+ RA_opt(static_cast<const RA_opt&>(matrixToCopy)),
438
+ nextInsertIndex_(matrixToCopy.nextInsertIndex_),
439
+ colSettings_(colSettings == nullptr ? matrixToCopy.colSettings_ : colSettings)
440
+ {
441
+ matrix_.reserve(matrixToCopy.matrix_.size());
442
+ for (const auto& cont : matrixToCopy.matrix_){
443
+ if constexpr (Master_matrix::Option_list::has_map_column_container){
444
+ _container_insert(cont.second, cont.first);
445
+ } else {
446
+ _container_insert(cont);
447
+ }
448
+ }
449
+ }
450
+
451
+ template <class Master_matrix>
452
+ inline Boundary_matrix<Master_matrix>::Boundary_matrix(Boundary_matrix&& other) noexcept
453
+ : Dim_opt(std::move(static_cast<Dim_opt&>(other))),
454
+ Swap_opt(std::move(static_cast<Swap_opt&>(other))),
455
+ Pair_opt(std::move(static_cast<Pair_opt&>(other))),
456
+ RA_opt(std::move(static_cast<RA_opt&>(other))),
457
+ matrix_(std::move(other.matrix_)),
458
+ nextInsertIndex_(std::exchange(other.nextInsertIndex_, 0)),
459
+ colSettings_(std::exchange(other.colSettings_, nullptr))
460
+ {}
461
+
462
+ template <class Master_matrix>
463
+ template <class Boundary_range>
464
+ inline typename Boundary_matrix<Master_matrix>::Index Boundary_matrix<Master_matrix>::insert_boundary(
465
+ const Boundary_range& boundary, Dimension dim)
466
+ {
467
+ return insert_boundary(nextInsertIndex_, boundary, dim);
468
+ }
469
+
470
+ template <class Master_matrix>
471
+ template <class Boundary_range>
472
+ inline typename Boundary_matrix<Master_matrix>::Index Boundary_matrix<Master_matrix>::insert_boundary(
473
+ ID_index cellIndex, const Boundary_range& boundary, Dimension dim)
474
+ {
475
+ if (dim == -1) dim = boundary.size() == 0 ? 0 : boundary.size() - 1;
476
+
477
+ _orderRowsIfNecessary();
478
+
479
+ //updates container sizes
480
+ if constexpr (Master_matrix::Option_list::has_row_access && !Master_matrix::Option_list::has_removable_rows) {
481
+ if (boundary.size() != 0){
482
+ ID_index pivot;
483
+ if constexpr (Master_matrix::Option_list::is_z2) {
484
+ pivot = *std::prev(boundary.end());
485
+ } else {
486
+ pivot = std::prev(boundary.end())->first;
487
+ }
488
+ //row container
489
+ if (RA_opt::rows_->size() <= pivot) RA_opt::rows_->resize(pivot + 1);
490
+ }
491
+ }
492
+
493
+ //row swap map containers
494
+ if constexpr (Master_matrix::Option_list::has_map_column_container) {
495
+ if constexpr (activeSwapOption) {
496
+ Swap_opt::indexToRow_.emplace(cellIndex, cellIndex);
497
+ Swap_opt::rowToIndex_.emplace(cellIndex, cellIndex);
498
+ }
499
+ } else {
500
+ if constexpr (activeSwapOption) {
501
+ for (Index i = Swap_opt::indexToRow_.size(); i <= cellIndex; ++i) {
502
+ Swap_opt::indexToRow_.push_back(i);
503
+ Swap_opt::rowToIndex_.push_back(i);
504
+ }
505
+ }
506
+ }
507
+
508
+ //maps for possible shifting between column content and position indices used for birth events
509
+ if constexpr (activePairingOption){
510
+ if (cellIndex != nextInsertIndex_){
511
+ Pair_opt::idToPosition_.emplace(cellIndex, nextInsertIndex_);
512
+ if constexpr (Master_matrix::Option_list::has_removable_columns){
513
+ Pair_opt::PIDM::map_.emplace(nextInsertIndex_, cellIndex);
514
+ }
515
+ }
516
+ }
517
+
518
+ _container_insert(boundary, nextInsertIndex_, dim);
519
+
520
+ return nextInsertIndex_++;
521
+ }
522
+
523
+ template <class Master_matrix>
524
+ inline typename Boundary_matrix<Master_matrix>::Column& Boundary_matrix<Master_matrix>::get_column(Index columnIndex)
525
+ {
526
+ _orderRowsIfNecessary();
527
+
528
+ return _get_column(columnIndex);
529
+ }
530
+
531
+ template <class Master_matrix>
532
+ inline typename Boundary_matrix<Master_matrix>::Row& Boundary_matrix<Master_matrix>::get_row(Index rowIndex)
533
+ {
534
+ static_assert(Master_matrix::Option_list::has_row_access, "'get_row' is not implemented for the chosen options.");
535
+
536
+ _orderRowsIfNecessary();
537
+
538
+ return RA_opt::get_row(rowIndex);
539
+ }
540
+
541
+ template <class Master_matrix>
542
+ inline typename Boundary_matrix<Master_matrix>::Index Boundary_matrix<Master_matrix>::remove_last()
543
+ {
544
+ static_assert(Master_matrix::Option_list::has_removable_columns,
545
+ "'remove_last' is not implemented for the chosen options.");
546
+
547
+ if (nextInsertIndex_ == 0) return -1; // empty matrix
548
+ --nextInsertIndex_;
549
+
550
+ //updates dimension max
551
+ if constexpr (activeDimOption) {
552
+ Dim_opt::update_down(matrix_.at(nextInsertIndex_).get_dimension());
553
+ }
554
+
555
+ //computes pivot and removes column from matrix_
556
+ ID_index pivot;
557
+ if constexpr (Master_matrix::Option_list::has_map_column_container) {
558
+ auto it = matrix_.find(nextInsertIndex_);
559
+ pivot = it->second.get_pivot();
560
+ if constexpr (activeSwapOption) {
561
+ // if the removed column is positive, the pivot won't change value
562
+ if (Swap_opt::rowSwapped_ && pivot != static_cast<ID_index>(-1)) {
563
+ Swap_opt::_orderRows();
564
+ pivot = it->second.get_pivot();
565
+ }
566
+ }
567
+ matrix_.erase(it);
568
+ } else {
569
+ pivot = matrix_[nextInsertIndex_].get_pivot();
570
+ if constexpr (activeSwapOption) {
571
+ // if the removed column is positive, the pivot won't change value
572
+ if (Swap_opt::rowSwapped_ && pivot != static_cast<ID_index>(-1)) {
573
+ Swap_opt::_orderRows();
574
+ pivot = matrix_[nextInsertIndex_].get_pivot();
575
+ }
576
+ }
577
+ if constexpr (Master_matrix::Option_list::has_row_access) {
578
+ GUDHI_CHECK(nextInsertIndex_ == matrix_.size() - 1,
579
+ std::logic_error("Boundary_matrix::remove_last - Indexation problem."));
580
+ matrix_.pop_back();
581
+ } else {
582
+ matrix_[nextInsertIndex_].clear();
583
+ }
584
+ }
585
+
586
+ erase_empty_row(nextInsertIndex_); // maximal, so empty
587
+
588
+ //updates barcode
589
+ if constexpr (activePairingOption) {
590
+ Pair_opt::_remove_last(nextInsertIndex_);
591
+ }
592
+
593
+ return pivot;
594
+ }
595
+
596
+ template <class Master_matrix>
597
+ inline void Boundary_matrix<Master_matrix>::erase_empty_row(Index rowIndex)
598
+ {
599
+ //computes real row index and erases it if necessary from the row swap map containers
600
+ ID_index rowID = rowIndex;
601
+ if constexpr (activeSwapOption) {
602
+ if constexpr (Master_matrix::Option_list::has_map_column_container) {
603
+ auto it = Swap_opt::indexToRow_.find(rowIndex);
604
+ rowID = it->second;
605
+ Swap_opt::rowToIndex_.erase(rowID);
606
+ Swap_opt::indexToRow_.erase(it);
607
+ } else {
608
+ rowID = Swap_opt::indexToRow_[rowIndex];
609
+ }
610
+ }
611
+
612
+ if constexpr (Master_matrix::Option_list::has_row_access && Master_matrix::Option_list::has_removable_rows) {
613
+ RA_opt::erase_empty_row(rowID);
614
+ }
615
+ }
616
+
617
+ template <class Master_matrix>
618
+ inline typename Boundary_matrix<Master_matrix>::Index Boundary_matrix<Master_matrix>::get_number_of_columns() const
619
+ {
620
+ if constexpr (Master_matrix::Option_list::has_map_column_container) {
621
+ return matrix_.size();
622
+ } else {
623
+ return nextInsertIndex_; // matrix could have been resized much bigger while insert
624
+ }
625
+ }
626
+
627
+ template <class Master_matrix>
628
+ inline typename Boundary_matrix<Master_matrix>::Dimension Boundary_matrix<Master_matrix>::get_column_dimension(
629
+ Index columnIndex) const
630
+ {
631
+ return _get_column(columnIndex).get_dimension();
632
+ }
633
+
634
+ template <class Master_matrix>
635
+ inline void Boundary_matrix<Master_matrix>::add_to(Index sourceColumnIndex, Index targetColumnIndex)
636
+ {
637
+ _get_column(targetColumnIndex) += _get_column(sourceColumnIndex);
638
+ }
639
+
640
+ template <class Master_matrix>
641
+ inline void Boundary_matrix<Master_matrix>::multiply_target_and_add_to(Index sourceColumnIndex,
642
+ const Field_element& coefficient,
643
+ Index targetColumnIndex)
644
+ {
645
+ _get_column(targetColumnIndex).multiply_target_and_add(coefficient, _get_column(sourceColumnIndex));
646
+ }
647
+
648
+ template <class Master_matrix>
649
+ inline void Boundary_matrix<Master_matrix>::multiply_source_and_add_to(const Field_element& coefficient,
650
+ Index sourceColumnIndex,
651
+ Index targetColumnIndex)
652
+ {
653
+ _get_column(targetColumnIndex).multiply_source_and_add(_get_column(sourceColumnIndex), coefficient);
654
+ }
655
+
656
+ template <class Master_matrix>
657
+ inline void Boundary_matrix<Master_matrix>::zero_entry(Index columnIndex, Index rowIndex)
658
+ {
659
+ _get_column(columnIndex).clear(_get_real_row_index(rowIndex));
660
+ }
661
+
662
+ template <class Master_matrix>
663
+ inline void Boundary_matrix<Master_matrix>::zero_column(Index columnIndex)
664
+ {
665
+ _get_column(columnIndex).clear();
666
+ }
667
+
668
+ template <class Master_matrix>
669
+ inline bool Boundary_matrix<Master_matrix>::is_zero_entry(Index columnIndex, Index rowIndex) const
670
+ {
671
+ return !(_get_column(columnIndex).is_non_zero(_get_real_row_index(rowIndex)));
672
+ }
673
+
674
+ template <class Master_matrix>
675
+ inline bool Boundary_matrix<Master_matrix>::is_zero_column(Index columnIndex)
676
+ {
677
+ return _get_column(columnIndex).is_empty();
678
+ }
679
+
680
+ template <class Master_matrix>
681
+ inline typename Boundary_matrix<Master_matrix>::Index Boundary_matrix<Master_matrix>::get_pivot(Index columnIndex)
682
+ {
683
+ _orderRowsIfNecessary();
684
+
685
+ return _get_column(columnIndex).get_pivot();
686
+ }
687
+
688
+ template <class Master_matrix>
689
+ inline Boundary_matrix<Master_matrix>& Boundary_matrix<Master_matrix>::operator=(const Boundary_matrix& other)
690
+ {
691
+ Dim_opt::operator=(other);
692
+ Swap_opt::operator=(other);
693
+ Pair_opt::operator=(other);
694
+ RA_opt::operator=(other);
695
+
696
+ matrix_.clear();
697
+ nextInsertIndex_ = other.nextInsertIndex_;
698
+ colSettings_ = other.colSettings_;
699
+
700
+ matrix_.reserve(other.matrix_.size());
701
+ for (const auto& cont : other.matrix_){
702
+ if constexpr (Master_matrix::Option_list::has_map_column_container){
703
+ _container_insert(cont.second, cont.first);
704
+ } else {
705
+ _container_insert(cont);
706
+ }
707
+ }
708
+
709
+ return *this;
710
+ }
711
+
712
+ template <class Master_matrix>
713
+ inline void Boundary_matrix<Master_matrix>::print(Index startCol, Index endCol, Index startRow, Index endRow)
714
+ {
715
+ if (endCol == static_cast<Index>(-1)) endCol = nextInsertIndex_;
716
+ if (endRow == static_cast<Index>(-1)) endRow = nextInsertIndex_;
717
+ if constexpr (activeSwapOption) {
718
+ if (Swap_opt::rowSwapped_) Swap_opt::_orderRows();
719
+ }
720
+ std::cout << "Boundary_matrix:\n";
721
+ for (Index i = startCol; i < endCol && i < nextInsertIndex_; ++i) {
722
+ Column& col = matrix_[i];
723
+ auto cont = col.get_content(endRow);
724
+ for (Index j = startRow; j < endRow; ++j) {
725
+ if (cont[j] == 0u)
726
+ std::cout << "- ";
727
+ else
728
+ std::cout << cont[j] << " ";
729
+ }
730
+ std::cout << "\n";
731
+ }
732
+ std::cout << "\n";
733
+ if constexpr (Master_matrix::Option_list::has_row_access) {
734
+ std::cout << "Row Matrix:\n";
735
+ for (ID_index i = startRow; i < endRow && i < nextInsertIndex_; ++i) {
736
+ const auto& row = (*RA_opt::rows_)[i];
737
+ auto it = row.begin();
738
+ std::advance(it, startCol);
739
+ for (; it != row.end() && startCol < endCol; ++it, ++startCol) {
740
+ std::cout << it->get_column_index() << " ";
741
+ }
742
+ std::cout << "(" << i << ")\n";
743
+ }
744
+ std::cout << "\n";
745
+ }
746
+ }
747
+
748
+ template <class Master_matrix>
749
+ inline void Boundary_matrix<Master_matrix>::_orderRowsIfNecessary()
750
+ {
751
+ if constexpr (activeSwapOption) {
752
+ if (Swap_opt::rowSwapped_) Swap_opt::_orderRows();
753
+ }
754
+ }
755
+
756
+ template <class Master_matrix>
757
+ inline const typename Boundary_matrix<Master_matrix>::Column& Boundary_matrix<Master_matrix>::_get_column(
758
+ Index columnIndex) const
759
+ {
760
+ if constexpr (Master_matrix::Option_list::has_map_column_container) {
761
+ return matrix_.at(columnIndex);
762
+ } else {
763
+ return matrix_[columnIndex];
764
+ }
765
+ }
766
+
767
+ template <class Master_matrix>
768
+ inline typename Boundary_matrix<Master_matrix>::Column& Boundary_matrix<Master_matrix>::_get_column(
769
+ Index columnIndex)
770
+ {
771
+ if constexpr (Master_matrix::Option_list::has_map_column_container) {
772
+ return matrix_.at(columnIndex);
773
+ } else {
774
+ return matrix_[columnIndex];
775
+ }
776
+ }
777
+
778
+ template <class Master_matrix>
779
+ inline typename Boundary_matrix<Master_matrix>::Index Boundary_matrix<Master_matrix>::_get_real_row_index(
780
+ Index rowIndex) const
781
+ {
782
+ if constexpr (Master_matrix::Option_list::has_column_and_row_swaps || Master_matrix::Option_list::has_vine_update) {
783
+ if constexpr (Master_matrix::Option_list::has_map_column_container) {
784
+ return Swap_opt::indexToRow_.at(rowIndex);
785
+ } else {
786
+ return Swap_opt::indexToRow_[rowIndex];
787
+ }
788
+ } else {
789
+ return rowIndex;
790
+ }
791
+ }
792
+
793
+ template <class Master_matrix>
794
+ template <class Container>
795
+ inline void Boundary_matrix<Master_matrix>::_container_insert(const Container& column,
796
+ Index pos,
797
+ Dimension dim)
798
+ {
799
+ if constexpr (Master_matrix::Option_list::has_map_column_container) {
800
+ if constexpr (Master_matrix::Option_list::has_row_access) {
801
+ matrix_.try_emplace(pos, Column(pos, column, dim, RA_opt::rows_, colSettings_));
802
+ } else {
803
+ matrix_.try_emplace(pos, Column(column, dim, colSettings_));
804
+ }
805
+ } else {
806
+ if constexpr (Master_matrix::Option_list::has_row_access) {
807
+ matrix_.emplace_back(pos, column, dim, RA_opt::rows_, colSettings_);
808
+ } else {
809
+ if (matrix_.size() <= pos) {
810
+ matrix_.emplace_back(column, dim, colSettings_);
811
+ } else {
812
+ matrix_[pos] = Column(column, dim, colSettings_);
813
+ }
814
+ }
815
+ }
816
+ if constexpr (activeDimOption) {
817
+ Dim_opt::update_up(dim);
818
+ }
819
+ }
820
+
821
+ template <class Master_matrix>
822
+ inline void Boundary_matrix<Master_matrix>::_container_insert(const Column& column, [[maybe_unused]] Index pos)
823
+ {
824
+ if constexpr (Master_matrix::Option_list::has_map_column_container) {
825
+ if constexpr (Master_matrix::Option_list::has_row_access) {
826
+ matrix_.try_emplace(pos, Column(column, column.get_column_index(), RA_opt::rows_, colSettings_));
827
+ } else {
828
+ matrix_.try_emplace(pos, Column(column, colSettings_));
829
+ }
830
+ } else {
831
+ if constexpr (Master_matrix::Option_list::has_row_access) {
832
+ matrix_.emplace_back(column, column.get_column_index(), RA_opt::rows_, colSettings_);
833
+ } else {
834
+ matrix_.emplace_back(column, colSettings_);
835
+ }
836
+ }
837
+ }
838
+
839
+ } // namespace persistence_matrix
840
+ } // namespace Gudhi
841
+
842
+ #endif // PM_BOUNDARY_MATRIX_H