17#ifndef MATRIX_FIELD_ZP_H_
18#define MATRIX_FIELD_ZP_H_
37template <
unsigned int characteristic,
38 typename Unsigned_integer_type =
unsigned int,
39 class = std::enable_if_t<std::is_unsigned_v<Unsigned_integer_type> > >
46 using isInteger = std::enable_if_t<std::is_integral_v<T> >;
51 Zp_field_element() : element_(0) {
static_assert(_is_prime(),
"Characteristic has to be a prime number."); }
59 template <
typename Integer_type,
class = isInteger<Integer_type> >
62 static_assert(_is_prime(),
"Characteristic has to be a prime number.");
86 f1.element_ = Zp_field_element::_add(f1.element_, f2.element_);
101 template <
typename Integer_type,
class = isInteger<Integer_type> >
104 f.element_ = Zp_field_element::_add(f.element_, _get_value(v));
112 template <
typename Integer_type,
class = isInteger<Integer_type> >
124 template <
typename Integer_type,
class = isInteger<Integer_type> >
136 f1.element_ = Zp_field_element::_subtract(f1.element_, f2.element_);
151 template <
typename Integer_type,
class = isInteger<Integer_type> >
154 f.element_ = Zp_field_element::_subtract(f.element_, _get_value(v));
162 template <
typename Integer_type,
class = isInteger<Integer_type> >
174 template <
typename Integer_type,
class = isInteger<Integer_type> >
177 return Zp_field_element::_subtract(_get_value(v), f.element_);
185 f1.element_ = Zp_field_element::_multiply(f1.element_, f2.element_);
200 template <
typename Integer_type,
class = isInteger<Integer_type> >
203 f.element_ = Zp_field_element::_multiply(f.element_, _get_value(v));
211 template <
typename Integer_type,
class = isInteger<Integer_type> >
223 template <
typename Integer_type,
class = isInteger<Integer_type> >
240 template <
typename Integer_type,
class = isInteger<Integer_type> >
243 return Zp_field_element::_get_value(v) == f.element_;
251 template <
typename Integer_type,
class = isInteger<Integer_type> >
254 return Zp_field_element::_get_value(v) == f.element_;
267 template <
typename Integer_type,
class = isInteger<Integer_type> >
278 template <
typename Integer_type,
class = isInteger<Integer_type> >
289 std::swap(element_, other.element_);
298 if (
this == &other)
return *
this;
300 element_ = std::exchange(other.element_, 0);
309 template <
typename Integer_type,
class = isInteger<Integer_type> >
312 element_ = _get_value(value);
324 operator unsigned int()
const {
return element_; }
333 if (element_ != 0 && inverse_[element_] == 0) {
334 inverse_[element_] = _get_inverse(element_);
346 std::pair<Zp_field_element, unsigned int>
get_partial_inverse(
unsigned int productOfCharacteristics)
const
394 static inline std::array<unsigned int, characteristic> inverse_;
398 if (UINT_MAX - element < v) {
401 element -= characteristic;
406 if (element >= characteristic) element -= characteristic;
414 element += characteristic;
429 if (v >= characteristic - element) element -= characteristic;
435 if (v >= characteristic - v) temp_b -= characteristic;
442 static int _get_inverse(
Element element)
445 int M = characteristic;
450 int quotient = A / M;
456 y = x - quotient * y;
460 if (x < 0) x += characteristic;
465 template <
typename Integer_type,
class = isInteger<Integer_type> >
466 static constexpr Element _get_value(Integer_type e)
468 if constexpr (std::is_signed_v<Integer_type>) {
469 if (e < -
static_cast<Integer_type
>(characteristic)) e = e % characteristic;
470 if (e < 0)
return e += characteristic;
471 return e < static_cast<Integer_type>(characteristic) ? e : e % characteristic;
473 return e < characteristic ? e : e % characteristic;
477 static constexpr bool _is_prime()
479 if (characteristic <= 1)
return false;
480 if (characteristic <= 3)
return true;
481 if (characteristic % 2 == 0 || characteristic % 3 == 0)
return false;
483 for (
long i = 5; i * i <= characteristic; i = i + 6)
484 if (characteristic % i == 0 || characteristic % (i + 2) == 0)
return false;
Class representing an element of the field for any prime number .
Definition Zp_field.h:41
Zp_field_element(Integer_type element)
Constructor setting the element to the given value.
Definition Zp_field.h:60
Zp_field_element & operator=(Zp_field_element other)
Assign operator.
Definition Zp_field.h:287
friend Zp_field_element operator-(Zp_field_element f1, const Zp_field_element &f2)
operator-
Definition Zp_field.h:142
Zp_field_element & operator=(const Integer_type &value)
Assign operator.
Definition Zp_field.h:310
friend Zp_field_element operator-(Zp_field_element f, const Integer_type &v)
operator-
Definition Zp_field.h:163
friend Integer_type operator*(const Integer_type &v, Zp_field_element f)
operator*
Definition Zp_field.h:224
static Zp_field_element get_multiplicative_identity()
Returns the multiplicative identity of the field.
Definition Zp_field.h:363
Zp_field_element get_inverse() const
Returns the inverse of the element in the field.
Definition Zp_field.h:331
Unsigned_integer_type Element
Definition Zp_field.h:43
friend Integer_type operator+(const Integer_type &v, Zp_field_element f)
operator+
Definition Zp_field.h:125
friend bool operator!=(const Integer_type &v, const Zp_field_element &f)
operator!=
Definition Zp_field.h:268
friend void operator+=(Zp_field_element &f, const Integer_type &v)
operator+=
Definition Zp_field.h:102
friend Zp_field_element operator*(Zp_field_element f, const Integer_type &v)
operator*
Definition Zp_field.h:212
friend void operator-=(Zp_field_element &f1, const Zp_field_element &f2)
operator-=
Definition Zp_field.h:134
friend bool operator==(const Zp_field_element &f1, const Zp_field_element &f2)
operator==
Definition Zp_field.h:233
Element get_value() const
Returns the value of the element.
Definition Zp_field.h:388
friend void operator*=(Zp_field_element &f, const Integer_type &v)
operator*=
Definition Zp_field.h:201
Zp_field_element & operator=(Zp_field_element &&other) noexcept
Move assign operator.
Definition Zp_field.h:296
friend void operator*=(Zp_field_element &f1, const Zp_field_element &f2)
operator*=
Definition Zp_field.h:183
friend Integer_type operator-(const Integer_type &v, const Zp_field_element &f)
operator-
Definition Zp_field.h:175
Zp_field_element(Zp_field_element &&toMove) noexcept
Move constructor.
Definition Zp_field.h:77
std::pair< Zp_field_element, unsigned int > get_partial_inverse(unsigned int productOfCharacteristics) const
For interface purposes with multi-fields. Returns the inverse together with the argument.
Definition Zp_field.h:346
static Zp_field_element get_partial_multiplicative_identity(unsigned int productOfCharacteristics)
For interface purposes with multi-fields. Returns the multiplicative identity of the field.
Definition Zp_field.h:371
friend Zp_field_element operator*(Zp_field_element f1, const Zp_field_element &f2)
operator*
Definition Zp_field.h:191
friend Zp_field_element operator+(Zp_field_element f, const Integer_type &v)
operator+
Definition Zp_field.h:113
friend void operator-=(Zp_field_element &f, const Integer_type &v)
operator-=
Definition Zp_field.h:152
friend bool operator==(const Zp_field_element &f, const Integer_type &v)
operator==
Definition Zp_field.h:252
Zp_field_element()
Default constructor. Sets the element to 0.
Definition Zp_field.h:51
friend bool operator!=(const Zp_field_element &f, const Integer_type &v)
operator!=
Definition Zp_field.h:279
static Zp_field_element get_additive_identity()
Returns the additive identity of the field.
Definition Zp_field.h:356
static constexpr unsigned int get_characteristic()
Returns the current characteristic.
Definition Zp_field.h:381
friend void swap(Zp_field_element &f1, Zp_field_element &f2) noexcept
Swap operator.
Definition Zp_field.h:319
friend bool operator==(const Integer_type &v, const Zp_field_element &f)
operator==
Definition Zp_field.h:241
Zp_field_element(const Zp_field_element &toCopy)=default
Copy constructor.
friend Zp_field_element operator+(Zp_field_element f1, const Zp_field_element &f2)
operator+
Definition Zp_field.h:92
friend bool operator!=(const Zp_field_element &f1, const Zp_field_element &f2)
operator!=
Definition Zp_field.h:260
Element Characteristic
Definition Zp_field.h:44
friend void operator+=(Zp_field_element &f1, const Zp_field_element &f2)
operator+=
Definition Zp_field.h:84
Field namespace.
Definition Intro_field_elements_and_operators.h:16
Gudhi namespace.
Definition SimplicialComplexForAlpha.h:14