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
22namespace Gudhi {
23namespace persistence_fields {
24
32{
33 public:
34 using Element = bool;
35 using Characteristic = 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 get_characteristic() { return 2; }
52
61 template <typename Integer_type, class = isInteger<Integer_type> >
62 static Element 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 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 subtract(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 subtract_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 subtract_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 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 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 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 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, Characteristic> get_partial_inverse(
343 Unsigned_integer_type e, Characteristic productOfCharacteristics) {
344 return {get_inverse(e), productOfCharacteristics};
345 }
346
352 static constexpr Element get_additive_identity() { return false; }
358 static constexpr Element get_multiplicative_identity() { return true; }
366 [[maybe_unused]] Characteristic 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
static Element 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 subtract_inplace_front(Unsigned_integer_type &e1, Unsigned_integer_type e2)
Stores in the first element the subtraction in the field of the first element by the second element,...
Definition: Z2_field_operators.h:130
static Element 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
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 constexpr Element get_multiplicative_identity()
Returns the multiplicative identity of the field.
Definition: Z2_field_operators.h:358
static constexpr Element get_additive_identity()
Returns the additive identity of the field.
Definition: Z2_field_operators.h:352
static std::pair< Element, Characteristic > get_partial_inverse(Unsigned_integer_type e, Characteristic productOfCharacteristics)
For interface purposes with multi-fields. Returns the inverse together with the second argument.
Definition: Z2_field_operators.h:342
static Element subtract(Unsigned_integer_type e1, Unsigned_integer_type e2)
Returns the subtraction in the field of the first element by the second element.
Definition: Z2_field_operators.h:113
static constexpr Characteristic get_characteristic()
Returns the characteristic of the field, that is 2.
Definition: Z2_field_operators.h:51
static void subtract_inplace_back(Unsigned_integer_type e1, Unsigned_integer_type &e2)
Stores in the second element the subtraction in the field of the first element by the second element,...
Definition: Z2_field_operators.h:146
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 Element 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 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 get_partial_multiplicative_identity(Characteristic productOfCharacteristics)
For interface purposes with multi-fields. Returns the multiplicative identity of the field.
Definition: Z2_field_operators.h:365
unsigned int Characteristic
Definition: Z2_field_operators.h:35
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 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 Element 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 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
bool Element
Definition: Z2_field_operators.h:34
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
static Element get_inverse(Unsigned_integer_type e)
Returns the inverse of the given element in the field.
Definition: Z2_field_operators.h:326
Gudhi namespace.
Definition: SimplicialComplexForAlpha.h:14