17#ifndef MATRIX_FIELD_MULTI_SMALL_H_
18#define MATRIX_FIELD_MULTI_SMALL_H_
25#include <gudhi/Debug_utils.h>
43template <
unsigned int minimum,
45 typename Unsigned_integer_type =
unsigned int,
46 class = std::enable_if_t<std::is_unsigned_v<Unsigned_integer_type> > >
53 using isInteger = std::enable_if_t<std::is_integral_v<T> >;
60 static_assert(maximum >= 2,
"Characteristics have to be positive.");
61 static_assert(minimum <= maximum,
"The given interval is not valid.");
62 static_assert(minimum != maximum || _is_prime(minimum),
"The given interval does not contain a prime number.");
63 static_assert(productOfAllCharacteristics_ != 1,
"The given interval does not contain a prime number.");
71 template <
typename Integer_type,
class = isInteger<Integer_type> >
74 static_assert(maximum >= 2,
"Characteristics has to be positive.");
75 static_assert(minimum <= maximum,
"The given interval is not valid.");
76 static_assert(minimum != maximum || _is_prime(minimum),
"The given interval does not contain a prime number.");
77 static_assert(productOfAllCharacteristics_ != 1,
"The given interval does not contain a prime number.");
86 f1.element_ = _add(f1.element_, f2.element_);
105 template <
typename Integer_type,
class = isInteger<Integer_type> >
108 f.element_ = _add(f.element_, _get_value(v));
116 template <
typename Integer_type,
class = isInteger<Integer_type> >
118 const Integer_type& v)
129 template <
typename Integer_type,
class = isInteger<Integer_type> >
142 f1.element_ = _subtract(f1.element_, f2.element_);
161 template <
typename Integer_type,
class = isInteger<Integer_type> >
164 f.element_ = _subtract(f.element_, _get_value(v));
172 template <
typename Integer_type,
class = isInteger<Integer_type> >
174 const Integer_type& v)
185 template <
typename Integer_type,
class = isInteger<Integer_type> >
188 return _subtract(_get_value(v), f.element_);
197 f1.element_ = _multiply(f1.element_, f2.element_);
216 template <
typename Integer_type,
class = isInteger<Integer_type> >
219 f.element_ = _multiply(f.element_, _get_value(v));
227 template <
typename Integer_type,
class = isInteger<Integer_type> >
229 const Integer_type& v)
240 template <
typename Integer_type,
class = isInteger<Integer_type> >
253 return f1.element_ == f2.element_;
261 template <
typename Integer_type,
class = isInteger<Integer_type> >
264 return _get_value(v) == f.element_;
272 template <
typename Integer_type,
class = isInteger<Integer_type> >
275 return _get_value(v) == f.element_;
292 template <
typename Integer_type,
class = isInteger<Integer_type> >
303 template <
typename Integer_type,
class = isInteger<Integer_type> >
327 std::swap(f1.element_, f2.element_);
333 operator unsigned int()
const {
return element_; }
355 GUDHI_CHECK(productOfCharacteristics >= 0 && productOfCharacteristics <= productOfAllCharacteristics_,
356 std::invalid_argument(
357 "The given product is not the product of a subset of the current Multi-field characteristics."));
359 Characteristic gcd = std::gcd(element_, productOfAllCharacteristics_);
361 if (gcd == productOfCharacteristics)
366 const Element inv_qt = _get_inverse(element_, QT);
404 GUDHI_CHECK(productOfCharacteristics >= 0 && productOfCharacteristics <= productOfAllCharacteristics_,
405 std::invalid_argument(
406 "The given product is not the product of a subset of the current Multi-field characteristics."));
408 if (productOfCharacteristics == 0 || productOfCharacteristics == productOfAllCharacteristics_) {
413 if ((productOfCharacteristics % primes_[idx]) == 0) {
414 mult += partials_[idx];
435 static constexpr bool _is_prime(
const unsigned int p)
437 if (p <= 1)
return false;
438 if (p <= 3)
return true;
439 if (p % 2 == 0 || p % 3 == 0)
return false;
441 for (
unsigned long i = 5; i * i <= p; i = i + 6)
442 if (p % i == 0 || p % (i + 2) == 0)
return false;
452 if (b < a) std::swap(a, b);
457 if (b >= productOfAllCharacteristics_ - res) res -= productOfAllCharacteristics_;
464 if (b >= productOfAllCharacteristics_ - b) temp_b -= productOfAllCharacteristics_;
472 if (UINT_MAX - element < v) {
475 element -= productOfAllCharacteristics_;
480 if (element >= productOfAllCharacteristics_) element -= productOfAllCharacteristics_;
488 element += productOfAllCharacteristics_;
495 static constexpr int _get_inverse(
Element element,
const Element mod)
503 int quotient = A / M;
509 y = x - quotient * y;
518 template <
typename Integer_type,
class = isInteger<Integer_type> >
519 static constexpr Element _get_value(Integer_type e)
521 if constexpr (std::is_signed_v<Integer_type>) {
522 if (e < -
static_cast<Integer_type
>(productOfAllCharacteristics_)) e = e % productOfAllCharacteristics_;
523 if (e < 0)
return e += productOfAllCharacteristics_;
524 return e < static_cast<Integer_type>(productOfAllCharacteristics_) ? e : e % productOfAllCharacteristics_;
526 return e < productOfAllCharacteristics_ ? e : e % productOfAllCharacteristics_;
531 static inline const std::vector<Characteristic> primes_ = []() {
532 std::vector<Characteristic> res;
540 static constexpr Characteristic productOfAllCharacteristics_ = []() {
549 static inline const std::vector<Characteristic> partials_ = []() {
550 std::vector<Characteristic> res;
552 if (productOfAllCharacteristics_ == 1)
return res;
562 if (exp & 1) res.back() = _multiply(res.back(), base);
565 base = _multiply(base, base);
573 static constexpr Element multiplicativeID_ = 1;
friend Multi_field_element_with_small_characteristics operator-(Multi_field_element_with_small_characteristics f1, Multi_field_element_with_small_characteristics const &f2)
operator-
Definition Multi_field_small.h:148
friend void swap(Multi_field_element_with_small_characteristics &f1, Multi_field_element_with_small_characteristics &f2) noexcept
Assign operator.
Definition Multi_field_small.h:324
friend void operator+=(Multi_field_element_with_small_characteristics &f, const Integer_type &v)
operator+=
Definition Multi_field_small.h:106
friend void operator-=(Multi_field_element_with_small_characteristics &f, const Integer_type &v)
operator-=
Definition Multi_field_small.h:162
friend void operator*=(Multi_field_element_with_small_characteristics &f1, Multi_field_element_with_small_characteristics const &f2)
operator*=
Definition Multi_field_small.h:194
friend bool operator!=(const Integer_type v, const Multi_field_element_with_small_characteristics &f)
operator!=
Definition Multi_field_small.h:293
friend void operator-=(Multi_field_element_with_small_characteristics &f1, Multi_field_element_with_small_characteristics const &f2)
operator-=
Definition Multi_field_small.h:139
Element get_value() const
Returns the value of the element.
Definition Multi_field_small.h:432
friend bool operator==(const Integer_type v, const Multi_field_element_with_small_characteristics &f)
operator==
Definition Multi_field_small.h:262
Multi_field_element_with_small_characteristics()
Default constructor. Sets the element to 0.
Definition Multi_field_small.h:58
friend Integer_type operator-(const Integer_type &v, const Multi_field_element_with_small_characteristics &f)
operator-
Definition Multi_field_small.h:186
std::pair< Multi_field_element_with_small_characteristics, Characteristic > get_partial_inverse(Characteristic productOfCharacteristics) const
Returns the inverse of the element with respect to a sub-product of the characteristics in the multi-...
Definition Multi_field_small.h:352
friend Multi_field_element_with_small_characteristics operator*(Multi_field_element_with_small_characteristics f, const Integer_type &v)
operator*
Definition Multi_field_small.h:228
friend Integer_type operator+(const Integer_type &v, Multi_field_element_with_small_characteristics f)
operator+
Definition Multi_field_small.h:130
Multi_field_element_with_small_characteristics get_inverse() const
Returns the inverse of the element in the multi-field, see boissonnat:hal-00922572.
Definition Multi_field_small.h:340
friend Multi_field_element_with_small_characteristics operator+(Multi_field_element_with_small_characteristics f1, Multi_field_element_with_small_characteristics const &f2)
operator+
Definition Multi_field_small.h:92
Element Characteristic
Definition Multi_field_small.h:51
static Multi_field_element_with_small_characteristics get_partial_multiplicative_identity(const Characteristic &productOfCharacteristics)
Returns the partial multiplicative identity of the multi-field from the given product....
Definition Multi_field_small.h:401
Multi_field_element_with_small_characteristics(Integer_type element)
Constructor setting the element to the given value.
Definition Multi_field_small.h:72
friend Multi_field_element_with_small_characteristics operator-(Multi_field_element_with_small_characteristics f, const Integer_type &v)
operator-
Definition Multi_field_small.h:173
Unsigned_integer_type Element
Definition Multi_field_small.h:50
friend Multi_field_element_with_small_characteristics operator*(Multi_field_element_with_small_characteristics f1, Multi_field_element_with_small_characteristics const &f2)
operator*
Definition Multi_field_small.h:203
friend bool operator==(const Multi_field_element_with_small_characteristics &f, const Integer_type v)
operator==
Definition Multi_field_small.h:273
friend void operator+=(Multi_field_element_with_small_characteristics &f1, Multi_field_element_with_small_characteristics const &f2)
operator+=
Definition Multi_field_small.h:83
static Multi_field_element_with_small_characteristics get_additive_identity()
Returns the additive identity of a field.
Definition Multi_field_small.h:379
friend bool operator!=(const Multi_field_element_with_small_characteristics &f, const Integer_type v)
operator!=
Definition Multi_field_small.h:304
friend bool operator!=(const Multi_field_element_with_small_characteristics &f1, const Multi_field_element_with_small_characteristics &f2)
operator!=
Definition Multi_field_small.h:281
static Multi_field_element_with_small_characteristics get_multiplicative_identity()
Returns the multiplicative identity of a field.
Definition Multi_field_small.h:389
static constexpr Characteristic get_characteristic()
Returns the product of all characteristics.
Definition Multi_field_small.h:425
friend Integer_type operator*(const Integer_type &v, Multi_field_element_with_small_characteristics f)
operator*
Definition Multi_field_small.h:241
friend void operator*=(Multi_field_element_with_small_characteristics &f, const Integer_type &v)
operator*=
Definition Multi_field_small.h:217
friend Multi_field_element_with_small_characteristics operator+(Multi_field_element_with_small_characteristics f, const Integer_type &v)
operator+
Definition Multi_field_small.h:117
friend bool operator==(const Multi_field_element_with_small_characteristics &f1, const Multi_field_element_with_small_characteristics &f2)
operator==
Definition Multi_field_small.h:250
Field namespace.
Definition Intro_field_elements_and_operators.h:16
Gudhi namespace.
Definition SimplicialComplexForAlpha.h:14