Z2_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 
17 #ifndef MATRIX_FIELD_Z2_OPERATORS_H_
18 #define MATRIX_FIELD_Z2_OPERATORS_H_
19 
20 #include <utility>
21 
22 namespace Gudhi {
23 namespace persistence_fields {
24 
32 {
33  public:
34  using element_type = bool;
35  using characteristic_type = unsigned int;
36  template <class T>
37  using isUnsignedInteger = std::enable_if_t<std::is_unsigned_v<T> >;
38  template <class T>
39  using isInteger = std::enable_if_t<std::is_integral_v<T> >;
40 
45 
51  static constexpr characteristic_type get_characteristic() { return 2; }
52 
61  template <typename Integer_type, class = isInteger<Integer_type> >
62  static element_type get_value(Integer_type e) {
63  if constexpr (std::is_same_v<Integer_type, bool>) {
64  return e;
65  } else {
66  return e < 2 && e >= 0 ? e : e % 2; // returns bool, so %2 won't be negative and is optimized to &
67  }
68  }
69 
78  template <typename Unsigned_integer_type, class = isUnsignedInteger<Unsigned_integer_type> >
79  static element_type add(Unsigned_integer_type e1, Unsigned_integer_type e2) {
80  if constexpr (std::is_same_v<Unsigned_integer_type, bool>) {
81  return e1 != e2;
82  } else {
83  return get_value(e1) != get_value(e2);
84  }
85  }
86 
95  template <typename Unsigned_integer_type, class = isUnsignedInteger<Unsigned_integer_type> >
96  static void add_inplace(Unsigned_integer_type& e1, Unsigned_integer_type e2) {
97  if constexpr (std::is_same_v<Unsigned_integer_type, bool>) {
98  e1 = e1 != e2;
99  } else {
100  e1 = get_value(e1) != get_value(e2);
101  }
102  }
103 
112  template <typename Unsigned_integer_type, class = isUnsignedInteger<Unsigned_integer_type> >
113  static element_type substract(Unsigned_integer_type e1, Unsigned_integer_type e2) {
114  if constexpr (std::is_same_v<Unsigned_integer_type, bool>) {
115  return e1 != e2;
116  } else {
117  return get_value(e1) != get_value(e2);
118  }
119  }
120 
129  template <typename Unsigned_integer_type, class = isUnsignedInteger<Unsigned_integer_type> >
130  static void substract_inplace_front(Unsigned_integer_type& e1, Unsigned_integer_type e2) {
131  if constexpr (std::is_same_v<Unsigned_integer_type, bool>) {
132  e1 = e1 != e2;
133  } else {
134  e1 = get_value(e1) != get_value(e2);
135  }
136  }
145  template <typename Unsigned_integer_type, class = isUnsignedInteger<Unsigned_integer_type> >
146  static void substract_inplace_back(Unsigned_integer_type e1, Unsigned_integer_type& e2) {
147  if constexpr (std::is_same_v<Unsigned_integer_type, bool>) {
148  e2 = e1 != e2;
149  } else {
150  e2 = get_value(e1) != get_value(e2);
151  }
152  }
153 
162  template <typename Unsigned_integer_type, class = isUnsignedInteger<Unsigned_integer_type> >
163  static element_type multiply(Unsigned_integer_type e1, Unsigned_integer_type e2) {
164  if constexpr (std::is_same_v<Unsigned_integer_type, bool>) {
165  return e1 && e2;
166  } else {
167  return get_value(e1) ? get_value(e2) : false;
168  }
169  }
170 
179  template <typename Unsigned_integer_type, class = isUnsignedInteger<Unsigned_integer_type> >
180  static void multiply_inplace(Unsigned_integer_type& e1, Unsigned_integer_type e2) {
181  if constexpr (std::is_same_v<Unsigned_integer_type, bool>) {
182  e1 = e1 && e2;
183  } else {
184  e1 = get_value(e1) ? get_value(e2) : false;
185  }
186  }
187 
197  template <typename Unsigned_integer_type, class = isUnsignedInteger<Unsigned_integer_type> >
198  static element_type multiply_and_add(Unsigned_integer_type e, Unsigned_integer_type m, Unsigned_integer_type a) {
199  if constexpr (std::is_same_v<Unsigned_integer_type, bool>) {
200  return (e && m) != a;
201  } else {
202  return multiply(e, m) != get_value(a);
203  }
204  }
205 
215  template <typename Unsigned_integer_type, class = isUnsignedInteger<Unsigned_integer_type> >
216  static void multiply_and_add_inplace_front(Unsigned_integer_type& e,
217  Unsigned_integer_type m,
218  Unsigned_integer_type a) {
219  if constexpr (std::is_same_v<Unsigned_integer_type, bool>) {
220  e = (e && m) != a;
221  } else {
222  e = multiply(e, m) != get_value(a);
223  }
224  }
225 
235  template <typename Unsigned_integer_type, class = isUnsignedInteger<Unsigned_integer_type> >
236  static void multiply_and_add_inplace_back(Unsigned_integer_type e,
237  Unsigned_integer_type m,
238  Unsigned_integer_type& a) {
239  if constexpr (std::is_same_v<Unsigned_integer_type, bool>) {
240  a = (e && m) != a;
241  } else {
242  a = multiply(e, m) != get_value(a);
243  }
244  }
245 
256  template <typename Unsigned_integer_type, class = isUnsignedInteger<Unsigned_integer_type> >
257  static element_type add_and_multiply(Unsigned_integer_type e, Unsigned_integer_type a, Unsigned_integer_type m) {
258  if constexpr (std::is_same_v<Unsigned_integer_type, bool>) {
259  return (e != a) && m;
260  } else {
261  return add(e, a) ? get_value(m) : false;
262  }
263  }
264 
274  template <typename Unsigned_integer_type, class = isUnsignedInteger<Unsigned_integer_type> >
275  static void add_and_multiply_inplace_front(Unsigned_integer_type& e, Unsigned_integer_type a, Unsigned_integer_type m) {
276  if constexpr (std::is_same_v<Unsigned_integer_type, bool>) {
277  e = (e != a) && m;
278  } else {
279  e = add(e, a) ? get_value(m) : false;
280  }
281  }
291  template <typename Unsigned_integer_type, class = isUnsignedInteger<Unsigned_integer_type> >
292  static void add_and_multiply_inplace_back(Unsigned_integer_type& e, Unsigned_integer_type a, Unsigned_integer_type m) {
293  if constexpr (std::is_same_v<Unsigned_integer_type, bool>) {
294  m = (e != a) && m;
295  } else {
296  m = add(e, a) ? get_value(m) : false;
297  }
298  }
299 
309  template <typename Unsigned_integer_type, class = isUnsignedInteger<Unsigned_integer_type> >
310  static bool are_equal(Unsigned_integer_type e1, Unsigned_integer_type e2) {
311  if constexpr (std::is_same_v<Unsigned_integer_type, bool>) {
312  return e1 == e2;
313  } else {
314  return get_value(e1) == get_value(e2);
315  }
316  }
317 
325  template <typename Unsigned_integer_type, class = isUnsignedInteger<Unsigned_integer_type> >
326  static element_type get_inverse(Unsigned_integer_type e) {
327  if constexpr (std::is_same_v<Unsigned_integer_type, bool>) {
328  return e;
329  } else {
330  return get_value(e);
331  }
332  }
341  template <typename Unsigned_integer_type, class = isUnsignedInteger<Unsigned_integer_type> >
342  static std::pair<element_type, characteristic_type> get_partial_inverse(
343  Unsigned_integer_type e, characteristic_type productOfCharacteristics) {
344  return {get_inverse(e), productOfCharacteristics};
345  }
346 
352  static constexpr element_type get_additive_identity() { return false; }
358  static constexpr element_type get_multiplicative_identity() { return true; }
366  [[maybe_unused]] characteristic_type productOfCharacteristics) {
367  return true;
368  }
369 
370  // static constexpr bool handles_only_z2() { return true; }
371 };
372 
373 } // namespace persistence_fields
374 } // namespace Gudhi
375 
376 #endif // MATRIX_FIELD_Z2_OPERATORS_H_
Class defining operators for the field.
Definition: Z2_field_operators.h:32
static void add_inplace(Unsigned_integer_type &e1, Unsigned_integer_type e2)
Stores in the first element the sum of two given elements in the field, that is (e1 + e2) % 2,...
Definition: Z2_field_operators.h:96
bool element_type
Definition: Z2_field_operators.h:34
static void substract_inplace_front(Unsigned_integer_type &e1, Unsigned_integer_type e2)
Stores in the first element the substraction in the field of the first element by the second element,...
Definition: Z2_field_operators.h:130
static element_type multiply_and_add(Unsigned_integer_type e, Unsigned_integer_type m, Unsigned_integer_type a)
Multiplies the first element with the second one and adds the third one. Returns the result in the fi...
Definition: Z2_field_operators.h:198
static void substract_inplace_back(Unsigned_integer_type e1, Unsigned_integer_type &e2)
Stores in the second element the substraction in the field of the first element by the second element...
Definition: Z2_field_operators.h:146
static void add_and_multiply_inplace_back(Unsigned_integer_type &e, Unsigned_integer_type a, Unsigned_integer_type m)
Adds the first element to the second one and multiplies the third one with it, that is ((e + a) * m) ...
Definition: Z2_field_operators.h:292
static element_type substract(Unsigned_integer_type e1, Unsigned_integer_type e2)
Returns the substraction in the field of the first element by the second element.
Definition: Z2_field_operators.h:113
static element_type multiply(Unsigned_integer_type e1, Unsigned_integer_type e2)
Returns the multiplication of two elements in the field.
Definition: Z2_field_operators.h:163
static constexpr element_type get_partial_multiplicative_identity([[maybe_unused]] characteristic_type productOfCharacteristics)
For interface purposes with multi-fields. Returns the multiplicative identity of the field.
Definition: Z2_field_operators.h:365
static constexpr element_type get_multiplicative_identity()
Returns the multiplicative identity of the field.
Definition: Z2_field_operators.h:358
static element_type add(Unsigned_integer_type e1, Unsigned_integer_type e2)
Returns the sum of two elements in the field.
Definition: Z2_field_operators.h:79
static element_type add_and_multiply(Unsigned_integer_type e, Unsigned_integer_type a, Unsigned_integer_type m)
Adds the first element to the second one and multiplies the third one with it. Returns the result in ...
Definition: Z2_field_operators.h:257
static element_type get_inverse(Unsigned_integer_type e)
Returns the inverse of the given element in the field.
Definition: Z2_field_operators.h:326
static void multiply_and_add_inplace_back(Unsigned_integer_type e, Unsigned_integer_type m, Unsigned_integer_type &a)
Multiplies the first element with the second one and adds the third one, that is (e * m + a) % 2,...
Definition: Z2_field_operators.h:236
static void multiply_and_add_inplace_front(Unsigned_integer_type &e, Unsigned_integer_type m, Unsigned_integer_type a)
Multiplies the first element with the second one and adds the third one, that is (e * m + a) % 2,...
Definition: Z2_field_operators.h:216
static constexpr characteristic_type get_characteristic()
Returns the characteristic of the field, that is 2.
Definition: Z2_field_operators.h:51
static bool are_equal(Unsigned_integer_type e1, Unsigned_integer_type e2)
Returns true if the two given elements are equal in the field, false otherwise.
Definition: Z2_field_operators.h:310
static void add_and_multiply_inplace_front(Unsigned_integer_type &e, Unsigned_integer_type a, Unsigned_integer_type m)
Adds the first element to the second one and multiplies the third one with it, that is ((e + a) * m) ...
Definition: Z2_field_operators.h:275
unsigned int characteristic_type
Definition: Z2_field_operators.h:35
static constexpr element_type get_additive_identity()
Returns the additive identity of the field.
Definition: Z2_field_operators.h:352
static std::pair< element_type, characteristic_type > get_partial_inverse(Unsigned_integer_type e, characteristic_type productOfCharacteristics)
For interface purposes with multi-fields. Returns the inverse together with the second argument.
Definition: Z2_field_operators.h:342
static element_type get_value(Integer_type e)
Returns the value of an integer in the field. That is the positive value of the integer modulo the cu...
Definition: Z2_field_operators.h:62
Z2_field_operators()
Default constructor.
Definition: Z2_field_operators.h:44
static void multiply_inplace(Unsigned_integer_type &e1, Unsigned_integer_type e2)
Stores in the first element the multiplication of two given elements in the field,...
Definition: Z2_field_operators.h:180
Gudhi namespace.
Definition: SimplicialComplexForAlpha.h:14