Loading...
Searching...
No Matches
Zp_field_operators.h
Go to the documentation of this file.
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
16
17#ifndef MATRIX_FIELD_ZP_OPERATOR_H_
18#define MATRIX_FIELD_ZP_OPERATOR_H_
19
20#include <stdexcept>
21#include <utility>
22#include <vector>
23#include <limits.h>
24
25namespace Gudhi {
27namespace persistence_fields {
28
38template <typename Unsigned_integer_type = unsigned int,
39 class = std::enable_if_t<std::is_unsigned_v<Unsigned_integer_type> > >
41{
42 public:
43 using Element = Unsigned_integer_type;
45 template <class T>
46 using isSignedInteger = std::enable_if_t<std::is_signed_v<T> >;
47
51 constexpr static const Characteristic nullCharacteristic = 0;
52
60 {
61 if (characteristic != nullCharacteristic) set_characteristic(characteristic);
62 }
63
70 {
71 if (characteristic <= 1) throw std::invalid_argument("Characteristic must be a strictly positive prime number.");
72
73 inverse_.resize(characteristic);
74 inverse_[0] = 0;
75 for (unsigned int i = 1; i < characteristic; ++i) {
76 unsigned int inv = 1;
77 unsigned int mult = inv * i;
78 while ((mult % characteristic) != 1) {
79 ++inv;
80 if (mult == characteristic) throw std::invalid_argument("Characteristic must be a prime number.");
81 mult = inv * i;
82 }
83 inverse_[i] = inv;
84 }
85
86 characteristic_ = characteristic;
87 }
88
94 const Characteristic& get_characteristic() const { return characteristic_; }
95
103 Element get_value(Element e) const { return e < characteristic_ ? e : e % characteristic_; }
104
113 template <typename Signed_integer_type, class = isSignedInteger<Signed_integer_type> >
114 Element get_value(Signed_integer_type e) const
115 {
116 if (e < -static_cast<Signed_integer_type>(characteristic_)) e = e % characteristic_;
117 if (e < 0) return e += characteristic_;
118 return e < static_cast<Signed_integer_type>(characteristic_) ? e : e % characteristic_;
119 }
120
128 Element add(Element e1, Element e2) const { return _add(get_value(e1), get_value(e2), characteristic_); }
129
137 void add_inplace(Element& e1, Element e2) const { e1 = _add(get_value(e1), get_value(e2), characteristic_); }
138
146 Element subtract(Element e1, Element e2) const { return _subtract(get_value(e1), get_value(e2), characteristic_); }
147
156 {
157 e1 = _subtract(get_value(e1), get_value(e2), characteristic_);
158 }
159
168 {
169 e2 = _subtract(get_value(e1), get_value(e2), characteristic_);
170 }
171
179 Element multiply(Element e1, Element e2) const { return _multiply(get_value(e1), get_value(e2), characteristic_); }
180
188 void multiply_inplace(Element& e1, Element e2) const
189 {
190 e1 = _multiply(get_value(e1), get_value(e2), characteristic_);
191 }
192
203 Element multiply_and_add(Element e, Element m, Element a) const { return get_value((e * m) + a); }
204
215 void multiply_and_add_inplace_front(Element& e, Element m, Element a) const { e = get_value((e * m) + a); }
216
227 void multiply_and_add_inplace_back(Element e, Element m, Element& a) const { a = get_value((e * m) + a); }
228
240 Element add_and_multiply(Element e, Element a, Element m) const { return get_value((e + a) * m); }
241
252 void add_and_multiply_inplace_front(Element& e, Element a, Element m) const { e = get_value((e + a) * m); }
253
264 void add_and_multiply_inplace_back(Element e, Element a, Element& m) const { m = get_value((e + a) * m); }
265
274 bool are_equal(Element e1, Element e2) const { return get_value(e1) == get_value(e2); }
275
282 Element get_inverse(Element e) const { return inverse_[get_value(e)]; }
283
291 std::pair<Element, Characteristic> get_partial_inverse(Element e, Characteristic productOfCharacteristics) const
292 {
293 return {get_inverse(e), productOfCharacteristics};
294 }
295
301 static constexpr Element get_additive_identity() { return 0; }
302
308 static constexpr Element get_multiplicative_identity() { return 1; }
309
316 static constexpr Element get_partial_multiplicative_identity([[maybe_unused]] Characteristic productOfCharacteristics)
317 {
318 return 1;
319 }
320
324 friend void swap(Zp_field_operators& f1, Zp_field_operators& f2) noexcept
325 {
326 std::swap(f1.characteristic_, f2.characteristic_);
327 f1.inverse_.swap(f2.inverse_);
328 }
329
330 private:
331 Characteristic characteristic_;
332 std::vector<Element> inverse_;
333
334 static Element _add(Element e1, Element e2, Characteristic characteristic)
335 {
336 if (UINT_MAX - e1 < e2) {
337 // automatic unsigned integer overflow behaviour will make it work
338 e1 += e2;
339 e1 -= characteristic;
340 return e1;
341 }
342
343 e1 += e2;
344 if (e1 >= characteristic) e1 -= characteristic;
345
346 return e1;
347 }
348
349 static Element _subtract(Element e1, Element e2, Characteristic characteristic)
350 {
351 if (e1 < e2) {
352 e1 += characteristic;
353 }
354 e1 -= e2;
355
356 return e1;
357 }
358
359 static Element _multiply(Element e1, Element e2, Characteristic characteristic)
360 {
361 unsigned int a = e1;
362 e1 = 0;
363 unsigned int temp_b;
364
365 while (a != 0) {
366 if (a & 1) {
367 if (e2 >= characteristic - e1) e1 -= characteristic;
368 e1 += e2;
369 }
370 a >>= 1;
371
372 temp_b = e2;
373 if (e2 >= characteristic - e2) temp_b -= characteristic;
374 e2 += temp_b;
375 }
376
377 return e1;
378 }
379};
380
381} // namespace persistence_fields
382} // namespace Gudhi
383
384#endif // MATRIX_FIELD_ZP_OPERATOR_H_
void multiply_and_add_inplace_back(Element e, Element m, Element &a) const
Multiplies the first element with the second one and adds the third one, that is (e * m + a) % charac...
Definition Zp_field_operators.h:227
const Characteristic & get_characteristic() const
Returns the current characteristic.
Definition Zp_field_operators.h:94
Element get_inverse(Element e) const
Returns the inverse of the given element in the field.
Definition Zp_field_operators.h:282
Element multiply_and_add(Element e, Element m, Element a) const
Multiplies the first element with the second one and adds the third one. Returns the result in the fi...
Definition Zp_field_operators.h:203
Element get_value(Element e) const
Returns the value of an integer in the field. That is the positive value of the integer modulo the cu...
Definition Zp_field_operators.h:103
Element add(Element e1, Element e2) const
Returns the sum of two elements in the field.
Definition Zp_field_operators.h:128
void set_characteristic(Characteristic characteristic)
Sets the characteristic of the field.
Definition Zp_field_operators.h:69
Element Characteristic
Definition Zp_field_operators.h:44
std::pair< Element, Characteristic > get_partial_inverse(Element e, Characteristic productOfCharacteristics) const
For interface purposes with multi-fields. Returns the inverse together with the second argument.
Definition Zp_field_operators.h:291
void add_and_multiply_inplace_back(Element e, Element a, Element &m) const
Adds the first element to the second one and multiplies the third one with it, that is ((e + a) * m) ...
Definition Zp_field_operators.h:264
Unsigned_integer_type Element
Definition Zp_field_operators.h:43
static constexpr Element get_multiplicative_identity()
Returns the multiplicative identity of the field.
Definition Zp_field_operators.h:308
bool are_equal(Element e1, Element e2) const
Returns true if the two given elements are equal in the field, false otherwise.
Definition Zp_field_operators.h:274
void add_and_multiply_inplace_front(Element &e, Element a, Element m) const
Adds the first element to the second one and multiplies the third one with it, that is ((e + a) * m) ...
Definition Zp_field_operators.h:252
static constexpr Element get_additive_identity()
Returns the additive identity of the field.
Definition Zp_field_operators.h:301
void subtract_inplace_back(Element e1, Element &e2) const
Stores in the second element the subtraction in the field of the first element by the second element,...
Definition Zp_field_operators.h:167
Element get_value(Signed_integer_type e) const
Returns the value of an integer in the field. That is the positive value of the integer modulo the cu...
Definition Zp_field_operators.h:114
static constexpr Element get_partial_multiplicative_identity(Characteristic productOfCharacteristics)
For interface purposes with multi-fields. Returns the multiplicative identity of the field.
Definition Zp_field_operators.h:316
Element multiply(Element e1, Element e2) const
Returns the multiplication of two elements in the field.
Definition Zp_field_operators.h:179
Element subtract(Element e1, Element e2) const
Returns the subtraction in the field of the first element by the second element.
Definition Zp_field_operators.h:146
void multiply_and_add_inplace_front(Element &e, Element m, Element a) const
Multiplies the first element with the second one and adds the third one, that is (e * m + a) % charac...
Definition Zp_field_operators.h:215
void multiply_inplace(Element &e1, Element e2) const
Stores in the first element the multiplication of two given elements in the field,...
Definition Zp_field_operators.h:188
Zp_field_operators(Characteristic characteristic=nullCharacteristic)
Default constructor. If a non-zero characteristic is given, initializes the field with it....
Definition Zp_field_operators.h:59
friend void swap(Zp_field_operators &f1, Zp_field_operators &f2) noexcept
Swap operator.
Definition Zp_field_operators.h:324
void subtract_inplace_front(Element &e1, Element e2) const
Stores in the first element the subtraction in the field of the first element by the second element,...
Definition Zp_field_operators.h:155
Element add_and_multiply(Element e, Element a, Element m) const
Adds the first element to the second one and multiplies the third one with it. Returns the result in ...
Definition Zp_field_operators.h:240
void add_inplace(Element &e1, Element e2) const
Stores in the first element the sum of two given elements in the field, that is (e1 + e2) % character...
Definition Zp_field_operators.h:137
static constexpr const Characteristic nullCharacteristic
Value of a non initialized characteristic.
Definition Zp_field_operators.h:51
Field namespace.
Definition Intro_field_elements_and_operators.h:16
Gudhi namespace.
Definition SimplicialComplexForAlpha.h:14