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,910 @@
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 RU_matrix.h
13
+ * @author Hannah Schreiber
14
+ * @brief Contains the @ref Gudhi::persistence_matrix::RU_matrix class.
15
+ */
16
+
17
+ #ifndef PM_RU_MATRIX_H
18
+ #define PM_RU_MATRIX_H
19
+
20
+ #include <vector>
21
+ #include <utility> //std::swap, std::move & std::exchange
22
+ #include <iostream> //print() only
23
+
24
+ namespace Gudhi {
25
+ namespace persistence_matrix {
26
+
27
+ /**
28
+ * @class RU_matrix RU_matrix.h gudhi/Persistence_matrix/RU_matrix.h
29
+ * @ingroup persistence_matrix
30
+ *
31
+ * @brief %Matrix structure to store the ordered @ref boundarymatrix "boundary matrix" \f$ R \cdot U \f$ of a filtered
32
+ * complex in order to compute its persistent homology, as well as representative cycles.
33
+ * Supports vineyards (see @cite vineyards) and the removal of maximal cells while maintaining
34
+ * a valid barcode. Provides an access to its columns and rows.
35
+ *
36
+ * @tparam Master_matrix An instantiation of @ref Matrix from which all types and options are deduced.
37
+ */
38
+ template <class Master_matrix>
39
+ class RU_matrix : public Master_matrix::RU_pairing_option,
40
+ public Master_matrix::RU_vine_swap_option,
41
+ public Master_matrix::RU_representative_cycles_option
42
+ {
43
+ public:
44
+ /**
45
+ * @brief Field operators class. Necessary only if @ref PersistenceMatrixOptions::is_z2 is false.
46
+ */
47
+ using Field_operators = typename Master_matrix::Field_operators;
48
+ using Field_element = typename Master_matrix::Element; /**< Type of an field element. */
49
+ using Column = typename Master_matrix::Column; /**< Column type. */
50
+ using Row = typename Master_matrix::Row; /**< Row type,
51
+ only necessary with row access option. */
52
+ using Entry_constructor = typename Master_matrix::Entry_constructor; /**< Factory of @ref Entry classes. */
53
+ using Column_settings = typename Master_matrix::Column_settings; /**< Structure giving access to the columns to
54
+ necessary external classes. */
55
+ using Boundary = typename Master_matrix::Boundary; /**< Type of an input column. */
56
+ using Index = typename Master_matrix::Index; /**< @ref MatIdx index type. */
57
+ using ID_index = typename Master_matrix::ID_index; /**< @ref IDIdx index type. */
58
+ using Pos_index = typename Master_matrix::Pos_index; /**< @ref PosIdx index type. */
59
+ using Dimension = typename Master_matrix::Dimension; /**< Dimension value type. */
60
+
61
+ /**
62
+ * @brief Constructs an empty matrix.
63
+ *
64
+ * @param colSettings Pointer to an existing setting structure for the columns. The structure should contain all
65
+ * the necessary external classes specifically necessary for the choosen column type, such as custom allocators.
66
+ */
67
+ RU_matrix(Column_settings* colSettings);
68
+ /**
69
+ * @brief Constructs a new matrix from the given ranges of @ref Matrix::Entry_representative. Each range corresponds
70
+ * to a column (the order of the ranges are preserved). The content of the ranges is assumed to be sorted by
71
+ * increasing IDs. The IDs of the simplices are also assumed to be consecutive, ordered by filtration value, starting
72
+ * with 0.
73
+ *
74
+ * @tparam Boundary_range Range type for @ref Matrix::Entry_representative ranges.
75
+ * Assumed to have a begin(), end() and size() method.
76
+ * @param orderedBoundaries Range of boundaries: @p orderedBoundaries is interpreted as a boundary matrix of a
77
+ * filtered **simplicial** complex, whose boundaries are ordered by filtration order.
78
+ * Therefore, `orderedBoundaries[i]` should store the boundary of the \f$ i^{th} \f$ simplex in the filtration,
79
+ * as an ordered list of indices of its facets (again those indices correspond to their respective position
80
+ * in the matrix). That is why the indices of the simplices are assumed to be consecutive and starting with 0
81
+ * (an empty boundary is interpreted as a vertex boundary and not as a non existing simplex).
82
+ * All dimensions up to the maximal dimension of interest have to be present. If only a higher dimension is of
83
+ * interest and not everything should be stored, then use the @ref insert_boundary method instead (after creating the
84
+ * matrix with the @ref RU_matrix(unsigned int, Column_settings*) constructor preferably).
85
+ * @param colSettings Pointer to an existing setting structure for the columns. The structure should contain all
86
+ * the necessary external classes specifically necessary for the choosen column type, such as custom allocators.
87
+ */
88
+ template <class Boundary_range = Boundary>
89
+ RU_matrix(const std::vector<Boundary_range>& orderedBoundaries, Column_settings* colSettings);
90
+ /**
91
+ * @brief Constructs a new empty matrix and reserves space for the given number of columns.
92
+ *
93
+ * @param numberOfColumns Number of columns to reserve space for.
94
+ * @param colSettings Pointer to an existing setting structure for the columns. The structure should contain all
95
+ * the necessary external classes specifically necessary for the choosen column type, such as custom allocators.
96
+ */
97
+ RU_matrix(unsigned int numberOfColumns, Column_settings* colSettings);
98
+ /**
99
+ * @brief Copy constructor. If @p colSettings is not a null pointer, its value is kept
100
+ * instead of the one in the copied matrix.
101
+ *
102
+ * @param matrixToCopy Matrix to copy.
103
+ * @param colSettings Either a pointer to an existing setting structure for the columns or a null pointer.
104
+ * The structure should contain all the necessary external classes specifically necessary for the choosen column type,
105
+ * such as custom allocators. If null pointer, the pointer stored in @p matrixToCopy is used instead.
106
+ */
107
+ RU_matrix(const RU_matrix& matrixToCopy, Column_settings* colSettings = nullptr);
108
+ /**
109
+ * @brief Move constructor.
110
+ *
111
+ * @param other Matrix to move.
112
+ */
113
+ RU_matrix(RU_matrix&& other) noexcept;
114
+
115
+ /**
116
+ * @brief Inserts at the end of the matrix a new ordered column corresponding to the given boundary.
117
+ * This means that it is assumed that this method is called on boundaries in the order of the filtration.
118
+ * It also assumes that the cells in the given boundary are identified by their relative position in the filtration,
119
+ * starting at 0. If it is not the case, use the other
120
+ * @ref insert_boundary(ID_index, const Boundary_range&, Dimension) "insert_boundary" instead by indicating the
121
+ * cell ID used in the boundaries when the cell is inserted.
122
+ *
123
+ * Different to the constructor, the boundaries do not have to come from a simplicial complex, but also from
124
+ * a more general entry complex. This includes cubical complexes or Morse complexes for example.
125
+ *
126
+ * At the insertion, the boundary is stored in its reduced form and the barcode, if enabled, is updated.
127
+ *
128
+ * @tparam Boundary_range Range of @ref Matrix::Entry_representative. Assumed to have a begin(), end() and size()
129
+ * method.
130
+ * @param boundary Boundary generating the new column. The content should be ordered by ID.
131
+ * @param dim Dimension of the cell whose boundary is given. If the complex is simplicial,
132
+ * this parameter can be omitted as it can be deduced from the size of the boundary.
133
+ */
134
+ template <class Boundary_range = Boundary>
135
+ void insert_boundary(const Boundary_range& boundary, Dimension dim = -1);
136
+ /**
137
+ * @brief It does the same as the other version, but allows the boundary cells to be identified without restrictions
138
+ * except that all IDs have to be strictly increasing in the order of filtration. Note that you should avoid then
139
+ * to use the other insertion method to avoid overwriting IDs.
140
+ *
141
+ * As a cell has to be inserted before one of its cofaces in a valid filtration (recall that it is assumed that
142
+ * the cells are inserted by order of filtration), it is sufficient to indicate the ID of the cell being inserted.
143
+ *
144
+ * @tparam Boundary_range Range of @ref Matrix::Entry_representative. Assumed to have a begin(), end() and size()
145
+ * method.
146
+ * @param cellIndex @ref IDIdx index to use to identify the new cell.
147
+ * @param boundary Boundary generating the new column. The indices of the boundary have to correspond to the
148
+ * @p cellIndex values of precedent calls of the method for the corresponding cells and should be ordered in
149
+ * increasing order.
150
+ * @param dim Dimension of the cell whose boundary is given. If the complex is simplicial,
151
+ * this parameter can be omitted as it can be deduced from the size of the boundary.
152
+ */
153
+ template <class Boundary_range = Boundary>
154
+ void insert_boundary(ID_index cellIndex, const Boundary_range& boundary, Dimension dim = -1);
155
+ /**
156
+ * @brief Returns the column at the given @ref MatIdx index in \f$ R \f$ if @p inR is true and
157
+ * in \f$ U \f$ if @p inR is false.
158
+ * The type of the column depends on the choosen options, see @ref PersistenceMatrixOptions::column_type.
159
+ *
160
+ * Note that before returning the column, all column entries can eventually be reordered, if lazy swaps occurred.
161
+ * It is therefore recommended to avoid calling @ref get_column between vine swaps, otherwise the benefits
162
+ * of the the laziness is lost.
163
+ *
164
+ * @param columnIndex @ref MatIdx index of the column to return.
165
+ * @param inR If true, returns the column in \f$ R \f$, if false, returns the column in \f$ U \f$.
166
+ * Default value: true.
167
+ * @return Reference to the column.
168
+ */
169
+ Column& get_column(Index columnIndex, bool inR = true);
170
+ /**
171
+ * @brief Returns the row at the given @ref rowindex "row index" in \f$ R \f$ if @p inR is true and
172
+ * in \f$ U \f$ if @p inR is false.
173
+ * The type of the row depends on the choosen options, see @ref PersistenceMatrixOptions::has_intrusive_rows.
174
+ *
175
+ * Note that before returning the row, all column entries can eventually be reordered, if lazy swaps occurred.
176
+ * It is therefore recommended to avoid calling @ref get_row between vine swaps, otherwise the benefits
177
+ * of the the laziness is lost.
178
+ *
179
+ * @param rowIndex @ref rowindex "Row index" of the row to return.
180
+ * @param inR If true, returns the row in \f$ R \f$, if false, returns the row in \f$ U \f$.
181
+ * Default value: true.
182
+ * @return Reference to the row.
183
+ */
184
+ Row& get_row(Index rowIndex, bool inR = true);
185
+ /**
186
+ * @brief If @ref PersistenceMatrixOptions::has_row_access and @ref PersistenceMatrixOptions::has_removable_rows
187
+ * are true: assumes that the row is empty in \f$ R \f$ and removes it from \f$ R \f$. If the matrix is valid,
188
+ * a row will never be empty in \f$ U \f$, so \f$ U \f$ won't be affected.
189
+ * If @ref PersistenceMatrixOptions::has_map_column_container
190
+ * and @ref PersistenceMatrixOptions::has_column_and_row_swaps are true: cleans up maps used for the lazy row swaps.
191
+ * Otherwise, does nothing.
192
+ *
193
+ * @warning The removed rows are always assumed to be empty in \f$ R \f$. If it is not the case, the deleted row
194
+ * entries are not removed from their columns. And in the case of intrusive rows, this will generate a segmentation
195
+ * fault when the column entries are destroyed later. The row access is just meant as a "read only" access to the
196
+ * rows and the @ref erase_empty_row method just as a way to specify that a row is empty and can therefore be removed
197
+ * from dictionaries. This allows to avoid testing the emptiness of a row at each column entry removal, what can
198
+ * be quite frequent.
199
+ *
200
+ * @param rowIndex @ref rowindex "Row index" of the empty row.
201
+ */
202
+ void erase_empty_row(Index rowIndex);
203
+ /**
204
+ * @brief Only available if @ref PersistenceMatrixOptions::has_removable_columns and
205
+ * @ref PersistenceMatrixOptions::has_vine_update are true.
206
+ * Assumes that the cell is maximal in the current complex and removes it such that the matrix remains consistent
207
+ * (i.e., RU is still an upper triangular decomposition of the @ref boundarymatrix "boundary matrix").
208
+ * The maximality of the cell is not verified.
209
+ * Also updates the barcode if it is stored.
210
+ *
211
+ * See also @ref remove_last.
212
+ *
213
+ * @param columnIndex @ref MatIdx index of the cell to remove.
214
+ */
215
+ void remove_maximal_cell(Index columnIndex);
216
+ /**
217
+ * @brief Only available if @ref PersistenceMatrixOptions::has_removable_columns is true.
218
+ * Removes the last cell in the filtration from the matrix and updates the barcode if it is stored.
219
+ *
220
+ * See also @ref remove_maximal_cell.
221
+ */
222
+ void remove_last();
223
+
224
+ /**
225
+ * @brief Returns the maximal dimension of a cell stored in the matrix.
226
+ * Only available if @ref PersistenceMatrixOptions::has_matrix_maximal_dimension_access is true.
227
+ *
228
+ * @return The maximal dimension.
229
+ */
230
+ Dimension get_max_dimension() const;
231
+ /**
232
+ * @brief Returns the current number of columns in the matrix.
233
+ *
234
+ * @return The number of columns.
235
+ */
236
+ Index get_number_of_columns() const;
237
+ /**
238
+ * @brief Returns the dimension of the given column.
239
+ *
240
+ * @param columnIndex @ref MatIdx index of the column representing the cell.
241
+ * @return Dimension of the cell.
242
+ */
243
+ Dimension get_column_dimension(Index columnIndex) const;
244
+
245
+ /**
246
+ * @brief Adds column at @p sourceColumnIndex onto the column at @p targetColumnIndex in the matrix.
247
+ *
248
+ * @warning They will be no verification to ensure that the addition makes sense for the validity of a
249
+ * boundary matrix of a filtered complex. For example, a right-to-left addition could corrupt the computation
250
+ * of the barcode if done blindly. So should be used with care.
251
+ *
252
+ * @param sourceColumnIndex @ref MatIdx index of the source column.
253
+ * @param targetColumnIndex @ref MatIdx index of the target column.
254
+ */
255
+ void add_to(Index sourceColumnIndex, Index targetColumnIndex);
256
+ /**
257
+ * @brief Multiplies the target column with the coefficient and then adds the source column to it.
258
+ * That is: `targetColumn = (targetColumn * coefficient) + sourceColumn`.
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 sourceColumnIndex @ref MatIdx index of the source column.
265
+ * @param coefficient Value to multiply.
266
+ * @param targetColumnIndex @ref MatIdx index of the target column.
267
+ */
268
+ void multiply_target_and_add_to(Index sourceColumnIndex, const Field_element& coefficient, Index targetColumnIndex);
269
+ /**
270
+ * @brief Multiplies the source column with the coefficient before adding it to the target column.
271
+ * That is: `targetColumn += (coefficient * sourceColumn)`. The source column will **not** be modified.
272
+ *
273
+ * @warning They will be no verification to ensure that the addition makes sense for the validity of a
274
+ * boundary matrix of a filtered complex. For example, a right-to-left addition could corrupt the computation
275
+ * of the barcode if done blindly. So should be used with care.
276
+ *
277
+ * @param coefficient Value to multiply.
278
+ * @param sourceColumnIndex @ref MatIdx index of the source column.
279
+ * @param targetColumnIndex @ref MatIdx index of the target column.
280
+ */
281
+ void multiply_source_and_add_to(const Field_element& coefficient, Index sourceColumnIndex, Index targetColumnIndex);
282
+
283
+ /**
284
+ * @brief Zeroes the entry at the given coordinates in \f$ R \f$ if @p inR is true or in
285
+ * \f$ U \f$ if @p inR is false. Should be used with care to not destroy the validity of the persistence
286
+ * related properties of the matrix.
287
+ *
288
+ * @param columnIndex @ref MatIdx index of the column of the entry.
289
+ * @param rowIndex @ref rowindex "Row index" of the row of the entry.
290
+ * @param inR Boolean indicating in which matrix to zero: if true in \f$ R \f$ and if false in \f$ U \f$.
291
+ * Default value: true.
292
+ */
293
+ void zero_entry(Index columnIndex, Index rowIndex, bool inR = true);
294
+ /**
295
+ * @brief Zeroes the column at the given index in \f$ R \f$ if @p inR is true or in
296
+ * \f$ U \f$ if @p inR is false. Should be used with care to not destroy the validity of the persistence
297
+ * related properties of the matrix.
298
+ *
299
+ * @param columnIndex @ref MatIdx index of the column to zero.
300
+ * @param inR Boolean indicating in which matrix to zero: if true in \f$ R \f$ and if false in \f$ U \f$.
301
+ * Default value: true.
302
+ */
303
+ void zero_column(Index columnIndex, bool inR = true);
304
+ /**
305
+ * @brief Indicates if the entry at given coordinates has value zero in \f$ R \f$
306
+ * if @p inR is true or in \f$ U \f$ if @p inR is false.
307
+ *
308
+ * @param columnIndex @ref MatIdx index of the column of the entry.
309
+ * @param rowIndex @ref rowindex "Row index" of the row of the entry.
310
+ * @param inR Boolean indicating in which matrix to look: if true in \f$ R \f$ and if false in \f$ U \f$.
311
+ * Default value: true.
312
+ * @return true If the entry has value zero.
313
+ * @return false Otherwise.
314
+ */
315
+ bool is_zero_entry(Index columnIndex, Index rowIndex, bool inR = true) const;
316
+ /**
317
+ * @brief Indicates if the column at given index has value zero in \f$ R \f$
318
+ * if @p inR is true or in \f$ U \f$ if @p inR is false.
319
+ *
320
+ * Note that if @p inR is false, this method should usually return false.
321
+ *
322
+ * @param columnIndex @ref MatIdx index of the column.
323
+ * @param inR Boolean indicating in which matrix to look: if true in \f$ R \f$ and if false in \f$ U \f$.
324
+ * Default value: true.
325
+ * @return true If the column has value zero.
326
+ * @return false Otherwise.
327
+ */
328
+ bool is_zero_column(Index columnIndex, bool inR = true);
329
+
330
+ /**
331
+ * @brief Returns the @ref MatIdx index of the column which has the given @ref rowindex "row index" as pivot in
332
+ * \f$ R \f$. Assumes that the pivot exists.
333
+ *
334
+ * @param cellIndex @ref rowindex "Row index" of the pivot.
335
+ * @return @ref MatIdx index of the column in \f$ R \f$ with the given pivot.
336
+ */
337
+ Index get_column_with_pivot(Index cellIndex) const;
338
+ /**
339
+ * @brief Returns the @ref rowindex "row index" of the pivot of the given column in \f$ R \f$.
340
+ *
341
+ * @param columnIndex @ref MatIdx index of the column in \f$ R \f$.
342
+ * @return The @ref rowindex "row index" of the pivot.
343
+ */
344
+ Index get_pivot(Index columnIndex);
345
+
346
+ /**
347
+ * @brief Resets the matrix to an empty matrix.
348
+ *
349
+ * @param colSettings Pointer to an existing setting structure for the columns. The structure should contain all
350
+ * the necessary external classes specifically necessary for the choosen column type, such as custom allocators.
351
+ */
352
+ void reset(Column_settings* colSettings) {
353
+ reducedMatrixR_.reset(colSettings);
354
+ mirrorMatrixU_.reset(colSettings);
355
+ pivotToColumnIndex_.clear();
356
+ nextEventIndex_ = 0;
357
+ if constexpr (!Master_matrix::Option_list::is_z2) {
358
+ operators_ = &(colSettings->operators);
359
+ }
360
+ }
361
+
362
+ /**
363
+ * @brief Assign operator.
364
+ */
365
+ RU_matrix& operator=(const RU_matrix& other);
366
+ /**
367
+ * @brief Swap operator.
368
+ */
369
+ friend void swap(RU_matrix& matrix1, RU_matrix& matrix2) {
370
+ swap(static_cast<typename Master_matrix::RU_pairing_option&>(matrix1),
371
+ static_cast<typename Master_matrix::RU_pairing_option&>(matrix2));
372
+ swap(static_cast<typename Master_matrix::RU_vine_swap_option&>(matrix1),
373
+ static_cast<typename Master_matrix::RU_vine_swap_option&>(matrix2));
374
+ swap(static_cast<typename Master_matrix::RU_representative_cycles_option&>(matrix1),
375
+ static_cast<typename Master_matrix::RU_representative_cycles_option&>(matrix2));
376
+ swap(matrix1.reducedMatrixR_, matrix2.reducedMatrixR_);
377
+ swap(matrix1.mirrorMatrixU_, matrix2.mirrorMatrixU_);
378
+ matrix1.pivotToColumnIndex_.swap(matrix2.pivotToColumnIndex_);
379
+ std::swap(matrix1.nextEventIndex_, matrix2.nextEventIndex_);
380
+ std::swap(matrix1.operators_, matrix2.operators_);
381
+ }
382
+
383
+ void print(Index startCol = 0, Index endCol = -1, Index startRow = 0, Index endRow = -1); // for debug
384
+
385
+ private:
386
+ using Swap_opt = typename Master_matrix::RU_vine_swap_option;
387
+ using Pair_opt = typename Master_matrix::RU_pairing_option;
388
+ using Rep_opt = typename Master_matrix::RU_representative_cycles_option;
389
+ using Dictionary = typename Master_matrix::template Dictionary<Index>;
390
+ using Barcode = typename Master_matrix::Barcode;
391
+ using Bar_dictionary = typename Master_matrix::Bar_dictionary;
392
+ using R_matrix = typename Master_matrix::Master_boundary_matrix;
393
+ using U_matrix = typename Master_matrix::Master_base_matrix;
394
+
395
+ friend Rep_opt; // direct access to the two matrices
396
+ friend Swap_opt; // direct access to the two matrices
397
+
398
+ R_matrix reducedMatrixR_; /**< R. */
399
+ // TODO: make U not accessible by default and add option to enable access? Inaccessible, it
400
+ // needs less options and we could avoid some ifs.
401
+ U_matrix mirrorMatrixU_; /**< U. */
402
+ Dictionary pivotToColumnIndex_; /**< Map from pivot row index to column @ref MatIdx index. */
403
+ Pos_index nextEventIndex_; /**< Next birth or death index. */
404
+ Field_operators* operators_; /**< Field operators,
405
+ can be nullptr if @ref PersistenceMatrixOptions::is_z2 is true. */
406
+
407
+ void _insert_boundary(Index currentIndex);
408
+ void _initialize_U();
409
+ void _reduce();
410
+ void _reduce_last_column(Index lastIndex);
411
+ void _reduce_column(Index target, Index eventIndex);
412
+ void _reduce_column_by(Index target, Index source);
413
+ void _update_barcode(ID_index birthPivot, Pos_index death);
414
+ void _add_bar(Dimension dim, Pos_index birth);
415
+ void _remove_last_in_barcode(Pos_index eventIndex);
416
+
417
+ constexpr Bar_dictionary& _indexToBar();
418
+ };
419
+
420
+ template <class Master_matrix>
421
+ inline RU_matrix<Master_matrix>::RU_matrix(Column_settings* colSettings)
422
+ : Pair_opt(),
423
+ Swap_opt(),
424
+ Rep_opt(),
425
+ reducedMatrixR_(colSettings),
426
+ mirrorMatrixU_(colSettings),
427
+ nextEventIndex_(0),
428
+ operators_(nullptr)
429
+ {
430
+ if constexpr (!Master_matrix::Option_list::is_z2) {
431
+ operators_ = &(colSettings->operators);
432
+ }
433
+ }
434
+
435
+ template <class Master_matrix>
436
+ template <class Boundary_range>
437
+ inline RU_matrix<Master_matrix>::RU_matrix(const std::vector<Boundary_range>& orderedBoundaries,
438
+ Column_settings* colSettings)
439
+ : Pair_opt(),
440
+ Swap_opt(),
441
+ Rep_opt(),
442
+ reducedMatrixR_(orderedBoundaries, colSettings),
443
+ mirrorMatrixU_(orderedBoundaries.size(), colSettings),
444
+ nextEventIndex_(orderedBoundaries.size()),
445
+ operators_(nullptr)
446
+ {
447
+ if constexpr (!Master_matrix::Option_list::is_z2) {
448
+ operators_ = &(colSettings->operators);
449
+ }
450
+
451
+ if constexpr (Master_matrix::Option_list::has_map_column_container) {
452
+ pivotToColumnIndex_.reserve(orderedBoundaries.size());
453
+ } else {
454
+ pivotToColumnIndex_.resize(orderedBoundaries.size(), -1);
455
+ }
456
+
457
+ _initialize_U();
458
+ _reduce();
459
+ }
460
+
461
+ template <class Master_matrix>
462
+ inline RU_matrix<Master_matrix>::RU_matrix(unsigned int numberOfColumns, Column_settings* colSettings)
463
+ : Pair_opt(),
464
+ Swap_opt(),
465
+ Rep_opt(),
466
+ reducedMatrixR_(numberOfColumns, colSettings),
467
+ mirrorMatrixU_(numberOfColumns, colSettings),
468
+ nextEventIndex_(0),
469
+ operators_(nullptr)
470
+ {
471
+ if constexpr (!Master_matrix::Option_list::is_z2) {
472
+ operators_ = &(colSettings->operators);
473
+ }
474
+
475
+ if constexpr (Master_matrix::Option_list::has_map_column_container) {
476
+ pivotToColumnIndex_.reserve(numberOfColumns);
477
+ } else {
478
+ pivotToColumnIndex_.resize(numberOfColumns, -1);
479
+ }
480
+ if constexpr (Master_matrix::Option_list::has_column_pairings) {
481
+ _indexToBar().reserve(numberOfColumns);
482
+ }
483
+ if constexpr (Master_matrix::Option_list::has_vine_update) {
484
+ Swap_opt::_positionToRowIdx().reserve(numberOfColumns);
485
+ }
486
+ }
487
+
488
+ template <class Master_matrix>
489
+ inline RU_matrix<Master_matrix>::RU_matrix(const RU_matrix& matrixToCopy, Column_settings* colSettings)
490
+ : Pair_opt(static_cast<const Pair_opt&>(matrixToCopy)),
491
+ Swap_opt(static_cast<const Swap_opt&>(matrixToCopy)),
492
+ Rep_opt(static_cast<const Rep_opt&>(matrixToCopy)),
493
+ reducedMatrixR_(matrixToCopy.reducedMatrixR_, colSettings),
494
+ mirrorMatrixU_(matrixToCopy.mirrorMatrixU_, colSettings),
495
+ pivotToColumnIndex_(matrixToCopy.pivotToColumnIndex_),
496
+ nextEventIndex_(matrixToCopy.nextEventIndex_),
497
+ operators_(colSettings == nullptr ? matrixToCopy.operators_ : nullptr)
498
+ {
499
+ if constexpr (!Master_matrix::Option_list::is_z2) {
500
+ if (colSettings != nullptr) operators_ = &(colSettings->operators);
501
+ }
502
+ }
503
+
504
+ template <class Master_matrix>
505
+ inline RU_matrix<Master_matrix>::RU_matrix(RU_matrix&& other) noexcept
506
+ : Pair_opt(std::move(static_cast<Pair_opt&>(other))),
507
+ Swap_opt(std::move(static_cast<Swap_opt&>(other))),
508
+ Rep_opt(std::move(static_cast<Rep_opt&>(other))),
509
+ reducedMatrixR_(std::move(other.reducedMatrixR_)),
510
+ mirrorMatrixU_(std::move(other.mirrorMatrixU_)),
511
+ pivotToColumnIndex_(std::move(other.pivotToColumnIndex_)),
512
+ nextEventIndex_(std::exchange(other.nextEventIndex_, 0)),
513
+ operators_(std::exchange(other.operators_, nullptr))
514
+ {}
515
+
516
+ template <class Master_matrix>
517
+ template <class Boundary_range>
518
+ inline void RU_matrix<Master_matrix>::insert_boundary(const Boundary_range& boundary, Dimension dim)
519
+ {
520
+ _insert_boundary(reducedMatrixR_.insert_boundary(boundary, dim));
521
+ }
522
+
523
+ template <class Master_matrix>
524
+ template <class Boundary_range>
525
+ inline void RU_matrix<Master_matrix>::insert_boundary(ID_index cellIndex,
526
+ const Boundary_range& boundary,
527
+ Dimension dim)
528
+ {
529
+ // maps for possible shifting between column content and position indices used for birth events
530
+ if constexpr (Master_matrix::Option_list::has_column_pairings && !Master_matrix::Option_list::has_vine_update) {
531
+ if (cellIndex != nextEventIndex_) {
532
+ Pair_opt::idToPosition_.emplace(cellIndex, nextEventIndex_);
533
+ if constexpr (Master_matrix::Option_list::has_removable_columns) {
534
+ Pair_opt::PIDM::map_.emplace(nextEventIndex_, cellIndex);
535
+ }
536
+ }
537
+ }
538
+ if constexpr (Master_matrix::Option_list::has_vine_update) {
539
+ if (cellIndex != nextEventIndex_) {
540
+ Swap_opt::_positionToRowIdx().emplace(nextEventIndex_, cellIndex);
541
+ if constexpr (Master_matrix::Option_list::has_column_pairings) {
542
+ Swap_opt::template RU_pairing<Master_matrix>::idToPosition_.emplace(cellIndex, nextEventIndex_);
543
+ }
544
+ }
545
+ }
546
+ _insert_boundary(reducedMatrixR_.insert_boundary(cellIndex, boundary, dim));
547
+ }
548
+
549
+ template <class Master_matrix>
550
+ inline typename RU_matrix<Master_matrix>::Column& RU_matrix<Master_matrix>::get_column(Index columnIndex, bool inR)
551
+ {
552
+ if (inR) {
553
+ return reducedMatrixR_.get_column(columnIndex);
554
+ }
555
+ return mirrorMatrixU_.get_column(columnIndex);
556
+ }
557
+
558
+ template <class Master_matrix>
559
+ inline typename RU_matrix<Master_matrix>::Row& RU_matrix<Master_matrix>::get_row(Index rowIndex, bool inR)
560
+ {
561
+ static_assert(Master_matrix::Option_list::has_row_access, "'get_row' is not implemented for the chosen options.");
562
+
563
+ if (inR) {
564
+ return reducedMatrixR_.get_row(rowIndex);
565
+ }
566
+ return mirrorMatrixU_.get_row(rowIndex);
567
+ }
568
+
569
+ template <class Master_matrix>
570
+ inline void RU_matrix<Master_matrix>::erase_empty_row(Index rowIndex)
571
+ {
572
+ reducedMatrixR_.erase_empty_row(rowIndex);
573
+ }
574
+
575
+ template <class Master_matrix>
576
+ inline void RU_matrix<Master_matrix>::remove_maximal_cell(Index columnIndex)
577
+ {
578
+ static_assert(Master_matrix::Option_list::has_removable_columns && Master_matrix::Option_list::has_vine_update,
579
+ "'remove_maximal_cell' is not implemented for the chosen options.");
580
+
581
+ // TODO: is there an easy test to verify maximality even without row access?
582
+
583
+ for (Index curr = columnIndex; curr < nextEventIndex_ - 1; ++curr) {
584
+ Swap_opt::vine_swap(curr);
585
+ }
586
+
587
+ remove_last();
588
+ }
589
+
590
+ template <class Master_matrix>
591
+ inline void RU_matrix<Master_matrix>::remove_last()
592
+ {
593
+ static_assert(Master_matrix::Option_list::has_removable_columns,
594
+ "'remove_last' is not implemented for the chosen options.");
595
+
596
+ if (nextEventIndex_ == 0) return; // empty matrix
597
+ --nextEventIndex_;
598
+
599
+ // assumes PosIdx == MatIdx for boundary matrices.
600
+ _remove_last_in_barcode(nextEventIndex_);
601
+
602
+ mirrorMatrixU_.remove_last();
603
+ if constexpr (Master_matrix::Option_list::has_map_column_container) {
604
+ pivotToColumnIndex_.erase(reducedMatrixR_.remove_last());
605
+ } else {
606
+ ID_index lastPivot = reducedMatrixR_.remove_last();
607
+ if (lastPivot != static_cast<ID_index>(-1)) pivotToColumnIndex_[lastPivot] = -1;
608
+ }
609
+
610
+ // if has_vine_update and has_column_pairings are both true,
611
+ // then the element is already removed in _remove_last_in_barcode
612
+ if constexpr (Master_matrix::Option_list::has_vine_update && !Master_matrix::Option_list::has_column_pairings) {
613
+ Swap_opt::_positionToRowIdx().erase(nextEventIndex_);
614
+ }
615
+ }
616
+
617
+ template <class Master_matrix>
618
+ inline typename RU_matrix<Master_matrix>::Dimension RU_matrix<Master_matrix>::get_max_dimension() const
619
+ {
620
+ return reducedMatrixR_.get_max_dimension();
621
+ }
622
+
623
+ template <class Master_matrix>
624
+ inline typename RU_matrix<Master_matrix>::Index RU_matrix<Master_matrix>::get_number_of_columns() const
625
+ {
626
+ return reducedMatrixR_.get_number_of_columns();
627
+ }
628
+
629
+ template <class Master_matrix>
630
+ inline typename RU_matrix<Master_matrix>::Dimension RU_matrix<Master_matrix>::get_column_dimension(
631
+ Index columnIndex) const
632
+ {
633
+ return reducedMatrixR_.get_column_dimension(columnIndex);
634
+ }
635
+
636
+ template <class Master_matrix>
637
+ inline void RU_matrix<Master_matrix>::add_to(Index sourceColumnIndex, Index targetColumnIndex)
638
+ {
639
+ reducedMatrixR_.add_to(sourceColumnIndex, targetColumnIndex);
640
+ // U transposed to avoid row operations
641
+ if constexpr (Master_matrix::Option_list::is_z2)
642
+ mirrorMatrixU_.add_to(targetColumnIndex, sourceColumnIndex);
643
+ else
644
+ mirrorMatrixU_.add_to(sourceColumnIndex, targetColumnIndex);
645
+ }
646
+
647
+ template <class Master_matrix>
648
+ inline void RU_matrix<Master_matrix>::multiply_target_and_add_to(Index sourceColumnIndex,
649
+ const Field_element& coefficient,
650
+ Index targetColumnIndex)
651
+ {
652
+ static_assert(!Master_matrix::Option_list::is_z2,
653
+ "Multiplication with something else than the identity is not allowed with Z2 coefficients.");
654
+ reducedMatrixR_.multiply_target_and_add_to(sourceColumnIndex, coefficient, targetColumnIndex);
655
+ mirrorMatrixU_.multiply_target_and_add_to(sourceColumnIndex, coefficient, targetColumnIndex);
656
+ }
657
+
658
+ template <class Master_matrix>
659
+ inline void RU_matrix<Master_matrix>::multiply_source_and_add_to(const Field_element& coefficient,
660
+ Index sourceColumnIndex,
661
+ Index targetColumnIndex)
662
+ {
663
+ static_assert(!Master_matrix::Option_list::is_z2,
664
+ "Multiplication with something else than the identity is not allowed with Z2 coefficients.");
665
+ reducedMatrixR_.multiply_source_and_add_to(coefficient, sourceColumnIndex, targetColumnIndex);
666
+ mirrorMatrixU_.multiply_source_and_add_to(coefficient, sourceColumnIndex, targetColumnIndex);
667
+ }
668
+
669
+ template <class Master_matrix>
670
+ inline void RU_matrix<Master_matrix>::zero_entry(Index columnIndex, Index rowIndex, bool inR)
671
+ {
672
+ if (inR) {
673
+ return reducedMatrixR_.zero_entry(columnIndex, rowIndex);
674
+ }
675
+ return mirrorMatrixU_.zero_entry(columnIndex, rowIndex);
676
+ }
677
+
678
+ template <class Master_matrix>
679
+ inline void RU_matrix<Master_matrix>::zero_column(Index columnIndex, bool inR)
680
+ {
681
+ if (inR) {
682
+ return reducedMatrixR_.zero_column(columnIndex);
683
+ }
684
+ return mirrorMatrixU_.zero_column(columnIndex);
685
+ }
686
+
687
+ template <class Master_matrix>
688
+ inline bool RU_matrix<Master_matrix>::is_zero_entry(Index columnIndex, Index rowIndex, bool inR) const
689
+ {
690
+ if (inR) {
691
+ return reducedMatrixR_.is_zero_entry(columnIndex, rowIndex);
692
+ }
693
+ return mirrorMatrixU_.is_zero_entry(columnIndex, rowIndex);
694
+ }
695
+
696
+ template <class Master_matrix>
697
+ inline bool RU_matrix<Master_matrix>::is_zero_column(Index columnIndex, bool inR)
698
+ {
699
+ if (inR) {
700
+ return reducedMatrixR_.is_zero_column(columnIndex);
701
+ }
702
+ return mirrorMatrixU_.is_zero_column(columnIndex);
703
+ }
704
+
705
+ template <class Master_matrix>
706
+ inline typename RU_matrix<Master_matrix>::Index RU_matrix<Master_matrix>::get_column_with_pivot(Index cellIndex) const
707
+ {
708
+ if constexpr (Master_matrix::Option_list::has_map_column_container) {
709
+ return pivotToColumnIndex_.at(cellIndex);
710
+ } else {
711
+ return pivotToColumnIndex_[cellIndex];
712
+ }
713
+ }
714
+
715
+ template <class Master_matrix>
716
+ inline typename RU_matrix<Master_matrix>::Index RU_matrix<Master_matrix>::get_pivot(Index columnIndex)
717
+ {
718
+ return reducedMatrixR_.get_column(columnIndex).get_pivot();
719
+ }
720
+
721
+ template <class Master_matrix>
722
+ inline RU_matrix<Master_matrix>& RU_matrix<Master_matrix>::operator=(const RU_matrix& other)
723
+ {
724
+ Swap_opt::operator=(other);
725
+ Pair_opt::operator=(other);
726
+ Rep_opt::operator=(other);
727
+ reducedMatrixR_ = other.reducedMatrixR_;
728
+ mirrorMatrixU_ = other.mirrorMatrixU_;
729
+ pivotToColumnIndex_ = other.pivotToColumnIndex_;
730
+ nextEventIndex_ = other.nextEventIndex_;
731
+ operators_ = other.operators_;
732
+ return *this;
733
+ }
734
+
735
+ template <class Master_matrix>
736
+ inline void RU_matrix<Master_matrix>::print(Index startCol, Index endCol, Index startRow, Index endRow)
737
+ {
738
+ std::cout << "R_matrix:\n";
739
+ reducedMatrixR_.print(startCol, endCol, startRow, endRow);
740
+ std::cout << "U_matrix:\n";
741
+ mirrorMatrixU_.print(startCol, endCol, startCol, endCol);
742
+ }
743
+
744
+ template <class Master_matrix>
745
+ inline void RU_matrix<Master_matrix>::_insert_boundary(Index currentIndex)
746
+ {
747
+ if constexpr (Master_matrix::Option_list::is_z2) {
748
+ mirrorMatrixU_.insert_column({currentIndex});
749
+ } else {
750
+ mirrorMatrixU_.insert_column({{currentIndex, 1}});
751
+ }
752
+
753
+ if constexpr (!Master_matrix::Option_list::has_map_column_container) {
754
+ ID_index pivot = reducedMatrixR_.get_column(currentIndex).get_pivot();
755
+ if (pivot != static_cast<ID_index>(-1) && pivotToColumnIndex_.size() <= pivot)
756
+ pivotToColumnIndex_.resize((pivot + 1) * 2, -1);
757
+ }
758
+
759
+ _reduce_last_column(currentIndex);
760
+ ++nextEventIndex_;
761
+ }
762
+
763
+ template <class Master_matrix>
764
+ inline void RU_matrix<Master_matrix>::_initialize_U()
765
+ {
766
+ typename std::conditional<Master_matrix::Option_list::is_z2, Index, std::pair<Index, Field_element> >::type id;
767
+ if constexpr (!Master_matrix::Option_list::is_z2) id.second = 1;
768
+
769
+ for (ID_index i = 0; i < reducedMatrixR_.get_number_of_columns(); i++) {
770
+ if constexpr (Master_matrix::Option_list::is_z2)
771
+ id = i;
772
+ else
773
+ id.first = i;
774
+ mirrorMatrixU_.insert_column({id});
775
+ }
776
+ }
777
+
778
+ template <class Master_matrix>
779
+ inline void RU_matrix<Master_matrix>::_reduce()
780
+ {
781
+ if constexpr (Master_matrix::Option_list::has_column_pairings) {
782
+ _indexToBar().reserve(reducedMatrixR_.get_number_of_columns());
783
+ }
784
+
785
+ for (Index i = 0; i < reducedMatrixR_.get_number_of_columns(); i++) {
786
+ if (!(reducedMatrixR_.is_zero_column(i))) {
787
+ _reduce_column(i, i);
788
+ } else {
789
+ _add_bar(get_column_dimension(i), i);
790
+ }
791
+ }
792
+ }
793
+
794
+ template <class Master_matrix>
795
+ inline void RU_matrix<Master_matrix>::_reduce_last_column(Index lastIndex)
796
+ {
797
+ if (reducedMatrixR_.get_column(lastIndex).is_empty()) {
798
+ _add_bar(get_column_dimension(lastIndex), nextEventIndex_);
799
+ return;
800
+ }
801
+
802
+ _reduce_column(lastIndex, nextEventIndex_);
803
+ }
804
+
805
+ template <class Master_matrix>
806
+ inline void RU_matrix<Master_matrix>::_reduce_column(Index target, Index eventIndex)
807
+ {
808
+ auto get_column_with_pivot_ = [&](ID_index pivot) -> Index {
809
+ if (pivot == static_cast<ID_index>(-1)) return -1;
810
+ if constexpr (Master_matrix::Option_list::has_map_column_container) {
811
+ auto it = pivotToColumnIndex_.find(pivot);
812
+ if (it == pivotToColumnIndex_.end())
813
+ return -1;
814
+ else
815
+ return it->second;
816
+ } else {
817
+ return pivotToColumnIndex_[pivot];
818
+ }
819
+ };
820
+
821
+ Column& curr = reducedMatrixR_.get_column(target);
822
+ ID_index pivot = curr.get_pivot();
823
+ Index currIndex = get_column_with_pivot_(pivot);
824
+
825
+ while (pivot != static_cast<ID_index>(-1) && currIndex != static_cast<Index>(-1)) {
826
+ _reduce_column_by(target, currIndex);
827
+ pivot = curr.get_pivot();
828
+ currIndex = get_column_with_pivot_(pivot);
829
+ }
830
+
831
+ if (pivot != static_cast<ID_index>(-1)) {
832
+ if constexpr (Master_matrix::Option_list::has_map_column_container) {
833
+ pivotToColumnIndex_.try_emplace(pivot, target);
834
+ } else {
835
+ pivotToColumnIndex_[pivot] = target;
836
+ }
837
+ _update_barcode(pivot, eventIndex);
838
+ } else {
839
+ _add_bar(get_column_dimension(target), eventIndex);
840
+ }
841
+ }
842
+
843
+ template <class Master_matrix>
844
+ inline void RU_matrix<Master_matrix>::_reduce_column_by(Index target, Index source)
845
+ {
846
+ Column& curr = reducedMatrixR_.get_column(target);
847
+ if constexpr (Master_matrix::Option_list::is_z2) {
848
+ curr += reducedMatrixR_.get_column(source);
849
+ // to avoid having to do line operations during vineyards, U is transposed
850
+ // TODO: explain this somewhere in the documentation...
851
+ mirrorMatrixU_.get_column(source).push_back(*mirrorMatrixU_.get_column(target).begin());
852
+ } else {
853
+ Column& toadd = reducedMatrixR_.get_column(source);
854
+ Field_element coef = toadd.get_pivot_value();
855
+ coef = operators_->get_inverse(coef);
856
+ operators_->multiply_inplace(coef, operators_->get_characteristic() - curr.get_pivot_value());
857
+
858
+ curr.multiply_source_and_add(toadd, coef);
859
+ // but no transposition for Zp, careful if there will be vineyard or rep cycles in Zp one day
860
+ // TODO: explain this somewhere in the documentation...
861
+ mirrorMatrixU_.multiply_source_and_add_to(coef, source, target);
862
+ }
863
+ }
864
+
865
+ template <class Master_matrix>
866
+ inline void RU_matrix<Master_matrix>::_update_barcode(ID_index birthPivot, Pos_index death)
867
+ {
868
+ if constexpr (Master_matrix::Option_list::has_column_pairings) {
869
+ if constexpr (Master_matrix::Option_list::has_vine_update)
870
+ Swap_opt::template RU_pairing<Master_matrix>::_update_barcode(birthPivot, death);
871
+ else
872
+ Pair_opt::_update_barcode(birthPivot, death);
873
+ }
874
+ }
875
+
876
+ template <class Master_matrix>
877
+ inline void RU_matrix<Master_matrix>::_add_bar(Dimension dim, Pos_index birth)
878
+ {
879
+ if constexpr (Master_matrix::Option_list::has_column_pairings) {
880
+ if constexpr (Master_matrix::Option_list::has_vine_update)
881
+ Swap_opt::template RU_pairing<Master_matrix>::_add_bar(dim, birth);
882
+ else
883
+ Pair_opt::_add_bar(dim, birth);
884
+ }
885
+ }
886
+
887
+ template <class Master_matrix>
888
+ inline void RU_matrix<Master_matrix>::_remove_last_in_barcode(Pos_index eventIndex)
889
+ {
890
+ if constexpr (Master_matrix::Option_list::has_column_pairings) {
891
+ if constexpr (Master_matrix::Option_list::has_vine_update)
892
+ Swap_opt::template RU_pairing<Master_matrix>::_remove_last(eventIndex);
893
+ else
894
+ Pair_opt::_remove_last(eventIndex);
895
+ }
896
+ }
897
+
898
+ template <class Master_matrix>
899
+ inline constexpr typename RU_matrix<Master_matrix>::Bar_dictionary& RU_matrix<Master_matrix>::_indexToBar()
900
+ {
901
+ if constexpr (Master_matrix::Option_list::has_vine_update)
902
+ return Swap_opt::template RU_pairing<Master_matrix>::indexToBar_;
903
+ else
904
+ return Pair_opt::indexToBar_;
905
+ }
906
+
907
+ } // namespace persistence_matrix
908
+ } // namespace Gudhi
909
+
910
+ #endif // PM_RU_MATRIX_H