multipers 2.3.3b6__cp313-cp313-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.
- multipers/.dylibs/libc++.1.0.dylib +0 -0
- multipers/.dylibs/libtbb.12.16.dylib +0 -0
- multipers/__init__.py +33 -0
- multipers/_signed_measure_meta.py +453 -0
- multipers/_slicer_meta.py +211 -0
- multipers/array_api/__init__.py +45 -0
- multipers/array_api/numpy.py +41 -0
- multipers/array_api/torch.py +58 -0
- multipers/data/MOL2.py +458 -0
- multipers/data/UCR.py +18 -0
- multipers/data/__init__.py +1 -0
- multipers/data/graphs.py +466 -0
- multipers/data/immuno_regions.py +27 -0
- multipers/data/minimal_presentation_to_st_bf.py +0 -0
- multipers/data/pytorch2simplextree.py +91 -0
- multipers/data/shape3d.py +101 -0
- multipers/data/synthetic.py +113 -0
- multipers/distances.py +202 -0
- multipers/filtration_conversions.pxd +229 -0
- multipers/filtration_conversions.pxd.tp +84 -0
- multipers/filtrations/__init__.py +18 -0
- multipers/filtrations/density.py +574 -0
- multipers/filtrations/filtrations.py +361 -0
- multipers/filtrations.pxd +224 -0
- multipers/function_rips.cpython-313-darwin.so +0 -0
- multipers/function_rips.pyx +105 -0
- multipers/grids.cpython-313-darwin.so +0 -0
- multipers/grids.pyx +433 -0
- multipers/gudhi/Persistence_slices_interface.h +132 -0
- multipers/gudhi/Simplex_tree_interface.h +239 -0
- multipers/gudhi/Simplex_tree_multi_interface.h +551 -0
- multipers/gudhi/cubical_to_boundary.h +59 -0
- multipers/gudhi/gudhi/Bitmap_cubical_complex.h +450 -0
- multipers/gudhi/gudhi/Bitmap_cubical_complex_base.h +1070 -0
- multipers/gudhi/gudhi/Bitmap_cubical_complex_periodic_boundary_conditions_base.h +579 -0
- multipers/gudhi/gudhi/Debug_utils.h +45 -0
- multipers/gudhi/gudhi/Fields/Multi_field.h +484 -0
- multipers/gudhi/gudhi/Fields/Multi_field_operators.h +455 -0
- multipers/gudhi/gudhi/Fields/Multi_field_shared.h +450 -0
- multipers/gudhi/gudhi/Fields/Multi_field_small.h +531 -0
- multipers/gudhi/gudhi/Fields/Multi_field_small_operators.h +507 -0
- multipers/gudhi/gudhi/Fields/Multi_field_small_shared.h +531 -0
- multipers/gudhi/gudhi/Fields/Z2_field.h +355 -0
- multipers/gudhi/gudhi/Fields/Z2_field_operators.h +376 -0
- multipers/gudhi/gudhi/Fields/Zp_field.h +420 -0
- multipers/gudhi/gudhi/Fields/Zp_field_operators.h +400 -0
- multipers/gudhi/gudhi/Fields/Zp_field_shared.h +418 -0
- multipers/gudhi/gudhi/Flag_complex_edge_collapser.h +337 -0
- multipers/gudhi/gudhi/Matrix.h +2107 -0
- multipers/gudhi/gudhi/Multi_critical_filtration.h +1038 -0
- multipers/gudhi/gudhi/Multi_persistence/Box.h +174 -0
- multipers/gudhi/gudhi/Multi_persistence/Line.h +282 -0
- multipers/gudhi/gudhi/Off_reader.h +173 -0
- multipers/gudhi/gudhi/One_critical_filtration.h +1441 -0
- multipers/gudhi/gudhi/Persistence_matrix/Base_matrix.h +769 -0
- multipers/gudhi/gudhi/Persistence_matrix/Base_matrix_with_column_compression.h +686 -0
- multipers/gudhi/gudhi/Persistence_matrix/Boundary_matrix.h +842 -0
- multipers/gudhi/gudhi/Persistence_matrix/Chain_matrix.h +1350 -0
- multipers/gudhi/gudhi/Persistence_matrix/Id_to_index_overlay.h +1105 -0
- multipers/gudhi/gudhi/Persistence_matrix/Position_to_index_overlay.h +859 -0
- multipers/gudhi/gudhi/Persistence_matrix/RU_matrix.h +910 -0
- multipers/gudhi/gudhi/Persistence_matrix/allocators/entry_constructors.h +139 -0
- multipers/gudhi/gudhi/Persistence_matrix/base_pairing.h +230 -0
- multipers/gudhi/gudhi/Persistence_matrix/base_swap.h +211 -0
- multipers/gudhi/gudhi/Persistence_matrix/boundary_cell_position_to_id_mapper.h +60 -0
- multipers/gudhi/gudhi/Persistence_matrix/boundary_face_position_to_id_mapper.h +60 -0
- multipers/gudhi/gudhi/Persistence_matrix/chain_pairing.h +136 -0
- multipers/gudhi/gudhi/Persistence_matrix/chain_rep_cycles.h +190 -0
- multipers/gudhi/gudhi/Persistence_matrix/chain_vine_swap.h +616 -0
- multipers/gudhi/gudhi/Persistence_matrix/columns/chain_column_extra_properties.h +150 -0
- multipers/gudhi/gudhi/Persistence_matrix/columns/column_dimension_holder.h +106 -0
- multipers/gudhi/gudhi/Persistence_matrix/columns/column_utilities.h +219 -0
- multipers/gudhi/gudhi/Persistence_matrix/columns/entry_types.h +327 -0
- multipers/gudhi/gudhi/Persistence_matrix/columns/heap_column.h +1140 -0
- multipers/gudhi/gudhi/Persistence_matrix/columns/intrusive_list_column.h +934 -0
- multipers/gudhi/gudhi/Persistence_matrix/columns/intrusive_set_column.h +934 -0
- multipers/gudhi/gudhi/Persistence_matrix/columns/list_column.h +980 -0
- multipers/gudhi/gudhi/Persistence_matrix/columns/naive_vector_column.h +1092 -0
- multipers/gudhi/gudhi/Persistence_matrix/columns/row_access.h +192 -0
- multipers/gudhi/gudhi/Persistence_matrix/columns/set_column.h +921 -0
- multipers/gudhi/gudhi/Persistence_matrix/columns/small_vector_column.h +1093 -0
- multipers/gudhi/gudhi/Persistence_matrix/columns/unordered_set_column.h +1012 -0
- multipers/gudhi/gudhi/Persistence_matrix/columns/vector_column.h +1244 -0
- multipers/gudhi/gudhi/Persistence_matrix/matrix_dimension_holders.h +186 -0
- multipers/gudhi/gudhi/Persistence_matrix/matrix_row_access.h +164 -0
- multipers/gudhi/gudhi/Persistence_matrix/ru_pairing.h +156 -0
- multipers/gudhi/gudhi/Persistence_matrix/ru_rep_cycles.h +376 -0
- multipers/gudhi/gudhi/Persistence_matrix/ru_vine_swap.h +540 -0
- multipers/gudhi/gudhi/Persistent_cohomology/Field_Zp.h +118 -0
- multipers/gudhi/gudhi/Persistent_cohomology/Multi_field.h +173 -0
- multipers/gudhi/gudhi/Persistent_cohomology/Persistent_cohomology_column.h +128 -0
- multipers/gudhi/gudhi/Persistent_cohomology.h +745 -0
- multipers/gudhi/gudhi/Points_off_io.h +171 -0
- multipers/gudhi/gudhi/Simple_object_pool.h +69 -0
- multipers/gudhi/gudhi/Simplex_tree/Simplex_tree_iterators.h +463 -0
- multipers/gudhi/gudhi/Simplex_tree/Simplex_tree_node_explicit_storage.h +83 -0
- multipers/gudhi/gudhi/Simplex_tree/Simplex_tree_siblings.h +106 -0
- multipers/gudhi/gudhi/Simplex_tree/Simplex_tree_star_simplex_iterators.h +277 -0
- multipers/gudhi/gudhi/Simplex_tree/hooks_simplex_base.h +62 -0
- multipers/gudhi/gudhi/Simplex_tree/indexing_tag.h +27 -0
- multipers/gudhi/gudhi/Simplex_tree/serialization_utils.h +62 -0
- multipers/gudhi/gudhi/Simplex_tree/simplex_tree_options.h +157 -0
- multipers/gudhi/gudhi/Simplex_tree.h +2794 -0
- multipers/gudhi/gudhi/Simplex_tree_multi.h +152 -0
- multipers/gudhi/gudhi/distance_functions.h +62 -0
- multipers/gudhi/gudhi/graph_simplicial_complex.h +104 -0
- multipers/gudhi/gudhi/persistence_interval.h +253 -0
- multipers/gudhi/gudhi/persistence_matrix_options.h +170 -0
- multipers/gudhi/gudhi/reader_utils.h +367 -0
- multipers/gudhi/mma_interface_coh.h +256 -0
- multipers/gudhi/mma_interface_h0.h +223 -0
- multipers/gudhi/mma_interface_matrix.h +293 -0
- multipers/gudhi/naive_merge_tree.h +536 -0
- multipers/gudhi/scc_io.h +310 -0
- multipers/gudhi/truc.h +1403 -0
- multipers/io.cpython-313-darwin.so +0 -0
- multipers/io.pyx +644 -0
- multipers/ml/__init__.py +0 -0
- multipers/ml/accuracies.py +90 -0
- multipers/ml/invariants_with_persistable.py +79 -0
- multipers/ml/kernels.py +176 -0
- multipers/ml/mma.py +713 -0
- multipers/ml/one.py +472 -0
- multipers/ml/point_clouds.py +352 -0
- multipers/ml/signed_measures.py +1589 -0
- multipers/ml/sliced_wasserstein.py +461 -0
- multipers/ml/tools.py +113 -0
- multipers/mma_structures.cpython-313-darwin.so +0 -0
- multipers/mma_structures.pxd +128 -0
- multipers/mma_structures.pyx +2786 -0
- multipers/mma_structures.pyx.tp +1094 -0
- multipers/multi_parameter_rank_invariant/diff_helpers.h +84 -0
- multipers/multi_parameter_rank_invariant/euler_characteristic.h +97 -0
- multipers/multi_parameter_rank_invariant/function_rips.h +322 -0
- multipers/multi_parameter_rank_invariant/hilbert_function.h +769 -0
- multipers/multi_parameter_rank_invariant/persistence_slices.h +148 -0
- multipers/multi_parameter_rank_invariant/rank_invariant.h +369 -0
- multipers/multiparameter_edge_collapse.py +41 -0
- multipers/multiparameter_module_approximation/approximation.h +2330 -0
- multipers/multiparameter_module_approximation/combinatory.h +129 -0
- multipers/multiparameter_module_approximation/debug.h +107 -0
- multipers/multiparameter_module_approximation/euler_curves.h +0 -0
- multipers/multiparameter_module_approximation/format_python-cpp.h +286 -0
- multipers/multiparameter_module_approximation/heap_column.h +238 -0
- multipers/multiparameter_module_approximation/images.h +79 -0
- multipers/multiparameter_module_approximation/list_column.h +174 -0
- multipers/multiparameter_module_approximation/list_column_2.h +232 -0
- multipers/multiparameter_module_approximation/ru_matrix.h +347 -0
- multipers/multiparameter_module_approximation/set_column.h +135 -0
- multipers/multiparameter_module_approximation/structure_higher_dim_barcode.h +36 -0
- multipers/multiparameter_module_approximation/unordered_set_column.h +166 -0
- multipers/multiparameter_module_approximation/utilities.h +403 -0
- multipers/multiparameter_module_approximation/vector_column.h +223 -0
- multipers/multiparameter_module_approximation/vector_matrix.h +331 -0
- multipers/multiparameter_module_approximation/vineyards.h +464 -0
- multipers/multiparameter_module_approximation/vineyards_trajectories.h +649 -0
- multipers/multiparameter_module_approximation.cpython-313-darwin.so +0 -0
- multipers/multiparameter_module_approximation.pyx +235 -0
- multipers/pickle.py +90 -0
- multipers/plots.py +456 -0
- multipers/point_measure.cpython-313-darwin.so +0 -0
- multipers/point_measure.pyx +395 -0
- multipers/simplex_tree_multi.cpython-313-darwin.so +0 -0
- multipers/simplex_tree_multi.pxd +134 -0
- multipers/simplex_tree_multi.pyx +10840 -0
- multipers/simplex_tree_multi.pyx.tp +2009 -0
- multipers/slicer.cpython-313-darwin.so +0 -0
- multipers/slicer.pxd +3034 -0
- multipers/slicer.pxd.tp +234 -0
- multipers/slicer.pyx +20481 -0
- multipers/slicer.pyx.tp +1088 -0
- multipers/tensor/tensor.h +672 -0
- multipers/tensor.pxd +13 -0
- multipers/test.pyx +44 -0
- multipers/tests/__init__.py +62 -0
- multipers/torch/__init__.py +1 -0
- multipers/torch/diff_grids.py +240 -0
- multipers/torch/rips_density.py +310 -0
- multipers-2.3.3b6.dist-info/METADATA +128 -0
- multipers-2.3.3b6.dist-info/RECORD +183 -0
- multipers-2.3.3b6.dist-info/WHEEL +6 -0
- multipers-2.3.3b6.dist-info/licenses/LICENSE +21 -0
- multipers-2.3.3b6.dist-info/top_level.txt +1 -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
|