17#ifndef MATRIX_FIELD_MULTI_SMALL_SHARED_H_
18#define MATRIX_FIELD_MULTI_SMALL_SHARED_H_
26#include <gudhi/Debug_utils.h>
45template <
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> >;
66 template <
typename Integer_type,
class = isInteger<Integer_type> >
78 static void initialize(
unsigned int minimum,
unsigned int maximum)
80 if (maximum < 2)
throw std::invalid_argument(
"Characteristic must be strictly positive");
81 if (minimum > maximum)
throw std::invalid_argument(
"The given interval is not valid.");
82 if (minimum == maximum && !_is_prime(minimum))
83 throw std::invalid_argument(
"The given interval does not contain a prime number.");
85 productOfAllCharacteristics_ = 1;
87 for (
unsigned int i = minimum; i <= maximum; ++i) {
90 productOfAllCharacteristics_ *= i;
94 if (primes_.empty())
throw std::invalid_argument(
"The given interval does not contain a prime number.");
96 partials_.resize(primes_.size());
105 if (exp & 1) partials_[i] = _multiply(partials_[i], base);
108 base = _multiply(base, base);
125 f1.element_ = _add(f1.element_, f2.element_);
144 template <
typename Integer_type,
class = isInteger<Integer_type> >
147 f.element_ = _add(f.element_, _get_value(v));
155 template <
typename Integer_type,
class = isInteger<Integer_type> >
158 const Integer_type& v)
169 template <
typename Integer_type,
class = isInteger<Integer_type> >
182 f1.element_ = _subtract(f1.element_, f2.element_);
201 template <
typename Integer_type,
class = isInteger<Integer_type> >
204 f.element_ = _subtract(f.element_, _get_value(v));
212 template <
typename Integer_type,
class = isInteger<Integer_type> >
215 const Integer_type& v)
226 template <
typename Integer_type,
class = isInteger<Integer_type> >
229 return _subtract(_get_value(v), f.element_);
238 f1.element_ = _multiply(f1.element_, f2.element_);
257 template <
typename Integer_type,
class = isInteger<Integer_type> >
260 f.element_ = _multiply(f.element_, _get_value(v));
268 template <
typename Integer_type,
class = isInteger<Integer_type> >
271 const Integer_type& v)
282 template <
typename Integer_type,
class = isInteger<Integer_type> >
295 return f1.element_ == f2.element_;
303 template <
typename Integer_type,
class = isInteger<Integer_type> >
306 return _get_value(v) == f.element_;
314 template <
typename Integer_type,
class = isInteger<Integer_type> >
317 return _get_value(v) == f.element_;
334 template <
typename Integer_type,
class = isInteger<Integer_type> >
345 template <
typename Integer_type,
class = isInteger<Integer_type> >
369 std::swap(f1.element_, f2.element_);
375 operator unsigned int()
const {
return element_; }
397 GUDHI_CHECK(productOfCharacteristics >= 0 && productOfCharacteristics <= productOfAllCharacteristics_,
398 std::invalid_argument(
399 "The given product is not the product of a subset of the current Multi-field characteristics."));
401 Characteristic gcd = std::gcd(element_, productOfAllCharacteristics_);
403 if (gcd == productOfCharacteristics)
408 const Element inv_qt = _get_inverse(element_, QT);
446 GUDHI_CHECK(productOfCharacteristics >= 0 && productOfCharacteristics <= productOfAllCharacteristics_,
447 std::invalid_argument(
448 "The given product is not the product of a subset of the current Multi-field characteristics."));
450 if (productOfCharacteristics == 0 || productOfCharacteristics == productOfAllCharacteristics_) {
455 if ((productOfCharacteristics % primes_[idx]) == 0) {
456 mult += partials_[idx];
477 static constexpr bool _is_prime(
const unsigned int p)
479 if (p <= 1)
return false;
480 if (p <= 3)
return true;
481 if (p % 2 == 0 || p % 3 == 0)
return false;
483 for (
unsigned long i = 5; i * i <= p; i = i + 6)
484 if (p % i == 0 || p % (i + 2) == 0)
return false;
494 if (b < a) std::swap(a, b);
499 if (b >= productOfAllCharacteristics_ - res) res -= productOfAllCharacteristics_;
506 if (b >= productOfAllCharacteristics_ - b) temp_b -= productOfAllCharacteristics_;
514 if (UINT_MAX - element < v) {
517 element -= productOfAllCharacteristics_;
522 if (element >= productOfAllCharacteristics_) element -= productOfAllCharacteristics_;
530 element += productOfAllCharacteristics_;
545 int quotient = A / M;
551 y = x - quotient * y;
560 template <
typename Integer_type,
class = isInteger<Integer_type> >
561 static constexpr Element _get_value(Integer_type e)
563 if constexpr (std::is_signed_v<Integer_type>) {
564 if (e < -
static_cast<Integer_type
>(productOfAllCharacteristics_)) e = e % productOfAllCharacteristics_;
565 if (e < 0)
return e += productOfAllCharacteristics_;
566 return e < static_cast<Integer_type>(productOfAllCharacteristics_) ? e : e % productOfAllCharacteristics_;
568 return e < productOfAllCharacteristics_ ? e : e % productOfAllCharacteristics_;
573 static inline std::vector<Characteristic> primes_;
575 static inline std::vector<Characteristic> partials_;
576 static constexpr Element multiplicativeID_ = 1;
friend Integer_type operator*(const Integer_type &v, Shared_multi_field_element_with_small_characteristics f)
operator*
Definition Multi_field_small_shared.h:283
friend void swap(Shared_multi_field_element_with_small_characteristics &f1, Shared_multi_field_element_with_small_characteristics &f2) noexcept
Assign operator.
Definition Multi_field_small_shared.h:366
static void initialize(unsigned int minimum, unsigned int maximum)
Initialize the multi-field to the characteristics (primes) contained in the given interval....
Definition Multi_field_small_shared.h:78
Shared_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_shared.h:382
friend Shared_multi_field_element_with_small_characteristics operator+(Shared_multi_field_element_with_small_characteristics f, const Integer_type &v)
operator+
Definition Multi_field_small_shared.h:156
friend Integer_type operator+(const Integer_type &v, Shared_multi_field_element_with_small_characteristics f)
operator+
Definition Multi_field_small_shared.h:170
friend Shared_multi_field_element_with_small_characteristics operator*(Shared_multi_field_element_with_small_characteristics f, const Integer_type &v)
operator*
Definition Multi_field_small_shared.h:269
friend void operator+=(Shared_multi_field_element_with_small_characteristics &f1, Shared_multi_field_element_with_small_characteristics const &f2)
operator+=
Definition Multi_field_small_shared.h:122
Shared_multi_field_element_with_small_characteristics(Integer_type element)
Constructor setting the element to the given value.
Definition Multi_field_small_shared.h:67
friend void operator-=(Shared_multi_field_element_with_small_characteristics &f, const Integer_type &v)
operator-=
Definition Multi_field_small_shared.h:202
friend bool operator!=(const Shared_multi_field_element_with_small_characteristics &f1, const Shared_multi_field_element_with_small_characteristics &f2)
operator!=
Definition Multi_field_small_shared.h:323
friend bool operator==(const Integer_type &v, const Shared_multi_field_element_with_small_characteristics &f)
operator==
Definition Multi_field_small_shared.h:304
static Shared_multi_field_element_with_small_characteristics get_multiplicative_identity()
Returns the multiplicative identity of a field.
Definition Multi_field_small_shared.h:431
friend Shared_multi_field_element_with_small_characteristics operator-(Shared_multi_field_element_with_small_characteristics f, const Integer_type &v)
operator-
Definition Multi_field_small_shared.h:213
Unsigned_integer_type Element
Definition Multi_field_small_shared.h:50
Element Characteristic
Definition Multi_field_small_shared.h:51
friend Shared_multi_field_element_with_small_characteristics operator-(Shared_multi_field_element_with_small_characteristics f1, Shared_multi_field_element_with_small_characteristics const &f2)
operator-
Definition Multi_field_small_shared.h:188
friend bool operator!=(const Integer_type v, const Shared_multi_field_element_with_small_characteristics &f)
operator!=
Definition Multi_field_small_shared.h:335
static Shared_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_shared.h:443
friend void operator+=(Shared_multi_field_element_with_small_characteristics &f, const Integer_type &v)
operator+=
Definition Multi_field_small_shared.h:145
static Characteristic get_characteristic()
Returns the product of all characteristics.
Definition Multi_field_small_shared.h:467
static Shared_multi_field_element_with_small_characteristics get_additive_identity()
Returns the additive identity of a field.
Definition Multi_field_small_shared.h:421
friend Shared_multi_field_element_with_small_characteristics operator+(Shared_multi_field_element_with_small_characteristics f1, Shared_multi_field_element_with_small_characteristics const &f2)
operator+
Definition Multi_field_small_shared.h:131
std::pair< Shared_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_shared.h:394
Shared_multi_field_element_with_small_characteristics()
Default constructor. Sets the element to 0.
Definition Multi_field_small_shared.h:58
friend Integer_type operator-(const Integer_type &v, const Shared_multi_field_element_with_small_characteristics &f)
operator-
Definition Multi_field_small_shared.h:227
friend Shared_multi_field_element_with_small_characteristics operator*(Shared_multi_field_element_with_small_characteristics f1, Shared_multi_field_element_with_small_characteristics const &f2)
operator*
Definition Multi_field_small_shared.h:244
friend bool operator==(const Shared_multi_field_element_with_small_characteristics &f, const Integer_type &v)
operator==
Definition Multi_field_small_shared.h:315
friend void operator*=(Shared_multi_field_element_with_small_characteristics &f, const Integer_type &v)
operator*=
Definition Multi_field_small_shared.h:258
friend void operator-=(Shared_multi_field_element_with_small_characteristics &f1, Shared_multi_field_element_with_small_characteristics const &f2)
operator-=
Definition Multi_field_small_shared.h:179
friend void operator*=(Shared_multi_field_element_with_small_characteristics &f1, Shared_multi_field_element_with_small_characteristics const &f2)
operator*=
Definition Multi_field_small_shared.h:235
Element get_value() const
Returns the value of the element.
Definition Multi_field_small_shared.h:474
friend bool operator==(const Shared_multi_field_element_with_small_characteristics &f1, const Shared_multi_field_element_with_small_characteristics &f2)
operator==
Definition Multi_field_small_shared.h:292
friend bool operator!=(const Shared_multi_field_element_with_small_characteristics &f, const Integer_type v)
operator!=
Definition Multi_field_small_shared.h:346
Field namespace.
Definition Intro_field_elements_and_operators.h:16
Gudhi namespace.
Definition SimplicialComplexForAlpha.h:14