multipers 2.3.3b6__cp312-cp312-macosx_10_13_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of multipers might be problematic. Click here for more details.

Files changed (183) hide show
  1. multipers/.dylibs/libc++.1.0.dylib +0 -0
  2. multipers/.dylibs/libtbb.12.16.dylib +0 -0
  3. multipers/__init__.py +33 -0
  4. multipers/_signed_measure_meta.py +453 -0
  5. multipers/_slicer_meta.py +211 -0
  6. multipers/array_api/__init__.py +45 -0
  7. multipers/array_api/numpy.py +41 -0
  8. multipers/array_api/torch.py +58 -0
  9. multipers/data/MOL2.py +458 -0
  10. multipers/data/UCR.py +18 -0
  11. multipers/data/__init__.py +1 -0
  12. multipers/data/graphs.py +466 -0
  13. multipers/data/immuno_regions.py +27 -0
  14. multipers/data/minimal_presentation_to_st_bf.py +0 -0
  15. multipers/data/pytorch2simplextree.py +91 -0
  16. multipers/data/shape3d.py +101 -0
  17. multipers/data/synthetic.py +113 -0
  18. multipers/distances.py +202 -0
  19. multipers/filtration_conversions.pxd +229 -0
  20. multipers/filtration_conversions.pxd.tp +84 -0
  21. multipers/filtrations/__init__.py +18 -0
  22. multipers/filtrations/density.py +574 -0
  23. multipers/filtrations/filtrations.py +361 -0
  24. multipers/filtrations.pxd +224 -0
  25. multipers/function_rips.cpython-312-darwin.so +0 -0
  26. multipers/function_rips.pyx +105 -0
  27. multipers/grids.cpython-312-darwin.so +0 -0
  28. multipers/grids.pyx +433 -0
  29. multipers/gudhi/Persistence_slices_interface.h +132 -0
  30. multipers/gudhi/Simplex_tree_interface.h +239 -0
  31. multipers/gudhi/Simplex_tree_multi_interface.h +551 -0
  32. multipers/gudhi/cubical_to_boundary.h +59 -0
  33. multipers/gudhi/gudhi/Bitmap_cubical_complex.h +450 -0
  34. multipers/gudhi/gudhi/Bitmap_cubical_complex_base.h +1070 -0
  35. multipers/gudhi/gudhi/Bitmap_cubical_complex_periodic_boundary_conditions_base.h +579 -0
  36. multipers/gudhi/gudhi/Debug_utils.h +45 -0
  37. multipers/gudhi/gudhi/Fields/Multi_field.h +484 -0
  38. multipers/gudhi/gudhi/Fields/Multi_field_operators.h +455 -0
  39. multipers/gudhi/gudhi/Fields/Multi_field_shared.h +450 -0
  40. multipers/gudhi/gudhi/Fields/Multi_field_small.h +531 -0
  41. multipers/gudhi/gudhi/Fields/Multi_field_small_operators.h +507 -0
  42. multipers/gudhi/gudhi/Fields/Multi_field_small_shared.h +531 -0
  43. multipers/gudhi/gudhi/Fields/Z2_field.h +355 -0
  44. multipers/gudhi/gudhi/Fields/Z2_field_operators.h +376 -0
  45. multipers/gudhi/gudhi/Fields/Zp_field.h +420 -0
  46. multipers/gudhi/gudhi/Fields/Zp_field_operators.h +400 -0
  47. multipers/gudhi/gudhi/Fields/Zp_field_shared.h +418 -0
  48. multipers/gudhi/gudhi/Flag_complex_edge_collapser.h +337 -0
  49. multipers/gudhi/gudhi/Matrix.h +2107 -0
  50. multipers/gudhi/gudhi/Multi_critical_filtration.h +1038 -0
  51. multipers/gudhi/gudhi/Multi_persistence/Box.h +174 -0
  52. multipers/gudhi/gudhi/Multi_persistence/Line.h +282 -0
  53. multipers/gudhi/gudhi/Off_reader.h +173 -0
  54. multipers/gudhi/gudhi/One_critical_filtration.h +1441 -0
  55. multipers/gudhi/gudhi/Persistence_matrix/Base_matrix.h +769 -0
  56. multipers/gudhi/gudhi/Persistence_matrix/Base_matrix_with_column_compression.h +686 -0
  57. multipers/gudhi/gudhi/Persistence_matrix/Boundary_matrix.h +842 -0
  58. multipers/gudhi/gudhi/Persistence_matrix/Chain_matrix.h +1350 -0
  59. multipers/gudhi/gudhi/Persistence_matrix/Id_to_index_overlay.h +1105 -0
  60. multipers/gudhi/gudhi/Persistence_matrix/Position_to_index_overlay.h +859 -0
  61. multipers/gudhi/gudhi/Persistence_matrix/RU_matrix.h +910 -0
  62. multipers/gudhi/gudhi/Persistence_matrix/allocators/entry_constructors.h +139 -0
  63. multipers/gudhi/gudhi/Persistence_matrix/base_pairing.h +230 -0
  64. multipers/gudhi/gudhi/Persistence_matrix/base_swap.h +211 -0
  65. multipers/gudhi/gudhi/Persistence_matrix/boundary_cell_position_to_id_mapper.h +60 -0
  66. multipers/gudhi/gudhi/Persistence_matrix/boundary_face_position_to_id_mapper.h +60 -0
  67. multipers/gudhi/gudhi/Persistence_matrix/chain_pairing.h +136 -0
  68. multipers/gudhi/gudhi/Persistence_matrix/chain_rep_cycles.h +190 -0
  69. multipers/gudhi/gudhi/Persistence_matrix/chain_vine_swap.h +616 -0
  70. multipers/gudhi/gudhi/Persistence_matrix/columns/chain_column_extra_properties.h +150 -0
  71. multipers/gudhi/gudhi/Persistence_matrix/columns/column_dimension_holder.h +106 -0
  72. multipers/gudhi/gudhi/Persistence_matrix/columns/column_utilities.h +219 -0
  73. multipers/gudhi/gudhi/Persistence_matrix/columns/entry_types.h +327 -0
  74. multipers/gudhi/gudhi/Persistence_matrix/columns/heap_column.h +1140 -0
  75. multipers/gudhi/gudhi/Persistence_matrix/columns/intrusive_list_column.h +934 -0
  76. multipers/gudhi/gudhi/Persistence_matrix/columns/intrusive_set_column.h +934 -0
  77. multipers/gudhi/gudhi/Persistence_matrix/columns/list_column.h +980 -0
  78. multipers/gudhi/gudhi/Persistence_matrix/columns/naive_vector_column.h +1092 -0
  79. multipers/gudhi/gudhi/Persistence_matrix/columns/row_access.h +192 -0
  80. multipers/gudhi/gudhi/Persistence_matrix/columns/set_column.h +921 -0
  81. multipers/gudhi/gudhi/Persistence_matrix/columns/small_vector_column.h +1093 -0
  82. multipers/gudhi/gudhi/Persistence_matrix/columns/unordered_set_column.h +1012 -0
  83. multipers/gudhi/gudhi/Persistence_matrix/columns/vector_column.h +1244 -0
  84. multipers/gudhi/gudhi/Persistence_matrix/matrix_dimension_holders.h +186 -0
  85. multipers/gudhi/gudhi/Persistence_matrix/matrix_row_access.h +164 -0
  86. multipers/gudhi/gudhi/Persistence_matrix/ru_pairing.h +156 -0
  87. multipers/gudhi/gudhi/Persistence_matrix/ru_rep_cycles.h +376 -0
  88. multipers/gudhi/gudhi/Persistence_matrix/ru_vine_swap.h +540 -0
  89. multipers/gudhi/gudhi/Persistent_cohomology/Field_Zp.h +118 -0
  90. multipers/gudhi/gudhi/Persistent_cohomology/Multi_field.h +173 -0
  91. multipers/gudhi/gudhi/Persistent_cohomology/Persistent_cohomology_column.h +128 -0
  92. multipers/gudhi/gudhi/Persistent_cohomology.h +745 -0
  93. multipers/gudhi/gudhi/Points_off_io.h +171 -0
  94. multipers/gudhi/gudhi/Simple_object_pool.h +69 -0
  95. multipers/gudhi/gudhi/Simplex_tree/Simplex_tree_iterators.h +463 -0
  96. multipers/gudhi/gudhi/Simplex_tree/Simplex_tree_node_explicit_storage.h +83 -0
  97. multipers/gudhi/gudhi/Simplex_tree/Simplex_tree_siblings.h +106 -0
  98. multipers/gudhi/gudhi/Simplex_tree/Simplex_tree_star_simplex_iterators.h +277 -0
  99. multipers/gudhi/gudhi/Simplex_tree/hooks_simplex_base.h +62 -0
  100. multipers/gudhi/gudhi/Simplex_tree/indexing_tag.h +27 -0
  101. multipers/gudhi/gudhi/Simplex_tree/serialization_utils.h +62 -0
  102. multipers/gudhi/gudhi/Simplex_tree/simplex_tree_options.h +157 -0
  103. multipers/gudhi/gudhi/Simplex_tree.h +2794 -0
  104. multipers/gudhi/gudhi/Simplex_tree_multi.h +152 -0
  105. multipers/gudhi/gudhi/distance_functions.h +62 -0
  106. multipers/gudhi/gudhi/graph_simplicial_complex.h +104 -0
  107. multipers/gudhi/gudhi/persistence_interval.h +253 -0
  108. multipers/gudhi/gudhi/persistence_matrix_options.h +170 -0
  109. multipers/gudhi/gudhi/reader_utils.h +367 -0
  110. multipers/gudhi/mma_interface_coh.h +256 -0
  111. multipers/gudhi/mma_interface_h0.h +223 -0
  112. multipers/gudhi/mma_interface_matrix.h +293 -0
  113. multipers/gudhi/naive_merge_tree.h +536 -0
  114. multipers/gudhi/scc_io.h +310 -0
  115. multipers/gudhi/truc.h +1403 -0
  116. multipers/io.cpython-312-darwin.so +0 -0
  117. multipers/io.pyx +644 -0
  118. multipers/ml/__init__.py +0 -0
  119. multipers/ml/accuracies.py +90 -0
  120. multipers/ml/invariants_with_persistable.py +79 -0
  121. multipers/ml/kernels.py +176 -0
  122. multipers/ml/mma.py +713 -0
  123. multipers/ml/one.py +472 -0
  124. multipers/ml/point_clouds.py +352 -0
  125. multipers/ml/signed_measures.py +1589 -0
  126. multipers/ml/sliced_wasserstein.py +461 -0
  127. multipers/ml/tools.py +113 -0
  128. multipers/mma_structures.cpython-312-darwin.so +0 -0
  129. multipers/mma_structures.pxd +128 -0
  130. multipers/mma_structures.pyx +2786 -0
  131. multipers/mma_structures.pyx.tp +1094 -0
  132. multipers/multi_parameter_rank_invariant/diff_helpers.h +84 -0
  133. multipers/multi_parameter_rank_invariant/euler_characteristic.h +97 -0
  134. multipers/multi_parameter_rank_invariant/function_rips.h +322 -0
  135. multipers/multi_parameter_rank_invariant/hilbert_function.h +769 -0
  136. multipers/multi_parameter_rank_invariant/persistence_slices.h +148 -0
  137. multipers/multi_parameter_rank_invariant/rank_invariant.h +369 -0
  138. multipers/multiparameter_edge_collapse.py +41 -0
  139. multipers/multiparameter_module_approximation/approximation.h +2330 -0
  140. multipers/multiparameter_module_approximation/combinatory.h +129 -0
  141. multipers/multiparameter_module_approximation/debug.h +107 -0
  142. multipers/multiparameter_module_approximation/euler_curves.h +0 -0
  143. multipers/multiparameter_module_approximation/format_python-cpp.h +286 -0
  144. multipers/multiparameter_module_approximation/heap_column.h +238 -0
  145. multipers/multiparameter_module_approximation/images.h +79 -0
  146. multipers/multiparameter_module_approximation/list_column.h +174 -0
  147. multipers/multiparameter_module_approximation/list_column_2.h +232 -0
  148. multipers/multiparameter_module_approximation/ru_matrix.h +347 -0
  149. multipers/multiparameter_module_approximation/set_column.h +135 -0
  150. multipers/multiparameter_module_approximation/structure_higher_dim_barcode.h +36 -0
  151. multipers/multiparameter_module_approximation/unordered_set_column.h +166 -0
  152. multipers/multiparameter_module_approximation/utilities.h +403 -0
  153. multipers/multiparameter_module_approximation/vector_column.h +223 -0
  154. multipers/multiparameter_module_approximation/vector_matrix.h +331 -0
  155. multipers/multiparameter_module_approximation/vineyards.h +464 -0
  156. multipers/multiparameter_module_approximation/vineyards_trajectories.h +649 -0
  157. multipers/multiparameter_module_approximation.cpython-312-darwin.so +0 -0
  158. multipers/multiparameter_module_approximation.pyx +235 -0
  159. multipers/pickle.py +90 -0
  160. multipers/plots.py +456 -0
  161. multipers/point_measure.cpython-312-darwin.so +0 -0
  162. multipers/point_measure.pyx +395 -0
  163. multipers/simplex_tree_multi.cpython-312-darwin.so +0 -0
  164. multipers/simplex_tree_multi.pxd +134 -0
  165. multipers/simplex_tree_multi.pyx +10840 -0
  166. multipers/simplex_tree_multi.pyx.tp +2009 -0
  167. multipers/slicer.cpython-312-darwin.so +0 -0
  168. multipers/slicer.pxd +3034 -0
  169. multipers/slicer.pxd.tp +234 -0
  170. multipers/slicer.pyx +20481 -0
  171. multipers/slicer.pyx.tp +1088 -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 +62 -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-2.3.3b6.dist-info/METADATA +128 -0
  180. multipers-2.3.3b6.dist-info/RECORD +183 -0
  181. multipers-2.3.3b6.dist-info/WHEEL +6 -0
  182. multipers-2.3.3b6.dist-info/licenses/LICENSE +21 -0
  183. multipers-2.3.3b6.dist-info/top_level.txt +1 -0
@@ -0,0 +1,507 @@
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, Clément Maria
4
+ *
5
+ * Copyright (C) 2022-24 Inria
6
+ *
7
+ * Modification(s):
8
+ * - YYYY/MM Author: Description of the modification
9
+ */
10
+
11
+ /**
12
+ * @file Multi_field_small_operators.h
13
+ * @author Hannah Schreiber, Clément Maria
14
+ * @brief Contains the @ref Gudhi::persistence_fields::Multi_field_operators_with_small_characteristics class.
15
+ */
16
+
17
+ #ifndef MATRIX_FIELD_MULTI_SMALL_OPERATORS_H_
18
+ #define MATRIX_FIELD_MULTI_SMALL_OPERATORS_H_
19
+
20
+ #include <utility>
21
+ #include <vector>
22
+ #include <limits.h>
23
+ #include <stdexcept>
24
+ #include <numeric>
25
+
26
+ namespace Gudhi {
27
+ namespace persistence_fields {
28
+
29
+ /**
30
+ * @class Multi_field_operators_with_small_characteristics Multi_field_small_operators.h \
31
+ * gudhi/Fields/Multi_field_small_operators.h
32
+ * @ingroup persistence_fields
33
+ *
34
+ * @brief Class defining operators for a multi-field with "consecutive" characteristic range, such that
35
+ * `productOfAllCharacteristics ^ 2` fits into an unsigned int.
36
+ */
37
+ class Multi_field_operators_with_small_characteristics
38
+ {
39
+ public:
40
+ using Element = unsigned int; /**< Type for the elements in the field. */
41
+ using Characteristic = Element; /**< Type for the field characteristic. */
42
+
43
+ /**
44
+ * @brief Default constructor, sets the product of all characteristics to 0.
45
+ */
46
+ Multi_field_operators_with_small_characteristics() : productOfAllCharacteristics_(0) /* , multiplicativeID_(1) */
47
+ {}
48
+ /**
49
+ * @brief Constructor setting the characteristics to all prime numbers between the two given integers.
50
+ * The product of all primes to the square has to fit into an unsigned int.
51
+ *
52
+ * @param minCharacteristic Smallest value of a prime.
53
+ * @param maxCharacteristic Highest value of a prime.
54
+ */
55
+ Multi_field_operators_with_small_characteristics(int minCharacteristic, int maxCharacteristic)
56
+ : productOfAllCharacteristics_(0) //, multiplicativeID_(1)
57
+ {
58
+ set_characteristic(minCharacteristic, maxCharacteristic);
59
+ }
60
+ /**
61
+ * @brief Copy constructor.
62
+ *
63
+ * @param toCopy Operators to copy.
64
+ */
65
+ Multi_field_operators_with_small_characteristics(const Multi_field_operators_with_small_characteristics& toCopy)
66
+ : primes_(toCopy.primes_),
67
+ productOfAllCharacteristics_(toCopy.productOfAllCharacteristics_),
68
+ partials_(toCopy.partials_) /* ,
69
+ multiplicativeID_(toCopy.multiplicativeID_) */
70
+ {}
71
+ /**
72
+ * @brief Move constructor.
73
+ *
74
+ * @param toMove Operators to move.
75
+ */
76
+ Multi_field_operators_with_small_characteristics(Multi_field_operators_with_small_characteristics&& toMove) noexcept
77
+ : primes_(std::move(toMove.primes_)),
78
+ productOfAllCharacteristics_(std::move(toMove.productOfAllCharacteristics_)),
79
+ partials_(std::move(toMove.partials_)) /* ,
80
+ multiplicativeID_(std::move(toMove.multiplicativeID_)) */
81
+ {}
82
+
83
+ /**
84
+ * @brief Set the characteristics of the field, which are stored in a single value as a product of all of them.
85
+ * The characteristics will be all prime numbers in the given interval.
86
+ * The product of all primes to the square has to fit into an unsigned int.
87
+ *
88
+ * @param minimum Smallest value of a prime.
89
+ * @param maximum Highest value of a prime.
90
+ */
91
+ void set_characteristic(int minimum, int maximum) {
92
+ if (maximum < 2) throw std::invalid_argument("Characteristic must be strictly positive");
93
+ if (minimum > maximum) throw std::invalid_argument("The given interval is not valid.");
94
+ if (minimum == maximum && !_is_prime(minimum))
95
+ throw std::invalid_argument("The given interval does not contain a prime number.");
96
+
97
+ productOfAllCharacteristics_ = 1;
98
+ primes_.clear();
99
+ for (unsigned int i = minimum; i <= static_cast<unsigned int>(maximum); ++i) {
100
+ if (_is_prime(i)) {
101
+ primes_.push_back(i);
102
+ productOfAllCharacteristics_ *= i;
103
+ }
104
+ }
105
+
106
+ if (primes_.empty()) throw std::invalid_argument("The given interval does not contain a prime number.");
107
+
108
+ partials_.resize(primes_.size());
109
+ for (unsigned int i = 0; i < primes_.size(); ++i) {
110
+ unsigned int p = primes_[i];
111
+ Characteristic base = productOfAllCharacteristics_ / p;
112
+ unsigned int exp = p - 1;
113
+ partials_[i] = 1;
114
+
115
+ while (exp > 0) {
116
+ // If exp is odd, multiply with result
117
+ if (exp & 1) partials_[i] = _multiply(partials_[i], base, productOfAllCharacteristics_);
118
+ // y must be even now
119
+ exp = exp >> 1; // y = y/2
120
+ base = _multiply(base, base, productOfAllCharacteristics_);
121
+ }
122
+ }
123
+
124
+ // If I understood the paper well, multiplicativeID_ always equals to 1. But in Clement's code,
125
+ // multiplicativeID_ is computed (see commented loop below). TODO: verify with Clement.
126
+ // for (unsigned int i = 0; i < partials_.size(); ++i){
127
+ // multiplicativeID_ = (multiplicativeID_ + partials_[i]) % productOfAllCharacteristics_;
128
+ // }
129
+ }
130
+ /**
131
+ * @brief Returns the current characteristics as the product of all of them.
132
+ *
133
+ * @return The value of the current characteristic.
134
+ */
135
+ const Characteristic& get_characteristic() const { return productOfAllCharacteristics_; }
136
+
137
+ /**
138
+ * @brief Returns the value of an element in the field.
139
+ * That is the positive value of the integer modulo the current characteristic.
140
+ *
141
+ * @param e Integer to return the value from.
142
+ * @return @p e modulo the current characteristic, such that the result is positive.
143
+ */
144
+ Element get_value(Element e) const {
145
+ return e < productOfAllCharacteristics_ ? e : e % productOfAllCharacteristics_;
146
+ }
147
+
148
+ /**
149
+ * @brief Returns the sum of two elements in the field.
150
+ *
151
+ * @param e1 First element.
152
+ * @param e2 Second element.
153
+ * @return `(e1 + e2) % productOfAllCharacteristics`, such that the result is positive.
154
+ */
155
+ Element add(Element e1, Element e2) const {
156
+ return _add(get_value(e1), get_value(e2), productOfAllCharacteristics_);
157
+ }
158
+
159
+ /**
160
+ * @brief Stores in the first element the sum of two given elements in the field, that is
161
+ * `(e1 + e2) % productOfAllCharacteristics`, such that the result is positive.
162
+ *
163
+ * @param e1 First element.
164
+ * @param e2 Second element.
165
+ */
166
+ void add_inplace(Element& e1, Element e2) const {
167
+ e1 = _add(get_value(e1), get_value(e2), productOfAllCharacteristics_);
168
+ }
169
+
170
+ /**
171
+ * @brief Returns the subtraction in the field of the first element by the second element.
172
+ *
173
+ * @param e1 First element.
174
+ * @param e2 Second element.
175
+ * @return `(e1 - e2) % productOfAllCharacteristics`, such that the result is positive.
176
+ */
177
+ Element subtract(Element e1, Element e2) const {
178
+ return _subtract(get_value(e1), get_value(e2), productOfAllCharacteristics_);
179
+ }
180
+
181
+ /**
182
+ * @brief Stores in the first element the subtraction in the field of the first element by the second element,
183
+ * that is `(e1 - e2) % productOfAllCharacteristics`, such that the result is positive.
184
+ *
185
+ * @param e1 First element.
186
+ * @param e2 Second element.
187
+ */
188
+ void subtract_inplace_front(Element& e1, Element e2) const {
189
+ e1 = _subtract(get_value(e1), get_value(e2), productOfAllCharacteristics_);
190
+ }
191
+ /**
192
+ * @brief Stores in the second element the subtraction in the field of the first element by the second element,
193
+ * that is `(e1 - e2) % productOfAllCharacteristics`, such that the result is positive.
194
+ *
195
+ * @param e1 First element.
196
+ * @param e2 Second element.
197
+ */
198
+ void subtract_inplace_back(Element e1, Element& e2) const {
199
+ e2 = _subtract(get_value(e1), get_value(e2), productOfAllCharacteristics_);
200
+ }
201
+
202
+ /**
203
+ * @brief Returns the multiplication of two elements in the field.
204
+ *
205
+ * @param e1 First element.
206
+ * @param e2 Second element.
207
+ * @return `(e1 * e2) % productOfAllCharacteristics`, such that the result is positive.
208
+ */
209
+ Element multiply(Element e1, Element e2) const {
210
+ return _multiply(get_value(e1), get_value(e2), productOfAllCharacteristics_);
211
+ }
212
+
213
+ /**
214
+ * @brief Stores in the first element the multiplication of two given elements in the field,
215
+ * that is `(e1 * e2) % productOfAllCharacteristics`, such that the result is positive.
216
+ *
217
+ * @param e1 First element.
218
+ * @param e2 Second element.
219
+ */
220
+ void multiply_inplace(Element& e1, Element e2) const {
221
+ e1 = _multiply(get_value(e1), get_value(e2), productOfAllCharacteristics_);
222
+ }
223
+
224
+ /**
225
+ * @brief Multiplies the first element with the second one and adds the third one. Returns the result in the field.
226
+ *
227
+ * @warning Not overflow safe.
228
+ *
229
+ * @param e First element.
230
+ * @param m Second element.
231
+ * @param a Third element.
232
+ * @return `(e * m + a) % productOfAllCharacteristics`, such that the result is positive.
233
+ */
234
+ Element multiply_and_add(Element e, Element m, Element a) const { return get_value(e * m + a); }
235
+
236
+ /**
237
+ * @brief Multiplies the first element with the second one and adds the third one, that is
238
+ * `(e * m + a) % productOfAllCharacteristics`, such that the result is positive.
239
+ * Stores the result in the first element.
240
+ *
241
+ * @warning Not overflow safe.
242
+ *
243
+ * @param e First element.
244
+ * @param m Second element.
245
+ * @param a Third element.
246
+ */
247
+ void multiply_and_add_inplace_front(Element& e, Element m, Element a) const {
248
+ e = get_value(e * m + a);
249
+ }
250
+ /**
251
+ * @brief Multiplies the first element with the second one and adds the third one, that is
252
+ * `(e * m + a) % productOfAllCharacteristics`, such that the result is positive.
253
+ * Stores the result in the third element.
254
+ *
255
+ * @warning Not overflow safe.
256
+ *
257
+ * @param e First element.
258
+ * @param m Second element.
259
+ * @param a Third element.
260
+ */
261
+ void multiply_and_add_inplace_back(Element e, Element m, Element& a) const {
262
+ a = get_value(e * m + a);
263
+ }
264
+
265
+ /**
266
+ * @brief Adds the first element to the second one and multiplies the third one with it.
267
+ * Returns the result in the field.
268
+ *
269
+ * @warning Not overflow safe.
270
+ *
271
+ * @param e First element.
272
+ * @param a Second element.
273
+ * @param m Third element.
274
+ * @return `((e + a) * m) % productOfAllCharacteristics`, such that the result is positive.
275
+ */
276
+ Element add_and_multiply(Element e, Element a, Element m) const { return get_value((e + a) * m); }
277
+
278
+ /**
279
+ * @brief Adds the first element to the second one and multiplies the third one with it, that is
280
+ * `((e + a) * m) % productOfAllCharacteristics`, such that the result is positive.
281
+ * Stores the result in the first element.
282
+ *
283
+ * @warning Not overflow safe.
284
+ *
285
+ * @param e First element.
286
+ * @param a Second element.
287
+ * @param m Third element.
288
+ */
289
+ void add_and_multiply_inplace_front(Element& e, Element a, Element m) const {
290
+ e = get_value((e + a) * m);
291
+ }
292
+ /**
293
+ * @brief Adds the first element to the second one and multiplies the third one with it, that is
294
+ * `((e + a) * m) % productOfAllCharacteristics`, such that the result is positive.
295
+ * Stores the result in the third element.
296
+ *
297
+ * @warning Not overflow safe.
298
+ *
299
+ * @param e First element.
300
+ * @param a Second element.
301
+ * @param m Third element.
302
+ */
303
+ void add_and_multiply_inplace_back(Element e, Element a, Element& m) const {
304
+ m = get_value((e + a) * m);
305
+ }
306
+
307
+ /**
308
+ * @brief Returns true if the two given elements are equal in the field, false otherwise.
309
+ *
310
+ * @param e1 First element to compare.
311
+ * @param e2 Second element to compare.
312
+ * @return true If `e1 % productOfAllCharacteristics == e2 % productOfAllCharacteristics`.
313
+ * @return false Otherwise.
314
+ */
315
+ bool are_equal(Element e1, Element e2) const { return get_value(e1) == get_value(e2); }
316
+
317
+ /**
318
+ * @brief Returns the inverse of the given element in the sense of @cite boissonnat:hal-00922572 with respect
319
+ * to the product of all characteristics.
320
+ *
321
+ * @param e Element to get the inverse from.
322
+ * @return Inverse in the current field.
323
+ */
324
+ Element get_inverse(const Element& e) const {
325
+ return get_partial_inverse(e, productOfAllCharacteristics_).first;
326
+ }
327
+ /**
328
+ * @brief Returns the inverse of the given element in the multi-field corresponding to the given sub-product
329
+ * of the product of all characteristics in the multi-field. See @cite boissonnat:hal-00922572 for more details.
330
+ *
331
+ * @param e Element to get the inverse from.
332
+ * @param productOfCharacteristics Product of the different characteristics to take into account in the multi-field.
333
+ * @return Pair of the inverse of @p e and the characteristic the inverse is coming from.
334
+ */
335
+ std::pair<Element, Characteristic> get_partial_inverse(
336
+ const Element& e, const Characteristic& productOfCharacteristics) const {
337
+ Characteristic gcd = std::gcd(e, productOfAllCharacteristics_);
338
+
339
+ if (gcd == productOfCharacteristics) return {0, get_multiplicative_identity()}; // partial inverse is 0
340
+
341
+ Characteristic QT = productOfCharacteristics / gcd;
342
+
343
+ const Characteristic inv_qt = _get_inverse(e, QT);
344
+
345
+ auto res = get_partial_multiplicative_identity(QT);
346
+ res = _multiply(res, inv_qt, productOfAllCharacteristics_);
347
+
348
+ return {res, QT};
349
+ }
350
+
351
+ /**
352
+ * @brief Returns the additive identity of a field.
353
+ *
354
+ * @return The additive identity of a field.
355
+ */
356
+ static constexpr Element get_additive_identity() { return 0; }
357
+ /**
358
+ * @brief Returns the multiplicative identity of a field.
359
+ *
360
+ * @return The multiplicative identity of a field.
361
+ */
362
+ static constexpr Element get_multiplicative_identity() { return 1; }
363
+ // static Element get_multiplicative_identity(){ return multiplicativeID_; }
364
+ /**
365
+ * @brief Returns the partial multiplicative identity of the multi-field from the given product.
366
+ * See @cite boissonnat:hal-00922572 for more details.
367
+ *
368
+ * @param productOfCharacteristics Product of the different characteristics to take into account in the multi-field.
369
+ * @return The partial multiplicative identity of the multi-field.
370
+ */
371
+ Element get_partial_multiplicative_identity(const Characteristic& productOfCharacteristics) const {
372
+ if (productOfCharacteristics == 0) {
373
+ return get_multiplicative_identity();
374
+ }
375
+ Element multIdentity = 0;
376
+ for (unsigned int idx = 0; idx < primes_.size(); ++idx) {
377
+ if ((productOfCharacteristics % primes_[idx]) == 0) {
378
+ multIdentity = _add(multIdentity, partials_[idx], productOfAllCharacteristics_);
379
+ }
380
+ }
381
+ return multIdentity;
382
+ }
383
+
384
+ // static constexpr bool handles_only_z2() { return false; }
385
+
386
+ /**
387
+ * @brief Assign operator.
388
+ */
389
+ Multi_field_operators_with_small_characteristics& operator=(Multi_field_operators_with_small_characteristics other) {
390
+ primes_.swap(other.primes_);
391
+ productOfAllCharacteristics_ = other.productOfAllCharacteristics_;
392
+ partials_.swap(other.partials_);
393
+
394
+ return *this;
395
+ }
396
+ /**
397
+ * @brief Swap operator.
398
+ */
399
+ friend void swap(Multi_field_operators_with_small_characteristics& f1,
400
+ Multi_field_operators_with_small_characteristics& f2) {
401
+ f1.primes_.swap(f2.primes_);
402
+ std::swap(f1.productOfAllCharacteristics_, f2.productOfAllCharacteristics_);
403
+ f1.partials_.swap(f2.partials_);
404
+ }
405
+
406
+ private:
407
+ std::vector<unsigned int> primes_; /**< All characteristics. */
408
+ Characteristic productOfAllCharacteristics_; /**< Product of all characteristics. */
409
+ std::vector<Characteristic> partials_; /**< Partial products of the characteristics. */
410
+ // static inline constexpr unsigned int multiplicativeID_ = 1;
411
+
412
+ static Element _add(Element element, Element v, Characteristic characteristic);
413
+ static Element _subtract(Element element, Element v, Characteristic characteristic);
414
+ static Element _multiply(Element a, Element b, Characteristic characteristic);
415
+ static constexpr long int _get_inverse(Element element, Characteristic mod);
416
+ static constexpr bool _is_prime(const int p);
417
+ };
418
+
419
+ inline Multi_field_operators_with_small_characteristics::Element
420
+ Multi_field_operators_with_small_characteristics::_add(Element element, Element v,
421
+ Characteristic characteristic) {
422
+ if (UINT_MAX - element < v) {
423
+ // automatic unsigned integer overflow behaviour will make it work
424
+ element += v;
425
+ element -= characteristic;
426
+ return element;
427
+ }
428
+
429
+ element += v;
430
+ if (element >= characteristic) element -= characteristic;
431
+
432
+ return element;
433
+ }
434
+
435
+ inline Multi_field_operators_with_small_characteristics::Element
436
+ Multi_field_operators_with_small_characteristics::_subtract(Element element, Element v,
437
+ Characteristic characteristic) {
438
+ if (element < v) {
439
+ element += characteristic;
440
+ }
441
+ element -= v;
442
+
443
+ return element;
444
+ }
445
+
446
+ inline Multi_field_operators_with_small_characteristics::Element
447
+ Multi_field_operators_with_small_characteristics::_multiply(Element a, Element b,
448
+ Characteristic characteristic) {
449
+ Element res = 0;
450
+ Element temp_b = 0;
451
+
452
+ if (b < a) std::swap(a, b);
453
+
454
+ while (a != 0) {
455
+ if (a & 1) {
456
+ /* Add b to res, modulo m, without overflow */
457
+ if (b >= characteristic - res) res -= characteristic;
458
+ res += b;
459
+ }
460
+ a >>= 1;
461
+
462
+ /* Double b, modulo m */
463
+ temp_b = b;
464
+ if (b >= characteristic - b) temp_b -= characteristic;
465
+ b += temp_b;
466
+ }
467
+ return res;
468
+ }
469
+
470
+ inline constexpr long int Multi_field_operators_with_small_characteristics::_get_inverse(Element element,
471
+ Characteristic mod) {
472
+ // to solve: Ax + My = 1
473
+ Element M = mod;
474
+ Element A = element;
475
+ long int y = 0, x = 1;
476
+ // extended euclidean division
477
+ while (A > 1) {
478
+ int quotient = A / M;
479
+ int temp = M;
480
+
481
+ M = A % M, A = temp;
482
+ temp = y;
483
+
484
+ y = x - quotient * y;
485
+ x = temp;
486
+ }
487
+
488
+ if (x < 0) x += mod;
489
+
490
+ return x;
491
+ }
492
+
493
+ inline constexpr bool Multi_field_operators_with_small_characteristics::_is_prime(const int p) {
494
+ if (p <= 1) return false;
495
+ if (p <= 3) return true;
496
+ if (p % 2 == 0 || p % 3 == 0) return false;
497
+
498
+ for (long i = 5; i * i <= p; i = i + 6)
499
+ if (p % i == 0 || p % (i + 2) == 0) return false;
500
+
501
+ return true;
502
+ }
503
+
504
+ } // namespace persistence_fields
505
+ } // namespace Gudhi
506
+
507
+ #endif // MATRIX_FIELD_MULTI_SMALL_OPERATORS_H_