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.
Files changed (184) hide show
  1. multipers/.dylibs/libboost_timer.dylib +0 -0
  2. multipers/.dylibs/libc++.1.0.dylib +0 -0
  3. multipers/.dylibs/libtbb.12.17.dylib +0 -0
  4. multipers/__init__.py +33 -0
  5. multipers/_signed_measure_meta.py +426 -0
  6. multipers/_slicer_meta.py +231 -0
  7. multipers/array_api/__init__.py +62 -0
  8. multipers/array_api/numpy.py +124 -0
  9. multipers/array_api/torch.py +133 -0
  10. multipers/data/MOL2.py +458 -0
  11. multipers/data/UCR.py +18 -0
  12. multipers/data/__init__.py +1 -0
  13. multipers/data/graphs.py +466 -0
  14. multipers/data/immuno_regions.py +27 -0
  15. multipers/data/minimal_presentation_to_st_bf.py +0 -0
  16. multipers/data/pytorch2simplextree.py +91 -0
  17. multipers/data/shape3d.py +101 -0
  18. multipers/data/synthetic.py +113 -0
  19. multipers/distances.py +202 -0
  20. multipers/filtration_conversions.pxd +736 -0
  21. multipers/filtration_conversions.pxd.tp +226 -0
  22. multipers/filtrations/__init__.py +21 -0
  23. multipers/filtrations/density.py +529 -0
  24. multipers/filtrations/filtrations.py +480 -0
  25. multipers/filtrations.pxd +534 -0
  26. multipers/filtrations.pxd.tp +332 -0
  27. multipers/function_rips.cpython-312-darwin.so +0 -0
  28. multipers/function_rips.pyx +104 -0
  29. multipers/grids.cpython-312-darwin.so +0 -0
  30. multipers/grids.pyx +538 -0
  31. multipers/gudhi/Persistence_slices_interface.h +213 -0
  32. multipers/gudhi/Simplex_tree_interface.h +274 -0
  33. multipers/gudhi/Simplex_tree_multi_interface.h +648 -0
  34. multipers/gudhi/gudhi/Bitmap_cubical_complex.h +450 -0
  35. multipers/gudhi/gudhi/Bitmap_cubical_complex_base.h +1070 -0
  36. multipers/gudhi/gudhi/Bitmap_cubical_complex_periodic_boundary_conditions_base.h +579 -0
  37. multipers/gudhi/gudhi/Debug_utils.h +52 -0
  38. multipers/gudhi/gudhi/Degree_rips_bifiltration.h +2307 -0
  39. multipers/gudhi/gudhi/Dynamic_multi_parameter_filtration.h +2524 -0
  40. multipers/gudhi/gudhi/Fields/Multi_field.h +453 -0
  41. multipers/gudhi/gudhi/Fields/Multi_field_operators.h +460 -0
  42. multipers/gudhi/gudhi/Fields/Multi_field_shared.h +444 -0
  43. multipers/gudhi/gudhi/Fields/Multi_field_small.h +584 -0
  44. multipers/gudhi/gudhi/Fields/Multi_field_small_operators.h +490 -0
  45. multipers/gudhi/gudhi/Fields/Multi_field_small_shared.h +580 -0
  46. multipers/gudhi/gudhi/Fields/Z2_field.h +391 -0
  47. multipers/gudhi/gudhi/Fields/Z2_field_operators.h +389 -0
  48. multipers/gudhi/gudhi/Fields/Zp_field.h +493 -0
  49. multipers/gudhi/gudhi/Fields/Zp_field_operators.h +384 -0
  50. multipers/gudhi/gudhi/Fields/Zp_field_shared.h +492 -0
  51. multipers/gudhi/gudhi/Flag_complex_edge_collapser.h +337 -0
  52. multipers/gudhi/gudhi/Matrix.h +2200 -0
  53. multipers/gudhi/gudhi/Multi_filtration/Multi_parameter_generator.h +1712 -0
  54. multipers/gudhi/gudhi/Multi_filtration/multi_filtration_conversions.h +237 -0
  55. multipers/gudhi/gudhi/Multi_filtration/multi_filtration_utils.h +225 -0
  56. multipers/gudhi/gudhi/Multi_parameter_filtered_complex.h +485 -0
  57. multipers/gudhi/gudhi/Multi_parameter_filtration.h +2643 -0
  58. multipers/gudhi/gudhi/Multi_persistence/Box.h +233 -0
  59. multipers/gudhi/gudhi/Multi_persistence/Line.h +309 -0
  60. multipers/gudhi/gudhi/Multi_persistence/Multi_parameter_filtered_complex_pcoh_interface.h +268 -0
  61. multipers/gudhi/gudhi/Multi_persistence/Persistence_interface_cohomology.h +159 -0
  62. multipers/gudhi/gudhi/Multi_persistence/Persistence_interface_matrix.h +463 -0
  63. multipers/gudhi/gudhi/Multi_persistence/Point.h +853 -0
  64. multipers/gudhi/gudhi/Off_reader.h +173 -0
  65. multipers/gudhi/gudhi/Persistence_matrix/Base_matrix.h +834 -0
  66. multipers/gudhi/gudhi/Persistence_matrix/Base_matrix_with_column_compression.h +838 -0
  67. multipers/gudhi/gudhi/Persistence_matrix/Boundary_matrix.h +833 -0
  68. multipers/gudhi/gudhi/Persistence_matrix/Chain_matrix.h +1367 -0
  69. multipers/gudhi/gudhi/Persistence_matrix/Id_to_index_overlay.h +1157 -0
  70. multipers/gudhi/gudhi/Persistence_matrix/Position_to_index_overlay.h +869 -0
  71. multipers/gudhi/gudhi/Persistence_matrix/RU_matrix.h +905 -0
  72. multipers/gudhi/gudhi/Persistence_matrix/allocators/entry_constructors.h +122 -0
  73. multipers/gudhi/gudhi/Persistence_matrix/base_pairing.h +260 -0
  74. multipers/gudhi/gudhi/Persistence_matrix/base_swap.h +288 -0
  75. multipers/gudhi/gudhi/Persistence_matrix/chain_pairing.h +170 -0
  76. multipers/gudhi/gudhi/Persistence_matrix/chain_rep_cycles.h +247 -0
  77. multipers/gudhi/gudhi/Persistence_matrix/chain_vine_swap.h +571 -0
  78. multipers/gudhi/gudhi/Persistence_matrix/columns/chain_column_extra_properties.h +182 -0
  79. multipers/gudhi/gudhi/Persistence_matrix/columns/column_dimension_holder.h +130 -0
  80. multipers/gudhi/gudhi/Persistence_matrix/columns/column_utilities.h +235 -0
  81. multipers/gudhi/gudhi/Persistence_matrix/columns/entry_types.h +312 -0
  82. multipers/gudhi/gudhi/Persistence_matrix/columns/heap_column.h +1092 -0
  83. multipers/gudhi/gudhi/Persistence_matrix/columns/intrusive_list_column.h +923 -0
  84. multipers/gudhi/gudhi/Persistence_matrix/columns/intrusive_set_column.h +914 -0
  85. multipers/gudhi/gudhi/Persistence_matrix/columns/list_column.h +930 -0
  86. multipers/gudhi/gudhi/Persistence_matrix/columns/naive_vector_column.h +1071 -0
  87. multipers/gudhi/gudhi/Persistence_matrix/columns/row_access.h +203 -0
  88. multipers/gudhi/gudhi/Persistence_matrix/columns/set_column.h +886 -0
  89. multipers/gudhi/gudhi/Persistence_matrix/columns/unordered_set_column.h +984 -0
  90. multipers/gudhi/gudhi/Persistence_matrix/columns/vector_column.h +1213 -0
  91. multipers/gudhi/gudhi/Persistence_matrix/index_mapper.h +58 -0
  92. multipers/gudhi/gudhi/Persistence_matrix/matrix_dimension_holders.h +227 -0
  93. multipers/gudhi/gudhi/Persistence_matrix/matrix_row_access.h +200 -0
  94. multipers/gudhi/gudhi/Persistence_matrix/ru_pairing.h +166 -0
  95. multipers/gudhi/gudhi/Persistence_matrix/ru_rep_cycles.h +319 -0
  96. multipers/gudhi/gudhi/Persistence_matrix/ru_vine_swap.h +562 -0
  97. multipers/gudhi/gudhi/Persistence_on_a_line.h +152 -0
  98. multipers/gudhi/gudhi/Persistence_on_rectangle.h +617 -0
  99. multipers/gudhi/gudhi/Persistent_cohomology/Field_Zp.h +118 -0
  100. multipers/gudhi/gudhi/Persistent_cohomology/Multi_field.h +173 -0
  101. multipers/gudhi/gudhi/Persistent_cohomology/Persistent_cohomology_column.h +128 -0
  102. multipers/gudhi/gudhi/Persistent_cohomology.h +769 -0
  103. multipers/gudhi/gudhi/Points_off_io.h +171 -0
  104. multipers/gudhi/gudhi/Projective_cover_kernel.h +379 -0
  105. multipers/gudhi/gudhi/Simple_object_pool.h +69 -0
  106. multipers/gudhi/gudhi/Simplex_tree/Simplex_tree_iterators.h +559 -0
  107. multipers/gudhi/gudhi/Simplex_tree/Simplex_tree_node_explicit_storage.h +83 -0
  108. multipers/gudhi/gudhi/Simplex_tree/Simplex_tree_siblings.h +121 -0
  109. multipers/gudhi/gudhi/Simplex_tree/Simplex_tree_star_simplex_iterators.h +277 -0
  110. multipers/gudhi/gudhi/Simplex_tree/filtration_value_utils.h +155 -0
  111. multipers/gudhi/gudhi/Simplex_tree/hooks_simplex_base.h +62 -0
  112. multipers/gudhi/gudhi/Simplex_tree/indexing_tag.h +27 -0
  113. multipers/gudhi/gudhi/Simplex_tree/serialization_utils.h +60 -0
  114. multipers/gudhi/gudhi/Simplex_tree/simplex_tree_options.h +105 -0
  115. multipers/gudhi/gudhi/Simplex_tree.h +3170 -0
  116. multipers/gudhi/gudhi/Slicer.h +848 -0
  117. multipers/gudhi/gudhi/Thread_safe_slicer.h +393 -0
  118. multipers/gudhi/gudhi/distance_functions.h +62 -0
  119. multipers/gudhi/gudhi/graph_simplicial_complex.h +104 -0
  120. multipers/gudhi/gudhi/multi_simplex_tree_helpers.h +147 -0
  121. multipers/gudhi/gudhi/persistence_interval.h +263 -0
  122. multipers/gudhi/gudhi/persistence_matrix_options.h +188 -0
  123. multipers/gudhi/gudhi/reader_utils.h +367 -0
  124. multipers/gudhi/gudhi/simple_mdspan.h +484 -0
  125. multipers/gudhi/gudhi/slicer_helpers.h +779 -0
  126. multipers/gudhi/tmp_h0_pers/mma_interface_h0.h +223 -0
  127. multipers/gudhi/tmp_h0_pers/naive_merge_tree.h +536 -0
  128. multipers/io.cpython-312-darwin.so +0 -0
  129. multipers/io.pyx +472 -0
  130. multipers/ml/__init__.py +0 -0
  131. multipers/ml/accuracies.py +90 -0
  132. multipers/ml/invariants_with_persistable.py +79 -0
  133. multipers/ml/kernels.py +176 -0
  134. multipers/ml/mma.py +713 -0
  135. multipers/ml/one.py +472 -0
  136. multipers/ml/point_clouds.py +352 -0
  137. multipers/ml/signed_measures.py +1667 -0
  138. multipers/ml/sliced_wasserstein.py +461 -0
  139. multipers/ml/tools.py +113 -0
  140. multipers/mma_structures.cpython-312-darwin.so +0 -0
  141. multipers/mma_structures.pxd +134 -0
  142. multipers/mma_structures.pyx +1483 -0
  143. multipers/mma_structures.pyx.tp +1126 -0
  144. multipers/multi_parameter_rank_invariant/diff_helpers.h +85 -0
  145. multipers/multi_parameter_rank_invariant/euler_characteristic.h +95 -0
  146. multipers/multi_parameter_rank_invariant/function_rips.h +317 -0
  147. multipers/multi_parameter_rank_invariant/hilbert_function.h +761 -0
  148. multipers/multi_parameter_rank_invariant/persistence_slices.h +149 -0
  149. multipers/multi_parameter_rank_invariant/rank_invariant.h +350 -0
  150. multipers/multiparameter_edge_collapse.py +41 -0
  151. multipers/multiparameter_module_approximation/approximation.h +2541 -0
  152. multipers/multiparameter_module_approximation/debug.h +107 -0
  153. multipers/multiparameter_module_approximation/format_python-cpp.h +292 -0
  154. multipers/multiparameter_module_approximation/utilities.h +428 -0
  155. multipers/multiparameter_module_approximation.cpython-312-darwin.so +0 -0
  156. multipers/multiparameter_module_approximation.pyx +286 -0
  157. multipers/ops.cpython-312-darwin.so +0 -0
  158. multipers/ops.pyx +231 -0
  159. multipers/pickle.py +89 -0
  160. multipers/plots.py +550 -0
  161. multipers/point_measure.cpython-312-darwin.so +0 -0
  162. multipers/point_measure.pyx +409 -0
  163. multipers/simplex_tree_multi.cpython-312-darwin.so +0 -0
  164. multipers/simplex_tree_multi.pxd +136 -0
  165. multipers/simplex_tree_multi.pyx +11719 -0
  166. multipers/simplex_tree_multi.pyx.tp +2102 -0
  167. multipers/slicer.cpython-312-darwin.so +0 -0
  168. multipers/slicer.pxd +2097 -0
  169. multipers/slicer.pxd.tp +263 -0
  170. multipers/slicer.pyx +13042 -0
  171. multipers/slicer.pyx.tp +1259 -0
  172. multipers/tensor/tensor.h +672 -0
  173. multipers/tensor.pxd +13 -0
  174. multipers/test.pyx +44 -0
  175. multipers/tests/__init__.py +70 -0
  176. multipers/torch/__init__.py +1 -0
  177. multipers/torch/diff_grids.py +240 -0
  178. multipers/torch/rips_density.py +310 -0
  179. multipers/vector_interface.pxd +46 -0
  180. multipers-2.4.0b1.dist-info/METADATA +131 -0
  181. multipers-2.4.0b1.dist-info/RECORD +184 -0
  182. multipers-2.4.0b1.dist-info/WHEEL +6 -0
  183. multipers-2.4.0b1.dist-info/licenses/LICENSE +21 -0
  184. multipers-2.4.0b1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,484 @@
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, David Loiseaux
4
+ *
5
+ * Copyright (C) 2025 Inria
6
+ *
7
+ * Modification(s):
8
+ * - YYYY/MM Author: Description of the modification
9
+ */
10
+
11
+ /**
12
+ * @private
13
+ * @file simple_mdspan.h
14
+ * @author Hannah Schreiber, David Loiseaux
15
+ */
16
+
17
+ #ifndef GUDHI_SIMPLE_MDSPAN_H_
18
+ #define GUDHI_SIMPLE_MDSPAN_H_
19
+
20
+ #include <cstddef> // std::size_t
21
+ #include <stdexcept>
22
+ #include <type_traits> // std::remove_cv_t, std::make_unsigned_t, std::integral_constant
23
+ #include <limits>
24
+ #include <initializer_list>
25
+ #include <utility>
26
+ #include <array>
27
+
28
+ #include <gudhi/Debug_utils.h>
29
+
30
+ namespace Gudhi {
31
+
32
+ inline constexpr std::size_t dynamic_extent = std::numeric_limits<std::size_t>::max();
33
+
34
+ template <class IndexType, std::size_t... Extents>
35
+ class extents;
36
+
37
+ namespace detail {
38
+
39
+ template <std::size_t v>
40
+ struct is_dynamic : std::integral_constant<std::size_t, 0> {};
41
+
42
+ template <>
43
+ struct is_dynamic<dynamic_extent> : std::integral_constant<std::size_t, 1> {};
44
+
45
+ template <std::size_t I, class T>
46
+ struct dynamic_count;
47
+
48
+ template <std::size_t I, std::size_t first, std::size_t... Tail>
49
+ struct dynamic_count<I, std::integer_sequence<std::size_t, first, Tail...> >
50
+ : std::integral_constant<std::size_t,
51
+ (is_dynamic<first>::value +
52
+ dynamic_count<I - 1, std::integer_sequence<std::size_t, Tail...>>::value)> {
53
+ };
54
+
55
+ template <std::size_t first, std::size_t... Tail>
56
+ struct dynamic_count<0, std::integer_sequence<std::size_t, first, Tail...> >
57
+ : std::integral_constant<std::size_t, is_dynamic<first>::value> {
58
+ };
59
+
60
+ template <std::size_t first>
61
+ struct dynamic_count<0, std::integer_sequence<std::size_t, first> >
62
+ : std::integral_constant<std::size_t, is_dynamic<first>::value> {};
63
+
64
+ template <std::size_t I, class T>
65
+ struct extent_value;
66
+
67
+ template <std::size_t I, std::size_t first, std::size_t... Tail>
68
+ struct extent_value<I, std::integer_sequence<std::size_t, first, Tail...>>
69
+ : extent_value<I - 1, std::integer_sequence<std::size_t, Tail...>> {};
70
+
71
+ template <std::size_t first, std::size_t... Tail>
72
+ struct extent_value<0, std::integer_sequence<std::size_t, first, Tail...>>
73
+ : std::integral_constant<std::size_t, first> {};
74
+
75
+ template <class T, T I, T N, T... integers>
76
+ struct dynamic_value_sequence {
77
+ using type = typename dynamic_value_sequence<T, I + 1, N, integers..., dynamic_extent>::type;
78
+ };
79
+
80
+ template <class T, T N, T... integers>
81
+ struct dynamic_value_sequence<T, N, N, integers...> {
82
+ using type = std::integer_sequence<T, integers...>;
83
+ };
84
+
85
+ template <class IndexType, std::size_t... Pack>
86
+ constexpr auto dynamic_value_extents(std::integer_sequence<std::size_t, Pack...>)
87
+ {
88
+ return extents<IndexType, Pack...>();
89
+ };
90
+
91
+ template <class IndexType, std::size_t Rank>
92
+ constexpr auto dynamic_value_extents_value =
93
+ dynamic_value_extents<IndexType>((typename Gudhi::detail::dynamic_value_sequence<std::size_t, 0, Rank>::type{}));
94
+
95
+ } // namespace detail
96
+
97
+ template <class IndexType, std::size_t Rank>
98
+ using dextents = decltype(detail::dynamic_value_extents_value<IndexType, Rank>);
99
+
100
+ /**
101
+ * @private
102
+ * @brief Reproduces the behaviour of C++23 `std::extents` class.
103
+ */
104
+ template <class IndexType, std::size_t... Extents>
105
+ class extents
106
+ {
107
+ public:
108
+ using index_type = IndexType;
109
+ using size_type = std::make_unsigned_t<index_type>;
110
+ using rank_type = std::size_t;
111
+
112
+ // observers of the multidimensional index space
113
+ static constexpr rank_type rank() noexcept { return sizeof...(Extents); }
114
+
115
+ static constexpr rank_type rank_dynamic() noexcept
116
+ {
117
+ return detail::dynamic_count<rank() - 1, std::integer_sequence<std::size_t, Extents...> >::value;
118
+ }
119
+
120
+ static constexpr std::size_t static_extent(rank_type r) noexcept
121
+ {
122
+ std::array<std::size_t, sizeof...(Extents)> exts{Extents...};
123
+ return exts[r];
124
+ }
125
+
126
+ constexpr index_type extent(rank_type r) const noexcept
127
+ {
128
+ if (dynamic_extent_shifts_[r] < 0) return static_extent(r);
129
+ return dynamic_extents_[dynamic_extent_shifts_[r]];
130
+ }
131
+
132
+ void update_dynamic_extent(rank_type r, index_type i){
133
+ if (dynamic_extent_shifts_[r] < 0) throw std::invalid_argument("Given rank is not dynamic.");
134
+ dynamic_extents_[dynamic_extent_shifts_[r]] = i;
135
+ }
136
+
137
+ // constructors
138
+ constexpr extents() noexcept : dynamic_extents_(), dynamic_extent_shifts_(_init_shifts()) {}
139
+
140
+ template <class OtherIndexType, std::size_t... OtherExtents>
141
+ constexpr explicit extents(const extents<OtherIndexType, OtherExtents...>& other) noexcept
142
+ : dynamic_extents_(), dynamic_extent_shifts_(_init_shifts())
143
+ {
144
+ for (rank_type r = 0; r < rank(); ++r) {
145
+ if (dynamic_extent_shifts_[r] >= 0) dynamic_extents_[dynamic_extent_shifts_[r]] = other.extent(r);
146
+ }
147
+ }
148
+
149
+ template <class... OtherIndexTypes>
150
+ constexpr explicit extents(OtherIndexTypes... extents) noexcept
151
+ : dynamic_extents_{static_cast<IndexType>(extents)...}, dynamic_extent_shifts_(_init_shifts())
152
+ {}
153
+
154
+ template <class OtherIndexType, std::size_t N>
155
+ constexpr explicit extents(const std::array<OtherIndexType, N>& other) noexcept
156
+ : dynamic_extents_{other}, dynamic_extent_shifts_(_init_shifts())
157
+ {}
158
+
159
+ // comparison operators
160
+ template <class OtherIndexType, std::size_t... OtherExtents>
161
+ friend constexpr bool operator==(const extents& e1, const extents<OtherIndexType, OtherExtents...>& e2) noexcept
162
+ {
163
+ if (e1.rank() != e2.rank()) return false;
164
+ for (rank_type r = 0; r < rank(); ++r) {
165
+ if (e1.extent(r) != e2.extent(r)) return false;
166
+ }
167
+ return true;
168
+ }
169
+
170
+ friend void swap(extents& e1, extents& e2) noexcept
171
+ {
172
+ e1.dynamic_extents_.swap(e2.dynamic_extents_);
173
+ e1.dynamic_extent_shifts_.swap(e2.dynamic_extent_shifts_);
174
+ }
175
+
176
+ friend std::ostream &operator<<(std::ostream &stream, const extents &e)
177
+ {
178
+ stream << "[ " << sizeof...(Extents) << " ] ";
179
+ ((stream << Extents << ' '), ...);
180
+
181
+ return stream;
182
+ }
183
+
184
+ private:
185
+ std::array<index_type, rank_dynamic()> dynamic_extents_;
186
+ std::array<int, rank()> dynamic_extent_shifts_;
187
+
188
+ static constexpr std::array<int, rank()> _init_shifts()
189
+ {
190
+ std::array<std::size_t, sizeof...(Extents)> exts{Extents...};
191
+ std::array<int, rank()> res = {};
192
+ std::size_t index = 0;
193
+ for (rank_type i = 0; i < rank(); ++i) {
194
+ if (exts[i] == dynamic_extent) {
195
+ res[i] = index;
196
+ ++index;
197
+ } else {
198
+ res[i] = -1;
199
+ }
200
+ }
201
+ return res;
202
+ }
203
+ };
204
+
205
+ // Does not seem to work with C++17(?) because the use of 'dextents' is not explicit enough:
206
+ // "trailing return type ‘Gudhi::dextents<long unsigned int, sizeof... (Integrals)>’ of deduction guide is not a
207
+ // specialization of ‘Gudhi::extents<IndexType, Extents>’"
208
+ // Or does someone knows a workaround...?
209
+ // template<class... Integrals>
210
+ // explicit extents(Integrals...) -> dextents<std::size_t, sizeof...(Integrals)>;
211
+
212
+ /**
213
+ * @private
214
+ * @brief Reproduces the behaviour of C++23 `std::layout_right` class.
215
+ */
216
+ class layout_right
217
+ {
218
+ public:
219
+ template<class Extents>
220
+ class mapping
221
+ {
222
+ public:
223
+ using extents_type = Extents;
224
+ using index_type = typename extents_type::index_type;
225
+ using size_type = typename extents_type::size_type;
226
+ using rank_type = typename extents_type::rank_type;
227
+ using layout_type = layout_right;
228
+
229
+ // constructors
230
+ mapping() noexcept = default;
231
+ mapping(const mapping&) noexcept = default;
232
+
233
+ mapping(const extents_type& exts) noexcept : exts_(exts)
234
+ {
235
+ if constexpr (extents_type::rank() != 0) _initialize_strides();
236
+ }
237
+
238
+ mapping& operator=(const mapping&) noexcept = default;
239
+
240
+ // observers
241
+ constexpr const extents_type& extents() const noexcept { return exts_; }
242
+
243
+ index_type required_span_size() const noexcept
244
+ {
245
+ if constexpr (extents_type::rank() == 0) return 0;
246
+ else return ext_shifts_[0] * exts_.extent(0);
247
+ }
248
+
249
+ template <class... Indices>
250
+ constexpr index_type operator()(Indices... indices) const
251
+ {
252
+ return operator()({static_cast<index_type>(indices)...});
253
+ }
254
+
255
+ template <class IndexRange = std::initializer_list<index_type> >
256
+ constexpr index_type operator()(const IndexRange& indices) const
257
+ {
258
+ GUDHI_CHECK(indices.size() == extents_type::rank(), "Wrong number of parameters.");
259
+
260
+ index_type newIndex = 0;
261
+ auto it = indices.begin();
262
+ GUDHI_CHECK_code(unsigned int i = 0);
263
+ for (auto stride : ext_shifts_) {
264
+ GUDHI_CHECK_code(GUDHI_CHECK(*it < exts_.extent(i), "Out of bound index."));
265
+ newIndex += (stride * (*it));
266
+ ++it;
267
+ GUDHI_CHECK_code(++i);
268
+ }
269
+
270
+ return newIndex;
271
+ }
272
+
273
+ static constexpr bool is_always_unique() noexcept { return true; }
274
+
275
+ static constexpr bool is_always_exhaustive() noexcept { return true; }
276
+
277
+ static constexpr bool is_always_strided() noexcept { return true; }
278
+
279
+ static constexpr bool is_unique() noexcept { return true; }
280
+
281
+ static constexpr bool is_exhaustive() noexcept { return true; }
282
+
283
+ static constexpr bool is_strided() noexcept { return true; }
284
+
285
+ index_type stride(rank_type r) const
286
+ {
287
+ GUDHI_CHECK(r < ext_shifts_.size(), "Stride out of bound.");
288
+ return ext_shifts_[r];
289
+ }
290
+
291
+ friend bool operator==(const mapping& m1, const mapping& m2) noexcept { return m1.exts_ == m2.exts_; }
292
+
293
+ friend void swap(mapping& m1, mapping& m2) noexcept
294
+ {
295
+ swap(m1.exts_, m2.exts_);
296
+ m1.ext_shifts_.swap(m2.ext_shifts_);
297
+ }
298
+
299
+ // update can be faster than reconstructing everytime if only relatively small r's are updated.
300
+ void update_extent(rank_type r, index_type new_value)
301
+ {
302
+ GUDHI_CHECK(r < extents_type::rank(), "Index out of bound.");
303
+ exts_.update_dynamic_extent(r, new_value);
304
+ _update_strides(r);
305
+ }
306
+
307
+ private:
308
+ extents_type exts_;
309
+ std::array<index_type,extents_type::rank()> ext_shifts_;
310
+
311
+ constexpr void _initialize_strides()
312
+ {
313
+ ext_shifts_[extents_type::rank() - 1] = 1;
314
+ for (auto i = extents_type::rank() - 1; i > 0; --i) {
315
+ ext_shifts_[i - 1] = ext_shifts_[i] * exts_.extent(i);
316
+ }
317
+ }
318
+
319
+ constexpr void _update_strides(rank_type start)
320
+ {
321
+ for (auto i = start; i > 0; --i) {
322
+ ext_shifts_[i - 1] = ext_shifts_[i] * exts_.extent(i);
323
+ }
324
+ }
325
+ };
326
+ };
327
+
328
+ /**
329
+ * @private
330
+ * @brief Simplified version of C++23 `std::mdspan` class that compiles with C++17.
331
+ *
332
+ * Main differences:
333
+ * - there is no AccessorPolicy template: the container pointed by the stored pointer is assumed to be vector-like,
334
+ * i.e., continuous and, e.g., you can do `ptr_ + 2` to access the third element,
335
+ * - does not implement any "submdspan" methods (C++26),
336
+ * - `object[i,j,k,...]` is replaced by either `object(i,j,k,...)` or `object[{i,j,k,...}]`, as C++17 does not
337
+ * allow more than one argument for `operator[]`,
338
+ * - two additional methods: `update_extent` and `update_data` to avoid recalculating the helpers in the mapping class
339
+ * at each size modification of the underlying container, when the update is trivial (i.e. when only rank 0 is
340
+ * modified, which happens often in our use case).
341
+ */
342
+ template <typename T, class Extents, class LayoutPolicy = layout_right>
343
+ class Simple_mdspan
344
+ {
345
+ public:
346
+ using layout_type = LayoutPolicy;
347
+ using mapping_type = typename LayoutPolicy::template mapping<Extents>;
348
+ using extents_type = Extents;
349
+ using element_type = T;
350
+ using value_type = std::remove_cv_t<T>;
351
+ using index_type = typename mapping_type::index_type;
352
+ using size_type = typename mapping_type::size_type;
353
+ using rank_type = typename mapping_type::rank_type;
354
+ using data_handle_type = T*;
355
+ using reference = T&;
356
+
357
+ Simple_mdspan() : ptr_(nullptr) {}
358
+
359
+ Simple_mdspan(const Simple_mdspan& rhs) = default;
360
+ Simple_mdspan(Simple_mdspan&& rhs) = default;
361
+
362
+ template <class... IndexTypes>
363
+ explicit Simple_mdspan(data_handle_type ptr, IndexTypes... exts)
364
+ : ptr_(ptr), map_(extents_type(exts...))
365
+ {
366
+ GUDHI_CHECK(ptr != nullptr || empty() || Extents::rank() == 0, "Given pointer is not properly initialized.");
367
+ }
368
+
369
+ template <class OtherIndexType, size_t N>
370
+ constexpr explicit Simple_mdspan(data_handle_type ptr, const std::array<OtherIndexType, N>& exts)
371
+ : ptr_(ptr), map_(extents_type(exts))
372
+ {
373
+ GUDHI_CHECK(ptr != nullptr || empty() || Extents::rank() == 0, "Given pointer is not properly initialized.");
374
+ }
375
+
376
+ Simple_mdspan(data_handle_type ptr, const mapping_type& m) : ptr_(ptr), map_(m) {}
377
+
378
+ Simple_mdspan& operator=(const Simple_mdspan& rhs) = default;
379
+ Simple_mdspan& operator=(Simple_mdspan&& rhs) = default;
380
+
381
+ // version with [] not possible before C++23
382
+ template <class... IndexTypes>
383
+ constexpr reference operator()(IndexTypes... indices) const
384
+ {
385
+ return operator[]({static_cast<index_type>(indices)...});
386
+ }
387
+
388
+ template <class IndexRange = std::initializer_list<index_type> >
389
+ reference operator[](const IndexRange& indices) const
390
+ {
391
+ return *(ptr_ + map_(indices));
392
+ }
393
+
394
+ constexpr rank_type rank() noexcept { return map_.extents().rank(); }
395
+
396
+ constexpr rank_type rank_dynamic() noexcept { return map_.extents().rank_dynamic(); }
397
+
398
+ static constexpr std::size_t static_extent(rank_type r) noexcept { return std::numeric_limits<std::size_t>::max(); }
399
+
400
+ constexpr index_type extent(rank_type r) const
401
+ {
402
+ GUDHI_CHECK(r < map_.extents().rank(), "Out of bound index.");
403
+ return map_.extents().extent(r);
404
+ }
405
+
406
+ constexpr size_type size() const noexcept { return map_.required_span_size(); }
407
+
408
+ constexpr bool empty() const noexcept { return map_.required_span_size() == 0; }
409
+
410
+ constexpr index_type stride(rank_type r) const { return map_.stride(r); }
411
+
412
+ constexpr const extents_type& extents() const noexcept { return map_.extents(); }
413
+
414
+ constexpr const data_handle_type& data_handle() const noexcept { return ptr_; }
415
+
416
+ constexpr const mapping_type& mapping() const noexcept { return map_; }
417
+
418
+ // if is_unique() is true for all possible instantiations of this class
419
+ static constexpr bool is_always_unique() { return mapping_type::is_always_unique(); }
420
+
421
+ // if is_exhaustive() is true for all possible instantiations of this class
422
+ static constexpr bool is_always_exhaustive() { return mapping_type::is_always_exhaustive(); }
423
+
424
+ // if is_strided() is true for all possible instantiations of this class
425
+ static constexpr bool is_always_strided() { return mapping_type::is_always_strided(); }
426
+
427
+ // unicity of the mapping (i,j,k,...) -> real index
428
+ constexpr bool is_unique() const { return map_.is_unique(); }
429
+
430
+ // if all real indices have a preimage in form (i,j,k,...)
431
+ constexpr bool is_exhaustive() const { return map_.is_exhaustive(); }
432
+
433
+ // if distance in memory is constant between two values in same rank
434
+ constexpr bool is_strided() const { return map_.is_strided(); }
435
+
436
+ friend constexpr void swap(Simple_mdspan& x, Simple_mdspan& y) noexcept
437
+ {
438
+ std::swap(x.ptr_, y.ptr_);
439
+ swap(x.map_, y.map_);
440
+ }
441
+
442
+ // as not everything is computed at compile time as for mdspan, update is usually faster than reconstructing
443
+ // everytime.
444
+ void update_extent(rank_type r, index_type new_value) { map_.update_extent(r, new_value); }
445
+
446
+ // for update_extent to make sense, as resizing the vector can move it in the memory
447
+ void update_data(data_handle_type ptr)
448
+ {
449
+ GUDHI_CHECK(ptr != nullptr, "Null pointer not valid input.");
450
+ ptr_ = ptr;
451
+ }
452
+
453
+ private:
454
+ data_handle_type ptr_;
455
+ mapping_type map_;
456
+ };
457
+
458
+ template <class CArray>
459
+ Simple_mdspan(CArray&)
460
+ -> Simple_mdspan<std::remove_all_extents_t<CArray>, Gudhi::extents<std::size_t, std::extent_v<CArray, 0>>>;
461
+
462
+ template <class Pointer>
463
+ Simple_mdspan(Pointer&&)
464
+ -> Simple_mdspan<std::remove_pointer_t<std::remove_reference_t<Pointer>>, Gudhi::extents<std::size_t>>;
465
+
466
+ template <class ElementType, class... Integrals>
467
+ explicit Simple_mdspan(ElementType*, Integrals...)
468
+ -> Simple_mdspan<ElementType, Gudhi::dextents<std::size_t, sizeof...(Integrals)>>;
469
+
470
+ template <class ElementType, class OtherIndexType, std::size_t N>
471
+ Simple_mdspan(ElementType*, const std::array<OtherIndexType, N>&)
472
+ -> Simple_mdspan<ElementType, Gudhi::dextents<std::size_t, N>>;
473
+
474
+ template <class ElementType, class IndexType, std::size_t... ExtentsPack>
475
+ Simple_mdspan(ElementType*, const Gudhi::extents<IndexType, ExtentsPack...>&)
476
+ -> Simple_mdspan<ElementType, Gudhi::extents<IndexType, ExtentsPack...>>;
477
+
478
+ template <class ElementType, class MappingType>
479
+ Simple_mdspan(ElementType*, const MappingType&)
480
+ -> Simple_mdspan<ElementType, typename MappingType::extents_type, typename MappingType::layout_type>;
481
+
482
+ } // namespace Gudhi
483
+
484
+ #endif // GUDHI_SIMPLE_MDSPAN_H_