multipers 2.4.0b1__cp312-cp312-macosx_11_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- multipers/.dylibs/libboost_timer.dylib +0 -0
- multipers/.dylibs/libc++.1.0.dylib +0 -0
- multipers/.dylibs/libtbb.12.17.dylib +0 -0
- multipers/__init__.py +33 -0
- multipers/_signed_measure_meta.py +426 -0
- multipers/_slicer_meta.py +231 -0
- multipers/array_api/__init__.py +62 -0
- multipers/array_api/numpy.py +124 -0
- multipers/array_api/torch.py +133 -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 +736 -0
- multipers/filtration_conversions.pxd.tp +226 -0
- multipers/filtrations/__init__.py +21 -0
- multipers/filtrations/density.py +529 -0
- multipers/filtrations/filtrations.py +480 -0
- multipers/filtrations.pxd +534 -0
- multipers/filtrations.pxd.tp +332 -0
- multipers/function_rips.cpython-312-darwin.so +0 -0
- multipers/function_rips.pyx +104 -0
- multipers/grids.cpython-312-darwin.so +0 -0
- multipers/grids.pyx +538 -0
- multipers/gudhi/Persistence_slices_interface.h +213 -0
- multipers/gudhi/Simplex_tree_interface.h +274 -0
- multipers/gudhi/Simplex_tree_multi_interface.h +648 -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 +52 -0
- multipers/gudhi/gudhi/Degree_rips_bifiltration.h +2307 -0
- multipers/gudhi/gudhi/Dynamic_multi_parameter_filtration.h +2524 -0
- multipers/gudhi/gudhi/Fields/Multi_field.h +453 -0
- multipers/gudhi/gudhi/Fields/Multi_field_operators.h +460 -0
- multipers/gudhi/gudhi/Fields/Multi_field_shared.h +444 -0
- multipers/gudhi/gudhi/Fields/Multi_field_small.h +584 -0
- multipers/gudhi/gudhi/Fields/Multi_field_small_operators.h +490 -0
- multipers/gudhi/gudhi/Fields/Multi_field_small_shared.h +580 -0
- multipers/gudhi/gudhi/Fields/Z2_field.h +391 -0
- multipers/gudhi/gudhi/Fields/Z2_field_operators.h +389 -0
- multipers/gudhi/gudhi/Fields/Zp_field.h +493 -0
- multipers/gudhi/gudhi/Fields/Zp_field_operators.h +384 -0
- multipers/gudhi/gudhi/Fields/Zp_field_shared.h +492 -0
- multipers/gudhi/gudhi/Flag_complex_edge_collapser.h +337 -0
- multipers/gudhi/gudhi/Matrix.h +2200 -0
- multipers/gudhi/gudhi/Multi_filtration/Multi_parameter_generator.h +1712 -0
- multipers/gudhi/gudhi/Multi_filtration/multi_filtration_conversions.h +237 -0
- multipers/gudhi/gudhi/Multi_filtration/multi_filtration_utils.h +225 -0
- multipers/gudhi/gudhi/Multi_parameter_filtered_complex.h +485 -0
- multipers/gudhi/gudhi/Multi_parameter_filtration.h +2643 -0
- multipers/gudhi/gudhi/Multi_persistence/Box.h +233 -0
- multipers/gudhi/gudhi/Multi_persistence/Line.h +309 -0
- multipers/gudhi/gudhi/Multi_persistence/Multi_parameter_filtered_complex_pcoh_interface.h +268 -0
- multipers/gudhi/gudhi/Multi_persistence/Persistence_interface_cohomology.h +159 -0
- multipers/gudhi/gudhi/Multi_persistence/Persistence_interface_matrix.h +463 -0
- multipers/gudhi/gudhi/Multi_persistence/Point.h +853 -0
- multipers/gudhi/gudhi/Off_reader.h +173 -0
- multipers/gudhi/gudhi/Persistence_matrix/Base_matrix.h +834 -0
- multipers/gudhi/gudhi/Persistence_matrix/Base_matrix_with_column_compression.h +838 -0
- multipers/gudhi/gudhi/Persistence_matrix/Boundary_matrix.h +833 -0
- multipers/gudhi/gudhi/Persistence_matrix/Chain_matrix.h +1367 -0
- multipers/gudhi/gudhi/Persistence_matrix/Id_to_index_overlay.h +1157 -0
- multipers/gudhi/gudhi/Persistence_matrix/Position_to_index_overlay.h +869 -0
- multipers/gudhi/gudhi/Persistence_matrix/RU_matrix.h +905 -0
- multipers/gudhi/gudhi/Persistence_matrix/allocators/entry_constructors.h +122 -0
- multipers/gudhi/gudhi/Persistence_matrix/base_pairing.h +260 -0
- multipers/gudhi/gudhi/Persistence_matrix/base_swap.h +288 -0
- multipers/gudhi/gudhi/Persistence_matrix/chain_pairing.h +170 -0
- multipers/gudhi/gudhi/Persistence_matrix/chain_rep_cycles.h +247 -0
- multipers/gudhi/gudhi/Persistence_matrix/chain_vine_swap.h +571 -0
- multipers/gudhi/gudhi/Persistence_matrix/columns/chain_column_extra_properties.h +182 -0
- multipers/gudhi/gudhi/Persistence_matrix/columns/column_dimension_holder.h +130 -0
- multipers/gudhi/gudhi/Persistence_matrix/columns/column_utilities.h +235 -0
- multipers/gudhi/gudhi/Persistence_matrix/columns/entry_types.h +312 -0
- multipers/gudhi/gudhi/Persistence_matrix/columns/heap_column.h +1092 -0
- multipers/gudhi/gudhi/Persistence_matrix/columns/intrusive_list_column.h +923 -0
- multipers/gudhi/gudhi/Persistence_matrix/columns/intrusive_set_column.h +914 -0
- multipers/gudhi/gudhi/Persistence_matrix/columns/list_column.h +930 -0
- multipers/gudhi/gudhi/Persistence_matrix/columns/naive_vector_column.h +1071 -0
- multipers/gudhi/gudhi/Persistence_matrix/columns/row_access.h +203 -0
- multipers/gudhi/gudhi/Persistence_matrix/columns/set_column.h +886 -0
- multipers/gudhi/gudhi/Persistence_matrix/columns/unordered_set_column.h +984 -0
- multipers/gudhi/gudhi/Persistence_matrix/columns/vector_column.h +1213 -0
- multipers/gudhi/gudhi/Persistence_matrix/index_mapper.h +58 -0
- multipers/gudhi/gudhi/Persistence_matrix/matrix_dimension_holders.h +227 -0
- multipers/gudhi/gudhi/Persistence_matrix/matrix_row_access.h +200 -0
- multipers/gudhi/gudhi/Persistence_matrix/ru_pairing.h +166 -0
- multipers/gudhi/gudhi/Persistence_matrix/ru_rep_cycles.h +319 -0
- multipers/gudhi/gudhi/Persistence_matrix/ru_vine_swap.h +562 -0
- multipers/gudhi/gudhi/Persistence_on_a_line.h +152 -0
- multipers/gudhi/gudhi/Persistence_on_rectangle.h +617 -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 +769 -0
- multipers/gudhi/gudhi/Points_off_io.h +171 -0
- multipers/gudhi/gudhi/Projective_cover_kernel.h +379 -0
- multipers/gudhi/gudhi/Simple_object_pool.h +69 -0
- multipers/gudhi/gudhi/Simplex_tree/Simplex_tree_iterators.h +559 -0
- multipers/gudhi/gudhi/Simplex_tree/Simplex_tree_node_explicit_storage.h +83 -0
- multipers/gudhi/gudhi/Simplex_tree/Simplex_tree_siblings.h +121 -0
- multipers/gudhi/gudhi/Simplex_tree/Simplex_tree_star_simplex_iterators.h +277 -0
- multipers/gudhi/gudhi/Simplex_tree/filtration_value_utils.h +155 -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 +60 -0
- multipers/gudhi/gudhi/Simplex_tree/simplex_tree_options.h +105 -0
- multipers/gudhi/gudhi/Simplex_tree.h +3170 -0
- multipers/gudhi/gudhi/Slicer.h +848 -0
- multipers/gudhi/gudhi/Thread_safe_slicer.h +393 -0
- multipers/gudhi/gudhi/distance_functions.h +62 -0
- multipers/gudhi/gudhi/graph_simplicial_complex.h +104 -0
- multipers/gudhi/gudhi/multi_simplex_tree_helpers.h +147 -0
- multipers/gudhi/gudhi/persistence_interval.h +263 -0
- multipers/gudhi/gudhi/persistence_matrix_options.h +188 -0
- multipers/gudhi/gudhi/reader_utils.h +367 -0
- multipers/gudhi/gudhi/simple_mdspan.h +484 -0
- multipers/gudhi/gudhi/slicer_helpers.h +779 -0
- multipers/gudhi/tmp_h0_pers/mma_interface_h0.h +223 -0
- multipers/gudhi/tmp_h0_pers/naive_merge_tree.h +536 -0
- multipers/io.cpython-312-darwin.so +0 -0
- multipers/io.pyx +472 -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 +1667 -0
- multipers/ml/sliced_wasserstein.py +461 -0
- multipers/ml/tools.py +113 -0
- multipers/mma_structures.cpython-312-darwin.so +0 -0
- multipers/mma_structures.pxd +134 -0
- multipers/mma_structures.pyx +1483 -0
- multipers/mma_structures.pyx.tp +1126 -0
- multipers/multi_parameter_rank_invariant/diff_helpers.h +85 -0
- multipers/multi_parameter_rank_invariant/euler_characteristic.h +95 -0
- multipers/multi_parameter_rank_invariant/function_rips.h +317 -0
- multipers/multi_parameter_rank_invariant/hilbert_function.h +761 -0
- multipers/multi_parameter_rank_invariant/persistence_slices.h +149 -0
- multipers/multi_parameter_rank_invariant/rank_invariant.h +350 -0
- multipers/multiparameter_edge_collapse.py +41 -0
- multipers/multiparameter_module_approximation/approximation.h +2541 -0
- multipers/multiparameter_module_approximation/debug.h +107 -0
- multipers/multiparameter_module_approximation/format_python-cpp.h +292 -0
- multipers/multiparameter_module_approximation/utilities.h +428 -0
- multipers/multiparameter_module_approximation.cpython-312-darwin.so +0 -0
- multipers/multiparameter_module_approximation.pyx +286 -0
- multipers/ops.cpython-312-darwin.so +0 -0
- multipers/ops.pyx +231 -0
- multipers/pickle.py +89 -0
- multipers/plots.py +550 -0
- multipers/point_measure.cpython-312-darwin.so +0 -0
- multipers/point_measure.pyx +409 -0
- multipers/simplex_tree_multi.cpython-312-darwin.so +0 -0
- multipers/simplex_tree_multi.pxd +136 -0
- multipers/simplex_tree_multi.pyx +11719 -0
- multipers/simplex_tree_multi.pyx.tp +2102 -0
- multipers/slicer.cpython-312-darwin.so +0 -0
- multipers/slicer.pxd +2097 -0
- multipers/slicer.pxd.tp +263 -0
- multipers/slicer.pyx +13042 -0
- multipers/slicer.pyx.tp +1259 -0
- multipers/tensor/tensor.h +672 -0
- multipers/tensor.pxd +13 -0
- multipers/test.pyx +44 -0
- multipers/tests/__init__.py +70 -0
- multipers/torch/__init__.py +1 -0
- multipers/torch/diff_grids.py +240 -0
- multipers/torch/rips_density.py +310 -0
- multipers/vector_interface.pxd +46 -0
- multipers-2.4.0b1.dist-info/METADATA +131 -0
- multipers-2.4.0b1.dist-info/RECORD +184 -0
- multipers-2.4.0b1.dist-info/WHEEL +6 -0
- multipers-2.4.0b1.dist-info/licenses/LICENSE +21 -0
- multipers-2.4.0b1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,838 @@
|
|
|
1
|
+
/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT.
|
|
2
|
+
* See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details.
|
|
3
|
+
* Author(s): Hannah Schreiber
|
|
4
|
+
*
|
|
5
|
+
* Copyright (C) 2022-24 Inria
|
|
6
|
+
*
|
|
7
|
+
* Modification(s):
|
|
8
|
+
* - YYYY/MM Author: Description of the modification
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @file Base_matrix_with_column_compression.h
|
|
13
|
+
* @author Hannah Schreiber
|
|
14
|
+
* @brief Contains the @ref Gudhi::persistence_matrix::Base_matrix_with_column_compression class.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
#ifndef PM_BASE_MATRIX_COMPRESSION_H
|
|
18
|
+
#define PM_BASE_MATRIX_COMPRESSION_H
|
|
19
|
+
|
|
20
|
+
#include <iostream> //print() only
|
|
21
|
+
#include <vector>
|
|
22
|
+
#include <utility> //std::swap, std::move & std::exchange
|
|
23
|
+
|
|
24
|
+
#include <boost/intrusive/set.hpp>
|
|
25
|
+
#include <boost/pending/disjoint_sets.hpp>
|
|
26
|
+
|
|
27
|
+
#include <gudhi/Simple_object_pool.h>
|
|
28
|
+
|
|
29
|
+
namespace Gudhi {
|
|
30
|
+
namespace persistence_matrix {
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @class Base_matrix_with_column_compression Base_matrix_with_column_compression.h \
|
|
34
|
+
* gudhi/Persistence_matrix/Base_matrix_with_column_compression.h
|
|
35
|
+
* @ingroup persistence_matrix
|
|
36
|
+
*
|
|
37
|
+
* @brief A @ref basematrix "base matrix" (also see @ref Base_matrix), but with column compression. That is, all
|
|
38
|
+
* identical columns in the matrix are compressed together as the same column. For matrices with a lot of redundant
|
|
39
|
+
* columns, this will save a lot of space. Also, any addition made onto a column will be performed at the same time
|
|
40
|
+
* on all other identical columns, which is an advantage for the cohomology algorithm for example.
|
|
41
|
+
*
|
|
42
|
+
* @tparam Master_matrix An instantiation of @ref Matrix from which all types and options are deduced.
|
|
43
|
+
*/
|
|
44
|
+
template <class Master_matrix>
|
|
45
|
+
class Base_matrix_with_column_compression : protected Master_matrix::Matrix_row_access_option
|
|
46
|
+
{
|
|
47
|
+
public:
|
|
48
|
+
using Index = typename Master_matrix::Index; /**< Container index type. */
|
|
49
|
+
using Dimension = typename Master_matrix::Dimension; /**< Dimension value type. */
|
|
50
|
+
/**
|
|
51
|
+
* @brief Field operators class. Necessary only if @ref PersistenceMatrixOptions::is_z2 is false.
|
|
52
|
+
*/
|
|
53
|
+
using Field_operators = typename Master_matrix::Field_operators;
|
|
54
|
+
using Field_element = typename Master_matrix::Element; /**< Field element value type. */
|
|
55
|
+
using Row = typename Master_matrix::Row; /**< Row type,
|
|
56
|
+
only necessary with row access option. */
|
|
57
|
+
using Entry_constructor = typename Master_matrix::Entry_constructor; /**< Factory of @ref Entry classes. */
|
|
58
|
+
using Column_settings = typename Master_matrix::Column_settings; /**< Structure giving access to the columns to
|
|
59
|
+
necessary external classes. */
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @brief Type for columns. Only one for each "column class" is explicitly constructed.
|
|
63
|
+
*/
|
|
64
|
+
class Column : public Master_matrix::Column,
|
|
65
|
+
public boost::intrusive::set_base_hook<boost::intrusive::link_mode<boost::intrusive::normal_link> >
|
|
66
|
+
{
|
|
67
|
+
public:
|
|
68
|
+
using Base = typename Master_matrix::Column;
|
|
69
|
+
|
|
70
|
+
Column(Column_settings* colSettings = nullptr) : Base(colSettings) {}
|
|
71
|
+
|
|
72
|
+
template <class Container>
|
|
73
|
+
Column(const Container& nonZeroRowIndices, Column_settings* colSettings) : Base(nonZeroRowIndices, colSettings)
|
|
74
|
+
{}
|
|
75
|
+
|
|
76
|
+
template <class Container, class Row_container>
|
|
77
|
+
Column(Index columnIndex,
|
|
78
|
+
const Container& nonZeroRowIndices,
|
|
79
|
+
Row_container* rowContainer,
|
|
80
|
+
Column_settings* colSettings)
|
|
81
|
+
: Base(columnIndex, nonZeroRowIndices, rowContainer, colSettings)
|
|
82
|
+
{}
|
|
83
|
+
|
|
84
|
+
template <class Container, class = std::enable_if_t<!std::is_arithmetic_v<Container> > >
|
|
85
|
+
Column(const Container& nonZeroRowIndices, Dimension dimension, Column_settings* colSettings)
|
|
86
|
+
: Base(nonZeroRowIndices, dimension, colSettings)
|
|
87
|
+
{}
|
|
88
|
+
|
|
89
|
+
template <class Container, class Row_container, class = std::enable_if_t<!std::is_arithmetic_v<Container> > >
|
|
90
|
+
Column(Index columnIndex,
|
|
91
|
+
const Container& nonZeroRowIndices,
|
|
92
|
+
Dimension dimension,
|
|
93
|
+
Row_container* rowContainer,
|
|
94
|
+
Column_settings* colSettings)
|
|
95
|
+
: Base(columnIndex, nonZeroRowIndices, dimension, rowContainer, colSettings)
|
|
96
|
+
{}
|
|
97
|
+
|
|
98
|
+
Column(Index idx, Dimension dimension, Column_settings* colSettings) : Base(idx, dimension, colSettings) {}
|
|
99
|
+
|
|
100
|
+
Column(Index idx, Field_element e, Dimension dimension, Column_settings* colSettings)
|
|
101
|
+
: Base(idx, e, dimension, colSettings)
|
|
102
|
+
{}
|
|
103
|
+
|
|
104
|
+
template <class Row_container>
|
|
105
|
+
Column(Index columnIndex, Index idx, Dimension dimension, Row_container* rowContainer, Column_settings* colSettings)
|
|
106
|
+
: Base(columnIndex, idx, dimension, rowContainer, colSettings)
|
|
107
|
+
{}
|
|
108
|
+
|
|
109
|
+
template <class Row_container>
|
|
110
|
+
Column(Index columnIndex,
|
|
111
|
+
Index idx,
|
|
112
|
+
Field_element e,
|
|
113
|
+
Dimension dimension,
|
|
114
|
+
Row_container* rowContainer,
|
|
115
|
+
Column_settings* colSettings)
|
|
116
|
+
: Base(columnIndex, idx, e, dimension, rowContainer, colSettings)
|
|
117
|
+
{}
|
|
118
|
+
|
|
119
|
+
Column(const Column& column, Column_settings* colSettings = nullptr)
|
|
120
|
+
: Base(static_cast<const Base&>(column), colSettings), rep_(column.rep_)
|
|
121
|
+
{}
|
|
122
|
+
|
|
123
|
+
template <class Row_container>
|
|
124
|
+
Column(const Column& column, Index columnIndex, Row_container* rowContainer, Column_settings* colSettings = nullptr)
|
|
125
|
+
: Base(static_cast<const Base&>(column), columnIndex, rowContainer, colSettings), rep_(column.rep_)
|
|
126
|
+
{}
|
|
127
|
+
|
|
128
|
+
Column(Column&& column) noexcept : Base(std::move(static_cast<Base&>(column))), rep_(std::exchange(column.rep_, 0))
|
|
129
|
+
{}
|
|
130
|
+
|
|
131
|
+
~Column() = default;
|
|
132
|
+
|
|
133
|
+
// TODO: is it possible to make this work?
|
|
134
|
+
// template <class... U>
|
|
135
|
+
// Column(U&&... u) : Base(std::forward<U>(u)...) {}
|
|
136
|
+
|
|
137
|
+
Index get_rep() const { return rep_; }
|
|
138
|
+
|
|
139
|
+
void set_rep(const Index& rep) { rep_ = rep; }
|
|
140
|
+
|
|
141
|
+
Column& operator=(const Column& other)
|
|
142
|
+
{
|
|
143
|
+
Base::operator=(other);
|
|
144
|
+
rep_ = other.rep_;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
Column& operator=(Column&& other) noexcept
|
|
148
|
+
{
|
|
149
|
+
Base::operator=(std::move(other));
|
|
150
|
+
rep_ = std::exchange(other.rep_, 0);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
struct Hasher {
|
|
154
|
+
size_t operator()(const Column& c) const { return std::hash<Base>()(static_cast<Base>(c)); }
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
private:
|
|
158
|
+
Index rep_; /**< Index in the union-find of the root of the set representing this column class. */
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* @brief Constructs an empty matrix.
|
|
163
|
+
*
|
|
164
|
+
* @param colSettings Pointer to an existing setting structure for the columns. The structure should contain all
|
|
165
|
+
* the necessary external classes specifically necessary for the chosen column type, such as custom allocators.
|
|
166
|
+
*/
|
|
167
|
+
Base_matrix_with_column_compression(Column_settings* colSettings);
|
|
168
|
+
/**
|
|
169
|
+
* @brief Constructs a matrix from the given ordered columns. The columns are inserted in the given order.
|
|
170
|
+
* If no identical column already existed, a copy of the column is stored. If an identical one existed, no new
|
|
171
|
+
* column is constructed and the relationship between the two is registered in an union-find structure.
|
|
172
|
+
*
|
|
173
|
+
* @tparam Container Range type for @ref Matrix::Entry_representative ranges.
|
|
174
|
+
* Assumed to have a begin(), end() and size() method.
|
|
175
|
+
* @param columns A vector of @ref Matrix::Entry_representative ranges to construct the columns from.
|
|
176
|
+
* The content of the ranges are assumed to be sorted by increasing ID value.
|
|
177
|
+
* @param colSettings Pointer to an existing setting structure for the columns. The structure should contain all
|
|
178
|
+
* the necessary external classes specifically necessary for the chosen column type, such as custom allocators.
|
|
179
|
+
*/
|
|
180
|
+
template <class Container>
|
|
181
|
+
Base_matrix_with_column_compression(const std::vector<Container>& columns, Column_settings* colSettings);
|
|
182
|
+
/**
|
|
183
|
+
* @brief Constructs a new empty matrix and reserves space for the given number of columns.
|
|
184
|
+
*
|
|
185
|
+
* @param numberOfColumns Number of columns to reserve space for.
|
|
186
|
+
* @param colSettings Pointer to an existing setting structure for the columns. The structure should contain all
|
|
187
|
+
* the necessary external classes specifically necessary for the chosen column type, such as custom allocators.
|
|
188
|
+
*/
|
|
189
|
+
Base_matrix_with_column_compression(unsigned int numberOfColumns, Column_settings* colSettings);
|
|
190
|
+
/**
|
|
191
|
+
* @brief Copy constructor. If @p colSettings is not a null pointer, its value is kept
|
|
192
|
+
* instead of the one in the copied matrix.
|
|
193
|
+
*
|
|
194
|
+
* @param matrixToCopy Matrix to copy.
|
|
195
|
+
* @param colSettings Either a pointer to an existing setting structure for the columns or a null pointer.
|
|
196
|
+
* The structure should contain all the necessary external classes specifically necessary for the chosen column type,
|
|
197
|
+
* such as custom allocators. If null pointer, the pointer stored in @p matrixToCopy is used instead.
|
|
198
|
+
*/
|
|
199
|
+
Base_matrix_with_column_compression(const Base_matrix_with_column_compression& matrixToCopy,
|
|
200
|
+
Column_settings* colSettings = nullptr);
|
|
201
|
+
/**
|
|
202
|
+
* @brief Move constructor.
|
|
203
|
+
*
|
|
204
|
+
* @param other Matrix to move.
|
|
205
|
+
*/
|
|
206
|
+
Base_matrix_with_column_compression(Base_matrix_with_column_compression&& other) noexcept;
|
|
207
|
+
/**
|
|
208
|
+
* @brief Destructor.
|
|
209
|
+
*/
|
|
210
|
+
~Base_matrix_with_column_compression();
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* @brief Inserts a new ordered column at the end of the matrix by copying the given range of
|
|
214
|
+
* @ref Matrix::Entry_representative. The content of the range is assumed to be sorted by increasing ID value.
|
|
215
|
+
*
|
|
216
|
+
* @tparam Container Range of @ref Matrix::Entry_representative. Assumed to have a begin(), end() and size() method.
|
|
217
|
+
* @param column Range of @ref Matrix::Entry_representative from which the column has to be constructed. Assumed to be
|
|
218
|
+
* ordered by increasing ID value.
|
|
219
|
+
*/
|
|
220
|
+
template <class Container, class = std::enable_if_t<!std::is_arithmetic_v<Container> > >
|
|
221
|
+
void insert_column(const Container& column);
|
|
222
|
+
/**
|
|
223
|
+
* @brief Inserts a new column at the end of the matrix. The column will consist of the given index only.
|
|
224
|
+
* Only available for Z2 coefficients. Otherwise, add the entry coefficient to the arguments.
|
|
225
|
+
*
|
|
226
|
+
* @param idx Entry ID.
|
|
227
|
+
*/
|
|
228
|
+
void insert_column(Index idx);
|
|
229
|
+
/**
|
|
230
|
+
* @brief Inserts a new column at the end of the matrix. The column will consist of the given index only.
|
|
231
|
+
* Only available for Zp coefficients. For Z2, do not specify the last argument.
|
|
232
|
+
*
|
|
233
|
+
* @param idx Entry ID.
|
|
234
|
+
* @param e Entry coefficient.
|
|
235
|
+
*/
|
|
236
|
+
void insert_column(Index idx, Field_element e);
|
|
237
|
+
/**
|
|
238
|
+
* @brief Same as @ref insert_column, only for interface purposes. The given dimension is ignored and not stored.
|
|
239
|
+
*
|
|
240
|
+
* @tparam Boundary_range Range of @ref Matrix::Entry_representative. Assumed to have a begin(), end() and size()
|
|
241
|
+
* method.
|
|
242
|
+
* @param boundary Range of @ref Matrix::Entry_representative from which the column has to be constructed. Assumed to
|
|
243
|
+
* be ordered by increasing ID value.
|
|
244
|
+
* @param dim Ignored.
|
|
245
|
+
*/
|
|
246
|
+
template <class Boundary_range>
|
|
247
|
+
void insert_boundary(const Boundary_range& boundary,
|
|
248
|
+
Dimension dim = Master_matrix::template get_null_value<Dimension>());
|
|
249
|
+
/**
|
|
250
|
+
* @brief Returns the column at the given @ref MatIdx index.
|
|
251
|
+
* The type of the column depends on the chosen options, see @ref PersistenceMatrixOptions::column_type.
|
|
252
|
+
*
|
|
253
|
+
* Remark: the method it-self is not const, because of the path compression optimization of the union-find structure,
|
|
254
|
+
* when a column is looked up.
|
|
255
|
+
*
|
|
256
|
+
* @param columnIndex @ref MatIdx index of the column to return.
|
|
257
|
+
* @return Const reference to the column.
|
|
258
|
+
*/
|
|
259
|
+
const Column& get_column(Index columnIndex);
|
|
260
|
+
/**
|
|
261
|
+
* @brief Only available if @ref PersistenceMatrixOptions::has_row_access is true.
|
|
262
|
+
* Returns the row at the given @ref rowindex "row index" of the compressed matrix.
|
|
263
|
+
* The type of the row depends on the chosen options, see @ref PersistenceMatrixOptions::has_intrusive_rows.
|
|
264
|
+
* Note that the row will be from the compressed matrix, that is, the one with only unique columns.
|
|
265
|
+
*
|
|
266
|
+
* @param rowIndex @ref rowindex "Row index" of the row to return.
|
|
267
|
+
* @return Const reference to the row.
|
|
268
|
+
*/
|
|
269
|
+
const Row& get_row(Index rowIndex) const;
|
|
270
|
+
/**
|
|
271
|
+
* @brief If @ref PersistenceMatrixOptions::has_row_access and @ref PersistenceMatrixOptions::has_removable_rows
|
|
272
|
+
* are true: assumes that the row is empty and removes it. Otherwise, does nothing.
|
|
273
|
+
*
|
|
274
|
+
* @warning The removed rows are always assumed to be empty. If it is not the case, the deleted row entries are not
|
|
275
|
+
* removed from their columns. And in the case of intrusive rows, this will generate a segmentation fault when
|
|
276
|
+
* the column entries are destroyed later. The row access is just meant as a "read only" access to the rows and the
|
|
277
|
+
* @ref erase_empty_row method just as a way to specify that a row is empty and can therefore be removed from
|
|
278
|
+
* dictionaries. This allows to avoid testing the emptiness of a row at each column entry removal, what can be
|
|
279
|
+
* quite frequent.
|
|
280
|
+
*
|
|
281
|
+
* @param rowIndex @ref rowindex "Row index" of the empty row.
|
|
282
|
+
*/
|
|
283
|
+
void erase_empty_row(Index rowIndex);
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* @brief Returns the current number of columns in the matrix, counting also the redundant columns.
|
|
287
|
+
*
|
|
288
|
+
* @return The number of columns.
|
|
289
|
+
*/
|
|
290
|
+
Index get_number_of_columns() const;
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* @brief Adds column represented by @p sourceColumn onto the column at @p targetColumnIndex in the matrix.
|
|
294
|
+
*
|
|
295
|
+
* The representatives of redundant columns are summed together, which means that
|
|
296
|
+
* all column compressed together with the target column are affected by the change, not only the target.
|
|
297
|
+
*
|
|
298
|
+
* @tparam Entry_range_or_column_index Either a range of @ref Entry with a begin() and end() method,
|
|
299
|
+
* or any integer type.
|
|
300
|
+
* @param sourceColumn Either an entry range or the @ref MatIdx index of the column to add.
|
|
301
|
+
* @param targetColumnIndex @ref MatIdx index of the target column.
|
|
302
|
+
*/
|
|
303
|
+
template <class Entry_range_or_column_index>
|
|
304
|
+
void add_to(const Entry_range_or_column_index& sourceColumn, Index targetColumnIndex);
|
|
305
|
+
/**
|
|
306
|
+
* @brief Multiplies the target column with the coefficient and then adds the source column to it.
|
|
307
|
+
* That is: `targetColumn = (targetColumn * coefficient) + sourceColumn`.
|
|
308
|
+
*
|
|
309
|
+
* The representatives of redundant columns are summed together, which means that
|
|
310
|
+
* all column compressed together with the target column are affected by the change, not only the target.
|
|
311
|
+
*
|
|
312
|
+
* @tparam Entry_range_or_column_index Either a range of @ref Entry with a begin() and end() method,
|
|
313
|
+
* or any integer type.
|
|
314
|
+
* @param sourceColumn Either a @ref Entry range or the @ref MatIdx index of the column to add.
|
|
315
|
+
* @param coefficient Value to multiply.
|
|
316
|
+
* @param targetColumnIndex @ref MatIdx index of the target column.
|
|
317
|
+
*/
|
|
318
|
+
template <class Entry_range_or_column_index>
|
|
319
|
+
void multiply_target_and_add_to(const Entry_range_or_column_index& sourceColumn,
|
|
320
|
+
const Field_element& coefficient,
|
|
321
|
+
Index targetColumnIndex);
|
|
322
|
+
/**
|
|
323
|
+
* @brief Multiplies the source column with the coefficient before adding it to the target column.
|
|
324
|
+
* That is: `targetColumn += (coefficient * sourceColumn)`. The source column will **not** be modified.
|
|
325
|
+
*
|
|
326
|
+
* The representatives of redundant columns are summed together, which means that
|
|
327
|
+
* all column compressed together with the target column are affected by the change, not only the target.
|
|
328
|
+
*
|
|
329
|
+
* @tparam Entry_range_or_column_index Either a range of @ref Entry with a begin() and end() method,
|
|
330
|
+
* or any integer type.
|
|
331
|
+
* @param coefficient Value to multiply.
|
|
332
|
+
* @param sourceColumn Either a @ref Entry range or the @ref MatIdx index of the column to add.
|
|
333
|
+
* @param targetColumnIndex @ref MatIdx index of the target column.
|
|
334
|
+
*/
|
|
335
|
+
template <class Entry_range_or_column_index>
|
|
336
|
+
void multiply_source_and_add_to(const Field_element& coefficient,
|
|
337
|
+
const Entry_range_or_column_index& sourceColumn,
|
|
338
|
+
Index targetColumnIndex);
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* @brief Indicates if the entry at given coordinates has value zero.
|
|
342
|
+
*
|
|
343
|
+
* @param columnIndex @ref MatIdx index of the column of the entry.
|
|
344
|
+
* @param rowIndex @ref rowindex "Row index" of the row of the entry.
|
|
345
|
+
* @return true If the entry has value zero.
|
|
346
|
+
* @return false Otherwise.
|
|
347
|
+
*/
|
|
348
|
+
bool is_zero_entry(Index columnIndex, Index rowIndex);
|
|
349
|
+
/**
|
|
350
|
+
* @brief Indicates if the column at given index has value zero.
|
|
351
|
+
*
|
|
352
|
+
* @param columnIndex @ref MatIdx index of the column.
|
|
353
|
+
* @return true If the column has value zero.
|
|
354
|
+
* @return false Otherwise.
|
|
355
|
+
*/
|
|
356
|
+
bool is_zero_column(Index columnIndex);
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* @brief Resets the matrix to an empty matrix.
|
|
360
|
+
*
|
|
361
|
+
* @param colSettings Pointer to the entry factory.
|
|
362
|
+
*/
|
|
363
|
+
void reset(Column_settings* colSettings)
|
|
364
|
+
{
|
|
365
|
+
columnToRep_.clear_and_dispose(Delete_disposer(this));
|
|
366
|
+
columnClasses_ = boost::disjoint_sets_with_storage<>();
|
|
367
|
+
repToColumn_.clear();
|
|
368
|
+
nextColumnIndex_ = 0;
|
|
369
|
+
colSettings_ = colSettings;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* @brief Assign operator.
|
|
374
|
+
*/
|
|
375
|
+
Base_matrix_with_column_compression& operator=(const Base_matrix_with_column_compression& other);
|
|
376
|
+
/**
|
|
377
|
+
* @brief Move assign operator.
|
|
378
|
+
*/
|
|
379
|
+
Base_matrix_with_column_compression& operator=(Base_matrix_with_column_compression&& other) noexcept;
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* @brief Swap operator.
|
|
383
|
+
*/
|
|
384
|
+
friend void swap(Base_matrix_with_column_compression& matrix1, Base_matrix_with_column_compression& matrix2) noexcept
|
|
385
|
+
{
|
|
386
|
+
matrix1.columnToRep_.swap(matrix2.columnToRep_);
|
|
387
|
+
std::swap(matrix1.columnClasses_, matrix2.columnClasses_);
|
|
388
|
+
matrix1.repToColumn_.swap(matrix2.repToColumn_);
|
|
389
|
+
std::swap(matrix1.nextColumnIndex_, matrix2.nextColumnIndex_);
|
|
390
|
+
std::swap(matrix1.colSettings_, matrix2.colSettings_);
|
|
391
|
+
std::swap(matrix1.columnPool_, matrix2.columnPool_);
|
|
392
|
+
|
|
393
|
+
if constexpr (Master_matrix::Option_list::has_row_access) {
|
|
394
|
+
swap(static_cast<typename Master_matrix::Matrix_row_access_option&>(matrix1),
|
|
395
|
+
static_cast<typename Master_matrix::Matrix_row_access_option&>(matrix2));
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
void print(); // for debug
|
|
400
|
+
|
|
401
|
+
private:
|
|
402
|
+
/**
|
|
403
|
+
* @brief The disposer object function for boost intrusive container
|
|
404
|
+
*/
|
|
405
|
+
struct Delete_disposer {
|
|
406
|
+
Delete_disposer(Base_matrix_with_column_compression* matrix) : matrix_(matrix) {}
|
|
407
|
+
|
|
408
|
+
void operator()(Column* delete_this) { matrix_->columnPool_->destroy(delete_this); }
|
|
409
|
+
|
|
410
|
+
Base_matrix_with_column_compression* matrix_;
|
|
411
|
+
};
|
|
412
|
+
|
|
413
|
+
using RA_opt = typename Master_matrix::Matrix_row_access_option;
|
|
414
|
+
using Col_dict = boost::intrusive::set<Column, boost::intrusive::constant_time_size<false> >;
|
|
415
|
+
|
|
416
|
+
Col_dict columnToRep_; /**< Map from a column to the index of its representative. */
|
|
417
|
+
boost::disjoint_sets_with_storage<> columnClasses_; /**< Union-find structure,
|
|
418
|
+
where two columns in the same set are identical. */
|
|
419
|
+
std::vector<Column*> repToColumn_; /**< Map from the representative index to
|
|
420
|
+
the representative Column. */
|
|
421
|
+
Index nextColumnIndex_; /**< Next unused column index. */
|
|
422
|
+
Column_settings* colSettings_; /**< Entry factory. */
|
|
423
|
+
/**
|
|
424
|
+
* @brief Column factory. Has to be a pointer as Simple_object_pool is not swappable, so their addresses have to be
|
|
425
|
+
* exchanged instead.
|
|
426
|
+
*/
|
|
427
|
+
std::unique_ptr<Simple_object_pool<Column> > columnPool_;
|
|
428
|
+
inline static const Column empty_column_; /**< Representative for empty columns. */
|
|
429
|
+
|
|
430
|
+
template <class F>
|
|
431
|
+
void _initialize_column(F&& get_column);
|
|
432
|
+
void _insert_column(Index columnIndex);
|
|
433
|
+
void _insert_double_column(Index columnIndex, typename Col_dict::iterator& doubleIt);
|
|
434
|
+
};
|
|
435
|
+
|
|
436
|
+
template <class Master_matrix>
|
|
437
|
+
inline Base_matrix_with_column_compression<Master_matrix>::Base_matrix_with_column_compression(
|
|
438
|
+
Column_settings* colSettings)
|
|
439
|
+
: RA_opt(), nextColumnIndex_(0), colSettings_(colSettings), columnPool_(new Simple_object_pool<Column>)
|
|
440
|
+
{
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
template <class Master_matrix>
|
|
444
|
+
template <class Container>
|
|
445
|
+
inline Base_matrix_with_column_compression<Master_matrix>::Base_matrix_with_column_compression(
|
|
446
|
+
const std::vector<Container>& columns,
|
|
447
|
+
Column_settings* colSettings)
|
|
448
|
+
: RA_opt(columns.size()),
|
|
449
|
+
columnClasses_(columns.size()),
|
|
450
|
+
repToColumn_(columns.size(), nullptr),
|
|
451
|
+
nextColumnIndex_(0),
|
|
452
|
+
colSettings_(colSettings),
|
|
453
|
+
columnPool_(new Simple_object_pool<Column>)
|
|
454
|
+
{
|
|
455
|
+
for (const Container& c : columns) {
|
|
456
|
+
insert_column(c);
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
template <class Master_matrix>
|
|
461
|
+
inline Base_matrix_with_column_compression<Master_matrix>::Base_matrix_with_column_compression(
|
|
462
|
+
unsigned int numberOfColumns,
|
|
463
|
+
Column_settings* colSettings)
|
|
464
|
+
: RA_opt(numberOfColumns),
|
|
465
|
+
columnClasses_(numberOfColumns),
|
|
466
|
+
repToColumn_(numberOfColumns, nullptr),
|
|
467
|
+
nextColumnIndex_(0),
|
|
468
|
+
colSettings_(colSettings),
|
|
469
|
+
columnPool_(new Simple_object_pool<Column>)
|
|
470
|
+
{
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
template <class Master_matrix>
|
|
474
|
+
inline Base_matrix_with_column_compression<Master_matrix>::Base_matrix_with_column_compression(
|
|
475
|
+
const Base_matrix_with_column_compression& matrixToCopy,
|
|
476
|
+
Column_settings* colSettings)
|
|
477
|
+
: RA_opt(static_cast<const RA_opt&>(matrixToCopy)),
|
|
478
|
+
columnClasses_(matrixToCopy.columnClasses_),
|
|
479
|
+
repToColumn_(matrixToCopy.repToColumn_.size(), nullptr),
|
|
480
|
+
nextColumnIndex_(0),
|
|
481
|
+
colSettings_(colSettings == nullptr ? matrixToCopy.colSettings_ : colSettings),
|
|
482
|
+
columnPool_(new Simple_object_pool<Column>)
|
|
483
|
+
{
|
|
484
|
+
for (const Column* col : matrixToCopy.repToColumn_) {
|
|
485
|
+
if (col != nullptr) {
|
|
486
|
+
if constexpr (Master_matrix::Option_list::has_row_access) {
|
|
487
|
+
repToColumn_[nextColumnIndex_] =
|
|
488
|
+
columnPool_->construct(*col, col->get_column_index(), RA_opt::_get_rows_ptr(), colSettings_);
|
|
489
|
+
} else {
|
|
490
|
+
repToColumn_[nextColumnIndex_] = columnPool_->construct(*col, colSettings_);
|
|
491
|
+
}
|
|
492
|
+
columnToRep_.insert(columnToRep_.end(), *repToColumn_[nextColumnIndex_]);
|
|
493
|
+
repToColumn_[nextColumnIndex_]->set_rep(nextColumnIndex_);
|
|
494
|
+
}
|
|
495
|
+
nextColumnIndex_++;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
template <class Master_matrix>
|
|
500
|
+
inline Base_matrix_with_column_compression<Master_matrix>::Base_matrix_with_column_compression(
|
|
501
|
+
Base_matrix_with_column_compression&& other) noexcept
|
|
502
|
+
: RA_opt(std::move(static_cast<RA_opt&>(other))),
|
|
503
|
+
columnToRep_(std::move(other.columnToRep_)),
|
|
504
|
+
columnClasses_(std::move(other.columnClasses_)),
|
|
505
|
+
repToColumn_(std::move(other.repToColumn_)),
|
|
506
|
+
nextColumnIndex_(std::exchange(other.nextColumnIndex_, 0)),
|
|
507
|
+
colSettings_(std::exchange(other.colSettings_, nullptr)),
|
|
508
|
+
columnPool_(std::exchange(other.columnPool_, nullptr))
|
|
509
|
+
{
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
template <class Master_matrix>
|
|
513
|
+
inline Base_matrix_with_column_compression<Master_matrix>::~Base_matrix_with_column_compression()
|
|
514
|
+
{
|
|
515
|
+
columnToRep_.clear_and_dispose(Delete_disposer(this));
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
template <class Master_matrix>
|
|
519
|
+
template <class Container, class>
|
|
520
|
+
inline void Base_matrix_with_column_compression<Master_matrix>::insert_column(const Container& column)
|
|
521
|
+
{
|
|
522
|
+
insert_boundary(column);
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
template <class Master_matrix>
|
|
526
|
+
inline void Base_matrix_with_column_compression<Master_matrix>::insert_column(Index idx)
|
|
527
|
+
{
|
|
528
|
+
static_assert(Master_matrix::Option_list::is_z2,
|
|
529
|
+
"Insertion method not available for Zp != Z2. Please specify the coefficient.");
|
|
530
|
+
|
|
531
|
+
if constexpr (Master_matrix::Option_list::has_row_access && !Master_matrix::Option_list::has_removable_rows) {
|
|
532
|
+
RA_opt::_resize(idx);
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
_initialize_column([&]() -> Column* {
|
|
536
|
+
if constexpr (Master_matrix::Option_list::has_row_access) {
|
|
537
|
+
return columnPool_->construct(nextColumnIndex_, idx, 0, RA_opt::_get_rows_ptr(), colSettings_);
|
|
538
|
+
} else {
|
|
539
|
+
return columnPool_->construct(idx, 0, colSettings_);
|
|
540
|
+
}
|
|
541
|
+
});
|
|
542
|
+
|
|
543
|
+
_insert_column(nextColumnIndex_);
|
|
544
|
+
|
|
545
|
+
nextColumnIndex_++;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
template <class Master_matrix>
|
|
549
|
+
inline void Base_matrix_with_column_compression<Master_matrix>::insert_column(Index idx,
|
|
550
|
+
Field_element e)
|
|
551
|
+
{
|
|
552
|
+
static_assert(!Master_matrix::Option_list::is_z2,
|
|
553
|
+
"Insertion method not available for Zp == Z2. Please do not specify any coefficient.");
|
|
554
|
+
|
|
555
|
+
if constexpr (Master_matrix::Option_list::has_row_access && !Master_matrix::Option_list::has_removable_rows) {
|
|
556
|
+
RA_opt::_resize(idx);
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
_initialize_column([&]() -> Column* {
|
|
560
|
+
if constexpr (Master_matrix::Option_list::has_row_access) {
|
|
561
|
+
return columnPool_->construct(nextColumnIndex_, idx, e, 0, RA_opt::_get_rows_ptr(), colSettings_);
|
|
562
|
+
} else {
|
|
563
|
+
return columnPool_->construct(idx, e, 0, colSettings_);
|
|
564
|
+
}
|
|
565
|
+
});
|
|
566
|
+
|
|
567
|
+
_insert_column(nextColumnIndex_);
|
|
568
|
+
|
|
569
|
+
nextColumnIndex_++;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
template <class Master_matrix>
|
|
573
|
+
template <class Boundary_range>
|
|
574
|
+
inline void Base_matrix_with_column_compression<Master_matrix>::insert_boundary(const Boundary_range& boundary,
|
|
575
|
+
Dimension dim)
|
|
576
|
+
{
|
|
577
|
+
// handles a dimension which is not actually stored.
|
|
578
|
+
// TODO: verify if this is not a problem for the cohomology algorithm and if yes,
|
|
579
|
+
// change how Column_dimension_option is chosen.
|
|
580
|
+
if (dim == Master_matrix::template get_null_value<Dimension>()) dim = boundary.size() == 0 ? 0 : boundary.size() - 1;
|
|
581
|
+
|
|
582
|
+
if constexpr (Master_matrix::Option_list::has_row_access && !Master_matrix::Option_list::has_removable_rows) {
|
|
583
|
+
if (boundary.begin() != boundary.end()) {
|
|
584
|
+
RA_opt::_resize(Master_matrix::get_row_index(*std::prev(boundary.end())));
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
_initialize_column([&]() -> Column* {
|
|
589
|
+
if constexpr (Master_matrix::Option_list::has_row_access) {
|
|
590
|
+
return columnPool_->construct(nextColumnIndex_, boundary, dim, RA_opt::_get_rows_ptr(), colSettings_);
|
|
591
|
+
} else {
|
|
592
|
+
return columnPool_->construct(boundary, dim, colSettings_);
|
|
593
|
+
}
|
|
594
|
+
});
|
|
595
|
+
|
|
596
|
+
_insert_column(nextColumnIndex_);
|
|
597
|
+
|
|
598
|
+
nextColumnIndex_++;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
template <class Master_matrix>
|
|
602
|
+
inline const typename Base_matrix_with_column_compression<Master_matrix>::Column&
|
|
603
|
+
Base_matrix_with_column_compression<Master_matrix>::get_column(Index columnIndex)
|
|
604
|
+
{
|
|
605
|
+
auto col = repToColumn_[columnClasses_.find_set(columnIndex)];
|
|
606
|
+
if (col == nullptr) return empty_column_;
|
|
607
|
+
return *col;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
template <class Master_matrix>
|
|
611
|
+
inline const typename Base_matrix_with_column_compression<Master_matrix>::Row&
|
|
612
|
+
Base_matrix_with_column_compression<Master_matrix>::get_row(Index rowIndex) const
|
|
613
|
+
{
|
|
614
|
+
static_assert(Master_matrix::Option_list::has_row_access, "Row access has to be enabled for this method.");
|
|
615
|
+
|
|
616
|
+
return RA_opt::get_row(rowIndex);
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
template <class Master_matrix>
|
|
620
|
+
inline void Base_matrix_with_column_compression<Master_matrix>::erase_empty_row(Index rowIndex)
|
|
621
|
+
{
|
|
622
|
+
if constexpr (Master_matrix::Option_list::has_row_access && Master_matrix::Option_list::has_removable_rows) {
|
|
623
|
+
RA_opt::erase_empty_row(rowIndex);
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
template <class Master_matrix>
|
|
628
|
+
inline typename Base_matrix_with_column_compression<Master_matrix>::Index
|
|
629
|
+
Base_matrix_with_column_compression<Master_matrix>::get_number_of_columns() const
|
|
630
|
+
{
|
|
631
|
+
return nextColumnIndex_;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
template <class Master_matrix>
|
|
635
|
+
template <class Entry_range_or_column_index>
|
|
636
|
+
inline void Base_matrix_with_column_compression<Master_matrix>::add_to(const Entry_range_or_column_index& sourceColumn,
|
|
637
|
+
Index targetColumnIndex)
|
|
638
|
+
{
|
|
639
|
+
// handle case where targetRep == sourceRep?
|
|
640
|
+
Index targetRep = columnClasses_.find_set(targetColumnIndex);
|
|
641
|
+
Column& target = *repToColumn_[targetRep];
|
|
642
|
+
columnToRep_.erase(target);
|
|
643
|
+
if constexpr (std::is_integral_v<Entry_range_or_column_index>) {
|
|
644
|
+
target += get_column(sourceColumn);
|
|
645
|
+
} else {
|
|
646
|
+
target += sourceColumn;
|
|
647
|
+
}
|
|
648
|
+
_insert_column(targetRep);
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
template <class Master_matrix>
|
|
652
|
+
template <class Entry_range_or_column_index>
|
|
653
|
+
inline void Base_matrix_with_column_compression<Master_matrix>::multiply_target_and_add_to(
|
|
654
|
+
const Entry_range_or_column_index& sourceColumn,
|
|
655
|
+
const Field_element& coefficient,
|
|
656
|
+
Index targetColumnIndex)
|
|
657
|
+
{
|
|
658
|
+
// handle case where targetRep == sourceRep?
|
|
659
|
+
Index targetRep = columnClasses_.find_set(targetColumnIndex);
|
|
660
|
+
Column& target = *repToColumn_[targetRep];
|
|
661
|
+
columnToRep_.erase(target);
|
|
662
|
+
if constexpr (std::is_integral_v<Entry_range_or_column_index>) {
|
|
663
|
+
target.multiply_target_and_add(coefficient, get_column(sourceColumn));
|
|
664
|
+
} else {
|
|
665
|
+
target.multiply_target_and_add(coefficient, sourceColumn);
|
|
666
|
+
}
|
|
667
|
+
_insert_column(targetRep);
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
template <class Master_matrix>
|
|
671
|
+
template <class Entry_range_or_column_index>
|
|
672
|
+
inline void Base_matrix_with_column_compression<Master_matrix>::multiply_source_and_add_to(
|
|
673
|
+
const Field_element& coefficient,
|
|
674
|
+
const Entry_range_or_column_index& sourceColumn,
|
|
675
|
+
Index targetColumnIndex)
|
|
676
|
+
{
|
|
677
|
+
// handle case where targetRep == sourceRep?
|
|
678
|
+
Index targetRep = columnClasses_.find_set(targetColumnIndex);
|
|
679
|
+
Column& target = *repToColumn_[targetRep];
|
|
680
|
+
columnToRep_.erase(target);
|
|
681
|
+
if constexpr (std::is_integral_v<Entry_range_or_column_index>) {
|
|
682
|
+
target.multiply_source_and_add(get_column(sourceColumn), coefficient);
|
|
683
|
+
} else {
|
|
684
|
+
target.multiply_source_and_add(sourceColumn, coefficient);
|
|
685
|
+
}
|
|
686
|
+
_insert_column(targetRep);
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
template <class Master_matrix>
|
|
690
|
+
inline bool Base_matrix_with_column_compression<Master_matrix>::is_zero_entry(Index columnIndex, Index rowIndex)
|
|
691
|
+
{
|
|
692
|
+
auto col = repToColumn_[columnClasses_.find_set(columnIndex)];
|
|
693
|
+
if (col == nullptr) return true;
|
|
694
|
+
return !col->is_non_zero(rowIndex);
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
template <class Master_matrix>
|
|
698
|
+
inline bool Base_matrix_with_column_compression<Master_matrix>::is_zero_column(Index columnIndex)
|
|
699
|
+
{
|
|
700
|
+
auto col = repToColumn_[columnClasses_.find_set(columnIndex)];
|
|
701
|
+
if (col == nullptr) return true;
|
|
702
|
+
return col->is_empty();
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
template <class Master_matrix>
|
|
706
|
+
inline Base_matrix_with_column_compression<Master_matrix>&
|
|
707
|
+
Base_matrix_with_column_compression<Master_matrix>::operator=(const Base_matrix_with_column_compression& other)
|
|
708
|
+
{
|
|
709
|
+
if (this == &other) return *this;
|
|
710
|
+
|
|
711
|
+
for (auto col : repToColumn_) {
|
|
712
|
+
if (col != nullptr) {
|
|
713
|
+
columnPool_->destroy(col);
|
|
714
|
+
col = nullptr;
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
RA_opt::operator=(other);
|
|
718
|
+
columnClasses_ = other.columnClasses_;
|
|
719
|
+
columnToRep_.reserve(other.columnToRep_.size());
|
|
720
|
+
repToColumn_.resize(other.repToColumn_.size(), nullptr);
|
|
721
|
+
nextColumnIndex_ = 0;
|
|
722
|
+
colSettings_ = other.colSettings_;
|
|
723
|
+
for (const Column* col : other.repToColumn_) {
|
|
724
|
+
if constexpr (Master_matrix::Option_list::has_row_access) {
|
|
725
|
+
repToColumn_[nextColumnIndex_] =
|
|
726
|
+
columnPool_->construct(*col, col->get_column_index(), RA_opt::_get_rows_ptr(), colSettings_);
|
|
727
|
+
} else {
|
|
728
|
+
repToColumn_[nextColumnIndex_] = columnPool_->construct(*col, colSettings_);
|
|
729
|
+
}
|
|
730
|
+
columnToRep_.insert(columnToRep_.end(), *repToColumn_[nextColumnIndex_]);
|
|
731
|
+
repToColumn_[nextColumnIndex_]->set_rep(nextColumnIndex_);
|
|
732
|
+
nextColumnIndex_++;
|
|
733
|
+
}
|
|
734
|
+
return *this;
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
template <class Master_matrix>
|
|
738
|
+
inline Base_matrix_with_column_compression<Master_matrix>&
|
|
739
|
+
Base_matrix_with_column_compression<Master_matrix>::operator=(Base_matrix_with_column_compression&& other) noexcept
|
|
740
|
+
{
|
|
741
|
+
if (&repToColumn_ == &(other.repToColumn_)) return *this;
|
|
742
|
+
|
|
743
|
+
RA_opt::operator=(std::move(other));
|
|
744
|
+
|
|
745
|
+
columnToRep_.clear_and_dispose(Delete_disposer(this));
|
|
746
|
+
|
|
747
|
+
columnToRep_ = std::move(other.columnToRep_);
|
|
748
|
+
columnClasses_ = std::move(other.columnClasses_);
|
|
749
|
+
repToColumn_ = std::move(other.repToColumn_);
|
|
750
|
+
nextColumnIndex_ = std::exchange(other.nextColumnIndex_, 0);
|
|
751
|
+
colSettings_ = std::exchange(other.colSettings_, nullptr);
|
|
752
|
+
columnPool_ = std::exchange(other.columnPool_, nullptr);
|
|
753
|
+
|
|
754
|
+
return *this;
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
template <class Master_matrix>
|
|
758
|
+
inline void Base_matrix_with_column_compression<Master_matrix>::print()
|
|
759
|
+
{
|
|
760
|
+
std::cout << "Compressed_matrix:\n";
|
|
761
|
+
for (Column& col : columnToRep_) {
|
|
762
|
+
for (auto e : col->get_content(nextColumnIndex_)) {
|
|
763
|
+
if (e == 0U)
|
|
764
|
+
std::cout << "- ";
|
|
765
|
+
else
|
|
766
|
+
std::cout << e << " ";
|
|
767
|
+
}
|
|
768
|
+
std::cout << "(";
|
|
769
|
+
for (Index i = 0; i < nextColumnIndex_; ++i) {
|
|
770
|
+
if (columnClasses_.find_set(i) == col.get_rep()) std::cout << i << " ";
|
|
771
|
+
}
|
|
772
|
+
std::cout << ")\n";
|
|
773
|
+
}
|
|
774
|
+
std::cout << "\n";
|
|
775
|
+
std::cout << "Row Matrix:\n";
|
|
776
|
+
for (Index i = 0; i < RA_opt::_get_rows_ptr()->size(); ++i) {
|
|
777
|
+
const Row& row = RA_opt::get_row(i);
|
|
778
|
+
for (const auto& entry : row) {
|
|
779
|
+
std::cout << entry.get_column_index() << " ";
|
|
780
|
+
}
|
|
781
|
+
std::cout << "(" << i << ")\n";
|
|
782
|
+
}
|
|
783
|
+
std::cout << "\n";
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
template <class Master_matrix>
|
|
787
|
+
template <class F>
|
|
788
|
+
inline void Base_matrix_with_column_compression<Master_matrix>::_initialize_column(F&& get_column)
|
|
789
|
+
{
|
|
790
|
+
if (repToColumn_.size() == nextColumnIndex_) {
|
|
791
|
+
// could perhaps be avoided, if find_set returns something special when it does not find
|
|
792
|
+
columnClasses_.link(nextColumnIndex_, nextColumnIndex_);
|
|
793
|
+
repToColumn_.push_back(std::forward<F>(get_column)());
|
|
794
|
+
} else {
|
|
795
|
+
repToColumn_[nextColumnIndex_] = std::forward<F>(get_column)();
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
template <class Master_matrix>
|
|
800
|
+
inline void Base_matrix_with_column_compression<Master_matrix>::_insert_column(Index columnIndex)
|
|
801
|
+
{
|
|
802
|
+
Column& col = *repToColumn_[columnIndex];
|
|
803
|
+
|
|
804
|
+
if (col.is_empty()) {
|
|
805
|
+
columnPool_->destroy(&col); // delete curr_col;
|
|
806
|
+
repToColumn_[columnIndex] = nullptr;
|
|
807
|
+
return;
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
col.set_rep(columnIndex);
|
|
811
|
+
auto res = columnToRep_.insert(col);
|
|
812
|
+
if (res.first->get_rep() != columnIndex) { // if true, then redundant column
|
|
813
|
+
_insert_double_column(columnIndex, res.first);
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
template <class Master_matrix>
|
|
818
|
+
inline void Base_matrix_with_column_compression<Master_matrix>::_insert_double_column(
|
|
819
|
+
Index columnIndex,
|
|
820
|
+
typename Col_dict::iterator& doubleIt)
|
|
821
|
+
{
|
|
822
|
+
Index doubleRep = doubleIt->get_rep();
|
|
823
|
+
columnClasses_.link(columnIndex, doubleRep); // both should be representatives
|
|
824
|
+
Index newRep = columnClasses_.find_set(columnIndex);
|
|
825
|
+
|
|
826
|
+
columnPool_->destroy(repToColumn_[columnIndex]);
|
|
827
|
+
repToColumn_[columnIndex] = nullptr;
|
|
828
|
+
|
|
829
|
+
if (newRep == columnIndex) {
|
|
830
|
+
std::swap(repToColumn_[doubleRep], repToColumn_[columnIndex]);
|
|
831
|
+
doubleIt->set_rep(columnIndex);
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
} // namespace persistence_matrix
|
|
836
|
+
} // namespace Gudhi
|
|
837
|
+
|
|
838
|
+
#endif // PM_BASE_MATRIX_COMPRESSION_H
|