17#ifndef MATRIX_FIELD_MULTI_H_
18#define MATRIX_FIELD_MULTI_H_
25#include <gudhi/Debug_utils.h>
40template <
unsigned int minimum,
unsigned int maximum>
52 static_assert(maximum >= 2,
"Characteristics have to be positive.");
53 static_assert(minimum <= maximum,
"The given interval is not valid.");
54 static_assert(minimum != maximum || _is_prime(minimum),
"The given interval does not contain a prime number.");
56 if (productOfAllCharacteristics_ == 1)
57 throw std::runtime_error(
"The given interval does not contain a prime number.");
67 static_assert(maximum >= 2,
"Characteristics has to be positive.");
68 static_assert(minimum <= maximum,
"The given interval is not valid.");
69 static_assert(minimum != maximum || _is_prime(minimum),
"The given interval does not contain a prime number.");
71 if (productOfAllCharacteristics_ == 1)
72 throw std::runtime_error(
"The given interval does not contain a prime number.");
74 mpz_mod(element_.get_mpz_t(), element_.get_mpz_t(), productOfAllCharacteristics_.get_mpz_t());
82 f1.element_ += f2.element_;
83 mpz_mod(f1.element_.get_mpz_t(), f1.element_.get_mpz_t(), productOfAllCharacteristics_.get_mpz_t());
101 mpz_mod(f.element_.get_mpz_t(), f.element_.get_mpz_t(), productOfAllCharacteristics_.get_mpz_t());
119 mpz_mod(v.get_mpz_t(), v.get_mpz_t(), productOfAllCharacteristics_.get_mpz_t());
128 f1.element_ -= f2.element_;
129 mpz_mod(f1.element_.get_mpz_t(), f1.element_.get_mpz_t(), productOfAllCharacteristics_.get_mpz_t());
147 mpz_mod(f.element_.get_mpz_t(), f.element_.get_mpz_t(), productOfAllCharacteristics_.get_mpz_t());
165 if (v >= productOfAllCharacteristics_)
166 mpz_mod(v.get_mpz_t(), v.get_mpz_t(), productOfAllCharacteristics_.get_mpz_t());
167 if (f.element_ > v) v += productOfAllCharacteristics_;
177 f1.element_ *= f2.element_;
178 mpz_mod(f1.element_.get_mpz_t(), f1.element_.get_mpz_t(), productOfAllCharacteristics_.get_mpz_t());
196 mpz_mod(f.element_.get_mpz_t(), f.element_.get_mpz_t(), productOfAllCharacteristics_.get_mpz_t());
214 mpz_mod(v.get_mpz_t(), v.get_mpz_t(), productOfAllCharacteristics_.get_mpz_t());
223 return f1.element_ == f2.element_;
231 if (v < productOfAllCharacteristics_)
return v == f.element_;
233 mpz_mod(e.get_mpz_t(), e.get_mpz_t(), productOfAllCharacteristics_.get_mpz_t());
234 return e == f.element_;
242 if (v < productOfAllCharacteristics_)
return v == f.element_;
244 mpz_mod(e.get_mpz_t(), e.get_mpz_t(), productOfAllCharacteristics_.get_mpz_t());
245 return e == f.element_;
280 operator unsigned int()
const {
return element_.get_ui(); }
285 explicit operator mpz_class()
const {
return element_; }
307 GUDHI_CHECK(productOfCharacteristics >= 0 && productOfCharacteristics <= productOfAllCharacteristics_,
308 std::invalid_argument(
309 "The given product is not the product of a subset of the current Multi-field characteristics."));
312 mpz_gcd(QR.get_mpz_t(), element_.get_mpz_t(), productOfCharacteristics.get_mpz_t());
319 mpz_invert(inv_qt.get_mpz_t(), element_.get_mpz_t(), QT.get_mpz_t());
353 GUDHI_CHECK(productOfCharacteristics >= 0 && productOfCharacteristics <= productOfAllCharacteristics_,
354 std::invalid_argument(
355 "The given product is not the product of a subset of the current Multi-field characteristics."));
357 if (productOfCharacteristics == 0 || productOfCharacteristics == productOfAllCharacteristics_) {
361 for (
unsigned int idx = 0; idx < primes_.size(); ++idx) {
362 if ((productOfCharacteristics % primes_[idx]) == 0) {
363 mult += partials_[idx];
385 static inline const std::vector<unsigned int> primes_ = []() {
386 std::vector<unsigned int> res;
388 unsigned int curr_prime = minimum;
390 mpz_init_set_ui(tmp_prime, minimum);
392 int is_prime = mpz_probab_prime_p(tmp_prime, 25);
395 mpz_nextprime(tmp_prime, tmp_prime);
396 curr_prime = mpz_get_ui(tmp_prime);
399 while (curr_prime <= maximum) {
400 res.push_back(curr_prime);
401 mpz_nextprime(tmp_prime, tmp_prime);
402 curr_prime = mpz_get_ui(tmp_prime);
404 mpz_clear(tmp_prime);
408 static inline const Characteristic productOfAllCharacteristics_ = []() {
410 for (
const auto p : primes_) {
416 static inline const std::vector<Characteristic> partials_ = []() {
417 std::vector<Characteristic> res;
419 if (productOfAllCharacteristics_ == 1)
return res;
421 for (
unsigned int p : primes_) {
422 res.emplace_back(productOfAllCharacteristics_ / p);
423 mpz_powm_ui(res.back().get_mpz_t(), res.back().get_mpz_t(), p - 1, productOfAllCharacteristics_.get_mpz_t());
430 static inline const Element multiplicativeID_ = 1;
439 static constexpr bool _is_prime(
const int p)
441 if (p <= 1)
return false;
442 if (p <= 3)
return true;
443 if (p % 2 == 0 || p % 3 == 0)
return false;
445 for (
long i = 5; i * i <= p; i = i + 6)
446 if (p % i == 0 || p % (i + 2) == 0)
return false;
Multi_field_element(Element element)
Constructor setting the element to the given value.
Definition Multi_field.h:65
friend bool operator!=(const Multi_field_element &f, const Element &v)
operator!=
Definition Multi_field.h:261
Element get_value() const
Returns the value of the element.
Definition Multi_field.h:381
mpz_class Element
Definition Multi_field.h:44
Element Characteristic
Definition Multi_field.h:45
friend Multi_field_element operator-(Multi_field_element f1, Multi_field_element const &f2)
operator-
Definition Multi_field.h:135
friend bool operator==(const Multi_field_element &f, const Element &v)
operator==
Definition Multi_field.h:240
friend Multi_field_element operator+(Multi_field_element f1, Multi_field_element const &f2)
operator+
Definition Multi_field.h:89
friend bool operator!=(const Element &v, const Multi_field_element &f)
operator!=
Definition Multi_field.h:256
friend void operator+=(Multi_field_element &f1, Multi_field_element const &f2)
operator+=
Definition Multi_field.h:80
friend void operator*=(Multi_field_element &f, const Element &v)
operator*=
Definition Multi_field.h:193
friend Multi_field_element operator*(Multi_field_element f, const Element &v)
operator*
Definition Multi_field.h:202
Multi_field_element get_inverse() const
Returns the inverse of the element in the multi-field, see boissonnat:hal-00922572.
Definition Multi_field.h:292
friend bool operator!=(const Multi_field_element &f1, const Multi_field_element &f2)
operator!=
Definition Multi_field.h:251
friend Element operator+(Element v, Multi_field_element const &f)
operator+
Definition Multi_field.h:116
friend Multi_field_element operator*(Multi_field_element f1, Multi_field_element const &f2)
operator*
Definition Multi_field.h:184
std::pair< 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.h:304
friend bool operator==(const Element &v, const Multi_field_element &f)
operator==
Definition Multi_field.h:229
static Multi_field_element get_additive_identity()
Returns the additive identity of a field.
Definition Multi_field.h:332
friend Multi_field_element operator+(Multi_field_element f, const Element &v)
operator+
Definition Multi_field.h:107
friend Element operator*(Element v, Multi_field_element const &f)
operator*
Definition Multi_field.h:211
Multi_field_element()
Default constructor. Sets the element to 0.
Definition Multi_field.h:50
friend Element operator-(Element v, Multi_field_element const &f)
operator-
Definition Multi_field.h:162
friend void swap(Multi_field_element &f1, Multi_field_element &f2) noexcept
Assign operator.
Definition Multi_field.h:275
static Multi_field_element get_multiplicative_identity()
Returns the multiplicative identity of a field.
Definition Multi_field.h:339
friend void operator+=(Multi_field_element &f, const Element &v)
operator+=
Definition Multi_field.h:98
static 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.h:351
friend void operator-=(Multi_field_element &f, const Element &v)
operator-=
Definition Multi_field.h:144
friend bool operator==(const Multi_field_element &f1, const Multi_field_element &f2)
operator==
Definition Multi_field.h:221
friend void operator*=(Multi_field_element &f1, Multi_field_element const &f2)
operator*=
Definition Multi_field.h:175
static Characteristic get_characteristic()
Returns the product of all characteristics.
Definition Multi_field.h:374
friend void operator-=(Multi_field_element &f1, Multi_field_element const &f2)
operator-=
Definition Multi_field.h:126
friend Multi_field_element operator-(Multi_field_element f, const Element &v)
operator-
Definition Multi_field.h:153
Field namespace.
Definition Intro_field_elements_and_operators.h:16
Gudhi namespace.
Definition SimplicialComplexForAlpha.h:14