17#ifndef MATRIX_FIELD_MULTI_SHARED_H_
18#define MATRIX_FIELD_MULTI_SHARED_H_
25#include <gudhi/Debug_utils.h>
57 mpz_mod(element_.get_mpz_t(), element_.get_mpz_t(), productOfAllCharacteristics_.get_mpz_t());
67 static void initialize(
unsigned int minimum,
unsigned int maximum)
69 if (maximum < 2)
throw std::invalid_argument(
"Characteristic must be strictly positive");
70 if (minimum > maximum)
throw std::invalid_argument(
"The given interval is not valid.");
71 if (minimum == maximum && !_is_prime(minimum))
72 throw std::invalid_argument(
"The given interval does not contain a prime number.");
74 unsigned int curr_prime = minimum;
76 mpz_init_set_ui(tmp_prime, minimum);
78 int is_prime = mpz_probab_prime_p(tmp_prime, 25);
81 mpz_nextprime(tmp_prime, tmp_prime);
82 curr_prime = mpz_get_ui(tmp_prime);
86 while (curr_prime <= maximum) {
87 primes_.push_back(curr_prime);
88 mpz_nextprime(tmp_prime, tmp_prime);
89 curr_prime = mpz_get_ui(tmp_prime);
93 if (primes_.empty())
throw std::invalid_argument(
"The given interval does not contain a prime number.");
95 productOfAllCharacteristics_ = 1;
96 for (
const unsigned int p : primes_) {
97 productOfAllCharacteristics_ *= p;
100 partials_.resize(primes_.size());
101 for (
unsigned int i = 0; i < primes_.size(); ++i) {
102 unsigned int p = primes_[i];
103 partials_[i] = productOfAllCharacteristics_ / p;
104 mpz_powm_ui(partials_[i].get_mpz_t(), partials_[i].get_mpz_t(), p - 1, productOfAllCharacteristics_.get_mpz_t());
119 f1.element_ += f2.element_;
120 mpz_mod(f1.element_.get_mpz_t(), f1.element_.get_mpz_t(), productOfAllCharacteristics_.get_mpz_t());
138 mpz_mod(f.element_.get_mpz_t(), f.element_.get_mpz_t(), productOfAllCharacteristics_.get_mpz_t());
156 mpz_mod(v.get_mpz_t(), v.get_mpz_t(), productOfAllCharacteristics_.get_mpz_t());
165 f1.element_ -= f2.element_;
166 mpz_mod(f1.element_.get_mpz_t(), f1.element_.get_mpz_t(), productOfAllCharacteristics_.get_mpz_t());
184 mpz_mod(f.element_.get_mpz_t(), f.element_.get_mpz_t(), productOfAllCharacteristics_.get_mpz_t());
201 if (v >= productOfAllCharacteristics_)
202 mpz_mod(v.get_mpz_t(), v.get_mpz_t(), productOfAllCharacteristics_.get_mpz_t());
203 if (f.element_ > v) v += productOfAllCharacteristics_;
213 f1.element_ *= f2.element_;
214 mpz_mod(f1.element_.get_mpz_t(), f1.element_.get_mpz_t(), productOfAllCharacteristics_.get_mpz_t());
232 mpz_mod(f.element_.get_mpz_t(), f.element_.get_mpz_t(), productOfAllCharacteristics_.get_mpz_t());
250 mpz_mod(v.get_mpz_t(), v.get_mpz_t(), productOfAllCharacteristics_.get_mpz_t());
259 return f1.element_ == f2.element_;
267 if (v < productOfAllCharacteristics_)
return v == f.element_;
269 mpz_mod(e.get_mpz_t(), e.get_mpz_t(), productOfAllCharacteristics_.get_mpz_t());
270 return e == f.element_;
278 if (v < productOfAllCharacteristics_)
return v == f.element_;
280 mpz_mod(e.get_mpz_t(), e.get_mpz_t(), productOfAllCharacteristics_.get_mpz_t());
281 return e == f.element_;
316 std::swap(f1.element_, f2.element_);
322 operator unsigned int()
const {
return element_.get_ui(); }
327 explicit operator mpz_class()
const {
return element_; }
349 GUDHI_CHECK(productOfCharacteristics >= 0 && productOfCharacteristics <= productOfAllCharacteristics_,
350 std::invalid_argument(
351 "The given product is not the product of a subset of the current Multi-field characteristics."));
354 mpz_gcd(QR.get_mpz_t(), element_.get_mpz_t(), productOfCharacteristics.get_mpz_t());
356 if (QR == productOfCharacteristics)
359 Element QT = productOfCharacteristics / QR;
362 mpz_invert(inv_qt.get_mpz_t(), element_.get_mpz_t(), QT.get_mpz_t());
393 GUDHI_CHECK(productOfCharacteristics >= 0 && productOfCharacteristics <= productOfAllCharacteristics_,
394 std::invalid_argument(
395 "The given product is not the product of a subset of the current Multi-field characteristics."));
397 if (productOfCharacteristics == 0 || productOfCharacteristics == productOfAllCharacteristics_) {
401 for (
unsigned int idx = 0; idx < primes_.size(); ++idx) {
402 if ((productOfCharacteristics % primes_[idx]) == 0) {
403 mult += partials_[idx];
425 static inline std::vector<unsigned int> primes_;
427 static inline std::vector<Element> partials_;
428 static inline const Element multiplicativeID_ = 1;
430 static constexpr bool _is_prime(
const unsigned int p)
432 if (p <= 1)
return false;
433 if (p <= 3)
return true;
434 if (p % 2 == 0 || p % 3 == 0)
return false;
436 for (
long i = 5; i * i <= p; i = i + 6)
437 if (p % i == 0 || p % (i + 2) == 0)
return false;
static Shared_multi_field_element get_partial_multiplicative_identity(const Characteristic &productOfCharacteristics)
Returns the partial multiplicative identity of the multi-field from the given product....
Definition Multi_field_shared.h:391
friend void operator*=(Shared_multi_field_element &f1, Shared_multi_field_element const &f2)
operator*=
Definition Multi_field_shared.h:211
friend Element operator-(Element v, Shared_multi_field_element const &f)
operator-
Definition Multi_field_shared.h:199
friend Shared_multi_field_element operator*(Shared_multi_field_element f, const Element &v)
operator*
Definition Multi_field_shared.h:238
friend void operator-=(Shared_multi_field_element &f1, Shared_multi_field_element const &f2)
operator-=
Definition Multi_field_shared.h:163
friend bool operator==(const Shared_multi_field_element &f1, const Shared_multi_field_element &f2)
operator==
Definition Multi_field_shared.h:257
mpz_class Element
Definition Multi_field_shared.h:42
friend Shared_multi_field_element operator*(Shared_multi_field_element f1, Shared_multi_field_element const &f2)
operator*
Definition Multi_field_shared.h:220
Element get_value() const
Returns the value of the element.
Definition Multi_field_shared.h:421
friend void operator+=(Shared_multi_field_element &f, const Element &v)
operator+=
Definition Multi_field_shared.h:135
friend Shared_multi_field_element operator+(Shared_multi_field_element f1, Shared_multi_field_element const &f2)
operator+
Definition Multi_field_shared.h:126
friend bool operator==(const Shared_multi_field_element &f, const Element &v)
operator==
Definition Multi_field_shared.h:276
Element Characteristic
Definition Multi_field_shared.h:43
static Shared_multi_field_element get_multiplicative_identity()
Returns the multiplicative identity of a field.
Definition Multi_field_shared.h:382
friend Shared_multi_field_element operator+(Shared_multi_field_element f, const Element &v)
operator+
Definition Multi_field_shared.h:144
Shared_multi_field_element get_inverse() const
Returns the inverse of the element in the multi-field, see boissonnat:hal-00922572.
Definition Multi_field_shared.h:334
friend bool operator!=(const Shared_multi_field_element &f, const Element &v)
operator!=
Definition Multi_field_shared.h:300
friend void swap(Shared_multi_field_element &f1, Shared_multi_field_element &f2) noexcept
Assign operator.
Definition Multi_field_shared.h:314
friend Shared_multi_field_element operator-(Shared_multi_field_element f, const Element &v)
operator-
Definition Multi_field_shared.h:190
Shared_multi_field_element()
Default constructor. Sets the element to 0.
Definition Multi_field_shared.h:48
std::pair< Shared_multi_field_element, Characteristic > get_partial_inverse(const Characteristic &productOfCharacteristics) const
Returns the inverse of the element with respect to a sub-product of the characteristics in the multi-...
Definition Multi_field_shared.h:346
friend void operator*=(Shared_multi_field_element &f, const Element &v)
operator*=
Definition Multi_field_shared.h:229
friend bool operator==(const Element &v, const Shared_multi_field_element &f)
operator==
Definition Multi_field_shared.h:265
friend Element operator*(Element v, Shared_multi_field_element const &f)
operator*
Definition Multi_field_shared.h:247
friend void operator-=(Shared_multi_field_element &f, const Element &v)
operator-=
Definition Multi_field_shared.h:181
static Shared_multi_field_element get_additive_identity()
Returns the additive identity of a field.
Definition Multi_field_shared.h:375
friend bool operator!=(const Shared_multi_field_element &f1, const Shared_multi_field_element &f2)
operator!=
Definition Multi_field_shared.h:287
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_shared.h:67
friend bool operator!=(const Element &v, const Shared_multi_field_element &f)
operator!=
Definition Multi_field_shared.h:295
friend Shared_multi_field_element operator-(Shared_multi_field_element f1, Shared_multi_field_element const &f2)
operator-
Definition Multi_field_shared.h:172
Shared_multi_field_element(Element element)
Constructor setting the element to the given value.
Definition Multi_field_shared.h:55
friend Element operator+(Element v, Shared_multi_field_element const &f)
operator+
Definition Multi_field_shared.h:153
friend void operator+=(Shared_multi_field_element &f1, Shared_multi_field_element const &f2)
operator+=
Definition Multi_field_shared.h:117
static Characteristic get_characteristic()
Returns the product of all characteristics.
Definition Multi_field_shared.h:414
Field namespace.
Definition Intro_field_elements_and_operators.h:16
Gudhi namespace.
Definition SimplicialComplexForAlpha.h:14