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.
- 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-312-x86_64-linux-gnu.so +0 -0
- multipers/function_rips.pyx +105 -0
- multipers/grids.cpython-312-x86_64-linux-gnu.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-312-x86_64-linux-gnu.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-312-x86_64-linux-gnu.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-312-x86_64-linux-gnu.so +0 -0
- multipers/multiparameter_module_approximation.pyx +235 -0
- multipers/pickle.py +90 -0
- multipers/plots.py +456 -0
- multipers/point_measure.cpython-312-x86_64-linux-gnu.so +0 -0
- multipers/point_measure.pyx +395 -0
- multipers/simplex_tree_multi.cpython-312-x86_64-linux-gnu.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-312-x86_64-linux-gnu.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 +182 -0
- multipers-2.3.3b6.dist-info/WHEEL +5 -0
- multipers-2.3.3b6.dist-info/licenses/LICENSE +21 -0
- multipers-2.3.3b6.dist-info/top_level.txt +1 -0
- multipers.libs/libtbb-ca48af5c.so.12.16 +0 -0
|
@@ -0,0 +1,2107 @@
|
|
|
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
|
+
/** @file Matrix.h
|
|
12
|
+
* @author Hannah Schreiber
|
|
13
|
+
* @brief Contains @ref Gudhi::persistence_matrix::Matrix class.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
#ifndef MASTER_MATRIX_H
|
|
17
|
+
#define MASTER_MATRIX_H
|
|
18
|
+
|
|
19
|
+
#include <type_traits>
|
|
20
|
+
#include <vector>
|
|
21
|
+
#include <unordered_map>
|
|
22
|
+
#include <map>
|
|
23
|
+
#include <initializer_list>
|
|
24
|
+
|
|
25
|
+
#include <boost/intrusive/list.hpp>
|
|
26
|
+
|
|
27
|
+
#include <gudhi/Debug_utils.h>
|
|
28
|
+
|
|
29
|
+
#include <gudhi/persistence_matrix_options.h>
|
|
30
|
+
#include <gudhi/persistence_interval.h>
|
|
31
|
+
|
|
32
|
+
#include <gudhi/Fields/Z2_field_operators.h>
|
|
33
|
+
|
|
34
|
+
#include <gudhi/Persistence_matrix/Id_to_index_overlay.h>
|
|
35
|
+
#include <gudhi/Persistence_matrix/Position_to_index_overlay.h>
|
|
36
|
+
|
|
37
|
+
#include <gudhi/Persistence_matrix/matrix_dimension_holders.h>
|
|
38
|
+
#include <gudhi/Persistence_matrix/matrix_row_access.h>
|
|
39
|
+
#include <gudhi/Persistence_matrix/base_swap.h>
|
|
40
|
+
#include <gudhi/Persistence_matrix/base_pairing.h>
|
|
41
|
+
#include <gudhi/Persistence_matrix/ru_pairing.h>
|
|
42
|
+
#include <gudhi/Persistence_matrix/ru_vine_swap.h>
|
|
43
|
+
#include <gudhi/Persistence_matrix/ru_rep_cycles.h>
|
|
44
|
+
#include <gudhi/Persistence_matrix/chain_pairing.h>
|
|
45
|
+
#include <gudhi/Persistence_matrix/chain_vine_swap.h>
|
|
46
|
+
#include <gudhi/Persistence_matrix/chain_rep_cycles.h>
|
|
47
|
+
|
|
48
|
+
#include <gudhi/Persistence_matrix/Base_matrix.h>
|
|
49
|
+
#include <gudhi/Persistence_matrix/Base_matrix_with_column_compression.h>
|
|
50
|
+
#include <gudhi/Persistence_matrix/Boundary_matrix.h>
|
|
51
|
+
#include <gudhi/Persistence_matrix/RU_matrix.h>
|
|
52
|
+
#include <gudhi/Persistence_matrix/Chain_matrix.h>
|
|
53
|
+
|
|
54
|
+
#include <gudhi/Persistence_matrix/allocators/entry_constructors.h>
|
|
55
|
+
#include <gudhi/Persistence_matrix/columns/entry_types.h>
|
|
56
|
+
#include <gudhi/Persistence_matrix/columns/row_access.h>
|
|
57
|
+
|
|
58
|
+
#include <gudhi/Persistence_matrix/columns/column_dimension_holder.h>
|
|
59
|
+
#include <gudhi/Persistence_matrix/columns/chain_column_extra_properties.h>
|
|
60
|
+
#include <gudhi/Persistence_matrix/columns/intrusive_list_column.h>
|
|
61
|
+
#include <gudhi/Persistence_matrix/columns/intrusive_set_column.h>
|
|
62
|
+
#include <gudhi/Persistence_matrix/columns/list_column.h>
|
|
63
|
+
#include <gudhi/Persistence_matrix/columns/set_column.h>
|
|
64
|
+
#include <gudhi/Persistence_matrix/columns/unordered_set_column.h>
|
|
65
|
+
#include <gudhi/Persistence_matrix/columns/vector_column.h>
|
|
66
|
+
#include <gudhi/Persistence_matrix/columns/naive_vector_column.h>
|
|
67
|
+
#include <gudhi/Persistence_matrix/columns/small_vector_column.h>
|
|
68
|
+
#include <gudhi/Persistence_matrix/columns/heap_column.h>
|
|
69
|
+
|
|
70
|
+
/// Gudhi namespace.
|
|
71
|
+
namespace Gudhi {
|
|
72
|
+
/// Persistence matrix namespace.
|
|
73
|
+
namespace persistence_matrix {
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @class Matrix matrix.h gudhi/matrix.h
|
|
77
|
+
* @ingroup persistence_matrix
|
|
78
|
+
*
|
|
79
|
+
* @brief Data structure for matrices, and in particular thought for matrices representing filtered complexes
|
|
80
|
+
* in order to compute persistence and/or representative cycles.
|
|
81
|
+
*
|
|
82
|
+
* @anchor mp_matrices __%Matrix types:__
|
|
83
|
+
*
|
|
84
|
+
* The are roughly three types of matrices available and one is selected automatically depending on the options chosen:
|
|
85
|
+
* - @anchor basematrix a @ref basematrix "basic matrix" which can represent any matrix and therefore will not make any
|
|
86
|
+
* assumption on its content. It is the only matrix type with the option of column compression (as it is the only one
|
|
87
|
+
* where it makes sense). This type is choosen by default when none of the homology related options are set to true:
|
|
88
|
+
* @ref PersistenceMatrixOptions::has_column_pairings, @ref PersistenceMatrixOptions::has_vine_update and
|
|
89
|
+
* @ref PersistenceMatrixOptions::can_retrieve_representative_cycles.
|
|
90
|
+
* - @anchor boundarymatrix a @ref boundarymatrix "boundary matrix" @f$ B = R \cdot U @f$ which either stores only
|
|
91
|
+
* @f$ R @f$ or the whole decomposition @f$ R @f$ and @f$ U @f$ depending on the options. This type is selected if
|
|
92
|
+
* @ref PersistenceMatrixOptions::is_of_boundary_type is set to true and at least one of the following options:
|
|
93
|
+
* @ref PersistenceMatrixOptions::has_column_pairings, @ref PersistenceMatrixOptions::has_vine_update and
|
|
94
|
+
* @ref PersistenceMatrixOptions::can_retrieve_representative_cycles. If only
|
|
95
|
+
* @ref PersistenceMatrixOptions::has_column_pairings is true, then only @f$ R @f$ is stored, but if either
|
|
96
|
+
* @ref PersistenceMatrixOptions::has_vine_update or @ref PersistenceMatrixOptions::can_retrieve_representative_cycles
|
|
97
|
+
* is true, then @f$ U @f$ also needs to be stored. Note that the option
|
|
98
|
+
* @ref PersistenceMatrixOptions::column_indexation_type will produce a small overhead when set to
|
|
99
|
+
* @ref Column_indexation_types::IDENTIFIER.
|
|
100
|
+
* - @anchor chainmatrix a @ref chainmatrix "chain complex matrix" representing a "compatible base" of a filtered chain
|
|
101
|
+
* complex (see @cite zigzag). This matrix is deduced from the boundary matrix and therefore encodes more or less the
|
|
102
|
+
* same information but differently and can therefore be better suited for certain applications. This type can be used
|
|
103
|
+
* the same way than the precedent type, only the option @ref PersistenceMatrixOptions::is_of_boundary_type has to be
|
|
104
|
+
* set to false. Note that the option @ref PersistenceMatrixOptions::column_indexation_type will produce a small
|
|
105
|
+
* overhead when set to @ref Column_indexation_types::POSITION or @ref Column_indexation_types::IDENTIFIER.
|
|
106
|
+
*
|
|
107
|
+
* @anchor mp_indexation __Indexation scheme:__
|
|
108
|
+
*
|
|
109
|
+
* The indexation system for columns of the different matrix types can be a bit tricky and different methods will not
|
|
110
|
+
* always take the same type of index as input (for optimization purposes). So, to avoid confusion, we will name and
|
|
111
|
+
* define here the different possibilities, such that we can directly refer to it in the descriptions of the methods.
|
|
112
|
+
* Note that every column and row in a @ref boundarymatrix "boundary" or @ref chainmatrix "chain matrix" is always
|
|
113
|
+
* associated to a single simplex/cell, so in order to avoid repeating formulations like "of the simplex associated to
|
|
114
|
+
* the column" all the time, we will amalgamate both notions together.
|
|
115
|
+
*
|
|
116
|
+
* Let @f$ c @f$ be a column.
|
|
117
|
+
* - @anchor MatIdx @ref MatIdx "MatIdx": This will correspond to the position of @f$ c @f$ in the matrix, i.e.,
|
|
118
|
+
* @f$ underlying\_container[MatIdx] = c @f$. This will be the only public indexing scheme for
|
|
119
|
+
* @ref basematrix "basic matrices".
|
|
120
|
+
* - @anchor PosIdx @ref PosIdx "PosIdx": This will correspond to the relative position of @f$ c @f$ in the current
|
|
121
|
+
* filtration compared to the other columns, starting the count at 0. For @ref boundarymatrix "boundary matrices",
|
|
122
|
+
* @ref PosIdx will always be equal to @ref MatIdx, but this is not true for @ref chainmatrix "chain matrices" when
|
|
123
|
+
* swaps or removals were performed.
|
|
124
|
+
* - @anchor IDIdx @ref IDIdx "IDIdx": This will correspond to the ID of @f$ c @f$ in the complex used to identify it in
|
|
125
|
+
* the boundaries. If at the insertion of @f$ c @f$, its ID was not specified and it was the @f$ n^{th} @f$ insertion,
|
|
126
|
+
* it is assumed that the ID is @f$ n @f$ (which means that @ref IDIdx and @ref PosIdx will only start to differ when
|
|
127
|
+
* swaps or removals are performed). If an ID is specified at the insertion of @f$ c @f$, the ID is stored as the
|
|
128
|
+
* @ref IDIdx of @f$ c @f$. IDs can be freely choosen with the only restriction that they have to be strictly
|
|
129
|
+
* increasing in the order of the filtration at initialisation.
|
|
130
|
+
*
|
|
131
|
+
* In conclusion, with default values, if no vine swaps or removals occurs, all three indexing schemes are the same.
|
|
132
|
+
*
|
|
133
|
+
* @anchor rowindex Let @f$ r @f$ be a row. Rows are indexed in two ways depending only if the matrix is a
|
|
134
|
+
* @ref chainmatrix "chain matrix" or not. If the matrix is a @ref chainmatrix "chain matrix", @f$ r @f$ is always
|
|
135
|
+
* indexed by its ID, so it correspond to the @ref IDIdx indexing scheme. If the matrix is not a
|
|
136
|
+
* @ref chainmatrix "chain matrix", @f$ r @f$ will originally also be indexed by the ID, but when a swap occurs,
|
|
137
|
+
* the rows also swap IDs and the new ID has to be used to access @f$ r @f$. This means that when the default
|
|
138
|
+
* @ref IDIdx scheme is used (the cells are numerated in order of appearance in the filtration starting at 0),
|
|
139
|
+
* the indexation of the rows correspond to @ref PosIdx.
|
|
140
|
+
*
|
|
141
|
+
* @tparam PersistenceMatrixOptions Structure encoding all the options of the matrix.
|
|
142
|
+
* See description of @ref PersistenceMatrixOptions for more details.
|
|
143
|
+
*/
|
|
144
|
+
template <class PersistenceMatrixOptions = Default_options<> >
|
|
145
|
+
class Matrix {
|
|
146
|
+
public:
|
|
147
|
+
using Option_list = PersistenceMatrixOptions; //to make it accessible from the other classes
|
|
148
|
+
using Index = typename PersistenceMatrixOptions::Index; /**< Type of @ref MatIdx index. */
|
|
149
|
+
using ID_index = typename PersistenceMatrixOptions::Index; /**< Type of @ref IDIdx index. */
|
|
150
|
+
using Pos_index = typename PersistenceMatrixOptions::Index; /**< Type of @ref PosIdx index. */
|
|
151
|
+
using Dimension = typename PersistenceMatrixOptions::Dimension; /**< Type for dimension value. */
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* @brief coefficients field type.
|
|
155
|
+
*/
|
|
156
|
+
using Field_operators =
|
|
157
|
+
typename std::conditional<PersistenceMatrixOptions::is_z2,
|
|
158
|
+
Gudhi::persistence_fields::Z2_field_operators,
|
|
159
|
+
typename PersistenceMatrixOptions::Field_coeff_operators
|
|
160
|
+
>::type;
|
|
161
|
+
/**
|
|
162
|
+
* @brief Type of a field element.
|
|
163
|
+
*/
|
|
164
|
+
using Element = typename Field_operators::Element;
|
|
165
|
+
using Characteristic = typename Field_operators::Characteristic;
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* @brief Type for a bar in the computed barcode. Stores the birth, death and dimension of the bar.
|
|
169
|
+
*/
|
|
170
|
+
using Bar = Persistence_interval<Dimension, Pos_index>;
|
|
171
|
+
|
|
172
|
+
//tags for boost to associate a row and a column to a same entry
|
|
173
|
+
struct Matrix_row_tag;
|
|
174
|
+
struct Matrix_column_tag;
|
|
175
|
+
|
|
176
|
+
using Base_hook_matrix_row =
|
|
177
|
+
boost::intrusive::list_base_hook<boost::intrusive::tag<Matrix_row_tag>,
|
|
178
|
+
boost::intrusive::link_mode<boost::intrusive::auto_unlink> >;
|
|
179
|
+
using Base_hook_matrix_list_column =
|
|
180
|
+
boost::intrusive::list_base_hook<boost::intrusive::tag<Matrix_column_tag>,
|
|
181
|
+
boost::intrusive::link_mode<boost::intrusive::safe_link> >;
|
|
182
|
+
using Base_hook_matrix_set_column =
|
|
183
|
+
boost::intrusive::set_base_hook<boost::intrusive::tag<Matrix_column_tag>,
|
|
184
|
+
boost::intrusive::link_mode<boost::intrusive::safe_link> >;
|
|
185
|
+
|
|
186
|
+
//Two dummies are necessary to avoid double inheritance as an entry can inherit both a row and a column hook.
|
|
187
|
+
struct Dummy_row_hook {};
|
|
188
|
+
struct Dummy_column_hook {};
|
|
189
|
+
|
|
190
|
+
using Row_hook = typename std::conditional<PersistenceMatrixOptions::has_row_access &&
|
|
191
|
+
PersistenceMatrixOptions::has_intrusive_rows,
|
|
192
|
+
Base_hook_matrix_row,
|
|
193
|
+
Dummy_row_hook
|
|
194
|
+
>::type;
|
|
195
|
+
using Column_hook = typename std::conditional<
|
|
196
|
+
PersistenceMatrixOptions::column_type == Column_types::INTRUSIVE_LIST,
|
|
197
|
+
Base_hook_matrix_list_column,
|
|
198
|
+
typename std::conditional<PersistenceMatrixOptions::column_type == Column_types::INTRUSIVE_SET,
|
|
199
|
+
Base_hook_matrix_set_column,
|
|
200
|
+
Dummy_column_hook
|
|
201
|
+
>::type
|
|
202
|
+
>::type;
|
|
203
|
+
|
|
204
|
+
//Option to store the column index within the entry (additionally to the row index). Necessary only with row access.
|
|
205
|
+
using Entry_column_index_option =
|
|
206
|
+
typename std::conditional<PersistenceMatrixOptions::has_row_access,
|
|
207
|
+
Entry_column_index<Index>,
|
|
208
|
+
Dummy_entry_column_index_mixin
|
|
209
|
+
>::type;
|
|
210
|
+
//Option to store the value of the entry.
|
|
211
|
+
//Unnecessary for values in Z_2 as there are always 1 (0-valued entries are never stored).
|
|
212
|
+
using Entry_field_element_option =
|
|
213
|
+
typename std::conditional<PersistenceMatrixOptions::is_z2,
|
|
214
|
+
Dummy_entry_field_element_mixin,
|
|
215
|
+
Entry_field_element<Element>
|
|
216
|
+
>::type;
|
|
217
|
+
/**
|
|
218
|
+
* @brief Type of a matrix entry. See @ref Entry for a more detailed description.
|
|
219
|
+
*/
|
|
220
|
+
using Matrix_entry = Entry<Matrix<PersistenceMatrixOptions> >;
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* @brief Default entry constructor/destructor, using classic new and delete.
|
|
224
|
+
* For now, only used as default value for columns constructed independently outside of the matrix by the user.
|
|
225
|
+
* Could be used in the future when parallel options are implemented, as usual pools are not thread safe.
|
|
226
|
+
*/
|
|
227
|
+
inline static New_entry_constructor<Matrix_entry> defaultEntryConstructor;
|
|
228
|
+
/**
|
|
229
|
+
* @brief Entry constructor/destructor used by the matrix. Uses a pool of entries to accelerate memory management,
|
|
230
|
+
* as entries are constructed and destroyed a lot during reduction, swaps or additions.
|
|
231
|
+
*/
|
|
232
|
+
using Entry_constructor = Pool_entry_constructor<Matrix_entry>;
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* @brief Type used to identify an entry, for example when inserting a boundary.
|
|
236
|
+
* If @ref PersistenceMatrixOptions::is_z2 is true, the type is an @ref IDIdx and corresponds to the row index of the
|
|
237
|
+
* entry (the entry value is assumed to be 1). If @ref PersistenceMatrixOptions::is_z2 is false, the type is a pair
|
|
238
|
+
* whose first element is the row index of the entry and the second element is the value of the entry (which again is
|
|
239
|
+
* assumed to be non-zero). The column index of the row is always deduced from the context in which the type is used.
|
|
240
|
+
*/
|
|
241
|
+
using Entry_representative = typename std::conditional<PersistenceMatrixOptions::is_z2,
|
|
242
|
+
ID_index,
|
|
243
|
+
std::pair<ID_index, Element>
|
|
244
|
+
>::type;
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* @brief Compares two entries by their position in the row. They are assume to be in the same row.
|
|
248
|
+
*/
|
|
249
|
+
struct RowEntryComp {
|
|
250
|
+
bool operator()(const Matrix_entry& c1, const Matrix_entry& c2) const {
|
|
251
|
+
return c1.get_column_index() < c2.get_column_index();
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* @brief Type of the rows stored in the matrix. Is either an intrusive list of @ref Matrix_entry (not ordered) if
|
|
257
|
+
* @ref PersistenceMatrixOptions::has_intrusive_rows is true, or a set of @ref Matrix_entry (ordered by
|
|
258
|
+
* column index) otherwise.
|
|
259
|
+
*/
|
|
260
|
+
using Row =
|
|
261
|
+
typename std::conditional<PersistenceMatrixOptions::has_intrusive_rows,
|
|
262
|
+
boost::intrusive::list<Matrix_entry,
|
|
263
|
+
boost::intrusive::constant_time_size<false>,
|
|
264
|
+
boost::intrusive::base_hook<Base_hook_matrix_row>
|
|
265
|
+
>,
|
|
266
|
+
std::set<Matrix_entry, RowEntryComp>
|
|
267
|
+
>::type;
|
|
268
|
+
|
|
269
|
+
using Row_container =
|
|
270
|
+
typename std::conditional<PersistenceMatrixOptions::has_removable_rows,
|
|
271
|
+
std::map<ID_index, Row>,
|
|
272
|
+
std::vector<Row>
|
|
273
|
+
>::type;
|
|
274
|
+
|
|
275
|
+
//Row access at column level
|
|
276
|
+
using Row_access_option =
|
|
277
|
+
typename std::conditional<PersistenceMatrixOptions::has_row_access,
|
|
278
|
+
Row_access<Matrix<PersistenceMatrixOptions> >,
|
|
279
|
+
Dummy_row_access
|
|
280
|
+
>::type;
|
|
281
|
+
//Row access at matrix level
|
|
282
|
+
using Matrix_row_access_option =
|
|
283
|
+
typename std::conditional<PersistenceMatrixOptions::has_row_access,
|
|
284
|
+
Matrix_row_access<Row,
|
|
285
|
+
Row_container,
|
|
286
|
+
PersistenceMatrixOptions::has_removable_rows,
|
|
287
|
+
ID_index>,
|
|
288
|
+
Dummy_matrix_row_access
|
|
289
|
+
>::type;
|
|
290
|
+
|
|
291
|
+
template <typename value_type>
|
|
292
|
+
using Dictionary =
|
|
293
|
+
typename std::conditional<PersistenceMatrixOptions::has_map_column_container,
|
|
294
|
+
std::unordered_map<unsigned int, value_type>,
|
|
295
|
+
std::vector<value_type>
|
|
296
|
+
>::type;
|
|
297
|
+
|
|
298
|
+
static const bool isNonBasic = PersistenceMatrixOptions::has_column_pairings ||
|
|
299
|
+
PersistenceMatrixOptions::has_vine_update ||
|
|
300
|
+
PersistenceMatrixOptions::can_retrieve_representative_cycles;
|
|
301
|
+
|
|
302
|
+
using Column_dimension_option =
|
|
303
|
+
typename std::conditional<isNonBasic,
|
|
304
|
+
Column_dimension_holder<Matrix<PersistenceMatrixOptions> >,
|
|
305
|
+
Dummy_dimension_holder
|
|
306
|
+
>::type;
|
|
307
|
+
//Extra information needed for a column when the matrix is a @ref chainmatrix "chain matrix".
|
|
308
|
+
using Chain_column_option =
|
|
309
|
+
typename std::conditional<isNonBasic && !PersistenceMatrixOptions::is_of_boundary_type,
|
|
310
|
+
Chain_column_extra_properties<Matrix<PersistenceMatrixOptions> >,
|
|
311
|
+
Dummy_chain_properties
|
|
312
|
+
>::type;
|
|
313
|
+
|
|
314
|
+
using Matrix_heap_column = Heap_column<Matrix<PersistenceMatrixOptions> >;
|
|
315
|
+
using Matrix_list_column = List_column<Matrix<PersistenceMatrixOptions> >;
|
|
316
|
+
using Matrix_vector_column = Vector_column<Matrix<PersistenceMatrixOptions> >;
|
|
317
|
+
using Matrix_naive_vector_column = Naive_vector_column<Matrix<PersistenceMatrixOptions> >;
|
|
318
|
+
using Matrix_small_vector_column = Small_vector_column<Matrix<PersistenceMatrixOptions> >;
|
|
319
|
+
using Matrix_set_column = Set_column<Matrix<PersistenceMatrixOptions> >;
|
|
320
|
+
using Matrix_unordered_set_column = Unordered_set_column<Matrix<PersistenceMatrixOptions> >;
|
|
321
|
+
using Matrix_intrusive_list_column = Intrusive_list_column<Matrix<PersistenceMatrixOptions> >;
|
|
322
|
+
using Matrix_intrusive_set_column = Intrusive_set_column<Matrix<PersistenceMatrixOptions> >;
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* @brief Type of the columns stored in the matrix. The type depends on the value of
|
|
326
|
+
* @ref PersistenceMatrixOptions::column_type defined in the given options. See @ref Column_types for a more detailed
|
|
327
|
+
* description. All columns follow the @ref PersistenceMatrixColumn concept.
|
|
328
|
+
*/
|
|
329
|
+
using Column = typename std::conditional<
|
|
330
|
+
PersistenceMatrixOptions::column_type == Column_types::HEAP,
|
|
331
|
+
Matrix_heap_column,
|
|
332
|
+
typename std::conditional<
|
|
333
|
+
PersistenceMatrixOptions::column_type == Column_types::LIST,
|
|
334
|
+
Matrix_list_column,
|
|
335
|
+
typename std::conditional<
|
|
336
|
+
PersistenceMatrixOptions::column_type == Column_types::SET,
|
|
337
|
+
Matrix_set_column,
|
|
338
|
+
typename std::conditional<
|
|
339
|
+
PersistenceMatrixOptions::column_type == Column_types::UNORDERED_SET,
|
|
340
|
+
Matrix_unordered_set_column,
|
|
341
|
+
typename std::conditional<
|
|
342
|
+
PersistenceMatrixOptions::column_type == Column_types::VECTOR,
|
|
343
|
+
Matrix_vector_column,
|
|
344
|
+
typename std::conditional<
|
|
345
|
+
PersistenceMatrixOptions::column_type == Column_types::INTRUSIVE_LIST,
|
|
346
|
+
Matrix_intrusive_list_column,
|
|
347
|
+
typename std::conditional<
|
|
348
|
+
PersistenceMatrixOptions::column_type == Column_types::NAIVE_VECTOR,
|
|
349
|
+
Matrix_naive_vector_column,
|
|
350
|
+
typename std::conditional_t<
|
|
351
|
+
PersistenceMatrixOptions::column_type == Column_types::SMALL_VECTOR,
|
|
352
|
+
Matrix_small_vector_column,
|
|
353
|
+
Matrix_intrusive_set_column>
|
|
354
|
+
>::type
|
|
355
|
+
>::type
|
|
356
|
+
>::type
|
|
357
|
+
>::type
|
|
358
|
+
>::type
|
|
359
|
+
>::type
|
|
360
|
+
>::type;
|
|
361
|
+
|
|
362
|
+
struct Column_z2_settings{
|
|
363
|
+
Column_z2_settings() : entryConstructor() {}
|
|
364
|
+
Column_z2_settings([[maybe_unused]] Characteristic characteristic) : entryConstructor() {}
|
|
365
|
+
Column_z2_settings(const Column_z2_settings& toCopy) : entryConstructor() {}
|
|
366
|
+
|
|
367
|
+
Entry_constructor entryConstructor; //will be replaced by more specific allocators depending on the column type.
|
|
368
|
+
};
|
|
369
|
+
|
|
370
|
+
struct Column_zp_settings {
|
|
371
|
+
Column_zp_settings() : operators(), entryConstructor() {}
|
|
372
|
+
//purposely triggers operators() instead of operators(characteristic) as the "dummy" values for the different
|
|
373
|
+
//operators can be different from -1.
|
|
374
|
+
Column_zp_settings(Characteristic characteristic) : operators(), entryConstructor() {
|
|
375
|
+
if (characteristic != static_cast<Characteristic>(-1)) operators.set_characteristic(characteristic);
|
|
376
|
+
}
|
|
377
|
+
Column_zp_settings(const Column_zp_settings& toCopy)
|
|
378
|
+
: operators(toCopy.operators.get_characteristic()), entryConstructor() {}
|
|
379
|
+
|
|
380
|
+
Field_operators operators;
|
|
381
|
+
Entry_constructor entryConstructor; //will be replaced by more specific allocators depending on the column type.
|
|
382
|
+
};
|
|
383
|
+
|
|
384
|
+
// struct Column_z2_with_rows_settings {
|
|
385
|
+
// Column_z2_with_rows_settings() : entryConstructor(), rows(nullptr) {}
|
|
386
|
+
// Column_z2_with_rows_settings([[maybe_unused]] Characteristic characteristic)
|
|
387
|
+
// : entryConstructor(), rows(nullptr) {}
|
|
388
|
+
|
|
389
|
+
// Entry_constructor entryConstructor;
|
|
390
|
+
// Row_container* rows;
|
|
391
|
+
// };
|
|
392
|
+
|
|
393
|
+
// struct Column_zp_with_rows_settings {
|
|
394
|
+
// Column_zp_with_rows_settings() : operators(), entryConstructor(), rows(nullptr) {}
|
|
395
|
+
// Column_zp_with_rows_settings(Characteristic characteristic)
|
|
396
|
+
// : operators(characteristic), entryConstructor(), rows(nullptr) {}
|
|
397
|
+
|
|
398
|
+
// Field_operators operators;
|
|
399
|
+
// Entry_constructor entryConstructor;
|
|
400
|
+
// Row_container* rows;
|
|
401
|
+
// };
|
|
402
|
+
|
|
403
|
+
//To prepare a more flexible use of the column types later (custom allocators depending on the column type etc.)
|
|
404
|
+
using Column_settings = typename std::conditional<
|
|
405
|
+
PersistenceMatrixOptions::is_z2,
|
|
406
|
+
Column_z2_settings,
|
|
407
|
+
Column_zp_settings
|
|
408
|
+
>::type;
|
|
409
|
+
|
|
410
|
+
// using Column_settings = typename std::conditional<
|
|
411
|
+
// PersistenceMatrixOptions::is_z2,
|
|
412
|
+
// typename std::conditional<PersistenceMatrixOptions::has_row_access,
|
|
413
|
+
// Column_z2_with_rows_settings,
|
|
414
|
+
// Column_z2_settings
|
|
415
|
+
// >::type,
|
|
416
|
+
// typename std::conditional<PersistenceMatrixOptions::has_row_access,
|
|
417
|
+
// Column_zp_with_rows_settings,
|
|
418
|
+
// Column_zp_settings
|
|
419
|
+
// >::type
|
|
420
|
+
// >::type;
|
|
421
|
+
|
|
422
|
+
using Column_container =
|
|
423
|
+
typename std::conditional<PersistenceMatrixOptions::has_map_column_container,
|
|
424
|
+
std::unordered_map<Index, Column>,
|
|
425
|
+
std::vector<Column>
|
|
426
|
+
>::type;
|
|
427
|
+
|
|
428
|
+
static const bool hasFixedBarcode = Option_list::is_of_boundary_type && !PersistenceMatrixOptions::has_vine_update;
|
|
429
|
+
/**
|
|
430
|
+
* @brief Type of the computed barcode. It is either a list of @ref Matrix::Bar or a vector of @ref Matrix::Bar,
|
|
431
|
+
* depending if bars need to be removed from the container as some point or not.
|
|
432
|
+
*/
|
|
433
|
+
using Barcode = typename std::conditional<hasFixedBarcode,
|
|
434
|
+
std::vector<Bar>,
|
|
435
|
+
typename std::conditional<PersistenceMatrixOptions::has_removable_columns,
|
|
436
|
+
std::list<Bar>,
|
|
437
|
+
std::vector<Bar>
|
|
438
|
+
>::type
|
|
439
|
+
>::type;
|
|
440
|
+
using Bar_dictionary =
|
|
441
|
+
typename std::conditional<hasFixedBarcode,
|
|
442
|
+
typename std::conditional<PersistenceMatrixOptions::can_retrieve_representative_cycles,
|
|
443
|
+
std::vector<Index>, //RU
|
|
444
|
+
std::unordered_map<Pos_index, Index> //boundary
|
|
445
|
+
>::type,
|
|
446
|
+
typename std::conditional<PersistenceMatrixOptions::has_removable_columns,
|
|
447
|
+
std::unordered_map<Pos_index, typename Barcode::iterator>,
|
|
448
|
+
std::vector<Index>
|
|
449
|
+
>::type
|
|
450
|
+
>::type;
|
|
451
|
+
|
|
452
|
+
//default type for boundaries to permit list initialization directly in function parameters
|
|
453
|
+
using Boundary = typename std::conditional<PersistenceMatrixOptions::is_z2,
|
|
454
|
+
std::initializer_list<ID_index>,
|
|
455
|
+
std::initializer_list<std::pair<ID_index, Element> >
|
|
456
|
+
>::type;
|
|
457
|
+
|
|
458
|
+
//i.e. is simple @ref boundarymatrix "boundary matrix". Also, only needed because of the reduction algorithm.
|
|
459
|
+
//TODO: remove the necessity and recalculate when needed or keep it like that?
|
|
460
|
+
static const bool maxDimensionIsNeeded =
|
|
461
|
+
PersistenceMatrixOptions::has_column_pairings && PersistenceMatrixOptions::is_of_boundary_type &&
|
|
462
|
+
!PersistenceMatrixOptions::has_vine_update && !PersistenceMatrixOptions::can_retrieve_representative_cycles;
|
|
463
|
+
|
|
464
|
+
using Matrix_dimension_option = typename std::conditional<
|
|
465
|
+
PersistenceMatrixOptions::has_matrix_maximal_dimension_access || maxDimensionIsNeeded,
|
|
466
|
+
typename std::conditional<PersistenceMatrixOptions::has_removable_columns,
|
|
467
|
+
Matrix_all_dimension_holder<Dimension>,
|
|
468
|
+
Matrix_max_dimension_holder<Dimension>
|
|
469
|
+
>::type,
|
|
470
|
+
Dummy_matrix_dimension_holder
|
|
471
|
+
>::type;
|
|
472
|
+
|
|
473
|
+
using Master_base_matrix =
|
|
474
|
+
typename std::conditional<PersistenceMatrixOptions::has_column_compression,
|
|
475
|
+
Base_matrix_with_column_compression<Matrix<PersistenceMatrixOptions> >,
|
|
476
|
+
Base_matrix<Matrix<PersistenceMatrixOptions> >
|
|
477
|
+
>::type;
|
|
478
|
+
using Master_boundary_matrix = Boundary_matrix<Matrix<PersistenceMatrixOptions> >;
|
|
479
|
+
using Master_RU_matrix = RU_matrix<Matrix<PersistenceMatrixOptions> >;
|
|
480
|
+
using Master_chain_matrix = Chain_matrix<Matrix<PersistenceMatrixOptions> >;
|
|
481
|
+
|
|
482
|
+
template <class Base>
|
|
483
|
+
using Base_swap_option =
|
|
484
|
+
typename std::conditional<PersistenceMatrixOptions::has_vine_update ||
|
|
485
|
+
PersistenceMatrixOptions::has_column_and_row_swaps,
|
|
486
|
+
Base_swap<Matrix<PersistenceMatrixOptions>, Base>,
|
|
487
|
+
Dummy_base_swap
|
|
488
|
+
>::type;
|
|
489
|
+
using Base_pairing_option =
|
|
490
|
+
typename std::conditional<PersistenceMatrixOptions::has_column_pairings &&
|
|
491
|
+
!PersistenceMatrixOptions::has_vine_update &&
|
|
492
|
+
!PersistenceMatrixOptions::can_retrieve_representative_cycles,
|
|
493
|
+
Base_pairing<Matrix<PersistenceMatrixOptions> >,
|
|
494
|
+
Dummy_base_pairing
|
|
495
|
+
>::type;
|
|
496
|
+
|
|
497
|
+
using RU_pairing_option =
|
|
498
|
+
typename std::conditional<PersistenceMatrixOptions::has_column_pairings &&
|
|
499
|
+
!PersistenceMatrixOptions::has_vine_update,
|
|
500
|
+
RU_pairing<Matrix<PersistenceMatrixOptions> >,
|
|
501
|
+
Dummy_ru_pairing
|
|
502
|
+
>::type;
|
|
503
|
+
using RU_vine_swap_option =
|
|
504
|
+
typename std::conditional<PersistenceMatrixOptions::has_vine_update,
|
|
505
|
+
RU_vine_swap<Matrix<PersistenceMatrixOptions> >,
|
|
506
|
+
Dummy_ru_vine_swap
|
|
507
|
+
>::type;
|
|
508
|
+
using RU_representative_cycles_option =
|
|
509
|
+
typename std::conditional<PersistenceMatrixOptions::can_retrieve_representative_cycles,
|
|
510
|
+
RU_representative_cycles<Matrix<PersistenceMatrixOptions> >,
|
|
511
|
+
Dummy_ru_representative_cycles
|
|
512
|
+
>::type;
|
|
513
|
+
|
|
514
|
+
using Chain_pairing_option =
|
|
515
|
+
typename std::conditional<PersistenceMatrixOptions::has_column_pairings &&
|
|
516
|
+
!PersistenceMatrixOptions::has_vine_update,
|
|
517
|
+
Chain_pairing<Matrix<PersistenceMatrixOptions> >,
|
|
518
|
+
Dummy_chain_pairing
|
|
519
|
+
>::type;
|
|
520
|
+
using Chain_vine_swap_option = typename std::conditional<PersistenceMatrixOptions::has_vine_update,
|
|
521
|
+
Chain_vine_swap<Matrix<PersistenceMatrixOptions> >,
|
|
522
|
+
Dummy_chain_vine_swap
|
|
523
|
+
>::type;
|
|
524
|
+
using Chain_representative_cycles_option =
|
|
525
|
+
typename std::conditional<PersistenceMatrixOptions::can_retrieve_representative_cycles,
|
|
526
|
+
Chain_representative_cycles<Matrix<PersistenceMatrixOptions> >,
|
|
527
|
+
Dummy_chain_representative_cycles
|
|
528
|
+
>::type;
|
|
529
|
+
|
|
530
|
+
/**
|
|
531
|
+
* @brief Type of a representative cycle. Vector of @ref rowindex "row indices".
|
|
532
|
+
*/
|
|
533
|
+
using Cycle = std::vector<ID_index>; //TODO: add coefficients
|
|
534
|
+
|
|
535
|
+
//Return types to factorize the corresponding methods
|
|
536
|
+
|
|
537
|
+
//The returned column is `const` if the matrix uses column compression
|
|
538
|
+
using Returned_column =
|
|
539
|
+
typename std::conditional<!isNonBasic && PersistenceMatrixOptions::has_column_compression,
|
|
540
|
+
const Column,
|
|
541
|
+
Column
|
|
542
|
+
>::type;
|
|
543
|
+
//The returned row is `const` if the matrix uses column compression
|
|
544
|
+
using Returned_row =
|
|
545
|
+
typename std::conditional<!isNonBasic && PersistenceMatrixOptions::has_column_compression,
|
|
546
|
+
const Row,
|
|
547
|
+
Row
|
|
548
|
+
>::type;
|
|
549
|
+
//If the matrix is a chain matrix, the insertion method returns the pivots of its unpaired columns used to reduce the
|
|
550
|
+
//inserted boundary. Otherwise, void.
|
|
551
|
+
using Insertion_return =
|
|
552
|
+
typename std::conditional<PersistenceMatrixOptions::is_of_boundary_type || !isNonBasic ||
|
|
553
|
+
PersistenceMatrixOptions::column_indexation_type ==
|
|
554
|
+
Column_indexation_types::POSITION,
|
|
555
|
+
void,
|
|
556
|
+
std::vector<Entry_representative>
|
|
557
|
+
>::type;
|
|
558
|
+
|
|
559
|
+
/**
|
|
560
|
+
* @brief Default constructor. Initializes an empty matrix.
|
|
561
|
+
*/
|
|
562
|
+
Matrix();
|
|
563
|
+
/**
|
|
564
|
+
* @brief Constructs a new matrix from the given ranges of @ref Entry_representative. Each range corresponds to a
|
|
565
|
+
* column (the order of the ranges are preserved). The content of the ranges is assumed to be sorted by increasing
|
|
566
|
+
* IDs. If the columns are representing a boundary matrix, the IDs of the simplices are also assumed to be
|
|
567
|
+
* consecutive, ordered by filtration value, starting with 0.
|
|
568
|
+
*
|
|
569
|
+
* See @ref mp_matrices "matrix descriptions" for further details on how the given matrix is handled.
|
|
570
|
+
*
|
|
571
|
+
* @tparam Container Range type for @ref Entry_representative ranges. Assumed to have a begin(), end() and size()
|
|
572
|
+
* method.
|
|
573
|
+
* @param columns For a @ref basematrix "base matrix", the columns are copied as is. If options related to homology
|
|
574
|
+
* are activated, @p columns is interpreted as a boundary matrix of a **simplicial** complex. In this case,
|
|
575
|
+
* `columns[i]` should store the boundary of simplex `i` as an ordered list of indices of its facets (again those
|
|
576
|
+
* indices correspond to their respective position in the matrix). Therefore the indices of the simplices are assumed
|
|
577
|
+
* to be consecutive and starting with 0 (an empty boundary is interpreted as a vertex boundary and not as a non
|
|
578
|
+
* existing simplex). All dimensions up to the maximal dimension of interest have to be present. If only a higher
|
|
579
|
+
* dimension is of interest and not everything should be stored, then use the @ref insert_boundary method instead
|
|
580
|
+
* (after creating the matrix with the @ref Matrix(unsigned int numberOfColumns, Characteristic characteristic)
|
|
581
|
+
* constructor preferably). If the persistence barcode has to be computed from this matrix, the simplices are also
|
|
582
|
+
* assumed to be ordered by appearance order in the filtration. Also, depending of the options, the matrix is
|
|
583
|
+
* eventually reduced on the fly or converted into a chain complex base, so the new matrix is not always identical to
|
|
584
|
+
* the old one.
|
|
585
|
+
* @param characteristic Characteristic of the coefficient field. Has to be specified if
|
|
586
|
+
* @ref PersistenceMatrixOptions::is_z2 is false. Default value is 11. Ignored if
|
|
587
|
+
* @ref PersistenceMatrixOptions::is_z2 is true.
|
|
588
|
+
*/
|
|
589
|
+
template <class Container = Boundary>
|
|
590
|
+
Matrix(const std::vector<Container>& columns, Characteristic characteristic = 11);
|
|
591
|
+
/**
|
|
592
|
+
* @brief Constructs a new empty matrix and reserves space for the given number of columns.
|
|
593
|
+
*
|
|
594
|
+
* @param numberOfColumns Number of columns to reserve space for.
|
|
595
|
+
* @param characteristic Characteristic of the coefficient field. If not specified and
|
|
596
|
+
* @ref PersistenceMatrixOptions::is_z2 is false, the characteristic has to be set later with the use of
|
|
597
|
+
* @ref set_characteristic before calling for the first time a method needing it. Ignored if
|
|
598
|
+
* @ref PersistenceMatrixOptions::is_z2 is true.
|
|
599
|
+
*/
|
|
600
|
+
Matrix(unsigned int numberOfColumns, Characteristic characteristic = static_cast<Characteristic>(-1));
|
|
601
|
+
/**
|
|
602
|
+
* @brief Constructs a new empty matrix with the given comparator functions. Only available when those comparators
|
|
603
|
+
* are necessary.
|
|
604
|
+
*
|
|
605
|
+
* That is, when **all** following options have following values:
|
|
606
|
+
* - @ref PersistenceMatrixOptions::is_of_boundary_type = false
|
|
607
|
+
* - @ref PersistenceMatrixOptions::has_vine_update = true
|
|
608
|
+
* - @ref PersistenceMatrixOptions::has_column_pairings = false
|
|
609
|
+
*
|
|
610
|
+
* Those comparators are necessary to distinguish cases in a vine update. When the matrix is of
|
|
611
|
+
* @ref boundarymatrix "boundary type" or if the column pairing is activated (i.e., the barcode is stored),
|
|
612
|
+
* the comparators can be easily deduced without overhead. If neither are true, we assume that one has additional
|
|
613
|
+
* information outside of the matrix about the barcode to provide a better suited comparator adapted to the situation
|
|
614
|
+
* (as in the implementation of the Zigzag algorithm @cite zigzag for example.)
|
|
615
|
+
*
|
|
616
|
+
* @param birthComparator Method taking two @ref PosIdx indices as parameter and returns true if and only if the first
|
|
617
|
+
* cell is associated to a bar with strictly smaller birth than the bar associated to the second one.
|
|
618
|
+
* @param deathComparator Method taking two @ref PosIdx indices as parameter and returns true if and only if the first
|
|
619
|
+
* cell is associated to a bar with strictly smaller death than the bar associated to the second one.
|
|
620
|
+
*/
|
|
621
|
+
Matrix(const std::function<bool(Pos_index,Pos_index)>& birthComparator,
|
|
622
|
+
const std::function<bool(Pos_index,Pos_index)>& deathComparator);
|
|
623
|
+
/**
|
|
624
|
+
* @brief Constructs a new matrix from the given ranges with the given comparator functions.
|
|
625
|
+
* Only available when those comparators are necessary.
|
|
626
|
+
*
|
|
627
|
+
* That is, when **all** following options have following values:
|
|
628
|
+
* - @ref PersistenceMatrixOptions::is_of_boundary_type = false
|
|
629
|
+
* - @ref PersistenceMatrixOptions::has_vine_update = true
|
|
630
|
+
* - @ref PersistenceMatrixOptions::has_column_pairings = false
|
|
631
|
+
*
|
|
632
|
+
* See description of @ref Matrix(const std::vector<Container>& columns, Characteristic characteristic)
|
|
633
|
+
* for more information about @p orderedBoundaries and
|
|
634
|
+
* @ref Matrix(const std::function<bool(Pos_index,Pos_index)>&, const std::function<bool(Pos_index,Pos_index)>&)
|
|
635
|
+
* for more information about the comparators.
|
|
636
|
+
*
|
|
637
|
+
* @tparam Boundary_range Range type for @ref Entry_representative ranges. Assumed to have a begin(), end() and size()
|
|
638
|
+
* method.
|
|
639
|
+
* @param orderedBoundaries Vector of ordered boundaries in filtration order. Indexed continuously starting at 0.
|
|
640
|
+
* @param birthComparator Method taking two @ref PosIdx indices as parameter and returns true if and only if the first
|
|
641
|
+
* cell is associated to a bar with strictly smaller birth than the bar associated to the second one.
|
|
642
|
+
* @param deathComparator Method taking two @ref PosIdx indices as parameter and returns true if and only if the first
|
|
643
|
+
* cell is associated to a bar with strictly smaller death than the bar associated to the second one.
|
|
644
|
+
* @param characteristic Characteristic of the coefficient field. Has to be specified if
|
|
645
|
+
* @ref PersistenceMatrixOptions::is_z2 is false. Default value is 11.
|
|
646
|
+
* Ignored if @ref PersistenceMatrixOptions::is_z2 is true.
|
|
647
|
+
*/
|
|
648
|
+
template <class Boundary_range = Boundary>
|
|
649
|
+
Matrix(const std::vector<Boundary_range>& orderedBoundaries,
|
|
650
|
+
const std::function<bool(Pos_index,Pos_index)>& birthComparator,
|
|
651
|
+
const std::function<bool(Pos_index,Pos_index)>& deathComparator,
|
|
652
|
+
Characteristic characteristic = 11);
|
|
653
|
+
/**
|
|
654
|
+
* @brief Constructs a new empty matrix and reserves space for the given number of columns.
|
|
655
|
+
* Only available when those comparators are necessary.
|
|
656
|
+
*
|
|
657
|
+
* That is, when **all** following options have following values:
|
|
658
|
+
* - @ref PersistenceMatrixOptions::is_of_boundary_type = false
|
|
659
|
+
* - @ref PersistenceMatrixOptions::has_vine_update = true
|
|
660
|
+
* - @ref PersistenceMatrixOptions::has_column_pairings = false
|
|
661
|
+
*
|
|
662
|
+
* See description of
|
|
663
|
+
* @ref Matrix(const std::function<bool(Pos_index,Pos_index)>&, const std::function<bool(Pos_index,Pos_index)>&)
|
|
664
|
+
* for more information about the comparators.
|
|
665
|
+
*
|
|
666
|
+
* @param numberOfColumns Number of columns to reserve space for.
|
|
667
|
+
* @param birthComparator Method taking two @ref PosIdx indices as parameter and returns true if and only if the first
|
|
668
|
+
* cell is associated to a bar with strictly smaller birth than the bar associated to the second one.
|
|
669
|
+
* @param deathComparator Method taking two @ref PosIdx indices as parameter and returns true if and only if the first
|
|
670
|
+
* cell is associated to a bar with strictly smaller death than the bar associated to the second one.
|
|
671
|
+
* @param characteristic Characteristic of the coefficient field. If not specified and
|
|
672
|
+
* @ref PersistenceMatrixOptions::is_z2 is false, the characteristic has to be set later with the use of
|
|
673
|
+
* @ref set_characteristic before calling for the first time a method needing it.
|
|
674
|
+
* Ignored if @ref PersistenceMatrixOptions::is_z2 is true.
|
|
675
|
+
*/
|
|
676
|
+
Matrix(unsigned int numberOfColumns,
|
|
677
|
+
const std::function<bool(Pos_index,Pos_index)>& birthComparator,
|
|
678
|
+
const std::function<bool(Pos_index,Pos_index)>& deathComparator,
|
|
679
|
+
Characteristic characteristic = static_cast<Characteristic>(-1));
|
|
680
|
+
/**
|
|
681
|
+
* @brief Copy constructor.
|
|
682
|
+
*
|
|
683
|
+
* @param matrixToCopy %Matrix to copy.
|
|
684
|
+
*/
|
|
685
|
+
Matrix(const Matrix& matrixToCopy);
|
|
686
|
+
/**
|
|
687
|
+
* @brief Move constructor.
|
|
688
|
+
* After the move, the given matrix will be empty.
|
|
689
|
+
*
|
|
690
|
+
* @param other %Matrix to move.
|
|
691
|
+
*/
|
|
692
|
+
Matrix(Matrix&& other) noexcept;
|
|
693
|
+
|
|
694
|
+
~Matrix();
|
|
695
|
+
|
|
696
|
+
//TODO: compatibility with multi fields:
|
|
697
|
+
// - set_characteristic(Characteristic min, Characteristic max)
|
|
698
|
+
// - readapt reduction?
|
|
699
|
+
/**
|
|
700
|
+
* @brief Sets the characteristic of the coefficient field if @ref PersistenceMatrixOptions::is_z2 is false,
|
|
701
|
+
* does nothing otherwise.
|
|
702
|
+
* Should be used if no characteristic could be specified at the creation of the empty matrix.
|
|
703
|
+
* Do not change the value of the characteristic once used.
|
|
704
|
+
*
|
|
705
|
+
* @warning The coefficient values stored in the matrix are stored after computing the corresponding modulo.
|
|
706
|
+
* Therefore, changing the characteristic after is very likely to invalidate all entry values.
|
|
707
|
+
*
|
|
708
|
+
* @param characteristic The characteristic to set.
|
|
709
|
+
*/
|
|
710
|
+
void set_characteristic(Characteristic characteristic);
|
|
711
|
+
|
|
712
|
+
// (TODO: if there is no row access and the column type corresponds to the internal column type of the matrix,
|
|
713
|
+
// moving the column instead of copying it should be possible. Is it worth implementing it?)
|
|
714
|
+
/**
|
|
715
|
+
* @brief Inserts a new ordered column at the end of the matrix by copying the given range of
|
|
716
|
+
* @ref Entry_representative. The content of the range is assumed to be sorted by increasing ID value.
|
|
717
|
+
*
|
|
718
|
+
* Only available for @ref basematrix "base matrices".
|
|
719
|
+
* Otherwise use @ref insert_boundary which will deduce a new column from the boundary given.
|
|
720
|
+
*
|
|
721
|
+
* @tparam Container Range of @ref Entry_representative. Assumed to have a begin(), end() and size() method.
|
|
722
|
+
* @param column Column to be inserted.
|
|
723
|
+
*/
|
|
724
|
+
template <class Container>
|
|
725
|
+
void insert_column(const Container& column);
|
|
726
|
+
/**
|
|
727
|
+
* @brief Inserts a new ordered column at the given index by copying the given range of @ref Entry_representative.
|
|
728
|
+
* There should not be any other column inserted at that index which was not explicitly removed before.
|
|
729
|
+
* The content of the range is assumed to be sorted by increasing ID value.
|
|
730
|
+
*
|
|
731
|
+
* Only available for @ref basematrix "base matrices" without column compression and without row access.
|
|
732
|
+
*
|
|
733
|
+
* @tparam Container Range of @ref Entry_representative. Assumed to have a begin(), end() and size() method.
|
|
734
|
+
* @param column Column to be inserted.
|
|
735
|
+
* @param columnIndex @ref MatIdx index to which the column has to be inserted.
|
|
736
|
+
*/
|
|
737
|
+
template <class Container>
|
|
738
|
+
void insert_column(const Container& column, Index columnIndex);
|
|
739
|
+
//TODO: for simple boundary matrices, add an index pointing to the first column inserted after the last call of
|
|
740
|
+
//get_current_barcode to enable several calls to get_current_barcode
|
|
741
|
+
/**
|
|
742
|
+
* @brief Inserts at the end of the matrix a new ordered column corresponding to the given boundary.
|
|
743
|
+
* This means that it is assumed that this method is called on boundaries in the order of the filtration.
|
|
744
|
+
* It also assumes that the cells in the given boundary are identified by their relative position in the filtration,
|
|
745
|
+
* starting at 0. If it is not the case, use the other
|
|
746
|
+
* @ref insert_boundary(ID_index cellIndex, const Boundary_range& boundary, Dimension dim) "insert_boundary"
|
|
747
|
+
* instead by indicating the cell ID used in the boundaries when the cell is inserted.
|
|
748
|
+
*
|
|
749
|
+
* Different to the constructor, the boundaries do not have to come from a simplicial complex, but also from
|
|
750
|
+
* a more general entry complex. This includes cubical complexes or Morse complexes for example.
|
|
751
|
+
*
|
|
752
|
+
* The content of the new column will vary depending on the underlying @ref mp_matrices "type of the matrix":
|
|
753
|
+
* - If it is a @ref basematrix "basic matrix" type, the boundary is copied as it is, i.e., the method is equivalent
|
|
754
|
+
* to @ref insert_column.
|
|
755
|
+
* - If it is a @ref boundarymatrix "boundary type matrix" and only \f$ R \f$ is stored, the boundary is also just
|
|
756
|
+
* copied. The column will only be reduced later when the barcode is requested in order to apply some optimizations
|
|
757
|
+
* with the additional knowledge. Hence, the barcode will also not be updated, so call @ref get_current_barcode only
|
|
758
|
+
* when the matrix is complete.
|
|
759
|
+
* - If it is a @ref boundarymatrix "boundary type matrix" and both \f$ R \f$ and \f$ U \f$ are stored, the new
|
|
760
|
+
* boundary is stored in its reduced form and the barcode, if active, is also updated.
|
|
761
|
+
* - If it is a @ref chainmatrix "chain type matrix", the new column is of the form `IDIdx + linear combination of
|
|
762
|
+
* older column IDIdxs`, where the combination is deduced while reducing the given boundary. If the barcode is stored,
|
|
763
|
+
* it will also be updated.
|
|
764
|
+
*
|
|
765
|
+
* @tparam Boundary_range Range of @ref Entry_representative. Assumed to have a begin(), end() and size() method.
|
|
766
|
+
* @param boundary Boundary generating the new column. The content should be ordered by ID.
|
|
767
|
+
* @param dim Dimension of the cell whose boundary is given. If the complex is simplicial,
|
|
768
|
+
* this parameter can be omitted as it can be deduced from the size of the boundary.
|
|
769
|
+
* @return If it is a @ref chainmatrix "chain matrix", the method returns the @ref MatIdx indices of the unpaired
|
|
770
|
+
* chains used to reduce the boundary. Otherwise, nothing.
|
|
771
|
+
*/
|
|
772
|
+
template <class Boundary_range = Boundary>
|
|
773
|
+
Insertion_return insert_boundary(const Boundary_range& boundary, Dimension dim = -1);
|
|
774
|
+
/**
|
|
775
|
+
* @brief Only available for @ref mp_matrices "non-basic matrices".
|
|
776
|
+
* It does the same as the other version, but allows the boundary cells to be identified without restrictions
|
|
777
|
+
* except that all IDs have to be strictly increasing in the order of filtration. Note that you should avoid then
|
|
778
|
+
* to use the other insertion method to avoid overwriting IDs.
|
|
779
|
+
*
|
|
780
|
+
* As a cell has to be inserted before one of its cofaces in a valid filtration (recall that it is assumed that
|
|
781
|
+
* for @ref mp_matrices "non-basic matrices", the cells are inserted by order of filtration), it is sufficient to
|
|
782
|
+
* indicate the ID of the cell being inserted.
|
|
783
|
+
*
|
|
784
|
+
* @tparam Boundary_range Range of @ref Entry_representative. Assumed to have a begin(), end() and size() method.
|
|
785
|
+
* @param cellIndex @ref IDIdx index to use to identify the new cell.
|
|
786
|
+
* @param boundary Boundary generating the new column. The indices of the boundary have to correspond to the
|
|
787
|
+
* @p cellIndex values of precedent calls of the method for the corresponding cells and should be ordered in
|
|
788
|
+
* increasing order.
|
|
789
|
+
* @param dim Dimension of the cell whose boundary is given. If the complex is simplicial,
|
|
790
|
+
* this parameter can be omitted as it can be deduced from the size of the boundary.
|
|
791
|
+
* @return If it is a @ref chainmatrix "chain matrix", the method returns the @ref MatIdx indices of the unpaired
|
|
792
|
+
* chains used to reduce the boundary. Otherwise, nothing.
|
|
793
|
+
*/
|
|
794
|
+
template <class Boundary_range = Boundary>
|
|
795
|
+
Insertion_return insert_boundary(ID_index cellIndex, const Boundary_range& boundary, Dimension dim = -1);
|
|
796
|
+
|
|
797
|
+
/**
|
|
798
|
+
* @brief Returns the column at the given @ref MatIdx index.
|
|
799
|
+
* For @ref boundarymatrix "RU matrices", is equivalent to
|
|
800
|
+
* @ref get_column(Index columnIndex, bool inR) "get_column(columnIndex, true)".
|
|
801
|
+
* The type of the column depends on the choosen options, see @ref PersistenceMatrixOptions::column_type.
|
|
802
|
+
*
|
|
803
|
+
* @param columnIndex @ref MatIdx index of the column to return.
|
|
804
|
+
* @return Reference to the column. Is `const` if the matrix has column compression.
|
|
805
|
+
*/
|
|
806
|
+
Returned_column& get_column(Index columnIndex);
|
|
807
|
+
/**
|
|
808
|
+
* @brief Only available for @ref chainmatrix "chain matrices". Returns the column at the given @ref MatIdx index.
|
|
809
|
+
* The type of the column depends on the choosen options, see @ref PersistenceMatrixOptions::column_type.
|
|
810
|
+
*
|
|
811
|
+
* @param columnIndex @ref MatIdx index of the column to return.
|
|
812
|
+
* @return Const reference to the column.
|
|
813
|
+
*/
|
|
814
|
+
const Column& get_column(Index columnIndex) const;
|
|
815
|
+
//TODO: there is no particular reason that this method is not available for identifier indexing,
|
|
816
|
+
// just has to be added to the interface...
|
|
817
|
+
/**
|
|
818
|
+
* @brief Only available for @ref boundarymatrix "RU matrices" without @ref Column_indexation_types::IDENTIFIER
|
|
819
|
+
* indexing. Returns the column at the given @ref MatIdx index in \f$ R \f$ if @p inR is true and in \f$ U \f$ if
|
|
820
|
+
* @p inR is false. The type of the column depends on the choosen options,
|
|
821
|
+
* see @ref PersistenceMatrixOptions::column_type.
|
|
822
|
+
*
|
|
823
|
+
* @param columnIndex @ref MatIdx index of the column to return.
|
|
824
|
+
* @param inR If true, returns the column in \f$ R \f$, if false, returns the column in \f$ U \f$.
|
|
825
|
+
* @return Const reference to the column.
|
|
826
|
+
*/
|
|
827
|
+
const Column& get_column(Index columnIndex, bool inR);
|
|
828
|
+
|
|
829
|
+
//TODO: update column indices when reordering rows (after lazy swap) such that always MatIdx are returned.
|
|
830
|
+
/**
|
|
831
|
+
* @brief Only available if @ref PersistenceMatrixOptions::has_row_access is true. Returns the row at the given
|
|
832
|
+
* @ref rowindex "row index". For @ref boundarymatrix "RU matrices", is equivalent to
|
|
833
|
+
* @ref get_row(ID_index rowIndex, bool inR) "get_row(columnIndex, true)". The type of the row depends on the
|
|
834
|
+
* choosen options, see @ref PersistenceMatrixOptions::has_intrusive_rows.
|
|
835
|
+
*
|
|
836
|
+
* @param rowIndex @ref rowindex "Row index" of the row to return: @ref IDIdx for @ref chainmatrix "chain matrices" or
|
|
837
|
+
* updated @ref IDIdx for @ref boundarymatrix "boundary matrices" if swaps occurred.
|
|
838
|
+
* @return Reference to the row. Is `const` if the matrix has column compression.
|
|
839
|
+
*/
|
|
840
|
+
Returned_row& get_row(ID_index rowIndex);
|
|
841
|
+
/**
|
|
842
|
+
* @brief Only available for @ref chainmatrix "chain matrices" and matrices with column compression.
|
|
843
|
+
* Returns the row at the given @ref rowindex "row index".
|
|
844
|
+
* The type of the row depends on the choosen options, see @ref PersistenceMatrixOptions::has_intrusive_rows.
|
|
845
|
+
*
|
|
846
|
+
* @param rowIndex @ref rowindex "Row index" of the row to return: @ref IDIdx for @ref chainmatrix "chain matrices"
|
|
847
|
+
* or updated @ref IDIdx for @ref boundarymatrix "boundary matrices" if swaps occurred.
|
|
848
|
+
* @return Const reference to the row.
|
|
849
|
+
*/
|
|
850
|
+
const Row& get_row(ID_index rowIndex) const;
|
|
851
|
+
//TODO: there is no particular reason that this method is not available for identifier indexing,
|
|
852
|
+
// just has to be added to the interface...
|
|
853
|
+
/**
|
|
854
|
+
* @brief Only available for @ref boundarymatrix "RU matrices" without @ref Column_indexation_types::IDENTIFIER
|
|
855
|
+
* indexing. Returns the row at the given @ref rowindex "row index" in \f$ R \f$ if @p inR is true and in \f$ U \f$ if
|
|
856
|
+
* @p inR is false. The type of the row depends on the choosen options, see
|
|
857
|
+
* @ref PersistenceMatrixOptions::has_intrusive_rows.
|
|
858
|
+
*
|
|
859
|
+
* @param rowIndex @ref rowindex "Row index" of the row to return: updated @ref IDIdx if swaps occurred.
|
|
860
|
+
* @param inR If true, returns the row in \f$ R \f$, if false, returns the row in \f$ U \f$.
|
|
861
|
+
* @return Const reference to the row.
|
|
862
|
+
*/
|
|
863
|
+
const Row& get_row(ID_index rowIndex, bool inR);
|
|
864
|
+
|
|
865
|
+
/**
|
|
866
|
+
* @brief Only available for @ref basematrix "base matrices" without column compression and if
|
|
867
|
+
* @ref PersistenceMatrixOptions::has_map_column_container is true. Otherwise, see @ref remove_last. Erases the given
|
|
868
|
+
* column from the matrix. If @ref PersistenceMatrixOptions::has_row_access is also true, the deleted column entries
|
|
869
|
+
* are also automatically removed from their respective rows.
|
|
870
|
+
*
|
|
871
|
+
* @param columnIndex @ref MatIdx index of the column to remove.
|
|
872
|
+
*/
|
|
873
|
+
void remove_column(Index columnIndex);
|
|
874
|
+
//TODO: rename method to be less confusing.
|
|
875
|
+
/**
|
|
876
|
+
* @brief The effect varies depending on the matrices and the options:
|
|
877
|
+
* - @ref basematrix "base matrix" and @ref boundarymatrix "boundary matrix":
|
|
878
|
+
* - @ref PersistenceMatrixOptions::has_map_column_container and @ref
|
|
879
|
+
* PersistenceMatrixOptions::has_column_and_row_swaps are true: cleans up maps used for the lazy row swaps.
|
|
880
|
+
* - @ref PersistenceMatrixOptions::has_row_access and @ref PersistenceMatrixOptions::has_removable_rows are true:
|
|
881
|
+
* assumes that the row is empty and removes it.
|
|
882
|
+
* - Otherwise, does nothing.
|
|
883
|
+
* - @ref boundarymatrix "boundary matrix" with \f$ U \f$ stored: only \f$ R \f$ is affected by the above. If properly
|
|
884
|
+
* used, \f$ U \f$ will never have empty rows.
|
|
885
|
+
* - @ref chainmatrix "chain matrix": only available if @ref PersistenceMatrixOptions::has_row_access and
|
|
886
|
+
* @ref PersistenceMatrixOptions::has_removable_rows are true. Assumes that the row is empty and removes it.
|
|
887
|
+
*
|
|
888
|
+
* @warning The removed rows are always assumed to be empty. If it is not the case, the deleted row entries are not
|
|
889
|
+
* removed from their columns. And in the case of intrusive rows, this will generate a segmentation fault when
|
|
890
|
+
* the column entries are destroyed later. The row access is just meant as a "read only" access to the rows and the
|
|
891
|
+
* @ref erase_empty_row method just as a way to specify that a row is empty and can therefore be removed from
|
|
892
|
+
* dictionaries. This allows to avoid testing the emptiness of a row at each column entry removal, what can be quite
|
|
893
|
+
* frequent.
|
|
894
|
+
*
|
|
895
|
+
* @param rowIndex @ref rowindex "Row index" of the empty row to remove.
|
|
896
|
+
*/
|
|
897
|
+
void erase_empty_row(ID_index rowIndex);
|
|
898
|
+
//TODO: for chain matrices, replace IDIdx input with MatIdx input to homogenize.
|
|
899
|
+
/**
|
|
900
|
+
* @brief Only available for @ref boundarymatrix "RU" and @ref chainmatrix "chain matrices" and if
|
|
901
|
+
* @ref PersistenceMatrixOptions::has_removable_columns and @ref PersistenceMatrixOptions::has_vine_update are true.
|
|
902
|
+
* For @ref chainmatrix "chain matrices", @ref PersistenceMatrixOptions::has_map_column_container and
|
|
903
|
+
* @ref PersistenceMatrixOptions::has_column_pairings also need to be true. Assumes that the cell is maximal in the
|
|
904
|
+
* current complex and removes it such that the matrix remains consistent (i.e., RU is still an upper triangular
|
|
905
|
+
* decomposition of the boundary matrix and chain is still a compatible bases of the chain complex in the sense
|
|
906
|
+
* of @cite zigzag). The maximality of the cell is not verified. Also updates the barcode if it was computed.
|
|
907
|
+
*
|
|
908
|
+
* For @ref chainmatrix "chain matrices", using the other version of the method could perform better depending on how
|
|
909
|
+
* the data is maintained on the side of the user. Then, @ref PersistenceMatrixOptions::has_column_pairings also do
|
|
910
|
+
* not need to be true.
|
|
911
|
+
*
|
|
912
|
+
* See also @ref remove_last and @ref remove_column.
|
|
913
|
+
*
|
|
914
|
+
* @param columnIndex If @ref boundarymatrix "boundary matrix", @ref MatIdx index of the cell to remove, otherwise the
|
|
915
|
+
* @ref IDIdx index.
|
|
916
|
+
*/
|
|
917
|
+
void remove_maximal_cell(Index columnIndex);
|
|
918
|
+
//TODO: See if it would be better to use something more general than a vector for columnsToSwap, such that
|
|
919
|
+
// the user do not have to construct the vector from scratch. Like passing iterators instead. But it would be nice,
|
|
920
|
+
// to still be able to do (cell, {})...
|
|
921
|
+
/**
|
|
922
|
+
* @brief Only available for @ref chainmatrix "chain matrices" and if
|
|
923
|
+
* @ref PersistenceMatrixOptions::has_removable_columns, @ref PersistenceMatrixOptions::has_vine_update and
|
|
924
|
+
* @ref PersistenceMatrixOptions::has_map_column_container are true. Assumes that the cell is maximal in the current
|
|
925
|
+
* complex and removes it such that the matrix remains consistent (i.e., it is still a compatible bases of the chain
|
|
926
|
+
* complex in the sense of @cite zigzag). The maximality of the cell is not verified. Also updates the barcode if it
|
|
927
|
+
* was computed.
|
|
928
|
+
*
|
|
929
|
+
* To maintain the compatibility, vine swaps are done to move the cell up to the end of the filtration. Once at the
|
|
930
|
+
* end, the removal is trivial. But for @ref chainmatrix "chain matrices", swaps do not actually swap the position of
|
|
931
|
+
* the column every time, so the cells appearing after @p cellIndex in the filtration have to be searched first within
|
|
932
|
+
* the matrix. If the user has an easy access to the @ref IDIdx of the cells in the order of filtration, passing them
|
|
933
|
+
* by argument with @p columnsToSwap allows to skip a linear search process. Typically, if the user knows that the
|
|
934
|
+
* cell he wants to remove is already the last cell of the filtration, calling
|
|
935
|
+
* @ref remove_maximal_cell(ID_index cellIndex, const std::vector<ID_index>& columnsToSwap)
|
|
936
|
+
* "remove_maximal_cell(cellID, {})" will be faster than @ref remove_last().
|
|
937
|
+
*
|
|
938
|
+
* See also @ref remove_last.
|
|
939
|
+
*
|
|
940
|
+
* @param cellIndex @ref IDIdx index of the cell to remove
|
|
941
|
+
* @param columnsToSwap Vector of @ref IDIdx indices of the cells coming after @p cellIndex in the filtration.
|
|
942
|
+
*/
|
|
943
|
+
void remove_maximal_cell(ID_index cellIndex, const std::vector<ID_index>& columnsToSwap);
|
|
944
|
+
/**
|
|
945
|
+
* @brief Removes the last inserted column/cell from the matrix.
|
|
946
|
+
* If the matrix is @ref mp_matrices "non basic", @ref PersistenceMatrixOptions::has_removable_columns has to be true
|
|
947
|
+
* for the method to be available. Additionally, if the matrix is a @ref chainmatrix "chain matrix", either
|
|
948
|
+
* @ref PersistenceMatrixOptions::has_map_column_container has to be true or
|
|
949
|
+
* @ref PersistenceMatrixOptions::has_vine_update has to be false. And if the matrix is a
|
|
950
|
+
* @ref basematrix "base matrix" it should be without column compression.
|
|
951
|
+
*
|
|
952
|
+
* See also @ref remove_maximal_cell and @ref remove_column.
|
|
953
|
+
*
|
|
954
|
+
* For @ref chainmatrix "chain matrices", if @ref PersistenceMatrixOptions::has_vine_update is true, the last cell
|
|
955
|
+
* does not have to be at the end of the matrix and therefore has to be searched first. In this case, if the user
|
|
956
|
+
* already knows the @ref IDIdx of the last cell, calling
|
|
957
|
+
* @ref remove_maximal_cell(ID_index cellIndex, const std::vector<ID_index>& columnsToSwap)
|
|
958
|
+
* "remove_maximal_cell(cellID, {})" instead allows to skip the search.
|
|
959
|
+
*/
|
|
960
|
+
void remove_last();
|
|
961
|
+
|
|
962
|
+
/**
|
|
963
|
+
* @brief Returns the maximal dimension of a cell stored in the matrix. Only available for
|
|
964
|
+
* @ref mp_matrices "non-basic matrices" and if @ref PersistenceMatrixOptions::has_matrix_maximal_dimension_access
|
|
965
|
+
* is true.
|
|
966
|
+
*
|
|
967
|
+
* @return The maximal dimension.
|
|
968
|
+
*/
|
|
969
|
+
Dimension get_max_dimension() const;
|
|
970
|
+
/**
|
|
971
|
+
* @brief Returns the current number of columns in the matrix.
|
|
972
|
+
*
|
|
973
|
+
* @return The number of columns.
|
|
974
|
+
*/
|
|
975
|
+
Index get_number_of_columns() const;
|
|
976
|
+
/**
|
|
977
|
+
* @brief Returns the dimension of the given cell. Only available for @ref mp_matrices "non-basic matrices".
|
|
978
|
+
*
|
|
979
|
+
* @param columnIndex @ref MatIdx index of the column representing the cell.
|
|
980
|
+
* @return Dimension of the cell.
|
|
981
|
+
*/
|
|
982
|
+
Dimension get_column_dimension(Index columnIndex) const;
|
|
983
|
+
|
|
984
|
+
/**
|
|
985
|
+
* @brief Adds column at @p sourceColumnIndex onto the column at @p targetColumnIndex in the matrix. Is available
|
|
986
|
+
* for every matrix type, but should be used with care with @ref mp_matrices "non-basic matrices", as they will be
|
|
987
|
+
* no verification to ensure that the addition makes sense for the meaning of the underlying object. For example,
|
|
988
|
+
* a right-to-left addition could corrupt the computation of the barcode or the representative cycles if done blindly.
|
|
989
|
+
*
|
|
990
|
+
* For @ref basematrix "basic matrices" with column compression, the representatives are summed together, which means
|
|
991
|
+
* that all column compressed together with the target column are affected by the change, not only the target.
|
|
992
|
+
*
|
|
993
|
+
* @tparam Integer_index Any signed or unsigned integer type.
|
|
994
|
+
* @param sourceColumnIndex @ref MatIdx index of the column to add.
|
|
995
|
+
* @param targetColumnIndex @ref MatIdx index of the target column.
|
|
996
|
+
*/
|
|
997
|
+
template <typename Integer_index>
|
|
998
|
+
std::enable_if_t<std::is_integral_v<Integer_index> > add_to(Integer_index sourceColumnIndex,
|
|
999
|
+
Integer_index targetColumnIndex);
|
|
1000
|
+
/**
|
|
1001
|
+
* @brief Adds the given range of @ref Entry onto the column at @p targetColumnIndex in the matrix. Only available
|
|
1002
|
+
* for @ref basematrix "basic matrices".
|
|
1003
|
+
*
|
|
1004
|
+
* For @ref basematrix "basic matrices" with column compression, the range is summed onto the representative, which
|
|
1005
|
+
* means that all column compressed together with the target column are affected by the change, not only the target.
|
|
1006
|
+
*
|
|
1007
|
+
* @tparam Entry_range Range of @ref Entry. Needs a begin() and end() method. A column index does not need to be
|
|
1008
|
+
* stored in the entries, even if @ref PersistenceMatrixOptions::has_row_access is true.
|
|
1009
|
+
* @param sourceColumn Source @ref Entry range.
|
|
1010
|
+
* @param targetColumnIndex @ref MatIdx index of the target column.
|
|
1011
|
+
*/
|
|
1012
|
+
template <class Entry_range>
|
|
1013
|
+
std::enable_if_t<!std::is_integral_v<Entry_range> > add_to(const Entry_range& sourceColumn, Index targetColumnIndex);
|
|
1014
|
+
|
|
1015
|
+
/**
|
|
1016
|
+
* @brief Multiplies the target column with the coefficient and then adds the source column to it.
|
|
1017
|
+
* That is: `targetColumn = (targetColumn * coefficient) + sourceColumn`.
|
|
1018
|
+
* Is available for every matrix type, but should be used with care with @ref mp_matrices "non-basic matrices",
|
|
1019
|
+
* as they will be no verification to ensure that the addition makes sense for the meaning of the underlying object.
|
|
1020
|
+
* For example, a right-to-left addition could corrupt the computation of the barcode or the representative cycles
|
|
1021
|
+
* if done blindly.
|
|
1022
|
+
*
|
|
1023
|
+
* For @ref basematrix "basic matrices" with column compression, the representatives are summed together, which means
|
|
1024
|
+
* that all column compressed together with the target column are affected by the change, not only the target.
|
|
1025
|
+
*
|
|
1026
|
+
* @tparam Integer_index Any signed or unsigned integer type.
|
|
1027
|
+
* @param sourceColumnIndex @ref MatIdx index of the column to add.
|
|
1028
|
+
* @param coefficient Value to multiply.
|
|
1029
|
+
* @param targetColumnIndex @ref MatIdx index of the target column.
|
|
1030
|
+
*/
|
|
1031
|
+
template <typename Integer_index>
|
|
1032
|
+
std::enable_if_t<std::is_integral_v<Integer_index> > multiply_target_and_add_to(Integer_index sourceColumnIndex,
|
|
1033
|
+
int coefficient,
|
|
1034
|
+
Integer_index targetColumnIndex);
|
|
1035
|
+
/**
|
|
1036
|
+
* @brief Multiplies the target column with the coefficient and then adds the given range of @ref Entry to it.
|
|
1037
|
+
* That is: `targetColumn = (targetColumn * coefficient) + sourceColumn`. Only available for
|
|
1038
|
+
* @ref basematrix "basic matrices".
|
|
1039
|
+
*
|
|
1040
|
+
* For @ref basematrix "basic matrices" with column compression, the range is summed onto the representative, which
|
|
1041
|
+
* means that all column compressed together with the target column are affected by the change, not only the target.
|
|
1042
|
+
*
|
|
1043
|
+
* @tparam Entry_range Range of @ref Entry. Needs a begin() and end() method. A column index does not need to be
|
|
1044
|
+
* stored in the entries, even if @ref PersistenceMatrixOptions::has_row_access is true.
|
|
1045
|
+
* @param sourceColumn Source @ref Entry range.
|
|
1046
|
+
* @param coefficient Value to multiply.
|
|
1047
|
+
* @param targetColumnIndex @ref MatIdx index of the target column.
|
|
1048
|
+
*/
|
|
1049
|
+
template <class Entry_range>
|
|
1050
|
+
std::enable_if_t<!std::is_integral_v<Entry_range> > multiply_target_and_add_to(const Entry_range& sourceColumn,
|
|
1051
|
+
int coefficient,
|
|
1052
|
+
Index targetColumnIndex);
|
|
1053
|
+
|
|
1054
|
+
/**
|
|
1055
|
+
* @brief Multiplies the source column with the coefficient before adding it to the target column.
|
|
1056
|
+
* That is: `targetColumn += (coefficient * sourceColumn)`. The source column will **not** be modified.
|
|
1057
|
+
* Is available for every matrix type, but should be used with care with @ref mp_matrices "non-basic matrices", as
|
|
1058
|
+
* they will be no verification to ensure that the addition makes sense for the meaning of the underlying object.
|
|
1059
|
+
* For example, a right-to-left addition could corrupt the computation of the barcode or the representative cycles
|
|
1060
|
+
* if done blindly.
|
|
1061
|
+
*
|
|
1062
|
+
* For @ref basematrix "basic matrices" with column compression, the representatives are summed together, which means
|
|
1063
|
+
* that all column compressed together with the target column are affected by the change, not only the target.
|
|
1064
|
+
*
|
|
1065
|
+
* @tparam Integer_index Any signed or unsigned integer type.
|
|
1066
|
+
* @param coefficient Value to multiply.
|
|
1067
|
+
* @param sourceColumnIndex @ref MatIdx index of the column to add.
|
|
1068
|
+
* @param targetColumnIndex @ref MatIdx index of the target column.
|
|
1069
|
+
*/
|
|
1070
|
+
template <typename Integer_index>
|
|
1071
|
+
std::enable_if_t<std::is_integral_v<Integer_index> > multiply_source_and_add_to(int coefficient,
|
|
1072
|
+
Integer_index sourceColumnIndex,
|
|
1073
|
+
Integer_index targetColumnIndex);
|
|
1074
|
+
/**
|
|
1075
|
+
* @brief Multiplies the source column with the coefficient before adding it to the target column.
|
|
1076
|
+
* That is: `targetColumn += (coefficient * sourceColumn)`. The source column will **not** be modified.
|
|
1077
|
+
* Only available for @ref basematrix "basic matrices".
|
|
1078
|
+
*
|
|
1079
|
+
* For @ref basematrix "basic matrices" with column compression, the range is summed onto the representative, which
|
|
1080
|
+
* means that all column compressed together with the target column are affected by the change, not only the target.
|
|
1081
|
+
*
|
|
1082
|
+
* @tparam Entry_range Range of @ref Entry. Needs a begin() and end() method. A column index does not need to be
|
|
1083
|
+
* stored in the entries, even if @ref PersistenceMatrixOptions::has_row_access is true.
|
|
1084
|
+
* @param coefficient Value to multiply.
|
|
1085
|
+
* @param sourceColumn Source @ref Entry range.
|
|
1086
|
+
* @param targetColumnIndex @ref MatIdx index of the target column.
|
|
1087
|
+
*/
|
|
1088
|
+
template <class Entry_range>
|
|
1089
|
+
std::enable_if_t<!std::is_integral_v<Entry_range> > multiply_source_and_add_to(int coefficient,
|
|
1090
|
+
const Entry_range& sourceColumn,
|
|
1091
|
+
Index targetColumnIndex);
|
|
1092
|
+
|
|
1093
|
+
/**
|
|
1094
|
+
* @brief Zeroes the entry at the given coordinates. Not available for @ref chainmatrix "chain matrices" and for
|
|
1095
|
+
* @ref basematrix "base matrices" with column compression. In general, should be used with care with
|
|
1096
|
+
* @ref mp_matrices "non-basic matrices" to not destroy the validity of the persistence related properties of the
|
|
1097
|
+
* matrix.
|
|
1098
|
+
*
|
|
1099
|
+
* For @ref boundarymatrix "RU matrices", equivalent to
|
|
1100
|
+
* @ref zero_entry(Index columnIndex, ID_index rowIndex, bool inR) "zero_entry(columnIndex, rowIndex, true)".
|
|
1101
|
+
*
|
|
1102
|
+
* @param columnIndex @ref MatIdx index of the column of the entry.
|
|
1103
|
+
* @param rowIndex @ref rowindex "Row index" of the row of the entry.
|
|
1104
|
+
*/
|
|
1105
|
+
void zero_entry(Index columnIndex, ID_index rowIndex);
|
|
1106
|
+
/**
|
|
1107
|
+
* @brief Only available for @ref boundarymatrix "RU matrices". Zeroes the entry at the given coordinates in \f$ R \f$
|
|
1108
|
+
* if @p inR is true or in \f$ U \f$ if @p inR is false. Should be used with care to not destroy the validity of the
|
|
1109
|
+
* persistence related properties of the matrix.
|
|
1110
|
+
*
|
|
1111
|
+
* @param columnIndex @ref MatIdx index of the column of the entry.
|
|
1112
|
+
* @param rowIndex @ref rowindex "Row index" of the row of the entry.
|
|
1113
|
+
* @param inR Boolean indicating in which matrix to zero: if true in \f$ R \f$ and if false in \f$ U \f$.
|
|
1114
|
+
*/
|
|
1115
|
+
void zero_entry(Index columnIndex, ID_index rowIndex, bool inR);
|
|
1116
|
+
/**
|
|
1117
|
+
* @brief Zeroes the column at the given index. Not available for @ref chainmatrix "chain matrices" and for
|
|
1118
|
+
* @ref basematrix "base matrices" with column compression. In general, should be used with care with
|
|
1119
|
+
* @ref mp_matrices "non-basic matrices" to not destroy the validity of the persistence related properties of the
|
|
1120
|
+
* matrix.
|
|
1121
|
+
*
|
|
1122
|
+
* For @ref boundarymatrix "RU matrices", equivalent to
|
|
1123
|
+
* @ref zero_column(Index columnIndex, bool inR) "zero_column(columnIndex, true)".
|
|
1124
|
+
*
|
|
1125
|
+
* @param columnIndex @ref MatIdx index of the column to zero.
|
|
1126
|
+
*/
|
|
1127
|
+
void zero_column(Index columnIndex);
|
|
1128
|
+
/**
|
|
1129
|
+
* @brief Only available for @ref boundarymatrix "RU matrices". Zeroes the column at the given index in \f$ R \f$ if
|
|
1130
|
+
* @p inR is true or in \f$ U \f$ if @p inR is false. Should be used with care to not destroy the validity of the
|
|
1131
|
+
* persistence related properties of the matrix.
|
|
1132
|
+
*
|
|
1133
|
+
* @param columnIndex @ref MatIdx index of the column to zero.
|
|
1134
|
+
* @param inR Boolean indicating in which matrix to zero: if true in \f$ R \f$ and if false in \f$ U \f$.
|
|
1135
|
+
*/
|
|
1136
|
+
void zero_column(Index columnIndex, bool inR);
|
|
1137
|
+
/**
|
|
1138
|
+
* @brief Indicates if the entry at given coordinates has value zero.
|
|
1139
|
+
*
|
|
1140
|
+
* For @ref boundarymatrix "RU matrices", equivalent to
|
|
1141
|
+
* @ref is_zero_entry(Index columnIndex, ID_index rowIndex, bool inR) const
|
|
1142
|
+
* "is_zero_entry(columnIndex, rowIndex, true)".
|
|
1143
|
+
*
|
|
1144
|
+
* @param columnIndex @ref MatIdx index of the column of the entry.
|
|
1145
|
+
* @param rowIndex @ref rowindex "Row index" of the row of the entry.
|
|
1146
|
+
* @return true If the entry has value zero.
|
|
1147
|
+
* @return false Otherwise.
|
|
1148
|
+
*/
|
|
1149
|
+
bool is_zero_entry(Index columnIndex, ID_index rowIndex);
|
|
1150
|
+
/**
|
|
1151
|
+
* @brief Only available for @ref boundarymatrix "RU matrices". Indicates if the entry at given coordinates has value
|
|
1152
|
+
* zero in \f$ R \f$ if @p inR is true or in \f$ U \f$ if @p inR is false.
|
|
1153
|
+
*
|
|
1154
|
+
* @param columnIndex @ref MatIdx index of the column of the entry.
|
|
1155
|
+
* @param rowIndex @ref rowindex "Row index" of the row of the entry.
|
|
1156
|
+
* @param inR Boolean indicating in which matrix to look: if true in \f$ R \f$ and if false in \f$ U \f$.
|
|
1157
|
+
* @return true If the entry has value zero.
|
|
1158
|
+
* @return false Otherwise.
|
|
1159
|
+
*/
|
|
1160
|
+
bool is_zero_entry(Index columnIndex, ID_index rowIndex, bool inR) const;
|
|
1161
|
+
/**
|
|
1162
|
+
* @brief Indicates if the column at given index has value zero.
|
|
1163
|
+
*
|
|
1164
|
+
* For @ref boundarymatrix "RU matrices", equivalent to
|
|
1165
|
+
* @ref is_zero_column(Index columnIndex, bool inR) "is_zero_column(columnIndex, true)".
|
|
1166
|
+
*
|
|
1167
|
+
* Note that for @ref chainmatrix "chain matrices", this method should always return false, as a valid
|
|
1168
|
+
* @ref chainmatrix "chain matrix" never has empty columns.
|
|
1169
|
+
*
|
|
1170
|
+
* @param columnIndex @ref MatIdx index of the column.
|
|
1171
|
+
* @return true If the column has value zero.
|
|
1172
|
+
* @return false Otherwise.
|
|
1173
|
+
*/
|
|
1174
|
+
bool is_zero_column(Index columnIndex);
|
|
1175
|
+
/**
|
|
1176
|
+
* @brief Only available for @ref boundarymatrix "RU matrices". Indicates if the column at given index has value zero
|
|
1177
|
+
* in \f$ R \f$ if @p inR is true or in \f$ U \f$ if @p inR is false.
|
|
1178
|
+
*
|
|
1179
|
+
* Note that if @p inR is false, this method should usually return false.
|
|
1180
|
+
*
|
|
1181
|
+
* @param columnIndex @ref MatIdx index of the column.
|
|
1182
|
+
* @param inR Boolean indicating in which matrix to look: if true in \f$ R \f$ and if false in \f$ U \f$.
|
|
1183
|
+
* @return true If the column has value zero.
|
|
1184
|
+
* @return false Otherwise.
|
|
1185
|
+
*/
|
|
1186
|
+
bool is_zero_column(Index columnIndex, bool inR);
|
|
1187
|
+
|
|
1188
|
+
/**
|
|
1189
|
+
* @brief Returns the @ref MatIdx index of the column which has the given @ref rowindex "row index" as pivot. Only
|
|
1190
|
+
* available for @ref boundarymatrix "RU" and @ref chainmatrix "chain matrices". Assumes that the pivot exists. For
|
|
1191
|
+
* @ref boundarymatrix "RU matrices", the column is returned from \f$ R \f$.
|
|
1192
|
+
*
|
|
1193
|
+
* Recall that the @ref rowindex "row indices" for @ref chainmatrix "chain matrices" correspond to the @ref IDIdx
|
|
1194
|
+
* indices and that the @ref rowindex "row indices" for a @ref boundarymatrix "RU matrix" correspond to the updated
|
|
1195
|
+
* @ref IDIdx indices which got potentially swapped by a vine swap.
|
|
1196
|
+
*
|
|
1197
|
+
* @param cellIndex @ref rowindex "Row index" of the pivot.
|
|
1198
|
+
* @return @ref MatIdx index of the column with the given pivot.
|
|
1199
|
+
*/
|
|
1200
|
+
Index get_column_with_pivot(ID_index cellIndex) const;
|
|
1201
|
+
/**
|
|
1202
|
+
* @brief Returns the @ref rowindex "row index" of the pivot of the given column. Only available for
|
|
1203
|
+
* @ref mp_matrices "non-basic matrices".
|
|
1204
|
+
*
|
|
1205
|
+
* @param columnIndex @ref MatIdx index of the column
|
|
1206
|
+
* @return The @ref rowindex "row index" of the pivot.
|
|
1207
|
+
*/
|
|
1208
|
+
ID_index get_pivot(Index columnIndex);
|
|
1209
|
+
|
|
1210
|
+
/**
|
|
1211
|
+
* @brief Assign operator.
|
|
1212
|
+
*
|
|
1213
|
+
* @param other %Matrix to copy
|
|
1214
|
+
* @return Reference to this object.
|
|
1215
|
+
*/
|
|
1216
|
+
Matrix& operator=(Matrix other);
|
|
1217
|
+
/**
|
|
1218
|
+
* @brief Swap operator for two matrices.
|
|
1219
|
+
*
|
|
1220
|
+
* @param matrix1 First matrix to swap.
|
|
1221
|
+
* @param matrix2 Second matrix to swap.
|
|
1222
|
+
*/
|
|
1223
|
+
friend void swap(Matrix& matrix1, Matrix& matrix2) {
|
|
1224
|
+
swap(matrix1.matrix_, matrix2.matrix_);
|
|
1225
|
+
std::swap(matrix1.colSettings_, matrix2.colSettings_);
|
|
1226
|
+
}
|
|
1227
|
+
|
|
1228
|
+
void print(Index startCol = 0, Index endCol = -1, Index startRow = 0, Index endRow = -1); // for debug
|
|
1229
|
+
|
|
1230
|
+
//TODO: change the behaviour for boundary matrices.
|
|
1231
|
+
/**
|
|
1232
|
+
* @brief Returns the current barcode of the matrix. Available only if
|
|
1233
|
+
* @ref PersistenceMatrixOptions::has_column_pairings is true.
|
|
1234
|
+
*
|
|
1235
|
+
* Recall that we assume that the boundaries were inserted in the order of filtration for the barcode to be valid.
|
|
1236
|
+
*
|
|
1237
|
+
* @warning For simple @ref boundarymatrix "boundary matrices" (only storing \f$ R \f$), we assume that
|
|
1238
|
+
* @ref get_current_barcode is only called once the matrix is completed and won't be modified again.
|
|
1239
|
+
*
|
|
1240
|
+
* @return A reference to the barcode. The barcode is a vector of @ref Matrix::Bar. A bar stores three informations:
|
|
1241
|
+
* the @ref PosIdx birth index, the @ref PosIdx death index and the dimension of the bar.
|
|
1242
|
+
*/
|
|
1243
|
+
const Barcode& get_current_barcode();
|
|
1244
|
+
/**
|
|
1245
|
+
* @brief Returns the current barcode of the matrix. Available only if
|
|
1246
|
+
* @ref PersistenceMatrixOptions::has_column_pairings is true.
|
|
1247
|
+
*
|
|
1248
|
+
* Recall that we assume that the boundaries were inserted in the order of filtration for the barcode to be valid.
|
|
1249
|
+
*
|
|
1250
|
+
* @warning For simple @ref boundarymatrix "boundary matrices" (only storing \f$ R \f$), we assume that
|
|
1251
|
+
* @ref get_current_barcode is only called once the matrix is completed and won't be modified again.
|
|
1252
|
+
*
|
|
1253
|
+
* @return A const reference to the barcode. The barcode is a vector of @ref Matrix::Bar. A bar stores three
|
|
1254
|
+
* informations: the @ref PosIdx birth index, the @ref PosIdx death index and the dimension of the bar.
|
|
1255
|
+
*/
|
|
1256
|
+
const Barcode& get_current_barcode() const;
|
|
1257
|
+
|
|
1258
|
+
/**
|
|
1259
|
+
* @brief Only available for @ref basematrix "base matrices" without column compression and simple
|
|
1260
|
+
* @ref boundarymatrix "boundary matrices" (only storing \f$ R \f$) and if
|
|
1261
|
+
* @ref PersistenceMatrixOptions::has_column_and_row_swaps is true. Swaps the two given columns. Note for
|
|
1262
|
+
* @ref boundarymatrix "boundary matrices", that it really just swaps two columns and does not update anything else,
|
|
1263
|
+
* nor performs additions to maintain some properties on the matrix.
|
|
1264
|
+
*
|
|
1265
|
+
* @param columnIndex1 First column @ref MatIdx index to swap.
|
|
1266
|
+
* @param columnIndex2 Second column @ref MatIdx index to swap.
|
|
1267
|
+
*/
|
|
1268
|
+
void swap_columns(Index columnIndex1, Index columnIndex2);
|
|
1269
|
+
/**
|
|
1270
|
+
* @brief Only available for @ref basematrix "base matrices" without column compression and simple
|
|
1271
|
+
* @ref boundarymatrix "boundary matrices" (only storing \f$ R \f$) and if
|
|
1272
|
+
* @ref PersistenceMatrixOptions::has_column_and_row_swaps is true. Swaps the two given rows. Note for
|
|
1273
|
+
* @ref boundarymatrix "boundary matrices", that it really just swaps two rows and does not update anything else,
|
|
1274
|
+
* nor performs additions to maintain some properties on the matrix.
|
|
1275
|
+
*
|
|
1276
|
+
* @param rowIndex1 First @ref rowindex "row index" to swap.
|
|
1277
|
+
* @param rowIndex2 Second @ref rowindex "row index" to swap.
|
|
1278
|
+
*/
|
|
1279
|
+
void swap_rows(Index rowIndex1, Index rowIndex2);
|
|
1280
|
+
//TODO: find better name. And benchmark also to verify if it is really worth it to have this extra version in addition
|
|
1281
|
+
//to vine_swap.
|
|
1282
|
+
/**
|
|
1283
|
+
* @brief Only available if @ref PersistenceMatrixOptions::has_vine_update is true and if it is either a boundary
|
|
1284
|
+
* matrix or @ref PersistenceMatrixOptions::column_indexation_type is set to @ref Column_indexation_types::POSITION.
|
|
1285
|
+
* Does the same than @ref vine_swap, but assumes that the swap is non trivial and therefore skips a part of the case
|
|
1286
|
+
* study.
|
|
1287
|
+
*
|
|
1288
|
+
* @param index @ref PosIdx index of the first cell to swap. The second one has to be at `index + 1`. Recall that for
|
|
1289
|
+
* @ref boundarymatrix "boundary matrices", @ref PosIdx == @ref MatIdx.
|
|
1290
|
+
* @return true If the barcode changed from the swap.
|
|
1291
|
+
* @return false Otherwise.
|
|
1292
|
+
*/
|
|
1293
|
+
bool vine_swap_with_z_eq_1_case(Pos_index index);
|
|
1294
|
+
/**
|
|
1295
|
+
* @brief Only available if @ref PersistenceMatrixOptions::has_vine_update is true and if it is either a
|
|
1296
|
+
* @ref chainmatrix "chain matrix" or @ref PersistenceMatrixOptions::column_indexation_type is set to
|
|
1297
|
+
* @ref Column_indexation_types::IDENTIFIER. Does the same than @ref vine_swap, but assumes that the swap is
|
|
1298
|
+
* non-trivial and therefore skips a part of the case study.
|
|
1299
|
+
*
|
|
1300
|
+
* @param columnIndex1 @ref MatIdx index of the first cell.
|
|
1301
|
+
* @param columnIndex2 @ref MatIdx index of the second cell. It is assumed that the @ref PosIdx of both only differs
|
|
1302
|
+
* by one.
|
|
1303
|
+
* @return Let \f$ pos1 \f$ be the @ref PosIdx index of @p columnIndex1 and \f$ pos2 \f$ be the @ref PosIdx index of
|
|
1304
|
+
* @p columnIndex2. The method returns the @ref MatIdx of the column which has now, after the swap, the @ref PosIdx
|
|
1305
|
+
* \f$ max(pos1, pos2) \f$.
|
|
1306
|
+
*/
|
|
1307
|
+
Index vine_swap_with_z_eq_1_case(Index columnIndex1, Index columnIndex2);
|
|
1308
|
+
/**
|
|
1309
|
+
* @brief Only available if @ref PersistenceMatrixOptions::has_vine_update is true and if it is either a
|
|
1310
|
+
* @ref boundarymatrix "boundary matrix" or @ref PersistenceMatrixOptions::column_indexation_type is set to
|
|
1311
|
+
* @ref Column_indexation_types::POSITION. Does a vine swap between two cells which are consecutive in the
|
|
1312
|
+
* filtration. Roughly, if \f$ F \f$ is the current filtration represented by the matrix, the method modifies the
|
|
1313
|
+
* matrix such that the new state corresponds to a valid state for the filtration \f$ F' \f$ equal to \f$ F \f$ but
|
|
1314
|
+
* with the two cells at position `index` and `index + 1` swapped. Of course, the two cells should not have a
|
|
1315
|
+
* face/coface relation which each other ; \f$ F' \f$ has to be a valid filtration.
|
|
1316
|
+
* See @cite vineyards for more information about vine and vineyards.
|
|
1317
|
+
*
|
|
1318
|
+
* @param index @ref PosIdx index of the first cell to swap. The second one has to be at `index + 1`. Recall that for
|
|
1319
|
+
* @ref boundarymatrix "boundary matrices", @ref PosIdx == @ref MatIdx.
|
|
1320
|
+
* @return true If the barcode changed from the swap.
|
|
1321
|
+
* @return false Otherwise.
|
|
1322
|
+
*/
|
|
1323
|
+
bool vine_swap(Pos_index index);
|
|
1324
|
+
/**
|
|
1325
|
+
* @brief Only available if @ref PersistenceMatrixOptions::has_vine_update is true and if it is either a
|
|
1326
|
+
* @ref chainmatrix "chain matrix" or @ref PersistenceMatrixOptions::column_indexation_type is set to
|
|
1327
|
+
* @ref Column_indexation_types::IDENTIFIER. Does a vine swap between two cells which are consecutive in the
|
|
1328
|
+
* filtration. Roughly, if \f$ F \f$ is the current filtration represented by the matrix, the method modifies the
|
|
1329
|
+
* matrix such that the new state corresponds to a valid state for the filtration \f$ F' \f$ equal to \f$ F \f$ but
|
|
1330
|
+
* with the two given cells at swapped positions. Of course, the two cells should not have a face/coface relation
|
|
1331
|
+
* which each other ; \f$ F' \f$ has to be a valid filtration.
|
|
1332
|
+
* See @cite vineyards for more information about vine and vineyards.
|
|
1333
|
+
*
|
|
1334
|
+
* @param columnIndex1 @ref MatIdx index of the first cell.
|
|
1335
|
+
* @param columnIndex2 @ref MatIdx index of the second cell. It is assumed that the @ref PosIdx of both only differs
|
|
1336
|
+
* by one.
|
|
1337
|
+
* @return Let \f$ pos1 \f$ be the @ref PosIdx index of @p columnIndex1 and \f$ pos2 \f$ be the @ref PosIdx index of
|
|
1338
|
+
* @p columnIndex2. The method returns the @ref MatIdx of the column which has now, after the swap, the @ref PosIdx
|
|
1339
|
+
* \f$ max(pos1, pos2) \f$.
|
|
1340
|
+
*/
|
|
1341
|
+
Index vine_swap(Index columnIndex1, Index columnIndex2);
|
|
1342
|
+
|
|
1343
|
+
//TODO: Rethink the interface for representative cycles
|
|
1344
|
+
/**
|
|
1345
|
+
* @brief Only available if @ref PersistenceMatrixOptions::can_retrieve_representative_cycles is true. Pre-computes
|
|
1346
|
+
* the representative cycles of the current state of the filtration represented by the matrix. It does not need to be
|
|
1347
|
+
* called before @ref get_representative_cycles is called for the first time, but needs to be called before calling
|
|
1348
|
+
* @ref get_representative_cycles again if the matrix was modified in between. Otherwise the old cycles will be
|
|
1349
|
+
* returned.
|
|
1350
|
+
*/
|
|
1351
|
+
void update_representative_cycles();
|
|
1352
|
+
// /**
|
|
1353
|
+
// * @brief Only available if @ref PersistenceMatrixOptions::can_retrieve_representative_cycles is true.
|
|
1354
|
+
// * Returns all representative cycles of the current filtration.
|
|
1355
|
+
// *
|
|
1356
|
+
// * @return A const reference to the vector of representative cycles.
|
|
1357
|
+
// */
|
|
1358
|
+
// const std::vector<Cycle>& get_representative_cycles();
|
|
1359
|
+
// /**
|
|
1360
|
+
// * @brief Only available if @ref PersistenceMatrixOptions::can_retrieve_representative_cycles is true.
|
|
1361
|
+
// * Returns the cycle representing the given bar.
|
|
1362
|
+
// *
|
|
1363
|
+
// * @param bar A bar from the current barcode.
|
|
1364
|
+
// * @return A const reference to the cycle representing @p bar.
|
|
1365
|
+
// */
|
|
1366
|
+
// const Cycle& get_representative_cycle(const Bar& bar);
|
|
1367
|
+
std::vector<std::vector<std::vector<typename Matrix<PersistenceMatrixOptions>::ID_index> > >
|
|
1368
|
+
get_representative_cycles_as_borders(bool detailed = false);
|
|
1369
|
+
|
|
1370
|
+
private:
|
|
1371
|
+
using Underlying_matrix =
|
|
1372
|
+
typename std::conditional<
|
|
1373
|
+
isNonBasic,
|
|
1374
|
+
typename std::conditional<
|
|
1375
|
+
PersistenceMatrixOptions::is_of_boundary_type,
|
|
1376
|
+
typename std::conditional<
|
|
1377
|
+
PersistenceMatrixOptions::has_vine_update ||
|
|
1378
|
+
PersistenceMatrixOptions::can_retrieve_representative_cycles,
|
|
1379
|
+
typename std::conditional<
|
|
1380
|
+
PersistenceMatrixOptions::column_indexation_type == Column_indexation_types::CONTAINER ||
|
|
1381
|
+
PersistenceMatrixOptions::column_indexation_type == Column_indexation_types::POSITION,
|
|
1382
|
+
Master_RU_matrix, Id_to_index_overlay<Master_RU_matrix, Matrix<PersistenceMatrixOptions> >
|
|
1383
|
+
>::type,
|
|
1384
|
+
typename std::conditional<
|
|
1385
|
+
PersistenceMatrixOptions::column_indexation_type == Column_indexation_types::CONTAINER ||
|
|
1386
|
+
PersistenceMatrixOptions::column_indexation_type == Column_indexation_types::POSITION,
|
|
1387
|
+
Master_boundary_matrix,
|
|
1388
|
+
Id_to_index_overlay<Master_boundary_matrix, Matrix<PersistenceMatrixOptions> >
|
|
1389
|
+
>::type
|
|
1390
|
+
>::type,
|
|
1391
|
+
typename std::conditional<
|
|
1392
|
+
PersistenceMatrixOptions::column_indexation_type == Column_indexation_types::CONTAINER,
|
|
1393
|
+
Master_chain_matrix,
|
|
1394
|
+
typename std::conditional<
|
|
1395
|
+
PersistenceMatrixOptions::column_indexation_type == Column_indexation_types::POSITION,
|
|
1396
|
+
Position_to_index_overlay<Master_chain_matrix, Matrix<PersistenceMatrixOptions> >,
|
|
1397
|
+
Id_to_index_overlay<Master_chain_matrix, Matrix<PersistenceMatrixOptions> >
|
|
1398
|
+
>::type
|
|
1399
|
+
>::type
|
|
1400
|
+
>::type,
|
|
1401
|
+
Master_base_matrix
|
|
1402
|
+
>::type;
|
|
1403
|
+
|
|
1404
|
+
// Field_operators* operators_;
|
|
1405
|
+
// Entry_constructor* entryPool_;
|
|
1406
|
+
Column_settings* colSettings_; //pointer because the of swap operator on matrix_ which also stores the pointer
|
|
1407
|
+
Underlying_matrix matrix_;
|
|
1408
|
+
|
|
1409
|
+
static constexpr void _assert_options();
|
|
1410
|
+
};
|
|
1411
|
+
|
|
1412
|
+
template <class PersistenceMatrixOptions>
|
|
1413
|
+
inline Matrix<PersistenceMatrixOptions>::Matrix()
|
|
1414
|
+
: colSettings_(new Column_settings()), matrix_(colSettings_)
|
|
1415
|
+
{
|
|
1416
|
+
static_assert(
|
|
1417
|
+
PersistenceMatrixOptions::is_of_boundary_type || !PersistenceMatrixOptions::has_vine_update ||
|
|
1418
|
+
PersistenceMatrixOptions::has_column_pairings,
|
|
1419
|
+
"When no barcode is recorded with vine swaps, comparaison functions for the columns have to be provided.");
|
|
1420
|
+
_assert_options();
|
|
1421
|
+
}
|
|
1422
|
+
|
|
1423
|
+
template <class PersistenceMatrixOptions>
|
|
1424
|
+
template <class Container>
|
|
1425
|
+
inline Matrix<PersistenceMatrixOptions>::Matrix(const std::vector<Container>& columns,
|
|
1426
|
+
Characteristic characteristic)
|
|
1427
|
+
: colSettings_(new Column_settings(characteristic)),
|
|
1428
|
+
matrix_(columns, colSettings_)
|
|
1429
|
+
{
|
|
1430
|
+
static_assert(PersistenceMatrixOptions::is_of_boundary_type || !PersistenceMatrixOptions::has_vine_update ||
|
|
1431
|
+
PersistenceMatrixOptions::has_column_pairings,
|
|
1432
|
+
"When no barcode is recorded with vine swaps for chain matrices, comparaison functions for the columns "
|
|
1433
|
+
"have to be provided.");
|
|
1434
|
+
_assert_options();
|
|
1435
|
+
}
|
|
1436
|
+
|
|
1437
|
+
template <class PersistenceMatrixOptions>
|
|
1438
|
+
inline Matrix<PersistenceMatrixOptions>::Matrix(unsigned int numberOfColumns, Characteristic characteristic)
|
|
1439
|
+
: colSettings_(new Column_settings(characteristic)),
|
|
1440
|
+
matrix_(numberOfColumns, colSettings_)
|
|
1441
|
+
{
|
|
1442
|
+
static_assert(PersistenceMatrixOptions::is_of_boundary_type || !PersistenceMatrixOptions::has_vine_update ||
|
|
1443
|
+
PersistenceMatrixOptions::has_column_pairings,
|
|
1444
|
+
"When no barcode is recorded with vine swaps for chain matrices, comparaison functions for the columns "
|
|
1445
|
+
"have to be provided.");
|
|
1446
|
+
_assert_options();
|
|
1447
|
+
}
|
|
1448
|
+
|
|
1449
|
+
template <class PersistenceMatrixOptions>
|
|
1450
|
+
inline Matrix<PersistenceMatrixOptions>::Matrix(const std::function<bool(Pos_index,Pos_index)>& birthComparator,
|
|
1451
|
+
const std::function<bool(Pos_index,Pos_index)>& deathComparator)
|
|
1452
|
+
: colSettings_(new Column_settings()),
|
|
1453
|
+
matrix_(colSettings_, birthComparator, deathComparator)
|
|
1454
|
+
{
|
|
1455
|
+
static_assert(
|
|
1456
|
+
!PersistenceMatrixOptions::is_of_boundary_type && PersistenceMatrixOptions::has_vine_update &&
|
|
1457
|
+
!PersistenceMatrixOptions::has_column_pairings,
|
|
1458
|
+
"Constructor only available for chain matrices when vine swaps are enabled, but the barcode is not recorded.");
|
|
1459
|
+
_assert_options();
|
|
1460
|
+
}
|
|
1461
|
+
|
|
1462
|
+
template <class PersistenceMatrixOptions>
|
|
1463
|
+
template <class Boundary_range>
|
|
1464
|
+
inline Matrix<PersistenceMatrixOptions>::Matrix(const std::vector<Boundary_range>& orderedBoundaries,
|
|
1465
|
+
const std::function<bool(Pos_index, Pos_index)>& birthComparator,
|
|
1466
|
+
const std::function<bool(Pos_index, Pos_index)>& deathComparator,
|
|
1467
|
+
Characteristic characteristic)
|
|
1468
|
+
: colSettings_(new Column_settings(characteristic)),
|
|
1469
|
+
matrix_(orderedBoundaries, colSettings_, birthComparator, deathComparator)
|
|
1470
|
+
{
|
|
1471
|
+
static_assert(
|
|
1472
|
+
!PersistenceMatrixOptions::is_of_boundary_type && PersistenceMatrixOptions::has_vine_update &&
|
|
1473
|
+
!PersistenceMatrixOptions::has_column_pairings,
|
|
1474
|
+
"Constructor only available for chain matrices when vine swaps are enabled, but the barcode is not recorded.");
|
|
1475
|
+
_assert_options();
|
|
1476
|
+
}
|
|
1477
|
+
|
|
1478
|
+
template <class PersistenceMatrixOptions>
|
|
1479
|
+
inline Matrix<PersistenceMatrixOptions>::Matrix(unsigned int numberOfColumns,
|
|
1480
|
+
const std::function<bool(Pos_index, Pos_index)>& birthComparator,
|
|
1481
|
+
const std::function<bool(Pos_index, Pos_index)>& deathComparator,
|
|
1482
|
+
Characteristic characteristic)
|
|
1483
|
+
: colSettings_(new Column_settings(characteristic)),
|
|
1484
|
+
matrix_(numberOfColumns, colSettings_, birthComparator, deathComparator)
|
|
1485
|
+
{
|
|
1486
|
+
static_assert(
|
|
1487
|
+
!PersistenceMatrixOptions::is_of_boundary_type && PersistenceMatrixOptions::has_vine_update &&
|
|
1488
|
+
!PersistenceMatrixOptions::has_column_pairings,
|
|
1489
|
+
"Constructor only available for chain matrices when vine swaps are enabled, but the barcode is not recorded.");
|
|
1490
|
+
_assert_options();
|
|
1491
|
+
}
|
|
1492
|
+
|
|
1493
|
+
template <class PersistenceMatrixOptions>
|
|
1494
|
+
inline Matrix<PersistenceMatrixOptions>::Matrix(const Matrix& matrixToCopy)
|
|
1495
|
+
: colSettings_(new Column_settings(*matrixToCopy.colSettings_)),
|
|
1496
|
+
matrix_(matrixToCopy.matrix_, colSettings_)
|
|
1497
|
+
{
|
|
1498
|
+
_assert_options();
|
|
1499
|
+
}
|
|
1500
|
+
|
|
1501
|
+
template <class PersistenceMatrixOptions>
|
|
1502
|
+
inline Matrix<PersistenceMatrixOptions>::Matrix(Matrix&& other) noexcept
|
|
1503
|
+
: colSettings_(std::exchange(other.colSettings_, nullptr)),
|
|
1504
|
+
matrix_(std::move(other.matrix_))
|
|
1505
|
+
{
|
|
1506
|
+
_assert_options();
|
|
1507
|
+
}
|
|
1508
|
+
|
|
1509
|
+
template <class PersistenceMatrixOptions>
|
|
1510
|
+
inline Matrix<PersistenceMatrixOptions>::~Matrix()
|
|
1511
|
+
{
|
|
1512
|
+
matrix_.reset(colSettings_);
|
|
1513
|
+
delete colSettings_;
|
|
1514
|
+
}
|
|
1515
|
+
|
|
1516
|
+
template <class PersistenceMatrixOptions>
|
|
1517
|
+
inline void Matrix<PersistenceMatrixOptions>::set_characteristic(Characteristic characteristic)
|
|
1518
|
+
{
|
|
1519
|
+
if constexpr (!PersistenceMatrixOptions::is_z2) {
|
|
1520
|
+
if (colSettings_->operators.get_characteristic() != static_cast<Characteristic>(-1)) {
|
|
1521
|
+
std::cerr << "Warning: Characteristic already initialised. Changing it could lead to incoherences in the matrix "
|
|
1522
|
+
"as the modulo was already applied to values in existing columns.";
|
|
1523
|
+
}
|
|
1524
|
+
|
|
1525
|
+
colSettings_->operators.set_characteristic(characteristic);
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1528
|
+
|
|
1529
|
+
template <class PersistenceMatrixOptions>
|
|
1530
|
+
template <class Container>
|
|
1531
|
+
inline void Matrix<PersistenceMatrixOptions>::insert_column(const Container& column)
|
|
1532
|
+
{
|
|
1533
|
+
if constexpr (!PersistenceMatrixOptions::is_z2){
|
|
1534
|
+
GUDHI_CHECK(colSettings_->operators.get_characteristic() != static_cast<Characteristic>(-1),
|
|
1535
|
+
std::logic_error("Matrix::insert_column - Columns cannot be initialized if the coefficient field "
|
|
1536
|
+
"characteristic is not specified."));
|
|
1537
|
+
}
|
|
1538
|
+
|
|
1539
|
+
static_assert(
|
|
1540
|
+
!isNonBasic,
|
|
1541
|
+
"'insert_column' not available for the chosen options. The input has to be in the form of a cell boundary.");
|
|
1542
|
+
matrix_.insert_column(column);
|
|
1543
|
+
}
|
|
1544
|
+
|
|
1545
|
+
template <class PersistenceMatrixOptions>
|
|
1546
|
+
template <class Container>
|
|
1547
|
+
inline void Matrix<PersistenceMatrixOptions>::insert_column(const Container& column, Index columnIndex)
|
|
1548
|
+
{
|
|
1549
|
+
if constexpr (!PersistenceMatrixOptions::is_z2){
|
|
1550
|
+
GUDHI_CHECK(colSettings_->operators.get_characteristic() != static_cast<Characteristic>(-1),
|
|
1551
|
+
std::logic_error("Matrix::insert_column - Columns cannot be initialized if the coefficient field "
|
|
1552
|
+
"characteristic is not specified."));
|
|
1553
|
+
}
|
|
1554
|
+
|
|
1555
|
+
static_assert(!isNonBasic && !PersistenceMatrixOptions::has_column_compression,
|
|
1556
|
+
"'insert_column' with those parameters is not available for the chosen options.");
|
|
1557
|
+
static_assert(!PersistenceMatrixOptions::has_row_access,
|
|
1558
|
+
"Columns have to be inserted at the end of the matrix when row access is enabled.");
|
|
1559
|
+
matrix_.insert_column(column, columnIndex);
|
|
1560
|
+
}
|
|
1561
|
+
|
|
1562
|
+
template <class PersistenceMatrixOptions>
|
|
1563
|
+
template <class Boundary_range>
|
|
1564
|
+
inline typename Matrix<PersistenceMatrixOptions>::Insertion_return
|
|
1565
|
+
Matrix<PersistenceMatrixOptions>::insert_boundary(const Boundary_range& boundary, Dimension dim)
|
|
1566
|
+
{
|
|
1567
|
+
if constexpr (!PersistenceMatrixOptions::is_z2){
|
|
1568
|
+
GUDHI_CHECK(colSettings_->operators.get_characteristic() != static_cast<Characteristic>(-1),
|
|
1569
|
+
std::logic_error("Matrix::insert_boundary - Columns cannot be initialized if the coefficient field "
|
|
1570
|
+
"characteristic is not specified."));
|
|
1571
|
+
}
|
|
1572
|
+
|
|
1573
|
+
if constexpr (isNonBasic && !PersistenceMatrixOptions::is_of_boundary_type &&
|
|
1574
|
+
PersistenceMatrixOptions::column_indexation_type == Column_indexation_types::CONTAINER)
|
|
1575
|
+
return matrix_.insert_boundary(boundary, dim);
|
|
1576
|
+
else
|
|
1577
|
+
matrix_.insert_boundary(boundary, dim);
|
|
1578
|
+
}
|
|
1579
|
+
|
|
1580
|
+
template <class PersistenceMatrixOptions>
|
|
1581
|
+
template <class Boundary_range>
|
|
1582
|
+
inline typename Matrix<PersistenceMatrixOptions>::Insertion_return
|
|
1583
|
+
Matrix<PersistenceMatrixOptions>::insert_boundary(ID_index cellIndex,
|
|
1584
|
+
const Boundary_range& boundary,
|
|
1585
|
+
Dimension dim)
|
|
1586
|
+
{
|
|
1587
|
+
if constexpr (!PersistenceMatrixOptions::is_z2){
|
|
1588
|
+
GUDHI_CHECK(colSettings_->operators.get_characteristic() != static_cast<Characteristic>(-1),
|
|
1589
|
+
std::logic_error("Matrix::insert_boundary - Columns cannot be initialized if the coefficient field "
|
|
1590
|
+
"characteristic is not specified."));
|
|
1591
|
+
}
|
|
1592
|
+
|
|
1593
|
+
static_assert(isNonBasic, "Only enabled for non-basic matrices.");
|
|
1594
|
+
if constexpr (!PersistenceMatrixOptions::is_of_boundary_type &&
|
|
1595
|
+
PersistenceMatrixOptions::column_indexation_type == Column_indexation_types::CONTAINER)
|
|
1596
|
+
return matrix_.insert_boundary(cellIndex, boundary, dim);
|
|
1597
|
+
else
|
|
1598
|
+
matrix_.insert_boundary(cellIndex, boundary, dim);
|
|
1599
|
+
}
|
|
1600
|
+
|
|
1601
|
+
template <class PersistenceMatrixOptions>
|
|
1602
|
+
inline typename Matrix<PersistenceMatrixOptions>::Returned_column& Matrix<PersistenceMatrixOptions>::get_column(
|
|
1603
|
+
Index columnIndex)
|
|
1604
|
+
{
|
|
1605
|
+
return matrix_.get_column(columnIndex);
|
|
1606
|
+
}
|
|
1607
|
+
|
|
1608
|
+
template <class PersistenceMatrixOptions>
|
|
1609
|
+
inline const typename Matrix<PersistenceMatrixOptions>::Column& Matrix<PersistenceMatrixOptions>::get_column(
|
|
1610
|
+
Index columnIndex) const
|
|
1611
|
+
{
|
|
1612
|
+
return matrix_.get_column(columnIndex);
|
|
1613
|
+
}
|
|
1614
|
+
|
|
1615
|
+
template <class PersistenceMatrixOptions>
|
|
1616
|
+
inline const typename Matrix<PersistenceMatrixOptions>::Column& Matrix<PersistenceMatrixOptions>::get_column(
|
|
1617
|
+
Index columnIndex, bool inR)
|
|
1618
|
+
{
|
|
1619
|
+
// TODO: I don't think there is a particular reason why the indexation is forced, should be removed.
|
|
1620
|
+
static_assert(
|
|
1621
|
+
isNonBasic && PersistenceMatrixOptions::is_of_boundary_type &&
|
|
1622
|
+
(PersistenceMatrixOptions::has_vine_update || PersistenceMatrixOptions::can_retrieve_representative_cycles) &&
|
|
1623
|
+
PersistenceMatrixOptions::column_indexation_type != Column_indexation_types::IDENTIFIER,
|
|
1624
|
+
"Only enabled for position indexed RU matrices.");
|
|
1625
|
+
|
|
1626
|
+
return matrix_.get_column(columnIndex, inR);
|
|
1627
|
+
}
|
|
1628
|
+
|
|
1629
|
+
template <class PersistenceMatrixOptions>
|
|
1630
|
+
inline typename Matrix<PersistenceMatrixOptions>::Returned_row& Matrix<PersistenceMatrixOptions>::get_row(
|
|
1631
|
+
ID_index rowIndex)
|
|
1632
|
+
{
|
|
1633
|
+
static_assert(PersistenceMatrixOptions::has_row_access, "'get_row' is not available for the chosen options.");
|
|
1634
|
+
|
|
1635
|
+
return matrix_.get_row(rowIndex);
|
|
1636
|
+
}
|
|
1637
|
+
|
|
1638
|
+
template <class PersistenceMatrixOptions>
|
|
1639
|
+
inline const typename Matrix<PersistenceMatrixOptions>::Row& Matrix<PersistenceMatrixOptions>::get_row(
|
|
1640
|
+
ID_index rowIndex) const
|
|
1641
|
+
{
|
|
1642
|
+
static_assert(PersistenceMatrixOptions::has_row_access, "'get_row' is not available for the chosen options.");
|
|
1643
|
+
|
|
1644
|
+
return matrix_.get_row(rowIndex);
|
|
1645
|
+
}
|
|
1646
|
+
|
|
1647
|
+
template <class PersistenceMatrixOptions>
|
|
1648
|
+
inline const typename Matrix<PersistenceMatrixOptions>::Row& Matrix<PersistenceMatrixOptions>::get_row(
|
|
1649
|
+
ID_index rowIndex, bool inR)
|
|
1650
|
+
{
|
|
1651
|
+
static_assert(PersistenceMatrixOptions::has_row_access, "'get_row' is not available for the chosen options.");
|
|
1652
|
+
// TODO: I don't think there is a particular reason why the indexation is forced, should be removed.
|
|
1653
|
+
static_assert(
|
|
1654
|
+
isNonBasic && PersistenceMatrixOptions::is_of_boundary_type &&
|
|
1655
|
+
(PersistenceMatrixOptions::has_vine_update || PersistenceMatrixOptions::can_retrieve_representative_cycles) &&
|
|
1656
|
+
PersistenceMatrixOptions::column_indexation_type != Column_indexation_types::IDENTIFIER,
|
|
1657
|
+
"Only enabled for position indexed RU matrices.");
|
|
1658
|
+
|
|
1659
|
+
return matrix_.get_row(rowIndex, inR);
|
|
1660
|
+
}
|
|
1661
|
+
|
|
1662
|
+
template <class PersistenceMatrixOptions>
|
|
1663
|
+
inline void Matrix<PersistenceMatrixOptions>::remove_column(Index columnIndex)
|
|
1664
|
+
{
|
|
1665
|
+
static_assert(PersistenceMatrixOptions::has_map_column_container && !isNonBasic &&
|
|
1666
|
+
!PersistenceMatrixOptions::has_column_compression,
|
|
1667
|
+
"'remove_column' is not available for the chosen options.");
|
|
1668
|
+
|
|
1669
|
+
matrix_.remove_column(columnIndex);
|
|
1670
|
+
}
|
|
1671
|
+
|
|
1672
|
+
template <class PersistenceMatrixOptions>
|
|
1673
|
+
inline void Matrix<PersistenceMatrixOptions>::erase_empty_row(ID_index rowIndex)
|
|
1674
|
+
{
|
|
1675
|
+
static_assert(
|
|
1676
|
+
!isNonBasic || PersistenceMatrixOptions::is_of_boundary_type || PersistenceMatrixOptions::has_removable_rows,
|
|
1677
|
+
"'erase_empty_row' is not available for the chosen options.");
|
|
1678
|
+
|
|
1679
|
+
matrix_.erase_empty_row(rowIndex);
|
|
1680
|
+
}
|
|
1681
|
+
|
|
1682
|
+
template <class PersistenceMatrixOptions>
|
|
1683
|
+
inline void Matrix<PersistenceMatrixOptions>::remove_maximal_cell(Index columnIndex)
|
|
1684
|
+
{
|
|
1685
|
+
static_assert(PersistenceMatrixOptions::has_removable_columns,
|
|
1686
|
+
"'remove_maximal_cell(ID_index)' is not available for the chosen options.");
|
|
1687
|
+
static_assert(isNonBasic && PersistenceMatrixOptions::has_vine_update,
|
|
1688
|
+
"'remove_maximal_cell(ID_index)' is not available for the chosen options.");
|
|
1689
|
+
static_assert(PersistenceMatrixOptions::is_of_boundary_type || (PersistenceMatrixOptions::has_map_column_container &&
|
|
1690
|
+
PersistenceMatrixOptions::has_column_pairings),
|
|
1691
|
+
"'remove_maximal_cell(ID_index)' is not available for the chosen options.");
|
|
1692
|
+
|
|
1693
|
+
matrix_.remove_maximal_cell(columnIndex);
|
|
1694
|
+
}
|
|
1695
|
+
|
|
1696
|
+
template <class PersistenceMatrixOptions>
|
|
1697
|
+
inline void Matrix<PersistenceMatrixOptions>::remove_maximal_cell(ID_index cellIndex,
|
|
1698
|
+
const std::vector<ID_index>& columnsToSwap)
|
|
1699
|
+
{
|
|
1700
|
+
static_assert(PersistenceMatrixOptions::has_removable_columns,
|
|
1701
|
+
"'remove_maximal_cell(ID_index,const std::vector<Index>&)' is not available for the chosen options.");
|
|
1702
|
+
static_assert(isNonBasic && !PersistenceMatrixOptions::is_of_boundary_type,
|
|
1703
|
+
"'remove_maximal_cell(ID_index,const std::vector<Index>&)' is not available for the chosen options.");
|
|
1704
|
+
static_assert(PersistenceMatrixOptions::has_map_column_container && PersistenceMatrixOptions::has_vine_update,
|
|
1705
|
+
"'remove_maximal_cell(ID_index,const std::vector<Index>&)' is not available for the chosen options.");
|
|
1706
|
+
|
|
1707
|
+
matrix_.remove_maximal_cell(cellIndex, columnsToSwap);
|
|
1708
|
+
}
|
|
1709
|
+
|
|
1710
|
+
template <class PersistenceMatrixOptions>
|
|
1711
|
+
inline void Matrix<PersistenceMatrixOptions>::remove_last()
|
|
1712
|
+
{
|
|
1713
|
+
static_assert(PersistenceMatrixOptions::has_removable_columns || !isNonBasic,
|
|
1714
|
+
"'remove_last' is not available for the chosen options.");
|
|
1715
|
+
static_assert(!PersistenceMatrixOptions::has_column_compression || isNonBasic,
|
|
1716
|
+
"'remove_last' is not available for the chosen options.");
|
|
1717
|
+
static_assert(!isNonBasic || PersistenceMatrixOptions::is_of_boundary_type ||
|
|
1718
|
+
PersistenceMatrixOptions::has_map_column_container || !PersistenceMatrixOptions::has_vine_update,
|
|
1719
|
+
"'remove_last' is not available for the chosen options.");
|
|
1720
|
+
|
|
1721
|
+
matrix_.remove_last();
|
|
1722
|
+
}
|
|
1723
|
+
|
|
1724
|
+
template <class PersistenceMatrixOptions>
|
|
1725
|
+
inline typename Matrix<PersistenceMatrixOptions>::Dimension Matrix<PersistenceMatrixOptions>::get_max_dimension()
|
|
1726
|
+
const
|
|
1727
|
+
{
|
|
1728
|
+
static_assert(isNonBasic, "'get_max_dimension' is not available for the chosen options.");
|
|
1729
|
+
|
|
1730
|
+
return matrix_.get_max_dimension();
|
|
1731
|
+
}
|
|
1732
|
+
|
|
1733
|
+
template <class PersistenceMatrixOptions>
|
|
1734
|
+
inline typename Matrix<PersistenceMatrixOptions>::Index Matrix<PersistenceMatrixOptions>::get_number_of_columns() const
|
|
1735
|
+
{
|
|
1736
|
+
return matrix_.get_number_of_columns();
|
|
1737
|
+
}
|
|
1738
|
+
|
|
1739
|
+
template <class PersistenceMatrixOptions>
|
|
1740
|
+
inline typename Matrix<PersistenceMatrixOptions>::Dimension Matrix<PersistenceMatrixOptions>::get_column_dimension(
|
|
1741
|
+
Index columnIndex) const
|
|
1742
|
+
{
|
|
1743
|
+
static_assert(isNonBasic, "'get_column_dimension' is not available for the chosen options.");
|
|
1744
|
+
|
|
1745
|
+
return matrix_.get_column_dimension(columnIndex);
|
|
1746
|
+
}
|
|
1747
|
+
|
|
1748
|
+
template <class PersistenceMatrixOptions>
|
|
1749
|
+
template <typename Integer_index>
|
|
1750
|
+
inline std::enable_if_t<std::is_integral_v<Integer_index> > Matrix<PersistenceMatrixOptions>::add_to(
|
|
1751
|
+
Integer_index sourceColumnIndex, Integer_index targetColumnIndex)
|
|
1752
|
+
{
|
|
1753
|
+
matrix_.add_to(sourceColumnIndex, targetColumnIndex);
|
|
1754
|
+
}
|
|
1755
|
+
|
|
1756
|
+
template <class PersistenceMatrixOptions>
|
|
1757
|
+
template <class Entry_range>
|
|
1758
|
+
inline std::enable_if_t<!std::is_integral_v<Entry_range> > Matrix<PersistenceMatrixOptions>::add_to(
|
|
1759
|
+
const Entry_range& sourceColumn, Index targetColumnIndex)
|
|
1760
|
+
{
|
|
1761
|
+
static_assert(!isNonBasic,
|
|
1762
|
+
"For boundary or chain matrices, only additions with columns inside the matrix is allowed to maintain "
|
|
1763
|
+
"algebraic consistency.");
|
|
1764
|
+
|
|
1765
|
+
matrix_.add_to(sourceColumn, targetColumnIndex);
|
|
1766
|
+
}
|
|
1767
|
+
|
|
1768
|
+
template <class PersistenceMatrixOptions>
|
|
1769
|
+
template <typename Integer_index>
|
|
1770
|
+
inline std::enable_if_t<std::is_integral_v<Integer_index> > Matrix<PersistenceMatrixOptions>::multiply_target_and_add_to(
|
|
1771
|
+
Integer_index sourceColumnIndex, int coefficient, Integer_index targetColumnIndex)
|
|
1772
|
+
{
|
|
1773
|
+
if constexpr (PersistenceMatrixOptions::is_z2) {
|
|
1774
|
+
// coef will be converted to bool, because of Element
|
|
1775
|
+
matrix_.multiply_target_and_add_to(sourceColumnIndex, coefficient % 2, targetColumnIndex);
|
|
1776
|
+
} else {
|
|
1777
|
+
matrix_.multiply_target_and_add_to(sourceColumnIndex, colSettings_->operators.get_value(coefficient), targetColumnIndex);
|
|
1778
|
+
}
|
|
1779
|
+
}
|
|
1780
|
+
|
|
1781
|
+
template <class PersistenceMatrixOptions>
|
|
1782
|
+
template <class Entry_range>
|
|
1783
|
+
inline std::enable_if_t<!std::is_integral_v<Entry_range> > Matrix<PersistenceMatrixOptions>::multiply_target_and_add_to(
|
|
1784
|
+
const Entry_range& sourceColumn, int coefficient, Index targetColumnIndex)
|
|
1785
|
+
{
|
|
1786
|
+
static_assert(!isNonBasic,
|
|
1787
|
+
"For boundary or chain matrices, only additions with columns inside the matrix is allowed to maintain "
|
|
1788
|
+
"algebraic consistency.");
|
|
1789
|
+
|
|
1790
|
+
if constexpr (PersistenceMatrixOptions::is_z2) {
|
|
1791
|
+
// coef will be converted to bool, because of Element
|
|
1792
|
+
matrix_.multiply_target_and_add_to(sourceColumn, coefficient % 2, targetColumnIndex);
|
|
1793
|
+
} else {
|
|
1794
|
+
matrix_.multiply_target_and_add_to(sourceColumn, colSettings_->operators.get_value(coefficient), targetColumnIndex);
|
|
1795
|
+
}
|
|
1796
|
+
}
|
|
1797
|
+
|
|
1798
|
+
template <class PersistenceMatrixOptions>
|
|
1799
|
+
template <typename Integer_index>
|
|
1800
|
+
inline std::enable_if_t<std::is_integral_v<Integer_index> > Matrix<PersistenceMatrixOptions>::multiply_source_and_add_to(
|
|
1801
|
+
int coefficient, Integer_index sourceColumnIndex, Integer_index targetColumnIndex)
|
|
1802
|
+
{
|
|
1803
|
+
if constexpr (PersistenceMatrixOptions::is_z2) {
|
|
1804
|
+
// coef will be converted to bool, because of Element
|
|
1805
|
+
matrix_.multiply_source_and_add_to(coefficient % 2, sourceColumnIndex, targetColumnIndex);
|
|
1806
|
+
} else {
|
|
1807
|
+
matrix_.multiply_source_and_add_to(colSettings_->operators.get_value(coefficient), sourceColumnIndex, targetColumnIndex);
|
|
1808
|
+
}
|
|
1809
|
+
}
|
|
1810
|
+
|
|
1811
|
+
template <class PersistenceMatrixOptions>
|
|
1812
|
+
template <class Entry_range>
|
|
1813
|
+
inline std::enable_if_t<!std::is_integral_v<Entry_range> > Matrix<PersistenceMatrixOptions>::multiply_source_and_add_to(
|
|
1814
|
+
int coefficient, const Entry_range& sourceColumn, Index targetColumnIndex)
|
|
1815
|
+
{
|
|
1816
|
+
static_assert(!isNonBasic,
|
|
1817
|
+
"For boundary or chain matrices, only additions with columns inside the matrix is allowed to maintain "
|
|
1818
|
+
"algebraic consistency.");
|
|
1819
|
+
|
|
1820
|
+
if constexpr (PersistenceMatrixOptions::is_z2) {
|
|
1821
|
+
// coef will be converted to bool, because of Element
|
|
1822
|
+
matrix_.multiply_source_and_add_to(coefficient % 2, sourceColumn, targetColumnIndex);
|
|
1823
|
+
} else {
|
|
1824
|
+
matrix_.multiply_source_and_add_to(colSettings_->operators.get_value(coefficient), sourceColumn, targetColumnIndex);
|
|
1825
|
+
}
|
|
1826
|
+
}
|
|
1827
|
+
|
|
1828
|
+
template <class PersistenceMatrixOptions>
|
|
1829
|
+
inline void Matrix<PersistenceMatrixOptions>::zero_entry(Index columnIndex, ID_index rowIndex)
|
|
1830
|
+
{
|
|
1831
|
+
static_assert(PersistenceMatrixOptions::is_of_boundary_type && !PersistenceMatrixOptions::has_column_compression,
|
|
1832
|
+
"'zero_entry' is not available for the chosen options.");
|
|
1833
|
+
|
|
1834
|
+
return matrix_.zero_entry(columnIndex, rowIndex);
|
|
1835
|
+
}
|
|
1836
|
+
|
|
1837
|
+
template <class PersistenceMatrixOptions>
|
|
1838
|
+
inline void Matrix<PersistenceMatrixOptions>::zero_entry(Index columnIndex, ID_index rowIndex, bool inR)
|
|
1839
|
+
{
|
|
1840
|
+
// TODO: I don't think there is a particular reason why the indexation is forced, should be removed.
|
|
1841
|
+
static_assert(
|
|
1842
|
+
isNonBasic && PersistenceMatrixOptions::is_of_boundary_type &&
|
|
1843
|
+
(PersistenceMatrixOptions::has_vine_update || PersistenceMatrixOptions::can_retrieve_representative_cycles) &&
|
|
1844
|
+
PersistenceMatrixOptions::column_indexation_type != Column_indexation_types::IDENTIFIER,
|
|
1845
|
+
"Only enabled for RU matrices.");
|
|
1846
|
+
|
|
1847
|
+
return matrix_.zero_entry(columnIndex, rowIndex, inR);
|
|
1848
|
+
}
|
|
1849
|
+
|
|
1850
|
+
template <class PersistenceMatrixOptions>
|
|
1851
|
+
inline void Matrix<PersistenceMatrixOptions>::zero_column(Index columnIndex)
|
|
1852
|
+
{
|
|
1853
|
+
static_assert(PersistenceMatrixOptions::is_of_boundary_type && !PersistenceMatrixOptions::has_column_compression,
|
|
1854
|
+
"'zero_column' is not available for the chosen options.");
|
|
1855
|
+
|
|
1856
|
+
return matrix_.zero_column(columnIndex);
|
|
1857
|
+
}
|
|
1858
|
+
|
|
1859
|
+
template <class PersistenceMatrixOptions>
|
|
1860
|
+
inline void Matrix<PersistenceMatrixOptions>::zero_column(Index columnIndex, bool inR)
|
|
1861
|
+
{
|
|
1862
|
+
// TODO: I don't think there is a particular reason why the indexation is forced, should be removed.
|
|
1863
|
+
static_assert(
|
|
1864
|
+
isNonBasic && PersistenceMatrixOptions::is_of_boundary_type &&
|
|
1865
|
+
(PersistenceMatrixOptions::has_vine_update || PersistenceMatrixOptions::can_retrieve_representative_cycles) &&
|
|
1866
|
+
PersistenceMatrixOptions::column_indexation_type != Column_indexation_types::IDENTIFIER,
|
|
1867
|
+
"Only enabled for RU matrices.");
|
|
1868
|
+
|
|
1869
|
+
return matrix_.zero_column(columnIndex, inR);
|
|
1870
|
+
}
|
|
1871
|
+
|
|
1872
|
+
template <class PersistenceMatrixOptions>
|
|
1873
|
+
inline bool Matrix<PersistenceMatrixOptions>::is_zero_entry(Index columnIndex, ID_index rowIndex)
|
|
1874
|
+
{
|
|
1875
|
+
return matrix_.is_zero_entry(columnIndex, rowIndex);
|
|
1876
|
+
}
|
|
1877
|
+
|
|
1878
|
+
template <class PersistenceMatrixOptions>
|
|
1879
|
+
inline bool Matrix<PersistenceMatrixOptions>::is_zero_entry(Index columnIndex, ID_index rowIndex, bool inR) const
|
|
1880
|
+
{
|
|
1881
|
+
// TODO: I don't think there is a particular reason why the indexation is forced, should be removed.
|
|
1882
|
+
static_assert(
|
|
1883
|
+
isNonBasic && PersistenceMatrixOptions::is_of_boundary_type &&
|
|
1884
|
+
(PersistenceMatrixOptions::has_vine_update || PersistenceMatrixOptions::can_retrieve_representative_cycles) &&
|
|
1885
|
+
PersistenceMatrixOptions::column_indexation_type != Column_indexation_types::IDENTIFIER,
|
|
1886
|
+
"Only enabled for RU matrices.");
|
|
1887
|
+
|
|
1888
|
+
return matrix_.is_zero_entry(columnIndex, rowIndex, inR);
|
|
1889
|
+
}
|
|
1890
|
+
|
|
1891
|
+
template <class PersistenceMatrixOptions>
|
|
1892
|
+
inline bool Matrix<PersistenceMatrixOptions>::is_zero_column(Index columnIndex)
|
|
1893
|
+
{
|
|
1894
|
+
return matrix_.is_zero_column(columnIndex);
|
|
1895
|
+
}
|
|
1896
|
+
|
|
1897
|
+
template <class PersistenceMatrixOptions>
|
|
1898
|
+
inline bool Matrix<PersistenceMatrixOptions>::is_zero_column(Index columnIndex, bool inR)
|
|
1899
|
+
{
|
|
1900
|
+
// TODO: I don't think there is a particular reason why the indexation is forced, should be removed.
|
|
1901
|
+
static_assert(
|
|
1902
|
+
isNonBasic && PersistenceMatrixOptions::is_of_boundary_type &&
|
|
1903
|
+
(PersistenceMatrixOptions::has_vine_update || PersistenceMatrixOptions::can_retrieve_representative_cycles) &&
|
|
1904
|
+
PersistenceMatrixOptions::column_indexation_type != Column_indexation_types::IDENTIFIER,
|
|
1905
|
+
"Only enabled for RU matrices.");
|
|
1906
|
+
|
|
1907
|
+
return matrix_.is_zero_column(columnIndex, inR);
|
|
1908
|
+
}
|
|
1909
|
+
|
|
1910
|
+
template <class PersistenceMatrixOptions>
|
|
1911
|
+
inline typename Matrix<PersistenceMatrixOptions>::Index Matrix<PersistenceMatrixOptions>::get_column_with_pivot(
|
|
1912
|
+
ID_index cellIndex) const
|
|
1913
|
+
{
|
|
1914
|
+
static_assert(isNonBasic && (!PersistenceMatrixOptions::is_of_boundary_type ||
|
|
1915
|
+
(PersistenceMatrixOptions::has_vine_update ||
|
|
1916
|
+
PersistenceMatrixOptions::can_retrieve_representative_cycles)),
|
|
1917
|
+
"'get_column_with_pivot' is not available for the chosen options.");
|
|
1918
|
+
|
|
1919
|
+
return matrix_.get_column_with_pivot(cellIndex);
|
|
1920
|
+
}
|
|
1921
|
+
|
|
1922
|
+
template <class PersistenceMatrixOptions>
|
|
1923
|
+
inline typename Matrix<PersistenceMatrixOptions>::ID_index Matrix<PersistenceMatrixOptions>::get_pivot(
|
|
1924
|
+
Index columnIndex)
|
|
1925
|
+
{
|
|
1926
|
+
static_assert(isNonBasic, "'get_pivot' is not available for the chosen options.");
|
|
1927
|
+
|
|
1928
|
+
return matrix_.get_pivot(columnIndex);
|
|
1929
|
+
}
|
|
1930
|
+
|
|
1931
|
+
template <class PersistenceMatrixOptions>
|
|
1932
|
+
inline Matrix<PersistenceMatrixOptions>& Matrix<PersistenceMatrixOptions>::operator=(Matrix other)
|
|
1933
|
+
{
|
|
1934
|
+
swap(matrix_, other.matrix_);
|
|
1935
|
+
std::swap(colSettings_, other.colSettings_);
|
|
1936
|
+
|
|
1937
|
+
return *this;
|
|
1938
|
+
}
|
|
1939
|
+
|
|
1940
|
+
template <class PersistenceMatrixOptions>
|
|
1941
|
+
inline void Matrix<PersistenceMatrixOptions>::print(Index startCol, Index endCol, Index startRow, Index endRow)
|
|
1942
|
+
{
|
|
1943
|
+
return matrix_.print(startCol, endCol, startRow, endRow);
|
|
1944
|
+
}
|
|
1945
|
+
|
|
1946
|
+
template <class PersistenceMatrixOptions>
|
|
1947
|
+
inline const typename Matrix<PersistenceMatrixOptions>::Barcode&
|
|
1948
|
+
Matrix<PersistenceMatrixOptions>::get_current_barcode()
|
|
1949
|
+
{
|
|
1950
|
+
static_assert(PersistenceMatrixOptions::has_column_pairings, "This method was not enabled.");
|
|
1951
|
+
|
|
1952
|
+
return matrix_.get_current_barcode();
|
|
1953
|
+
}
|
|
1954
|
+
|
|
1955
|
+
template <class PersistenceMatrixOptions>
|
|
1956
|
+
inline const typename Matrix<PersistenceMatrixOptions>::Barcode&
|
|
1957
|
+
Matrix<PersistenceMatrixOptions>::get_current_barcode() const
|
|
1958
|
+
{
|
|
1959
|
+
static_assert(PersistenceMatrixOptions::has_column_pairings, "This method was not enabled.");
|
|
1960
|
+
static_assert(
|
|
1961
|
+
!PersistenceMatrixOptions::is_of_boundary_type || PersistenceMatrixOptions::has_vine_update ||
|
|
1962
|
+
PersistenceMatrixOptions::can_retrieve_representative_cycles,
|
|
1963
|
+
"'get_current_barcode' is not const for boundary matrices as the barcode is only computed when explicitly "
|
|
1964
|
+
"asked.");
|
|
1965
|
+
|
|
1966
|
+
return matrix_.get_current_barcode();
|
|
1967
|
+
}
|
|
1968
|
+
|
|
1969
|
+
template <class PersistenceMatrixOptions>
|
|
1970
|
+
inline void Matrix<PersistenceMatrixOptions>::swap_columns(Index columnIndex1, Index columnIndex2)
|
|
1971
|
+
{
|
|
1972
|
+
static_assert(
|
|
1973
|
+
(!isNonBasic && !PersistenceMatrixOptions::has_column_compression) ||
|
|
1974
|
+
(isNonBasic && PersistenceMatrixOptions::is_of_boundary_type && !PersistenceMatrixOptions::has_vine_update &&
|
|
1975
|
+
!PersistenceMatrixOptions::can_retrieve_representative_cycles),
|
|
1976
|
+
"This method was not enabled.");
|
|
1977
|
+
return matrix_.swap_columns(columnIndex1, columnIndex2);
|
|
1978
|
+
}
|
|
1979
|
+
|
|
1980
|
+
template <class PersistenceMatrixOptions>
|
|
1981
|
+
inline void Matrix<PersistenceMatrixOptions>::swap_rows(Index rowIndex1, Index rowIndex2)
|
|
1982
|
+
{
|
|
1983
|
+
static_assert(
|
|
1984
|
+
(!isNonBasic && !PersistenceMatrixOptions::has_column_compression) ||
|
|
1985
|
+
(isNonBasic && PersistenceMatrixOptions::is_of_boundary_type && !PersistenceMatrixOptions::has_vine_update &&
|
|
1986
|
+
!PersistenceMatrixOptions::can_retrieve_representative_cycles),
|
|
1987
|
+
"This method was not enabled.");
|
|
1988
|
+
return matrix_.swap_rows(rowIndex1, rowIndex2);
|
|
1989
|
+
}
|
|
1990
|
+
|
|
1991
|
+
template <class PersistenceMatrixOptions>
|
|
1992
|
+
inline bool Matrix<PersistenceMatrixOptions>::vine_swap_with_z_eq_1_case(Pos_index index)
|
|
1993
|
+
{
|
|
1994
|
+
static_assert(PersistenceMatrixOptions::has_vine_update, "This method was not enabled.");
|
|
1995
|
+
static_assert(PersistenceMatrixOptions::column_indexation_type == Column_indexation_types::POSITION ||
|
|
1996
|
+
(PersistenceMatrixOptions::is_of_boundary_type &&
|
|
1997
|
+
PersistenceMatrixOptions::column_indexation_type == Column_indexation_types::CONTAINER),
|
|
1998
|
+
"This method was not enabled.");
|
|
1999
|
+
return matrix_.vine_swap_with_z_eq_1_case(index);
|
|
2000
|
+
}
|
|
2001
|
+
|
|
2002
|
+
template <class PersistenceMatrixOptions>
|
|
2003
|
+
inline typename Matrix<PersistenceMatrixOptions>::Index Matrix<PersistenceMatrixOptions>::vine_swap_with_z_eq_1_case(
|
|
2004
|
+
Index columnIndex1, Index columnIndex2)
|
|
2005
|
+
{
|
|
2006
|
+
static_assert(PersistenceMatrixOptions::has_vine_update, "This method was not enabled.");
|
|
2007
|
+
static_assert(PersistenceMatrixOptions::column_indexation_type == Column_indexation_types::IDENTIFIER ||
|
|
2008
|
+
(!PersistenceMatrixOptions::is_of_boundary_type &&
|
|
2009
|
+
PersistenceMatrixOptions::column_indexation_type == Column_indexation_types::CONTAINER),
|
|
2010
|
+
"This method was not enabled.");
|
|
2011
|
+
|
|
2012
|
+
return matrix_.vine_swap_with_z_eq_1_case(columnIndex1, columnIndex2);
|
|
2013
|
+
}
|
|
2014
|
+
|
|
2015
|
+
template <class PersistenceMatrixOptions>
|
|
2016
|
+
inline bool Matrix<PersistenceMatrixOptions>::vine_swap(Pos_index index)
|
|
2017
|
+
{
|
|
2018
|
+
static_assert(PersistenceMatrixOptions::has_vine_update, "This method was not enabled.");
|
|
2019
|
+
static_assert(PersistenceMatrixOptions::column_indexation_type == Column_indexation_types::POSITION ||
|
|
2020
|
+
(PersistenceMatrixOptions::is_of_boundary_type &&
|
|
2021
|
+
PersistenceMatrixOptions::column_indexation_type == Column_indexation_types::CONTAINER),
|
|
2022
|
+
"This method was not enabled.");
|
|
2023
|
+
return matrix_.vine_swap(index);
|
|
2024
|
+
}
|
|
2025
|
+
|
|
2026
|
+
template <class PersistenceMatrixOptions>
|
|
2027
|
+
inline typename Matrix<PersistenceMatrixOptions>::Index Matrix<PersistenceMatrixOptions>::vine_swap(
|
|
2028
|
+
Index columnIndex1, Index columnIndex2)
|
|
2029
|
+
{
|
|
2030
|
+
static_assert(PersistenceMatrixOptions::has_vine_update, "This method was not enabled.");
|
|
2031
|
+
static_assert(PersistenceMatrixOptions::column_indexation_type == Column_indexation_types::IDENTIFIER ||
|
|
2032
|
+
(!PersistenceMatrixOptions::is_of_boundary_type &&
|
|
2033
|
+
PersistenceMatrixOptions::column_indexation_type == Column_indexation_types::CONTAINER),
|
|
2034
|
+
"This method was not enabled.");
|
|
2035
|
+
return matrix_.vine_swap(columnIndex1, columnIndex2);
|
|
2036
|
+
}
|
|
2037
|
+
|
|
2038
|
+
template <class PersistenceMatrixOptions>
|
|
2039
|
+
inline void Matrix<PersistenceMatrixOptions>::update_representative_cycles()
|
|
2040
|
+
{
|
|
2041
|
+
static_assert(PersistenceMatrixOptions::can_retrieve_representative_cycles, "This method was not enabled.");
|
|
2042
|
+
matrix_.update_representative_cycles();
|
|
2043
|
+
}
|
|
2044
|
+
|
|
2045
|
+
// template <class PersistenceMatrixOptions>
|
|
2046
|
+
// inline const std::vector<typename Matrix<PersistenceMatrixOptions>::Cycle>&
|
|
2047
|
+
// Matrix<PersistenceMatrixOptions>::get_representative_cycles()
|
|
2048
|
+
// {
|
|
2049
|
+
// static_assert(PersistenceMatrixOptions::can_retrieve_representative_cycles, "This method was not enabled.");
|
|
2050
|
+
// return matrix_.get_representative_cycles();
|
|
2051
|
+
// }
|
|
2052
|
+
|
|
2053
|
+
// template <class PersistenceMatrixOptions>
|
|
2054
|
+
// inline const typename Matrix<PersistenceMatrixOptions>::Cycle&
|
|
2055
|
+
// Matrix<PersistenceMatrixOptions>::get_representative_cycle(const Bar& bar)
|
|
2056
|
+
// {
|
|
2057
|
+
// static_assert(PersistenceMatrixOptions::can_retrieve_representative_cycles, "This method was not enabled.");
|
|
2058
|
+
// return matrix_.get_representative_cycle(bar);
|
|
2059
|
+
// }
|
|
2060
|
+
|
|
2061
|
+
template <class PersistenceMatrixOptions>
|
|
2062
|
+
inline std::vector<std::vector<std::vector<typename Matrix<PersistenceMatrixOptions>::ID_index> > >
|
|
2063
|
+
Matrix<PersistenceMatrixOptions>::get_representative_cycles_as_borders(bool detailed) {
|
|
2064
|
+
static_assert(PersistenceMatrixOptions::can_retrieve_representative_cycles && PersistenceMatrixOptions::is_z2,
|
|
2065
|
+
"This method was not enabled.");
|
|
2066
|
+
return matrix_.get_representative_cycles_as_borders(detailed);
|
|
2067
|
+
}
|
|
2068
|
+
|
|
2069
|
+
template <class PersistenceMatrixOptions>
|
|
2070
|
+
inline constexpr void Matrix<PersistenceMatrixOptions>::_assert_options()
|
|
2071
|
+
{
|
|
2072
|
+
static_assert(
|
|
2073
|
+
PersistenceMatrixOptions::column_type != Column_types::HEAP || !PersistenceMatrixOptions::has_row_access,
|
|
2074
|
+
"Row access is not possible for heap columns.");
|
|
2075
|
+
static_assert(!PersistenceMatrixOptions::has_vine_update || PersistenceMatrixOptions::is_z2,
|
|
2076
|
+
"Vine update currently works only for Z_2 coefficients.");
|
|
2077
|
+
// static_assert(!PersistenceMatrixOptions::can_retrieve_representative_cycles || PersistenceMatrixOptions::is_z2,
|
|
2078
|
+
// "Representative cycles can currently only be computed with Z_2 coefficients.");
|
|
2079
|
+
static_assert(
|
|
2080
|
+
PersistenceMatrixOptions::column_type != Column_types::HEAP || !PersistenceMatrixOptions::has_column_compression,
|
|
2081
|
+
"Column compression not compatible with heap columns.");
|
|
2082
|
+
|
|
2083
|
+
// // This should be warnings instead, as PersistenceMatrixOptions::has_column_compression is just ignored in those
|
|
2084
|
+
// // cases and don't produces errors as long as the corresponding methods are not called.
|
|
2085
|
+
// static_assert(!PersistenceMatrixOptions::has_column_compression || !PersistenceMatrixOptions::has_column_pairings,
|
|
2086
|
+
// "Column compression not available to compute persistence homology (it would bring no advantages; "
|
|
2087
|
+
// "use it for co-homology instead).");
|
|
2088
|
+
// static_assert(!PersistenceMatrixOptions::has_column_compression || !PersistenceMatrixOptions::has_vine_update,
|
|
2089
|
+
// "Column compression not available for vineyards.");
|
|
2090
|
+
// static_assert(!PersistenceMatrixOptions::has_column_compression ||
|
|
2091
|
+
// !PersistenceMatrixOptions::can_retrieve_representative_cycles,
|
|
2092
|
+
// "Column compression not available to retrieve representative cycles.");
|
|
2093
|
+
// // Would column removal while column compression be useful? If yes, should erase() remove a single column or the
|
|
2094
|
+
// // class of columns identical to the input?
|
|
2095
|
+
// // For a single column, I have an implementation for union-find (not the current one) which allows deleting a
|
|
2096
|
+
// // single element in constant time, but find becomes log n in worst case.
|
|
2097
|
+
// // For a column class, we either just ignore the removed class (constant time), but this results in memory
|
|
2098
|
+
// // residues, or, we have an erase method which is at least linear in the size of the class.
|
|
2099
|
+
// static_assert(
|
|
2100
|
+
// !PersistenceMatrixOptions::has_column_compression || !PersistenceMatrixOptions::has_map_column_container,
|
|
2101
|
+
// "When column compression is used, the removal of columns is not implemented yet.");
|
|
2102
|
+
}
|
|
2103
|
+
|
|
2104
|
+
} // namespace persistence_matrix
|
|
2105
|
+
} // namespace Gudhi
|
|
2106
|
+
|
|
2107
|
+
#endif // MASTER_MATRIX_H
|