17#ifndef MATRIX_FIELD_ZP_H_ 
   18#define MATRIX_FIELD_ZP_H_ 
   25namespace persistence_fields {
 
   37template <
unsigned int characteristic, 
typename Unsigned_integer_type = 
unsigned int,
 
   38          class = std::enable_if_t<std::is_unsigned_v<Unsigned_integer_type> > >
 
   44  using isInteger = std::enable_if_t<std::is_integral_v<T> >;
 
   49  Zp_field_element() : element_(0) { 
static_assert(_is_prime(), 
"Characteristic has to be a prime number."); }
 
   56  template <
typename Integer_type, 
class = isInteger<Integer_type> >
 
   58    static_assert(_is_prime(), 
"Characteristic has to be a prime number.");
 
   77    f1.element_ = Zp_field_element::_add(f1.element_, f2.element_);
 
   89  template <
typename Integer_type, 
class = isInteger<Integer_type> >
 
   91    f.element_ = Zp_field_element::_add(f.element_, _get_value(v));
 
   98  template <
typename Integer_type, 
class = isInteger<Integer_type> >
 
  108  template <
typename Integer_type, 
class = isInteger<Integer_type> >
 
  118    f1.element_ = Zp_field_element::_subtract(f1.element_, f2.element_);
 
  130  template <
typename Integer_type, 
class = isInteger<Integer_type> >
 
  132    f.element_ = Zp_field_element::_subtract(f.element_, _get_value(v));
 
  139  template <
typename Integer_type, 
class = isInteger<Integer_type> >
 
  149  template <
typename Integer_type, 
class = isInteger<Integer_type> >
 
  151    return Zp_field_element::_subtract(_get_value(v), f.element_);
 
  158    f1.element_ = Zp_field_element::_multiply(f1.element_, f2.element_);
 
  170  template <
typename Integer_type, 
class = isInteger<Integer_type> >
 
  172    f.element_ = Zp_field_element::_multiply(f.element_, _get_value(v));
 
  179  template <
typename Integer_type, 
class = isInteger<Integer_type> >
 
  189  template <
typename Integer_type, 
class = isInteger<Integer_type> >
 
  199    return f1.element_ == f2.element_;
 
  206  template <
typename Integer_type, 
class = isInteger<Integer_type> >
 
  208    return Zp_field_element::_get_value(v) == f.element_;
 
  215  template <
typename Integer_type, 
class = isInteger<Integer_type> >
 
  217    return Zp_field_element::_get_value(v) == f.element_;
 
  228  template <
typename Integer_type, 
class = isInteger<Integer_type> >
 
  237  template <
typename Integer_type, 
class = isInteger<Integer_type> >
 
  246    std::swap(element_, other.element_);
 
  254  template <
typename Integer_type, 
class = isInteger<Integer_type> >
 
  256    element_ = _get_value(value);
 
  267  operator unsigned int()
 const { 
return element_; }
 
  275    if (element_ != 0 && inverse_[element_] == 0) {  
 
  276      inverse_[element_] = _get_inverse(element_);
 
  287  std::pair<Zp_field_element, unsigned int> 
get_partial_inverse(
unsigned int productOfCharacteristics)
 const {
 
  330  static inline std::array<unsigned int, characteristic> inverse_;  
 
  333    if (UINT_MAX - element < v) {
 
  336      element -= characteristic;
 
  341    if (element >= characteristic) element -= characteristic;
 
  347      element += characteristic;
 
  360        if (v >= characteristic - element) element -= characteristic;
 
  366      if (v >= characteristic - v) temp_b -= characteristic;
 
  372  static int _get_inverse(
Element element) {
 
  374    int M = characteristic;
 
  379      int quotient = A / M;
 
  385      y = x - quotient * y;
 
  389    if (x < 0) x += characteristic;
 
  394  template <
typename Integer_type, 
class = isInteger<Integer_type> >
 
  395  static constexpr Element _get_value(Integer_type e) {
 
  396    if constexpr (std::is_signed_v<Integer_type>) {
 
  397      if (e < -
static_cast<Integer_type
>(characteristic)) e = e % characteristic;
 
  398      if (e < 0) 
return e += characteristic;
 
  399      return e < static_cast<Integer_type>(characteristic) ? e : e % characteristic;
 
  401      return e < characteristic ? e : e % characteristic;
 
  405  static constexpr bool _is_prime() {
 
  406    if (characteristic <= 1) 
return false;
 
  407    if (characteristic <= 3) 
return true;
 
  408    if (characteristic % 2 == 0 || characteristic % 3 == 0) 
return false;
 
  410    for (
long i = 5; i * i <= characteristic; i = i + 6)
 
  411      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:39
 
Zp_field_element(Integer_type element)
Constructor setting the element to the given value.
Definition: Zp_field.h:57
 
Zp_field_element & operator=(Zp_field_element other)
Assign operator.
Definition: Zp_field.h:245
 
friend Zp_field_element operator-(Zp_field_element f1, const Zp_field_element &f2)
operator-
Definition: Zp_field.h:123
 
Zp_field_element & operator=(const Integer_type &value)
Assign operator.
Definition: Zp_field.h:255
 
friend Zp_field_element operator-(Zp_field_element f, const Integer_type &v)
operator-
Definition: Zp_field.h:140
 
friend Integer_type operator*(const Integer_type &v, Zp_field_element f)
operator*
Definition: Zp_field.h:190
 
static Zp_field_element get_multiplicative_identity()
Returns the multiplicative identity of the field.
Definition: Zp_field.h:302
 
Zp_field_element get_inverse() const
Returns the inverse of the element in the field.
Definition: Zp_field.h:274
 
Unsigned_integer_type Element
Definition: Zp_field.h:41
 
friend Integer_type operator+(const Integer_type &v, Zp_field_element f)
operator+
Definition: Zp_field.h:109
 
friend bool operator!=(const Integer_type &v, const Zp_field_element &f)
operator!=
Definition: Zp_field.h:229
 
friend void operator+=(Zp_field_element &f, const Integer_type &v)
operator+=
Definition: Zp_field.h:90
 
friend void swap(Zp_field_element &f1, Zp_field_element &f2)
Swap operator.
Definition: Zp_field.h:262
 
friend Zp_field_element operator*(Zp_field_element f, const Integer_type &v)
operator*
Definition: Zp_field.h:180
 
friend void operator-=(Zp_field_element &f1, const Zp_field_element &f2)
operator-=
Definition: Zp_field.h:117
 
friend bool operator==(const Zp_field_element &f1, const Zp_field_element &f2)
operator==
Definition: Zp_field.h:198
 
Element get_value() const
Returns the value of the element.
Definition: Zp_field.h:324
 
friend void operator*=(Zp_field_element &f, const Integer_type &v)
operator*=
Definition: Zp_field.h:171
 
friend void operator*=(Zp_field_element &f1, const Zp_field_element &f2)
operator*=
Definition: Zp_field.h:157
 
friend Integer_type operator-(const Integer_type &v, const Zp_field_element &f)
operator-
Definition: Zp_field.h:150
 
Zp_field_element(Zp_field_element &&toMove) noexcept
Move constructor.
Definition: Zp_field.h:71
 
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:287
 
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:309
 
friend Zp_field_element operator*(Zp_field_element f1, const Zp_field_element &f2)
operator*
Definition: Zp_field.h:163
 
Zp_field_element(const Zp_field_element &toCopy)
Copy constructor.
Definition: Zp_field.h:65
 
friend Zp_field_element operator+(Zp_field_element f, const Integer_type &v)
operator+
Definition: Zp_field.h:99
 
friend void operator-=(Zp_field_element &f, const Integer_type &v)
operator-=
Definition: Zp_field.h:131
 
friend bool operator==(const Zp_field_element &f, const Integer_type &v)
operator==
Definition: Zp_field.h:216
 
Zp_field_element()
Default constructor. Sets the element to 0.
Definition: Zp_field.h:49
 
friend bool operator!=(const Zp_field_element &f, const Integer_type &v)
operator!=
Definition: Zp_field.h:238
 
static Zp_field_element get_additive_identity()
Returns the additive identity of the field.
Definition: Zp_field.h:296
 
static constexpr unsigned int get_characteristic()
Returns the current characteristic.
Definition: Zp_field.h:317
 
friend bool operator==(const Integer_type &v, const Zp_field_element &f)
operator==
Definition: Zp_field.h:207
 
friend Zp_field_element operator+(Zp_field_element f1, const Zp_field_element &f2)
operator+
Definition: Zp_field.h:82
 
friend bool operator!=(const Zp_field_element &f1, const Zp_field_element &f2)
operator!=
Definition: Zp_field.h:222
 
Element Characteristic
Definition: Zp_field.h:42
 
friend void operator+=(Zp_field_element &f1, const Zp_field_element &f2)
operator+=
Definition: Zp_field.h:76
 
Gudhi namespace.
Definition: SimplicialComplexForAlpha.h:14