17 #ifndef MATRIX_FIELD_MULTI_H_
18 #define MATRIX_FIELD_MULTI_H_
26 namespace persistence_fields {
38 template <
unsigned int minimum,
unsigned int maximum>
71 f1.element_ += f2.element_;
72 mpz_mod(f1.element_.get_mpz_t(), f1.element_.get_mpz_t(), productOfAllCharacteristics_.get_mpz_t());
86 mpz_mod(f.element_.get_mpz_t(), f.element_.get_mpz_t(), productOfAllCharacteristics_.get_mpz_t());
100 mpz_mod(v.get_mpz_t(), v.get_mpz_t(), productOfAllCharacteristics_.get_mpz_t());
108 f1.element_ -= f2.element_;
109 mpz_mod(f1.element_.get_mpz_t(), f1.element_.get_mpz_t(), productOfAllCharacteristics_.get_mpz_t());
123 mpz_mod(f.element_.get_mpz_t(), f.element_.get_mpz_t(), productOfAllCharacteristics_.get_mpz_t());
137 if (v >= productOfAllCharacteristics_)
138 mpz_mod(v.get_mpz_t(), v.get_mpz_t(), productOfAllCharacteristics_.get_mpz_t());
139 if (f.element_ > v) v += productOfAllCharacteristics_;
148 f1.element_ *= f2.element_;
149 mpz_mod(f1.element_.get_mpz_t(), f1.element_.get_mpz_t(), productOfAllCharacteristics_.get_mpz_t());
163 mpz_mod(f.element_.get_mpz_t(), f.element_.get_mpz_t(), productOfAllCharacteristics_.get_mpz_t());
177 mpz_mod(v.get_mpz_t(), v.get_mpz_t(), productOfAllCharacteristics_.get_mpz_t());
185 return f1.element_ == f2.element_;
191 if (v < productOfAllCharacteristics_)
return v == f.element_;
193 mpz_mod(e.get_mpz_t(), e.get_mpz_t(), productOfAllCharacteristics_.get_mpz_t());
194 return e == f.element_;
200 if (v < productOfAllCharacteristics_)
return v == f.element_;
202 mpz_mod(e.get_mpz_t(), e.get_mpz_t(), productOfAllCharacteristics_.get_mpz_t());
203 return e == f.element_;
234 operator unsigned int()
const;
238 operator mpz_class()
const;
294 static inline const std::vector<unsigned int> primes_ = []() {
295 std::vector<unsigned int> res;
297 unsigned int curr_prime = minimum;
299 mpz_init_set_ui(tmp_prime, minimum);
301 int is_prime = mpz_probab_prime_p(tmp_prime, 25);
304 mpz_nextprime(tmp_prime, tmp_prime);
305 curr_prime = mpz_get_ui(tmp_prime);
308 while (curr_prime <= maximum) {
309 res.push_back(curr_prime);
310 mpz_nextprime(tmp_prime, tmp_prime);
311 curr_prime = mpz_get_ui(tmp_prime);
313 mpz_clear(tmp_prime);
319 for (
const auto p : primes_) {
325 static inline const std::vector<characteristic_type> partials_ = []() {
326 std::vector<characteristic_type> res;
328 if (productOfAllCharacteristics_ == 1)
return res;
330 for (
unsigned int i = 0; i < primes_.size(); ++i) {
331 unsigned int p = primes_[i];
332 res.push_back(productOfAllCharacteristics_ / p);
333 mpz_powm_ui(res.back().get_mpz_t(), res.back().get_mpz_t(), p - 1, productOfAllCharacteristics_.get_mpz_t());
349 static constexpr
bool _is_prime(
const int p);
352 template <
unsigned int minimum,
unsigned int maximum>
354 static_assert(maximum >= 2,
"Characteristics have to be positive.");
355 static_assert(minimum <= maximum,
"The given interval is not valid.");
356 static_assert(minimum != maximum || _is_prime(minimum),
"The given interval does not contain a prime number.");
358 if (productOfAllCharacteristics_ == 1)
359 throw std::runtime_error(
"The given interval does not contain a prime number.");
362 template <
unsigned int minimum,
unsigned int maximum>
364 static_assert(maximum >= 2,
"Characteristics has to be positive.");
365 static_assert(minimum <= maximum,
"The given interval is not valid.");
366 static_assert(minimum != maximum || _is_prime(minimum),
"The given interval does not contain a prime number.");
368 if (productOfAllCharacteristics_ == 1)
369 throw std::runtime_error(
"The given interval does not contain a prime number.");
371 mpz_mod(element_.get_mpz_t(), element_.get_mpz_t(), productOfAllCharacteristics_.get_mpz_t());
374 template <
unsigned int minimum,
unsigned int maximum>
376 : element_(toCopy.element_) {}
378 template <
unsigned int minimum,
unsigned int maximum>
381 : element_(std::move(toMove.element_)) {}
383 template <
unsigned int minimum,
unsigned int maximum>
386 std::swap(element_, other.element_);
390 template <
unsigned int minimum,
unsigned int maximum>
393 mpz_mod(element_.get_mpz_t(), value.get_mpz_t(), productOfAllCharacteristics_.get_mpz_t());
397 template <
unsigned int minimum,
unsigned int maximum>
399 return element_.get_ui();
402 template <
unsigned int minimum,
unsigned int maximum>
407 template <
unsigned int minimum,
unsigned int maximum>
409 return get_partial_inverse(productOfAllCharacteristics_).first;
412 template <
unsigned int minimum,
unsigned int maximum>
413 inline std::pair<Multi_field_element<minimum, maximum>,
417 mpz_gcd(QR.get_mpz_t(), element_.get_mpz_t(), productOfCharacteristics.get_mpz_t());
424 mpz_invert(inv_qt.get_mpz_t(), element_.get_mpz_t(), QT.get_mpz_t());
426 auto res = get_partial_multiplicative_identity(QT);
432 template <
unsigned int minimum,
unsigned int maximum>
437 template <
unsigned int minimum,
unsigned int maximum>
442 template <
unsigned int minimum,
unsigned int maximum>
445 if (productOfCharacteristics == 0) {
449 for (
unsigned int idx = 0; idx < primes_.size(); ++idx) {
450 if ((productOfCharacteristics % primes_[idx]) == 0) {
451 mult += partials_[idx];
457 template <
unsigned int minimum,
unsigned int maximum>
460 return productOfAllCharacteristics_;
463 template <
unsigned int minimum,
unsigned int maximum>
469 template <
unsigned int minimum,
unsigned int maximum>
471 if (p <= 1)
return false;
472 if (p <= 3)
return true;
473 if (p % 2 == 0 || p % 3 == 0)
return false;
475 for (
long i = 5; i * i <= p; i = i + 6)
476 if (p % i == 0 || p % (i + 2) == 0)
return false;
Class representing an element of a multi-field. The characteristics will corresponds to all prime num...
Definition: Multi_field.h:39
friend element_type operator-(element_type v, Multi_field_element const &f)
operator-
Definition: Multi_field.h:135
friend element_type operator*(element_type v, Multi_field_element const &f)
operator*
Definition: Multi_field.h:175
friend Multi_field_element operator+(Multi_field_element f, const element_type &v)
operator+
Definition: Multi_field.h:91
std::pair< Multi_field_element, characteristic_type > get_partial_inverse(const characteristic_type &productOfCharacteristics) const
Returns the inverse of the element with respect to a sub-product of the characteristics in the multi-...
Definition: Multi_field.h:415
friend Multi_field_element operator-(Multi_field_element f1, Multi_field_element const &f2)
operator-
Definition: Multi_field.h:114
static Multi_field_element get_additive_identity()
Returns the additive identity of a field.
Definition: Multi_field.h:433
friend bool operator==(const Multi_field_element &f, const element_type &v)
operator==
Definition: Multi_field.h:199
friend Multi_field_element operator+(Multi_field_element f1, Multi_field_element const &f2)
operator+
Definition: Multi_field.h:77
mpz_class element_type
Definition: Multi_field.h:41
static Multi_field_element get_multiplicative_identity()
Returns the multiplicative identity of a field.
Definition: Multi_field.h:438
friend void operator+=(Multi_field_element &f1, Multi_field_element const &f2)
operator+=
Definition: Multi_field.h:70
static characteristic_type get_characteristic()
Returns the product of all characteristics.
Definition: Multi_field.h:459
friend bool operator!=(const element_type &v, const Multi_field_element &f)
operator!=
Definition: Multi_field.h:212
friend Multi_field_element operator*(Multi_field_element f, const element_type &v)
operator*
Definition: Multi_field.h:168
friend Multi_field_element operator-(Multi_field_element f, const element_type &v)
operator-
Definition: Multi_field.h:128
friend void operator-=(Multi_field_element &f, const element_type &v)
operator-=
Definition: Multi_field.h:121
friend element_type operator+(element_type v, Multi_field_element const &f)
operator+
Definition: Multi_field.h:98
friend bool operator!=(const Multi_field_element &f1, const Multi_field_element &f2)
operator!=
Definition: Multi_field.h:208
friend Multi_field_element operator*(Multi_field_element f1, Multi_field_element const &f2)
operator*
Definition: Multi_field.h:154
friend bool operator!=(const Multi_field_element &f, const element_type &v)
operator!=
Definition: Multi_field.h:216
friend void operator+=(Multi_field_element &f, const element_type &v)
operator+=
Definition: Multi_field.h:84
friend void swap(Multi_field_element &f1, Multi_field_element &f2)
Swap operator.
Definition: Multi_field.h:229
element_type characteristic_type
Definition: Multi_field.h:42
friend bool operator==(const element_type &v, const Multi_field_element &f)
operator==
Definition: Multi_field.h:190
Multi_field_element()
Default constructor. Sets the element to 0.
Definition: Multi_field.h:353
Multi_field_element & operator=(Multi_field_element other)
Assign operator.
Definition: Multi_field.h:384
friend void operator*=(Multi_field_element &f, const element_type &v)
operator*=
Definition: Multi_field.h:161
element_type get_value() const
Returns the value of the element.
Definition: Multi_field.h:464
Multi_field_element get_inverse() const
Returns the inverse of the element in the multi-field, see .
Definition: Multi_field.h:408
friend bool operator==(const Multi_field_element &f1, const Multi_field_element &f2)
operator==
Definition: Multi_field.h:184
static Multi_field_element get_partial_multiplicative_identity(const characteristic_type &productOfCharacteristics)
Returns the partial multiplicative identity of the multi-field from the given product....
Definition: Multi_field.h:443
friend void operator*=(Multi_field_element &f1, Multi_field_element const &f2)
operator*=
Definition: Multi_field.h:147
friend void operator-=(Multi_field_element &f1, Multi_field_element const &f2)
operator-=
Definition: Multi_field.h:107
Gudhi namespace.
Definition: SimplicialComplexForAlpha.h:14