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,485 @@
|
|
|
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): David Loiseaux
|
|
4
|
+
*
|
|
5
|
+
* Copyright (C) 2023 Inria
|
|
6
|
+
*
|
|
7
|
+
* Modification(s):
|
|
8
|
+
* - 2025/04 Hannah Schreiber: Reorganization + documentation.
|
|
9
|
+
* - YYYY/MM Author: Description of the modification
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @file Multi_parameter_filtered_complex.h
|
|
14
|
+
* @author David Loiseaux
|
|
15
|
+
* @brief Contains the @ref Gudhi::multi_persistence::Multi_parameter_filtered_complex class.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
#ifndef MP_FILTERED_COMPLEX_H_INCLUDED
|
|
19
|
+
#define MP_FILTERED_COMPLEX_H_INCLUDED
|
|
20
|
+
|
|
21
|
+
#include <cstdint> //std::uint32_t
|
|
22
|
+
#include <algorithm>
|
|
23
|
+
#include <numeric>
|
|
24
|
+
#include <ostream>
|
|
25
|
+
#include <stdexcept>
|
|
26
|
+
#include <utility>
|
|
27
|
+
#include <vector>
|
|
28
|
+
|
|
29
|
+
#include <gudhi/Debug_utils.h>
|
|
30
|
+
#include <gudhi/Multi_parameter_filtration.h> //for lex order
|
|
31
|
+
#include <gudhi/Multi_filtration/multi_filtration_conversions.h>
|
|
32
|
+
#include <oneapi/tbb/parallel_for.h>
|
|
33
|
+
|
|
34
|
+
namespace Gudhi {
|
|
35
|
+
namespace multi_persistence {
|
|
36
|
+
|
|
37
|
+
// TODO: better name
|
|
38
|
+
/**
|
|
39
|
+
* @class Multi_parameter_filtered_complex Multi_parameter_filtered_complex.h gudhi/Multi_parameter_filtered_complex.h
|
|
40
|
+
* @ingroup multi_persistence
|
|
41
|
+
*
|
|
42
|
+
* @brief Class storing the boundaries, the dimensions and the filtration values of all cells composing a complex.
|
|
43
|
+
*
|
|
44
|
+
* @tparam MultiFiltrationValue Filtration value class respecting the @ref MultiFiltrationValue concept.
|
|
45
|
+
*/
|
|
46
|
+
template <class MultiFiltrationValue>
|
|
47
|
+
class Multi_parameter_filtered_complex
|
|
48
|
+
{
|
|
49
|
+
public:
|
|
50
|
+
using Index = std::uint32_t; /**< Complex index type. */
|
|
51
|
+
using Filtration_value = MultiFiltrationValue; /**< Filtration value type. */
|
|
52
|
+
using T = typename Filtration_value::value_type; /**< Numerical type of an element in a filtration value. */
|
|
53
|
+
using Filtration_value_container = std::vector<Filtration_value>; /**< Filtration value container type. */
|
|
54
|
+
using Boundary = std::vector<Index>; /**< Cell boundary type, represented by the complex indices of its faces. */
|
|
55
|
+
using Boundary_container = std::vector<Boundary>; /**< Boundary container type. */
|
|
56
|
+
using Dimension = int; /**< Dimension type. */
|
|
57
|
+
using Dimension_container = std::vector<Dimension>; /**< Dimension container type. */
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* @brief Default constructor. Constructs an empty complex.
|
|
61
|
+
*/
|
|
62
|
+
Multi_parameter_filtered_complex() : filtrationValues_(), maxDimension_(-1), isOrderedByDimension_(true) {}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* @brief Constructs the complex by copying all three given containers into the class.
|
|
66
|
+
*
|
|
67
|
+
* @param boundaries Container of boundaries. A boundary has to be described by the indices of its faces in this
|
|
68
|
+
* container. E.g., if a vertex \f$ v \f$ is stored at index \f$ i \f$ and another vertex at index \f$ j \f$, then
|
|
69
|
+
* `boundaries[i]` and `boundaries[j]` are both empty and if the edge \f$ (v,u) \f$ is at index \f$ k \f$, then
|
|
70
|
+
* `boundaries[k]` is equal to `{i, j}`. All boundaries are expected to be ordered by increasing index value.
|
|
71
|
+
* @param dimensions Dimension container. The value at index \f$ i \f$ has to correspond to the dimension of the
|
|
72
|
+
* cell at index \f$ i \f$ in `boundaries`.
|
|
73
|
+
* @param filtrationValues Filtration value container. The value at index \f$ i \f$ has to correspond to the
|
|
74
|
+
* filtration value of the cell at index \f$ i \f$ in `boundaries`.
|
|
75
|
+
*/
|
|
76
|
+
Multi_parameter_filtered_complex(const Boundary_container& boundaries,
|
|
77
|
+
const Dimension_container& dimensions,
|
|
78
|
+
const Filtration_value_container& filtrationValues)
|
|
79
|
+
: boundaries_(boundaries),
|
|
80
|
+
dimensions_(dimensions),
|
|
81
|
+
filtrationValues_(filtrationValues),
|
|
82
|
+
maxDimension_(-1),
|
|
83
|
+
isOrderedByDimension_(false)
|
|
84
|
+
{
|
|
85
|
+
_initialize_dimension_utils();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* @brief Constructs the complex by moving all three given containers to the class.
|
|
90
|
+
*
|
|
91
|
+
* @param boundaries Container of boundaries. A boundary has to be described by the indices of its faces in this
|
|
92
|
+
* container. E.g., if a vertex \f$ v \f$ is stored at index \f$ i \f$ and another vertex at index \f$ j \f$, then
|
|
93
|
+
* `boundaries[i]` and `boundaries[j]` are both empty and if the edge \f$ (v,u) \f$ is at index \f$ k \f$, then
|
|
94
|
+
* `boundaries[k]` is equal to `{i, j}`. All boundaries are expected to be ordered by increasing index value.
|
|
95
|
+
* @param dimensions Dimension container. The value at index \f$ i \f$ has to correspond to the dimension of the
|
|
96
|
+
* cell at index \f$ i \f$ in `boundaries`.
|
|
97
|
+
* @param filtrationValues Filtration value container. The value at index \f$ i \f$ has to correspond to the
|
|
98
|
+
* filtration value of the cell at index \f$ i \f$ in `boundaries`.
|
|
99
|
+
*/
|
|
100
|
+
Multi_parameter_filtered_complex(Boundary_container&& boundaries,
|
|
101
|
+
Dimension_container&& dimensions,
|
|
102
|
+
Filtration_value_container&& filtrationValues)
|
|
103
|
+
: boundaries_(std::move(boundaries)),
|
|
104
|
+
dimensions_(std::move(dimensions)),
|
|
105
|
+
filtrationValues_(std::move(filtrationValues)),
|
|
106
|
+
maxDimension_(0),
|
|
107
|
+
isOrderedByDimension_(false)
|
|
108
|
+
{
|
|
109
|
+
_initialize_dimension_utils();
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* @brief Copy constructor.
|
|
114
|
+
*/
|
|
115
|
+
Multi_parameter_filtered_complex(const Multi_parameter_filtered_complex& complex) = default;
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* @brief Copy constructor.
|
|
119
|
+
*/
|
|
120
|
+
template <class OtherFiltrationValue>
|
|
121
|
+
Multi_parameter_filtered_complex(const Multi_parameter_filtered_complex<OtherFiltrationValue>& complex)
|
|
122
|
+
: boundaries_(complex.get_boundaries()),
|
|
123
|
+
dimensions_(complex.get_dimensions()),
|
|
124
|
+
filtrationValues_(complex.get_filtration_values().size()),
|
|
125
|
+
maxDimension_(complex.get_max_dimension()),
|
|
126
|
+
isOrderedByDimension_(complex.is_ordered_by_dimension())
|
|
127
|
+
{
|
|
128
|
+
const auto& fils = complex.get_filtration_values();
|
|
129
|
+
for (Index i = 0; i < filtrationValues_.size(); ++i) {
|
|
130
|
+
filtrationValues_[i] = multi_filtration::as_type<MultiFiltrationValue>(fils[i]);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* @brief Move constructor.
|
|
136
|
+
*/
|
|
137
|
+
Multi_parameter_filtered_complex(Multi_parameter_filtered_complex&& complex) noexcept = default;
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* @brief Destructor.
|
|
141
|
+
*/
|
|
142
|
+
~Multi_parameter_filtered_complex() = default;
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* @brief Assign operator.
|
|
146
|
+
*/
|
|
147
|
+
Multi_parameter_filtered_complex& operator=(const Multi_parameter_filtered_complex& other) = default;
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* @brief Assign operator.
|
|
151
|
+
*/
|
|
152
|
+
template <class OtherFiltrationValue>
|
|
153
|
+
Multi_parameter_filtered_complex& operator=(const Multi_parameter_filtered_complex<OtherFiltrationValue>& other)
|
|
154
|
+
{
|
|
155
|
+
boundaries_ = other.get_boundaries();
|
|
156
|
+
dimensions_ = other.get_dimensions();
|
|
157
|
+
const auto& fils = other.get_filtration_values();
|
|
158
|
+
filtrationValues_ = Filtration_value_container(fils.size());
|
|
159
|
+
for (Index i = 0; i < filtrationValues_.size(); ++i) {
|
|
160
|
+
filtrationValues_[i] = multi_filtration::as_type<MultiFiltrationValue>(fils[i]);
|
|
161
|
+
}
|
|
162
|
+
maxDimension_ = other.get_max_dimension();
|
|
163
|
+
isOrderedByDimension_ = other.is_ordered_by_dimension();
|
|
164
|
+
|
|
165
|
+
return *this;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* @brief Move assign operator.
|
|
170
|
+
*/
|
|
171
|
+
Multi_parameter_filtered_complex& operator=(Multi_parameter_filtered_complex&& other) noexcept = default;
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* @brief Returns the number of cells in the complex.
|
|
175
|
+
*/
|
|
176
|
+
[[nodiscard]] Index get_number_of_cycle_generators() const { return boundaries_.size(); }
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* @brief Returns the number of parameters in the filtration.
|
|
180
|
+
*/
|
|
181
|
+
[[nodiscard]] Index get_number_of_parameters() const
|
|
182
|
+
{
|
|
183
|
+
if (filtrationValues_.empty()) return 0;
|
|
184
|
+
return filtrationValues_[0].num_parameters();
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* @brief Returns true if and only if the boundaries are ordered by dimension. That is, if an index increases,
|
|
189
|
+
* the represented cell at the new index can only have same or higher dimension than the cell at the index before.
|
|
190
|
+
*/
|
|
191
|
+
[[nodiscard]] bool is_ordered_by_dimension() const { return isOrderedByDimension_; }
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* @brief Returns a const reference to the filtration value container.
|
|
195
|
+
*/
|
|
196
|
+
const Filtration_value_container& get_filtration_values() const { return filtrationValues_; }
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* @brief Returns a reference to the filtration value container.
|
|
200
|
+
* @warning The container is not const such that the user can easily modify/update a filtration value. But do not
|
|
201
|
+
* modify the size of the container, its indices have still to correspond to the indices in the other containers.
|
|
202
|
+
*/
|
|
203
|
+
Filtration_value_container& get_filtration_values() { return filtrationValues_; }
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* @brief Returns a const reference to the dimension container.
|
|
207
|
+
*/
|
|
208
|
+
[[nodiscard]] const Dimension_container& get_dimensions() const { return dimensions_; }
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* @brief Returns a const reference to the boundary container.
|
|
212
|
+
*/
|
|
213
|
+
[[nodiscard]] const Boundary_container& get_boundaries() const { return boundaries_; }
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* @brief Returns the maximal dimension of a cell in the complex.
|
|
217
|
+
*/
|
|
218
|
+
[[nodiscard]] Dimension get_max_dimension() const { return maxDimension_; }
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* @brief Sorts the container internally such that the cells are ordered first by dimension and then
|
|
222
|
+
* co-lexicographically by filtration values. If two cells have same dimension and same filtration value, they are
|
|
223
|
+
* considered equal (i.e., they relative position from each other does not matter).
|
|
224
|
+
* Note that the indices of the cells changes therefore.
|
|
225
|
+
*/
|
|
226
|
+
void sort_by_dimension_co_lexicographically()
|
|
227
|
+
{
|
|
228
|
+
using namespace Gudhi::multi_filtration;
|
|
229
|
+
|
|
230
|
+
sort([&](Index i, Index j) -> bool {
|
|
231
|
+
if (dimensions_[i] == dimensions_[j]) {
|
|
232
|
+
return is_strict_less_than_lexicographically<true>(filtrationValues_[i], filtrationValues_[j]);
|
|
233
|
+
}
|
|
234
|
+
return dimensions_[i] < dimensions_[j];
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* @brief Sorts the internal containers using the given comparaison method.
|
|
240
|
+
* Note that the indices of the cells changes therefore.
|
|
241
|
+
*
|
|
242
|
+
* @tparam Comp Method type with signature (Index, Index)->bool.
|
|
243
|
+
* @param comparaison Method taking two complex indices (those before the sort) as input and returns true if and
|
|
244
|
+
* only if the cell at the first index is supposed to be placed before the cell at the second index.
|
|
245
|
+
*/
|
|
246
|
+
template <typename Comp>
|
|
247
|
+
void sort(Comp&& comparaison)
|
|
248
|
+
{
|
|
249
|
+
// TODO: test if it is not faster to just reconstruct everything instead of swapping
|
|
250
|
+
// Note: perm and inv have to be build in any case
|
|
251
|
+
// if we reconstruct, we additionally build three containers of vector of Index, of Index
|
|
252
|
+
// and of Filtration_value, which will be swapped respectively with boundaries_, dimensions_
|
|
253
|
+
// and filtrationValues_
|
|
254
|
+
// in this version (swapping), we additionally build two containers of Index instead
|
|
255
|
+
// so should theoretically be better, but not so sure if we replace the containers with
|
|
256
|
+
// completely flat containers one day, i.e. with no cheap swap method
|
|
257
|
+
std::vector<Index> perm(boundaries_.size());
|
|
258
|
+
std::iota(perm.begin(), perm.end(), 0);
|
|
259
|
+
std::vector<Index> pos = perm;
|
|
260
|
+
std::vector<Index> invPos = perm;
|
|
261
|
+
std::sort(perm.begin(), perm.end(), std::forward<Comp>(comparaison));
|
|
262
|
+
std::vector<Index> invPerm(boundaries_.size());
|
|
263
|
+
for (Index i = 0; i < perm.size(); ++i) invPerm[perm[i]] = i;
|
|
264
|
+
|
|
265
|
+
Dimension lastDim = -1;
|
|
266
|
+
isOrderedByDimension_ = true;
|
|
267
|
+
|
|
268
|
+
for (Index curr = 0; curr < perm.size(); ++curr) {
|
|
269
|
+
Index p = perm[curr];
|
|
270
|
+
Index i = pos[p];
|
|
271
|
+
if (i != curr) {
|
|
272
|
+
GUDHI_CHECK(curr < i, std::runtime_error("Got curr " + std::to_string(curr) + " >= i " + std::to_string(i)));
|
|
273
|
+
std::swap(boundaries_[curr], boundaries_[i]);
|
|
274
|
+
std::swap(dimensions_[curr], dimensions_[i]);
|
|
275
|
+
swap(filtrationValues_[curr], filtrationValues_[i]);
|
|
276
|
+
std::swap(pos[invPos[curr]], pos[p]);
|
|
277
|
+
std::swap(invPos[curr], invPos[pos[invPos[curr]]]);
|
|
278
|
+
}
|
|
279
|
+
for (Index& b : boundaries_[curr]) b = invPerm[b];
|
|
280
|
+
std::sort(boundaries_[curr].begin(), boundaries_[curr].end());
|
|
281
|
+
if (lastDim > dimensions_[curr]) isOrderedByDimension_ = false;
|
|
282
|
+
lastDim = dimensions_[curr];
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* @brief Removes completely from the complex all cells of dimension strictly higher than given.
|
|
288
|
+
*
|
|
289
|
+
* @warning If @ref is_ordered_by_dimension does not return true, the complex is sorted by dimension before pruning.
|
|
290
|
+
* So, the indexing changes afterwards.
|
|
291
|
+
*
|
|
292
|
+
* @param maxDim Maximal dimension to keep.
|
|
293
|
+
* @return Number of remaining cells in the complex.
|
|
294
|
+
*/
|
|
295
|
+
Index prune_above_dimension(int maxDim)
|
|
296
|
+
{
|
|
297
|
+
if (!isOrderedByDimension_) sort_by_dimension_co_lexicographically();
|
|
298
|
+
Index i = 0;
|
|
299
|
+
while (i < dimensions_.size() && dimensions_[i] < maxDim + 1) ++i;
|
|
300
|
+
boundaries_.resize(i);
|
|
301
|
+
dimensions_.resize(i);
|
|
302
|
+
filtrationValues_.resize(i);
|
|
303
|
+
maxDimension_ = dimensions_.empty() ? -1 : dimensions_.back();
|
|
304
|
+
return i;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* @brief Projects all filtration values into the given grid. If @p coordinate is false, the entries are set to
|
|
309
|
+
* the nearest upper bound value with the same parameter in the grid. Otherwise, the entries are set to the indices
|
|
310
|
+
* of those nearest upper bound values.
|
|
311
|
+
* An index \f$ i \f$ of the grid corresponds to the same parameter as the index \f$ i \f$ in a generator of the
|
|
312
|
+
* filtration value. The internal vectors correspond to the possible values of the parameters, ordered by increasing
|
|
313
|
+
* value, forming therefore all together a 2D grid.
|
|
314
|
+
*
|
|
315
|
+
* @param grid Vector of vector with size at least number of filtration parameters.
|
|
316
|
+
* @param coordinate If true, the values are set to the coordinates of the projection in the grid. If false,
|
|
317
|
+
* the values are set to the values at the coordinates of the projection.
|
|
318
|
+
*/
|
|
319
|
+
void coarsen_on_grid(const std::vector<std::vector<T> >& grid, bool coordinate = true)
|
|
320
|
+
{
|
|
321
|
+
// for (auto gen = 0U; gen < filtrationValues_.size(); ++gen) {
|
|
322
|
+
// filtrationValues_[gen].project_onto_grid(grid, coordinate);
|
|
323
|
+
// }
|
|
324
|
+
tbb::parallel_for(Index(0), Index(filtrationValues_.size()), [&](Index gen) {
|
|
325
|
+
// TODO : preallocate for tbb
|
|
326
|
+
filtrationValues_[gen].project_onto_grid(grid, coordinate);
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* @brief Builds a new complex by reordering the cells in the given complex with the given permutation map.
|
|
333
|
+
*/
|
|
334
|
+
friend Multi_parameter_filtered_complex build_permuted_complex(const Multi_parameter_filtered_complex& complex,
|
|
335
|
+
const std::vector<Index>& permutation)
|
|
336
|
+
{
|
|
337
|
+
if (permutation.size() > complex.get_number_of_cycle_generators())
|
|
338
|
+
throw std::invalid_argument("Invalid permutation size.");
|
|
339
|
+
|
|
340
|
+
const Index nullIndex = -1;
|
|
341
|
+
std::vector<Index> inv(complex.get_number_of_cycle_generators(), nullIndex);
|
|
342
|
+
for (Index i = 0; i < permutation.size(); ++i) inv[permutation[i]] = i;
|
|
343
|
+
|
|
344
|
+
Boundary_container newBoundaries;
|
|
345
|
+
newBoundaries.reserve(permutation.size());
|
|
346
|
+
Dimension_container newDimensions;
|
|
347
|
+
newDimensions.reserve(permutation.size());
|
|
348
|
+
Filtration_value_container newFiltrationValues;
|
|
349
|
+
newBoundaries.reserve(permutation.size());
|
|
350
|
+
|
|
351
|
+
for (Index i : permutation) {
|
|
352
|
+
Boundary boundary;
|
|
353
|
+
for (Index b : complex.boundaries_[i]) {
|
|
354
|
+
if (inv[b] != nullIndex) boundary.push_back(inv[b]);
|
|
355
|
+
}
|
|
356
|
+
std::sort(boundary.begin(), boundary.end());
|
|
357
|
+
newBoundaries.emplace_back(std::move(boundary));
|
|
358
|
+
newDimensions.push_back(complex.dimensions_[i]);
|
|
359
|
+
newFiltrationValues.emplace_back(complex.filtrationValues_[i]);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
return Multi_parameter_filtered_complex(
|
|
363
|
+
std::move(newBoundaries), std::move(newDimensions), std::move(newFiltrationValues));
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* @brief Builds a new complex by reordering the cells in the given complex the same way than
|
|
368
|
+
* @ref sort_by_dimension_co_lexicographically. Returns a pair with the new complex as first element and the
|
|
369
|
+
* permutation map used as second element.
|
|
370
|
+
*/
|
|
371
|
+
friend std::pair<Multi_parameter_filtered_complex, std::vector<Index> > build_permuted_complex(
|
|
372
|
+
const Multi_parameter_filtered_complex& complex)
|
|
373
|
+
{
|
|
374
|
+
using namespace Gudhi::multi_filtration;
|
|
375
|
+
|
|
376
|
+
std::vector<Index> perm(complex.get_number_of_cycle_generators());
|
|
377
|
+
std::iota(perm.begin(), perm.end(), 0);
|
|
378
|
+
std::sort(perm.begin(), perm.end(), [&](Index i, Index j) -> bool {
|
|
379
|
+
if (complex.dimensions_[i] == complex.dimensions_[j]) {
|
|
380
|
+
return is_strict_less_than_lexicographically<true>(complex.filtrationValues_[i], complex.filtrationValues_[j]);
|
|
381
|
+
}
|
|
382
|
+
return complex.dimensions_[i] < complex.dimensions_[j];
|
|
383
|
+
});
|
|
384
|
+
auto out = build_permuted_complex(complex, perm);
|
|
385
|
+
return std::make_pair(std::move(out), std::move(perm));
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* @brief Builds a new complex from the given one by projecting its filtration values on a grid.
|
|
390
|
+
* See @ref coarsen_on_grid with the paramater `coordinate` at true.
|
|
391
|
+
*/
|
|
392
|
+
friend auto build_complex_coarsen_on_grid(const Multi_parameter_filtered_complex& complex,
|
|
393
|
+
const std::vector<std::vector<T> >& grid)
|
|
394
|
+
{
|
|
395
|
+
using namespace Gudhi::multi_filtration;
|
|
396
|
+
using Return_filtration_value = decltype(std::declval<Filtration_value>().template as_type<std::int32_t>());
|
|
397
|
+
using Return_complex = Multi_parameter_filtered_complex<Return_filtration_value>;
|
|
398
|
+
|
|
399
|
+
typename Return_complex::Filtration_value_container coords(complex.get_number_of_cycle_generators());
|
|
400
|
+
for (Index gen = 0U; gen < coords.size(); ++gen) {
|
|
401
|
+
coords[gen] = compute_coordinates_in_grid<std::int32_t>(complex.filtrationValues_[gen], grid);
|
|
402
|
+
}
|
|
403
|
+
return Return_complex(complex.boundaries_, complex.dimensions_, coords);
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
// /**
|
|
407
|
+
// * @brief Compares two boundaries and returns true if and only if the size of the first is strictly smaller than
|
|
408
|
+
// the
|
|
409
|
+
// * second, or, if the two sizes are the same, the first is lexicographically strictly smaller than the second.
|
|
410
|
+
// * The boundaries are assumed to be ordered by increasing values.
|
|
411
|
+
// */
|
|
412
|
+
// static bool boundary_is_strictly_smaller_than(const Boundary& b1, const Boundary& b2) {
|
|
413
|
+
// // we want faces to be smaller than proper cofaces
|
|
414
|
+
// if (b1.size() < b2.size()) return true;
|
|
415
|
+
// if (b1.size() > b2.size()) return false;
|
|
416
|
+
|
|
417
|
+
// // lexico for others
|
|
418
|
+
// for (Index i = 0; i < b2.size(); ++i){
|
|
419
|
+
// if (b1[i] < b2[i]) return true;
|
|
420
|
+
// if (b1[i] > b2[i]) return false;
|
|
421
|
+
// }
|
|
422
|
+
|
|
423
|
+
// // equal
|
|
424
|
+
// return false;
|
|
425
|
+
// }
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* @brief Outstream operator.
|
|
429
|
+
*/
|
|
430
|
+
friend std::ostream& operator<<(std::ostream& stream, const Multi_parameter_filtered_complex& complex)
|
|
431
|
+
{
|
|
432
|
+
stream << "Boundary:\n";
|
|
433
|
+
stream << "{\n";
|
|
434
|
+
for (Index i = 0; i < complex.boundaries_.size(); ++i) {
|
|
435
|
+
const auto& boundary = complex.boundaries_[i];
|
|
436
|
+
stream << i << ": {";
|
|
437
|
+
for (auto b : boundary) stream << b << ", ";
|
|
438
|
+
if (!boundary.empty()) stream << "\b" << "\b ";
|
|
439
|
+
stream << "},\n";
|
|
440
|
+
}
|
|
441
|
+
stream << "}\n";
|
|
442
|
+
|
|
443
|
+
stream << "Dimensions: (max " << complex.get_max_dimension() << ")\n";
|
|
444
|
+
stream << "{";
|
|
445
|
+
for (auto d : complex.dimensions_) stream << d << ", ";
|
|
446
|
+
if (!complex.dimensions_.empty()) {
|
|
447
|
+
stream << "\b" << "\b";
|
|
448
|
+
}
|
|
449
|
+
stream << "}\n";
|
|
450
|
+
|
|
451
|
+
stream << "Filtration values:\n";
|
|
452
|
+
stream << "{\n";
|
|
453
|
+
for (auto f : complex.filtrationValues_) stream << f << "\n";
|
|
454
|
+
stream << "}\n";
|
|
455
|
+
|
|
456
|
+
return stream;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
private:
|
|
460
|
+
Boundary_container boundaries_; /**< Boundary container. */
|
|
461
|
+
Dimension_container dimensions_; /**< Dimension container. */
|
|
462
|
+
Filtration_value_container filtrationValues_; /**< Filtration value container. */
|
|
463
|
+
Dimension maxDimension_; /**< Maximal dimension of a cell. */
|
|
464
|
+
bool isOrderedByDimension_; /**< True if and only if the containers are ordered by dimension. */
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* @brief Initializes maxDimension_ and isOrderedByDimension_
|
|
468
|
+
*/
|
|
469
|
+
void _initialize_dimension_utils()
|
|
470
|
+
{
|
|
471
|
+
isOrderedByDimension_ = true;
|
|
472
|
+
if (dimensions_.empty()) return;
|
|
473
|
+
|
|
474
|
+
for (Index i = 0; i < dimensions_.size() - 1; ++i) {
|
|
475
|
+
maxDimension_ = std::max(dimensions_[i], maxDimension_);
|
|
476
|
+
if (dimensions_[i] > dimensions_[i + 1]) isOrderedByDimension_ = false;
|
|
477
|
+
}
|
|
478
|
+
maxDimension_ = std::max(dimensions_.back(), maxDimension_);
|
|
479
|
+
}
|
|
480
|
+
};
|
|
481
|
+
|
|
482
|
+
} // namespace multi_persistence
|
|
483
|
+
} // namespace Gudhi
|
|
484
|
+
|
|
485
|
+
#endif // MP_FILTERED_COMPLEX_H_INCLUDED
|