multipers 2.2.3__cp310-cp310-win_amd64.whl → 2.3.1__cp310-cp310-win_amd64.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 -31
- multipers/_signed_measure_meta.py +430 -430
- multipers/_slicer_meta.py +211 -212
- multipers/data/MOL2.py +458 -458
- multipers/data/UCR.py +18 -18
- multipers/data/graphs.py +466 -466
- multipers/data/immuno_regions.py +27 -27
- multipers/data/pytorch2simplextree.py +90 -90
- multipers/data/shape3d.py +101 -101
- multipers/data/synthetic.py +113 -111
- multipers/distances.py +198 -198
- multipers/filtration_conversions.pxd.tp +84 -84
- multipers/filtrations/__init__.py +18 -0
- multipers/{ml/convolutions.py → filtrations/density.py} +563 -520
- multipers/filtrations/filtrations.py +289 -0
- multipers/filtrations.pxd +224 -224
- multipers/function_rips.cp310-win_amd64.pyd +0 -0
- multipers/function_rips.pyx +105 -105
- multipers/grids.cp310-win_amd64.pyd +0 -0
- multipers/grids.pyx +350 -350
- multipers/gudhi/Persistence_slices_interface.h +132 -132
- multipers/gudhi/Simplex_tree_interface.h +239 -245
- multipers/gudhi/Simplex_tree_multi_interface.h +516 -561
- multipers/gudhi/cubical_to_boundary.h +59 -59
- multipers/gudhi/gudhi/Bitmap_cubical_complex.h +450 -450
- multipers/gudhi/gudhi/Bitmap_cubical_complex_base.h +1070 -1070
- multipers/gudhi/gudhi/Bitmap_cubical_complex_periodic_boundary_conditions_base.h +579 -579
- multipers/gudhi/gudhi/Debug_utils.h +45 -45
- multipers/gudhi/gudhi/Fields/Multi_field.h +484 -484
- multipers/gudhi/gudhi/Fields/Multi_field_operators.h +455 -455
- multipers/gudhi/gudhi/Fields/Multi_field_shared.h +450 -450
- multipers/gudhi/gudhi/Fields/Multi_field_small.h +531 -531
- multipers/gudhi/gudhi/Fields/Multi_field_small_operators.h +507 -507
- multipers/gudhi/gudhi/Fields/Multi_field_small_shared.h +531 -531
- multipers/gudhi/gudhi/Fields/Z2_field.h +355 -355
- multipers/gudhi/gudhi/Fields/Z2_field_operators.h +376 -376
- multipers/gudhi/gudhi/Fields/Zp_field.h +420 -420
- multipers/gudhi/gudhi/Fields/Zp_field_operators.h +400 -400
- multipers/gudhi/gudhi/Fields/Zp_field_shared.h +418 -418
- multipers/gudhi/gudhi/Flag_complex_edge_collapser.h +337 -337
- multipers/gudhi/gudhi/Matrix.h +2107 -2107
- multipers/gudhi/gudhi/Multi_critical_filtration.h +1038 -1038
- multipers/gudhi/gudhi/Multi_persistence/Box.h +171 -171
- multipers/gudhi/gudhi/Multi_persistence/Line.h +282 -282
- multipers/gudhi/gudhi/Off_reader.h +173 -173
- multipers/gudhi/gudhi/One_critical_filtration.h +1433 -1431
- multipers/gudhi/gudhi/Persistence_matrix/Base_matrix.h +769 -769
- multipers/gudhi/gudhi/Persistence_matrix/Base_matrix_with_column_compression.h +686 -686
- multipers/gudhi/gudhi/Persistence_matrix/Boundary_matrix.h +842 -842
- multipers/gudhi/gudhi/Persistence_matrix/Chain_matrix.h +1350 -1350
- multipers/gudhi/gudhi/Persistence_matrix/Id_to_index_overlay.h +1105 -1105
- multipers/gudhi/gudhi/Persistence_matrix/Position_to_index_overlay.h +859 -859
- multipers/gudhi/gudhi/Persistence_matrix/RU_matrix.h +910 -910
- multipers/gudhi/gudhi/Persistence_matrix/allocators/entry_constructors.h +139 -139
- multipers/gudhi/gudhi/Persistence_matrix/base_pairing.h +230 -230
- multipers/gudhi/gudhi/Persistence_matrix/base_swap.h +211 -211
- multipers/gudhi/gudhi/Persistence_matrix/boundary_cell_position_to_id_mapper.h +60 -60
- multipers/gudhi/gudhi/Persistence_matrix/boundary_face_position_to_id_mapper.h +60 -60
- multipers/gudhi/gudhi/Persistence_matrix/chain_pairing.h +136 -136
- multipers/gudhi/gudhi/Persistence_matrix/chain_rep_cycles.h +190 -190
- multipers/gudhi/gudhi/Persistence_matrix/chain_vine_swap.h +616 -616
- multipers/gudhi/gudhi/Persistence_matrix/columns/chain_column_extra_properties.h +150 -150
- multipers/gudhi/gudhi/Persistence_matrix/columns/column_dimension_holder.h +106 -106
- multipers/gudhi/gudhi/Persistence_matrix/columns/column_utilities.h +219 -219
- multipers/gudhi/gudhi/Persistence_matrix/columns/entry_types.h +327 -327
- multipers/gudhi/gudhi/Persistence_matrix/columns/heap_column.h +1140 -1140
- multipers/gudhi/gudhi/Persistence_matrix/columns/intrusive_list_column.h +934 -934
- multipers/gudhi/gudhi/Persistence_matrix/columns/intrusive_set_column.h +934 -934
- multipers/gudhi/gudhi/Persistence_matrix/columns/list_column.h +980 -980
- multipers/gudhi/gudhi/Persistence_matrix/columns/naive_vector_column.h +1092 -1092
- multipers/gudhi/gudhi/Persistence_matrix/columns/row_access.h +192 -192
- multipers/gudhi/gudhi/Persistence_matrix/columns/set_column.h +921 -921
- multipers/gudhi/gudhi/Persistence_matrix/columns/small_vector_column.h +1093 -1093
- multipers/gudhi/gudhi/Persistence_matrix/columns/unordered_set_column.h +1012 -1012
- multipers/gudhi/gudhi/Persistence_matrix/columns/vector_column.h +1244 -1244
- multipers/gudhi/gudhi/Persistence_matrix/matrix_dimension_holders.h +186 -186
- multipers/gudhi/gudhi/Persistence_matrix/matrix_row_access.h +164 -164
- multipers/gudhi/gudhi/Persistence_matrix/ru_pairing.h +156 -156
- multipers/gudhi/gudhi/Persistence_matrix/ru_rep_cycles.h +376 -376
- multipers/gudhi/gudhi/Persistence_matrix/ru_vine_swap.h +540 -540
- multipers/gudhi/gudhi/Persistent_cohomology/Field_Zp.h +118 -118
- multipers/gudhi/gudhi/Persistent_cohomology/Multi_field.h +173 -173
- multipers/gudhi/gudhi/Persistent_cohomology/Persistent_cohomology_column.h +128 -128
- multipers/gudhi/gudhi/Persistent_cohomology.h +745 -745
- multipers/gudhi/gudhi/Points_off_io.h +171 -171
- multipers/gudhi/gudhi/Simple_object_pool.h +69 -69
- multipers/gudhi/gudhi/Simplex_tree/Simplex_tree_iterators.h +463 -463
- multipers/gudhi/gudhi/Simplex_tree/Simplex_tree_node_explicit_storage.h +83 -83
- multipers/gudhi/gudhi/Simplex_tree/Simplex_tree_siblings.h +106 -106
- multipers/gudhi/gudhi/Simplex_tree/Simplex_tree_star_simplex_iterators.h +277 -277
- multipers/gudhi/gudhi/Simplex_tree/hooks_simplex_base.h +62 -62
- multipers/gudhi/gudhi/Simplex_tree/indexing_tag.h +27 -27
- multipers/gudhi/gudhi/Simplex_tree/serialization_utils.h +62 -62
- multipers/gudhi/gudhi/Simplex_tree/simplex_tree_options.h +157 -157
- multipers/gudhi/gudhi/Simplex_tree.h +2794 -2794
- multipers/gudhi/gudhi/Simplex_tree_multi.h +152 -163
- multipers/gudhi/gudhi/distance_functions.h +62 -62
- multipers/gudhi/gudhi/graph_simplicial_complex.h +104 -104
- multipers/gudhi/gudhi/persistence_interval.h +253 -253
- multipers/gudhi/gudhi/persistence_matrix_options.h +170 -170
- multipers/gudhi/gudhi/reader_utils.h +367 -367
- multipers/gudhi/mma_interface_coh.h +256 -255
- multipers/gudhi/mma_interface_h0.h +223 -231
- multipers/gudhi/mma_interface_matrix.h +291 -282
- multipers/gudhi/naive_merge_tree.h +536 -575
- multipers/gudhi/scc_io.h +310 -289
- multipers/gudhi/truc.h +957 -888
- multipers/io.cp310-win_amd64.pyd +0 -0
- multipers/io.pyx +714 -711
- multipers/ml/accuracies.py +90 -90
- multipers/ml/invariants_with_persistable.py +79 -79
- multipers/ml/kernels.py +176 -176
- multipers/ml/mma.py +713 -714
- multipers/ml/one.py +472 -472
- multipers/ml/point_clouds.py +352 -346
- multipers/ml/signed_measures.py +1589 -1589
- multipers/ml/sliced_wasserstein.py +461 -461
- multipers/ml/tools.py +113 -113
- multipers/mma_structures.cp310-win_amd64.pyd +0 -0
- multipers/mma_structures.pxd +127 -127
- multipers/mma_structures.pyx +4 -8
- multipers/mma_structures.pyx.tp +1083 -1085
- multipers/multi_parameter_rank_invariant/diff_helpers.h +84 -93
- multipers/multi_parameter_rank_invariant/euler_characteristic.h +97 -97
- multipers/multi_parameter_rank_invariant/function_rips.h +322 -322
- multipers/multi_parameter_rank_invariant/hilbert_function.h +769 -769
- multipers/multi_parameter_rank_invariant/persistence_slices.h +148 -148
- multipers/multi_parameter_rank_invariant/rank_invariant.h +369 -369
- multipers/multiparameter_edge_collapse.py +41 -41
- multipers/multiparameter_module_approximation/approximation.h +2298 -2295
- multipers/multiparameter_module_approximation/combinatory.h +129 -129
- multipers/multiparameter_module_approximation/debug.h +107 -107
- multipers/multiparameter_module_approximation/format_python-cpp.h +286 -286
- multipers/multiparameter_module_approximation/heap_column.h +238 -238
- multipers/multiparameter_module_approximation/images.h +79 -79
- multipers/multiparameter_module_approximation/list_column.h +174 -174
- multipers/multiparameter_module_approximation/list_column_2.h +232 -232
- multipers/multiparameter_module_approximation/ru_matrix.h +347 -347
- multipers/multiparameter_module_approximation/set_column.h +135 -135
- multipers/multiparameter_module_approximation/structure_higher_dim_barcode.h +36 -36
- multipers/multiparameter_module_approximation/unordered_set_column.h +166 -166
- multipers/multiparameter_module_approximation/utilities.h +403 -419
- multipers/multiparameter_module_approximation/vector_column.h +223 -223
- multipers/multiparameter_module_approximation/vector_matrix.h +331 -331
- multipers/multiparameter_module_approximation/vineyards.h +464 -464
- multipers/multiparameter_module_approximation/vineyards_trajectories.h +649 -649
- multipers/multiparameter_module_approximation.cp310-win_amd64.pyd +0 -0
- multipers/multiparameter_module_approximation.pyx +218 -217
- multipers/pickle.py +90 -53
- multipers/plots.py +342 -334
- multipers/point_measure.cp310-win_amd64.pyd +0 -0
- multipers/point_measure.pyx +322 -320
- multipers/simplex_tree_multi.cp310-win_amd64.pyd +0 -0
- multipers/simplex_tree_multi.pxd +133 -133
- multipers/simplex_tree_multi.pyx +115 -48
- multipers/simplex_tree_multi.pyx.tp +1947 -1935
- multipers/slicer.cp310-win_amd64.pyd +0 -0
- multipers/slicer.pxd +301 -120
- multipers/slicer.pxd.tp +218 -214
- multipers/slicer.pyx +1570 -507
- multipers/slicer.pyx.tp +931 -914
- multipers/tensor/tensor.h +672 -672
- multipers/tensor.pxd +13 -13
- multipers/test.pyx +44 -44
- multipers/tests/__init__.py +57 -57
- multipers/torch/diff_grids.py +217 -217
- multipers/torch/rips_density.py +310 -304
- {multipers-2.2.3.dist-info → multipers-2.3.1.dist-info}/LICENSE +21 -21
- {multipers-2.2.3.dist-info → multipers-2.3.1.dist-info}/METADATA +21 -11
- multipers-2.3.1.dist-info/RECORD +182 -0
- {multipers-2.2.3.dist-info → multipers-2.3.1.dist-info}/WHEEL +1 -1
- multipers/tests/test_diff_helper.py +0 -73
- multipers/tests/test_hilbert_function.py +0 -82
- multipers/tests/test_mma.py +0 -83
- multipers/tests/test_point_clouds.py +0 -49
- multipers/tests/test_python-cpp_conversion.py +0 -82
- multipers/tests/test_signed_betti.py +0 -181
- multipers/tests/test_signed_measure.py +0 -89
- multipers/tests/test_simplextreemulti.py +0 -221
- multipers/tests/test_slicer.py +0 -221
- multipers-2.2.3.dist-info/RECORD +0 -189
- {multipers-2.2.3.dist-info → multipers-2.3.1.dist-info}/top_level.txt +0 -0
|
@@ -1,219 +1,219 @@
|
|
|
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) 2024 Inria
|
|
6
|
-
*
|
|
7
|
-
* Modification(s):
|
|
8
|
-
* - YYYY/MM Author: Description of the modification
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* @file column_utilities.h
|
|
13
|
-
* @author Hannah Schreiber
|
|
14
|
-
* @brief Contains helper methods for column addition and column hasher.
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
#ifndef PM_COLUMN_UTILITIES_H
|
|
18
|
-
#define PM_COLUMN_UTILITIES_H
|
|
19
|
-
|
|
20
|
-
#include <cstddef>
|
|
21
|
-
#include <stdexcept>
|
|
22
|
-
|
|
23
|
-
#include <gudhi/persistence_matrix_options.h>
|
|
24
|
-
|
|
25
|
-
namespace Gudhi {
|
|
26
|
-
namespace persistence_matrix {
|
|
27
|
-
|
|
28
|
-
template <class Entry, typename Entry_iterator>
|
|
29
|
-
Entry* _get_entry(const Entry_iterator& itTarget)
|
|
30
|
-
{
|
|
31
|
-
if constexpr (Entry::Master::Option_list::column_type == Column_types::INTRUSIVE_LIST ||
|
|
32
|
-
Entry::Master::Option_list::column_type == Column_types::INTRUSIVE_SET) {
|
|
33
|
-
return &*itTarget;
|
|
34
|
-
} else {
|
|
35
|
-
return *itTarget;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// works only for ordered columns
|
|
40
|
-
template <class Column, class Entry_iterator, typename F1, typename F2, typename F3, typename F4>
|
|
41
|
-
void _generic_merge_entry_to_column(Column& targetColumn,
|
|
42
|
-
Entry_iterator& itSource,
|
|
43
|
-
typename Column::Column_support::iterator& itTarget,
|
|
44
|
-
F1&& process_target,
|
|
45
|
-
F2&& process_source,
|
|
46
|
-
F3&& update_target1,
|
|
47
|
-
F4&& update_target2,
|
|
48
|
-
bool& pivotIsZeroed)
|
|
49
|
-
{
|
|
50
|
-
typename Column::Entry* targetEntry = _get_entry<typename Column::Entry>(itTarget);
|
|
51
|
-
|
|
52
|
-
if (targetEntry->get_row_index() < itSource->get_row_index()) {
|
|
53
|
-
process_target(targetEntry);
|
|
54
|
-
++itTarget;
|
|
55
|
-
} else if (targetEntry->get_row_index() > itSource->get_row_index()) {
|
|
56
|
-
process_source(itSource, itTarget);
|
|
57
|
-
++itSource;
|
|
58
|
-
} else {
|
|
59
|
-
if constexpr (Column::Master::Option_list::is_z2) {
|
|
60
|
-
//_multiply_*_and_add never enters here so not treated
|
|
61
|
-
if constexpr (Column::Master::isNonBasic && !Column::Master::Option_list::is_of_boundary_type) {
|
|
62
|
-
if (targetEntry->get_row_index() == targetColumn.get_pivot()) pivotIsZeroed = true;
|
|
63
|
-
}
|
|
64
|
-
targetColumn._delete_entry(itTarget);
|
|
65
|
-
} else {
|
|
66
|
-
update_target1(targetEntry->get_element(), itSource);
|
|
67
|
-
if (targetEntry->get_element() == Column::Field_operators::get_additive_identity()) {
|
|
68
|
-
if constexpr (Column::Master::isNonBasic && !Column::Master::Option_list::is_of_boundary_type) {
|
|
69
|
-
if (targetEntry->get_row_index() == targetColumn.get_pivot()) pivotIsZeroed = true;
|
|
70
|
-
}
|
|
71
|
-
targetColumn._delete_entry(itTarget);
|
|
72
|
-
} else {
|
|
73
|
-
update_target2(targetEntry);
|
|
74
|
-
if constexpr (Column::Master::Option_list::has_row_access) targetColumn.update_entry(*targetEntry);
|
|
75
|
-
++itTarget;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
++itSource;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// works only for ordered columns
|
|
83
|
-
template <class Column, class Entry_range, typename F1, typename F2, typename F3, typename F4, typename F5>
|
|
84
|
-
bool _generic_add_to_column(const Entry_range& source,
|
|
85
|
-
Column& targetColumn,
|
|
86
|
-
F1&& process_target,
|
|
87
|
-
F2&& process_source,
|
|
88
|
-
F3&& update_target1,
|
|
89
|
-
F4&& update_target2,
|
|
90
|
-
F5&& finish_target)
|
|
91
|
-
{
|
|
92
|
-
bool pivotIsZeroed = false;
|
|
93
|
-
|
|
94
|
-
auto& target = targetColumn.column_;
|
|
95
|
-
auto itTarget = target.begin();
|
|
96
|
-
auto itSource = source.begin();
|
|
97
|
-
while (itTarget != target.end() && itSource != source.end()) {
|
|
98
|
-
_generic_merge_entry_to_column(targetColumn, itSource, itTarget,
|
|
99
|
-
process_target, process_source, update_target1, update_target2,
|
|
100
|
-
pivotIsZeroed);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
finish_target(itTarget);
|
|
104
|
-
|
|
105
|
-
while (itSource != source.end()) {
|
|
106
|
-
process_source(itSource, target.end());
|
|
107
|
-
++itSource;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
return pivotIsZeroed;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
template <class Column, class Entry_range>
|
|
114
|
-
bool _add_to_column(const Entry_range& source, Column& targetColumn)
|
|
115
|
-
{
|
|
116
|
-
return _generic_add_to_column(
|
|
117
|
-
source,
|
|
118
|
-
targetColumn,
|
|
119
|
-
[&]([[maybe_unused]] typename Column::Entry* entryTarget) {},
|
|
120
|
-
[&](typename Entry_range::const_iterator& itSource, const typename Column::Column_support::iterator& itTarget) {
|
|
121
|
-
if constexpr (Column::Master::Option_list::is_z2) {
|
|
122
|
-
targetColumn._insert_entry(itSource->get_row_index(), itTarget);
|
|
123
|
-
} else {
|
|
124
|
-
targetColumn._insert_entry(itSource->get_element(), itSource->get_row_index(), itTarget);
|
|
125
|
-
}
|
|
126
|
-
},
|
|
127
|
-
[&](typename Column::Field_element& targetElement, typename Entry_range::const_iterator& itSource) {
|
|
128
|
-
if constexpr (!Column::Master::Option_list::is_z2)
|
|
129
|
-
targetColumn.operators_->add_inplace(targetElement, itSource->get_element());
|
|
130
|
-
},
|
|
131
|
-
[&]([[maybe_unused]] typename Column::Entry* entryTarget) {},
|
|
132
|
-
[&]([[maybe_unused]] typename Column::Column_support::iterator& itTarget) {}
|
|
133
|
-
);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
template <class Column, class Entry_range>
|
|
137
|
-
bool _multiply_target_and_add_to_column(const typename Column::Field_element& val,
|
|
138
|
-
const Entry_range& source,
|
|
139
|
-
Column& targetColumn)
|
|
140
|
-
{
|
|
141
|
-
if (val == 0u) {
|
|
142
|
-
if constexpr (Column::Master::isNonBasic && !Column::Master::Option_list::is_of_boundary_type) {
|
|
143
|
-
throw std::invalid_argument("A chain column should not be multiplied by 0.");
|
|
144
|
-
// this would not only mess up the base, but also the pivots stored.
|
|
145
|
-
} else {
|
|
146
|
-
targetColumn.clear();
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
return _generic_add_to_column(
|
|
151
|
-
source,
|
|
152
|
-
targetColumn,
|
|
153
|
-
[&](typename Column::Entry* entryTarget) {
|
|
154
|
-
targetColumn.operators_->multiply_inplace(entryTarget->get_element(), val);
|
|
155
|
-
// targetColumn.RA_opt::update_entry(*itTarget) produces an internal compiler error
|
|
156
|
-
// even though it works in _generic_add_to_column... Probably because of the lambda.
|
|
157
|
-
if constexpr (Column::Master::Option_list::has_row_access) targetColumn.update_entry(*entryTarget);
|
|
158
|
-
},
|
|
159
|
-
[&](typename Entry_range::const_iterator& itSource, const typename Column::Column_support::iterator& itTarget) {
|
|
160
|
-
targetColumn._insert_entry(itSource->get_element(), itSource->get_row_index(), itTarget);
|
|
161
|
-
},
|
|
162
|
-
[&](typename Column::Field_element& targetElement, typename Entry_range::const_iterator& itSource) {
|
|
163
|
-
targetColumn.operators_->multiply_and_add_inplace_front(targetElement, val, itSource->get_element());
|
|
164
|
-
},
|
|
165
|
-
[&]([[maybe_unused]] typename Column::Entry* entryTarget) {},
|
|
166
|
-
[&](typename Column::Column_support::iterator& itTarget) {
|
|
167
|
-
while (itTarget != targetColumn.column_.end()) {
|
|
168
|
-
typename Column::Entry* targetEntry = _get_entry<typename Column::Entry>(itTarget);
|
|
169
|
-
targetColumn.operators_->multiply_inplace(targetEntry->get_element(), val);
|
|
170
|
-
if constexpr (Column::Master::Option_list::has_row_access) targetColumn.update_entry(*targetEntry);
|
|
171
|
-
itTarget++;
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
template <class Column, class Entry_range>
|
|
178
|
-
bool _multiply_source_and_add_to_column(const typename Column::Field_element& val,
|
|
179
|
-
const Entry_range& source,
|
|
180
|
-
Column& targetColumn)
|
|
181
|
-
{
|
|
182
|
-
if (val == 0u) {
|
|
183
|
-
return false;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
return _generic_add_to_column(
|
|
187
|
-
source,
|
|
188
|
-
targetColumn,
|
|
189
|
-
[]([[maybe_unused]] typename Column::Entry* entryTarget) {},
|
|
190
|
-
[&](typename Entry_range::const_iterator& itSource, const typename Column::Column_support::iterator& itTarget) {
|
|
191
|
-
typename Column::Entry* entry =
|
|
192
|
-
targetColumn._insert_entry(itSource->get_element(), itSource->get_row_index(), itTarget);
|
|
193
|
-
targetColumn.operators_->multiply_inplace(entry->get_element(), val);
|
|
194
|
-
if constexpr (Column::Master::Option_list::has_row_access) targetColumn.update_entry(*entry);
|
|
195
|
-
},
|
|
196
|
-
[&](typename Column::Field_element& targetElement, typename Entry_range::const_iterator& itSource) {
|
|
197
|
-
targetColumn.operators_->multiply_and_add_inplace_back(itSource->get_element(), val, targetElement);
|
|
198
|
-
},
|
|
199
|
-
[&]([[maybe_unused]] typename Column::Entry* entryTarget) {},
|
|
200
|
-
[]([[maybe_unused]] typename Column::Column_support::iterator& itTarget) {});
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
// column has to be ordered (ie. not suited for unordered_map and heap) and contain the exact values
|
|
204
|
-
// (ie. not suited for vector and heap). A same column but ordered differently will have another hash value.
|
|
205
|
-
template <class Column>
|
|
206
|
-
std::size_t hash_column(const Column& column)
|
|
207
|
-
{
|
|
208
|
-
std::size_t seed = 0;
|
|
209
|
-
for (auto& entry : column) {
|
|
210
|
-
seed ^= std::hash<unsigned int>()(entry.get_row_index() * static_cast<unsigned int>(entry.get_element())) +
|
|
211
|
-
0x9e3779b9 + (seed << 6) + (seed >> 2);
|
|
212
|
-
}
|
|
213
|
-
return seed;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
} // namespace persistence_matrix
|
|
217
|
-
} // namespace Gudhi
|
|
218
|
-
|
|
219
|
-
#endif // PM_COLUMN_UTILITIES_H
|
|
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) 2024 Inria
|
|
6
|
+
*
|
|
7
|
+
* Modification(s):
|
|
8
|
+
* - YYYY/MM Author: Description of the modification
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @file column_utilities.h
|
|
13
|
+
* @author Hannah Schreiber
|
|
14
|
+
* @brief Contains helper methods for column addition and column hasher.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
#ifndef PM_COLUMN_UTILITIES_H
|
|
18
|
+
#define PM_COLUMN_UTILITIES_H
|
|
19
|
+
|
|
20
|
+
#include <cstddef>
|
|
21
|
+
#include <stdexcept>
|
|
22
|
+
|
|
23
|
+
#include <gudhi/persistence_matrix_options.h>
|
|
24
|
+
|
|
25
|
+
namespace Gudhi {
|
|
26
|
+
namespace persistence_matrix {
|
|
27
|
+
|
|
28
|
+
template <class Entry, typename Entry_iterator>
|
|
29
|
+
Entry* _get_entry(const Entry_iterator& itTarget)
|
|
30
|
+
{
|
|
31
|
+
if constexpr (Entry::Master::Option_list::column_type == Column_types::INTRUSIVE_LIST ||
|
|
32
|
+
Entry::Master::Option_list::column_type == Column_types::INTRUSIVE_SET) {
|
|
33
|
+
return &*itTarget;
|
|
34
|
+
} else {
|
|
35
|
+
return *itTarget;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// works only for ordered columns
|
|
40
|
+
template <class Column, class Entry_iterator, typename F1, typename F2, typename F3, typename F4>
|
|
41
|
+
void _generic_merge_entry_to_column(Column& targetColumn,
|
|
42
|
+
Entry_iterator& itSource,
|
|
43
|
+
typename Column::Column_support::iterator& itTarget,
|
|
44
|
+
F1&& process_target,
|
|
45
|
+
F2&& process_source,
|
|
46
|
+
F3&& update_target1,
|
|
47
|
+
F4&& update_target2,
|
|
48
|
+
bool& pivotIsZeroed)
|
|
49
|
+
{
|
|
50
|
+
typename Column::Entry* targetEntry = _get_entry<typename Column::Entry>(itTarget);
|
|
51
|
+
|
|
52
|
+
if (targetEntry->get_row_index() < itSource->get_row_index()) {
|
|
53
|
+
process_target(targetEntry);
|
|
54
|
+
++itTarget;
|
|
55
|
+
} else if (targetEntry->get_row_index() > itSource->get_row_index()) {
|
|
56
|
+
process_source(itSource, itTarget);
|
|
57
|
+
++itSource;
|
|
58
|
+
} else {
|
|
59
|
+
if constexpr (Column::Master::Option_list::is_z2) {
|
|
60
|
+
//_multiply_*_and_add never enters here so not treated
|
|
61
|
+
if constexpr (Column::Master::isNonBasic && !Column::Master::Option_list::is_of_boundary_type) {
|
|
62
|
+
if (targetEntry->get_row_index() == targetColumn.get_pivot()) pivotIsZeroed = true;
|
|
63
|
+
}
|
|
64
|
+
targetColumn._delete_entry(itTarget);
|
|
65
|
+
} else {
|
|
66
|
+
update_target1(targetEntry->get_element(), itSource);
|
|
67
|
+
if (targetEntry->get_element() == Column::Field_operators::get_additive_identity()) {
|
|
68
|
+
if constexpr (Column::Master::isNonBasic && !Column::Master::Option_list::is_of_boundary_type) {
|
|
69
|
+
if (targetEntry->get_row_index() == targetColumn.get_pivot()) pivotIsZeroed = true;
|
|
70
|
+
}
|
|
71
|
+
targetColumn._delete_entry(itTarget);
|
|
72
|
+
} else {
|
|
73
|
+
update_target2(targetEntry);
|
|
74
|
+
if constexpr (Column::Master::Option_list::has_row_access) targetColumn.update_entry(*targetEntry);
|
|
75
|
+
++itTarget;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
++itSource;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// works only for ordered columns
|
|
83
|
+
template <class Column, class Entry_range, typename F1, typename F2, typename F3, typename F4, typename F5>
|
|
84
|
+
bool _generic_add_to_column(const Entry_range& source,
|
|
85
|
+
Column& targetColumn,
|
|
86
|
+
F1&& process_target,
|
|
87
|
+
F2&& process_source,
|
|
88
|
+
F3&& update_target1,
|
|
89
|
+
F4&& update_target2,
|
|
90
|
+
F5&& finish_target)
|
|
91
|
+
{
|
|
92
|
+
bool pivotIsZeroed = false;
|
|
93
|
+
|
|
94
|
+
auto& target = targetColumn.column_;
|
|
95
|
+
auto itTarget = target.begin();
|
|
96
|
+
auto itSource = source.begin();
|
|
97
|
+
while (itTarget != target.end() && itSource != source.end()) {
|
|
98
|
+
_generic_merge_entry_to_column(targetColumn, itSource, itTarget,
|
|
99
|
+
process_target, process_source, update_target1, update_target2,
|
|
100
|
+
pivotIsZeroed);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
finish_target(itTarget);
|
|
104
|
+
|
|
105
|
+
while (itSource != source.end()) {
|
|
106
|
+
process_source(itSource, target.end());
|
|
107
|
+
++itSource;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return pivotIsZeroed;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
template <class Column, class Entry_range>
|
|
114
|
+
bool _add_to_column(const Entry_range& source, Column& targetColumn)
|
|
115
|
+
{
|
|
116
|
+
return _generic_add_to_column(
|
|
117
|
+
source,
|
|
118
|
+
targetColumn,
|
|
119
|
+
[&]([[maybe_unused]] typename Column::Entry* entryTarget) {},
|
|
120
|
+
[&](typename Entry_range::const_iterator& itSource, const typename Column::Column_support::iterator& itTarget) {
|
|
121
|
+
if constexpr (Column::Master::Option_list::is_z2) {
|
|
122
|
+
targetColumn._insert_entry(itSource->get_row_index(), itTarget);
|
|
123
|
+
} else {
|
|
124
|
+
targetColumn._insert_entry(itSource->get_element(), itSource->get_row_index(), itTarget);
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
[&](typename Column::Field_element& targetElement, typename Entry_range::const_iterator& itSource) {
|
|
128
|
+
if constexpr (!Column::Master::Option_list::is_z2)
|
|
129
|
+
targetColumn.operators_->add_inplace(targetElement, itSource->get_element());
|
|
130
|
+
},
|
|
131
|
+
[&]([[maybe_unused]] typename Column::Entry* entryTarget) {},
|
|
132
|
+
[&]([[maybe_unused]] typename Column::Column_support::iterator& itTarget) {}
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
template <class Column, class Entry_range>
|
|
137
|
+
bool _multiply_target_and_add_to_column(const typename Column::Field_element& val,
|
|
138
|
+
const Entry_range& source,
|
|
139
|
+
Column& targetColumn)
|
|
140
|
+
{
|
|
141
|
+
if (val == 0u) {
|
|
142
|
+
if constexpr (Column::Master::isNonBasic && !Column::Master::Option_list::is_of_boundary_type) {
|
|
143
|
+
throw std::invalid_argument("A chain column should not be multiplied by 0.");
|
|
144
|
+
// this would not only mess up the base, but also the pivots stored.
|
|
145
|
+
} else {
|
|
146
|
+
targetColumn.clear();
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return _generic_add_to_column(
|
|
151
|
+
source,
|
|
152
|
+
targetColumn,
|
|
153
|
+
[&](typename Column::Entry* entryTarget) {
|
|
154
|
+
targetColumn.operators_->multiply_inplace(entryTarget->get_element(), val);
|
|
155
|
+
// targetColumn.RA_opt::update_entry(*itTarget) produces an internal compiler error
|
|
156
|
+
// even though it works in _generic_add_to_column... Probably because of the lambda.
|
|
157
|
+
if constexpr (Column::Master::Option_list::has_row_access) targetColumn.update_entry(*entryTarget);
|
|
158
|
+
},
|
|
159
|
+
[&](typename Entry_range::const_iterator& itSource, const typename Column::Column_support::iterator& itTarget) {
|
|
160
|
+
targetColumn._insert_entry(itSource->get_element(), itSource->get_row_index(), itTarget);
|
|
161
|
+
},
|
|
162
|
+
[&](typename Column::Field_element& targetElement, typename Entry_range::const_iterator& itSource) {
|
|
163
|
+
targetColumn.operators_->multiply_and_add_inplace_front(targetElement, val, itSource->get_element());
|
|
164
|
+
},
|
|
165
|
+
[&]([[maybe_unused]] typename Column::Entry* entryTarget) {},
|
|
166
|
+
[&](typename Column::Column_support::iterator& itTarget) {
|
|
167
|
+
while (itTarget != targetColumn.column_.end()) {
|
|
168
|
+
typename Column::Entry* targetEntry = _get_entry<typename Column::Entry>(itTarget);
|
|
169
|
+
targetColumn.operators_->multiply_inplace(targetEntry->get_element(), val);
|
|
170
|
+
if constexpr (Column::Master::Option_list::has_row_access) targetColumn.update_entry(*targetEntry);
|
|
171
|
+
itTarget++;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
template <class Column, class Entry_range>
|
|
178
|
+
bool _multiply_source_and_add_to_column(const typename Column::Field_element& val,
|
|
179
|
+
const Entry_range& source,
|
|
180
|
+
Column& targetColumn)
|
|
181
|
+
{
|
|
182
|
+
if (val == 0u) {
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return _generic_add_to_column(
|
|
187
|
+
source,
|
|
188
|
+
targetColumn,
|
|
189
|
+
[]([[maybe_unused]] typename Column::Entry* entryTarget) {},
|
|
190
|
+
[&](typename Entry_range::const_iterator& itSource, const typename Column::Column_support::iterator& itTarget) {
|
|
191
|
+
typename Column::Entry* entry =
|
|
192
|
+
targetColumn._insert_entry(itSource->get_element(), itSource->get_row_index(), itTarget);
|
|
193
|
+
targetColumn.operators_->multiply_inplace(entry->get_element(), val);
|
|
194
|
+
if constexpr (Column::Master::Option_list::has_row_access) targetColumn.update_entry(*entry);
|
|
195
|
+
},
|
|
196
|
+
[&](typename Column::Field_element& targetElement, typename Entry_range::const_iterator& itSource) {
|
|
197
|
+
targetColumn.operators_->multiply_and_add_inplace_back(itSource->get_element(), val, targetElement);
|
|
198
|
+
},
|
|
199
|
+
[&]([[maybe_unused]] typename Column::Entry* entryTarget) {},
|
|
200
|
+
[]([[maybe_unused]] typename Column::Column_support::iterator& itTarget) {});
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// column has to be ordered (ie. not suited for unordered_map and heap) and contain the exact values
|
|
204
|
+
// (ie. not suited for vector and heap). A same column but ordered differently will have another hash value.
|
|
205
|
+
template <class Column>
|
|
206
|
+
std::size_t hash_column(const Column& column)
|
|
207
|
+
{
|
|
208
|
+
std::size_t seed = 0;
|
|
209
|
+
for (auto& entry : column) {
|
|
210
|
+
seed ^= std::hash<unsigned int>()(entry.get_row_index() * static_cast<unsigned int>(entry.get_element())) +
|
|
211
|
+
0x9e3779b9 + (seed << 6) + (seed >> 2);
|
|
212
|
+
}
|
|
213
|
+
return seed;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
} // namespace persistence_matrix
|
|
217
|
+
} // namespace Gudhi
|
|
218
|
+
|
|
219
|
+
#endif // PM_COLUMN_UTILITIES_H
|