Loading...
Searching...
No Matches
Zp_field_shared.h
Go to the documentation of this file.
/* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT.
* See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details.
* Author(s): Hannah Schreiber
*
* Copyright (C) 2022 Inria
*
* Modification(s):
* - YYYY/MM Author: Description of the modification
*/
#ifndef MATRIX_FIELD_ZP_VAR_H_
#define MATRIX_FIELD_ZP_VAR_H_
#include <utility>
#include <vector>
#include <limits.h>
#include <stdexcept>
namespace Gudhi {
namespace persistence_fields {
template <typename Unsigned_integer_type = unsigned int,
class = std::enable_if_t<std::is_unsigned_v<Unsigned_integer_type> > >
class Shared_Zp_field_element {
public:
using Element = Unsigned_integer_type;
using Characteristic = Element;
template <class T>
using isInteger = std::enable_if_t<std::is_integral_v<T> >;
Shared_Zp_field_element() : element_(0) {}
template <typename Integer_type, class = isInteger<Integer_type> >
Shared_Zp_field_element(Integer_type element) : element_(_get_value(element)) {}
Shared_Zp_field_element(const Shared_Zp_field_element& toCopy) : element_(toCopy.element_) {}
Shared_Zp_field_element(Shared_Zp_field_element&& toMove) noexcept : element_(std::exchange(toMove.element_, 0)) {}
static void initialize(Characteristic characteristic) {
if (characteristic <= 1)
throw std::invalid_argument("Characteristic must be strictly positive and a prime number.");
inverse_.resize(characteristic);
inverse_[0] = 0;
for (Element i = 1; i < characteristic; ++i) {
Element inv = 1;
Element mult = inv * i;
while ((mult % characteristic) != 1) {
++inv;
if (mult == characteristic) throw std::invalid_argument("Characteristic must be a prime number.");
mult = inv * i;
}
inverse_[i] = inv;
}
characteristic_ = characteristic;
}
Element get_value() const { return element_; }
friend void operator+=(Shared_Zp_field_element& f1, const Shared_Zp_field_element& f2) {
f1.element_ = Shared_Zp_field_element::_add(f1.element_, f2.element_);
}
friend Shared_Zp_field_element operator+(Shared_Zp_field_element f1, const Shared_Zp_field_element& f2) {
f1 += f2;
return f1;
}
template <typename Integer_type, class = isInteger<Integer_type> >
friend void operator+=(Shared_Zp_field_element& f, const Integer_type& v) {
f.element_ = Shared_Zp_field_element::_add(f.element_, _get_value(v));
}
template <typename Integer_type, class = isInteger<Integer_type> >
friend Shared_Zp_field_element operator+(Shared_Zp_field_element f, const Integer_type& v) {
f += v;
return f;
}
template <typename Integer_type, class = isInteger<Integer_type> >
friend Integer_type operator+(const Integer_type& v, Shared_Zp_field_element f) {
f += v;
return f.element_;
}
friend void operator-=(Shared_Zp_field_element& f1, const Shared_Zp_field_element& f2) {
f1.element_ = Shared_Zp_field_element::_subtract(f1.element_, f2.element_);
}
friend Shared_Zp_field_element operator-(Shared_Zp_field_element f1, const Shared_Zp_field_element& f2) {
f1 -= f2;
return f1;
}
template <typename Integer_type, class = isInteger<Integer_type> >
friend void operator-=(Shared_Zp_field_element& f, const Integer_type& v) {
f.element_ = Shared_Zp_field_element::_subtract(f.element_, _get_value(v));
}
template <typename Integer_type, class = isInteger<Integer_type> >
friend Shared_Zp_field_element operator-(Shared_Zp_field_element f, const Integer_type& v) {
f -= v;
return f;
}
template <typename Integer_type, class = isInteger<Integer_type> >
friend Integer_type operator-(const Integer_type& v, const Shared_Zp_field_element& f) {
return Shared_Zp_field_element::_subtract(_get_value(v), f.element_);
}
friend void operator*=(Shared_Zp_field_element& f1, const Shared_Zp_field_element& f2) {
f1.element_ = Shared_Zp_field_element::_multiply(f1.element_, f2.element_);
}
friend Shared_Zp_field_element operator*(Shared_Zp_field_element f1, const Shared_Zp_field_element& f2) {
f1 *= f2;
return f1;
}
template <typename Integer_type, class = isInteger<Integer_type> >
friend void operator*=(Shared_Zp_field_element& f, const Integer_type& v) {
f.element_ = Shared_Zp_field_element::_multiply(f.element_, _get_value(v));
}
template <typename Integer_type, class = isInteger<Integer_type> >
friend Shared_Zp_field_element operator*(Shared_Zp_field_element f, const Integer_type& v) {
f *= v;
return f;
}
template <typename Integer_type, class = isInteger<Integer_type> >
friend Integer_type operator*(const Integer_type& v, Shared_Zp_field_element f) {
f *= v;
return f.element_;
}
friend bool operator==(const Shared_Zp_field_element& f1, const Shared_Zp_field_element& f2) {
return f1.element_ == f2.element_;
}
template <typename Integer_type, class = isInteger<Integer_type> >
friend bool operator==(const Integer_type& v, const Shared_Zp_field_element& f) {
return Shared_Zp_field_element::_get_value(v) == f.element_;
}
template <typename Integer_type, class = isInteger<Integer_type> >
friend bool operator==(const Shared_Zp_field_element& f, const Integer_type& v) {
return Shared_Zp_field_element::_get_value(v) == f.element_;
}
friend bool operator!=(const Shared_Zp_field_element& f1, const Shared_Zp_field_element& f2) { return !(f1 == f2); }
template <typename Integer_type, class = isInteger<Integer_type> >
friend bool operator!=(const Integer_type& v, const Shared_Zp_field_element& f) {
return !(v == f);
}
template <typename Integer_type, class = isInteger<Integer_type> >
friend bool operator!=(const Shared_Zp_field_element& f, const Integer_type& v) {
return !(v == f);
}
Shared_Zp_field_element& operator=(Shared_Zp_field_element other) {
std::swap(element_, other.element_);
return *this;
}
template <typename Integer_type, class = isInteger<Integer_type> >
Shared_Zp_field_element& operator=(const Integer_type& value) {
element_ = Shared_Zp_field_element::_get_value(value);
return *this;
}
friend void swap(Shared_Zp_field_element& f1, Shared_Zp_field_element& f2) { std::swap(f1.element_, f2.element_); }
operator unsigned int() const { return element_; }
Shared_Zp_field_element get_inverse() const { return Shared_Zp_field_element(inverse_[element_]); }
std::pair<Shared_Zp_field_element, Characteristic> get_partial_inverse(
Characteristic productOfCharacteristics) const {
return {get_inverse(), productOfCharacteristics};
}
static Shared_Zp_field_element get_additive_identity() { return Shared_Zp_field_element(); }
static Shared_Zp_field_element get_multiplicative_identity() { return Shared_Zp_field_element(1); }
static Shared_Zp_field_element get_partial_multiplicative_identity(
[[maybe_unused]] Characteristic productOfCharacteristics) {
return Shared_Zp_field_element(1);
}
static Characteristic get_characteristic() { return characteristic_; }
// static constexpr bool handles_only_z2() { return false; }
private:
Element element_;
static inline Characteristic characteristic_;
static inline std::vector<Element> inverse_;
static Element _add(Element element, Element v) {
if (UINT_MAX - element < v) {
// automatic unsigned integer overflow behaviour will make it work
element += v;
element -= characteristic_;
return element;
}
element += v;
if (element >= characteristic_) element -= characteristic_;
return element;
}
static Element _subtract(Element element, Element v) {
if (element < v) {
element += characteristic_;
}
element -= v;
return element;
}
static Element _multiply(Element element, Element v) {
Element a = element;
element = 0;
Element temp_b;
while (a != 0) {
if (a & 1) {
if (v >= characteristic_ - element) element -= characteristic_;
element += v;
}
a >>= 1;
temp_b = v;
if (v >= characteristic_ - v) temp_b -= characteristic_;
v += temp_b;
}
return element;
}
template <typename Integer_type, class = isInteger<Integer_type> >
static constexpr Element _get_value(Integer_type e) {
if constexpr (std::is_signed_v<Integer_type>){
if (e < -static_cast<Integer_type>(characteristic_)) e = e % characteristic_;
if (e < 0) return e += characteristic_;
return e < static_cast<Integer_type>(characteristic_) ? e : e % characteristic_;
} else {
return e < characteristic_ ? e : e % characteristic_;
}
}
};
} // namespace persistence_fields
} // namespace Gudhi
#endif // MATRIX_FIELD_ZP_VAR_H_
Gudhi::persistence_fields::Shared_Zp_field_element::initialize
static void initialize(Characteristic characteristic)
Initialize the field to the given characteristic. Should be called first before constructing the fiel...
Definition Zp_field_shared.h:80
Gudhi::persistence_fields::Shared_Zp_field_element::operator==
friend bool operator==(const Shared_Zp_field_element &f, const Integer_type &v)
operator==
Definition Zp_field_shared.h:256
Gudhi::persistence_fields::Shared_Zp_field_element::get_inverse
Shared_Zp_field_element get_inverse() const
Returns the inverse of the element in the field.
Definition Zp_field_shared.h:314
Gudhi::persistence_fields::Shared_Zp_field_element::operator==
friend bool operator==(const Shared_Zp_field_element &f1, const Shared_Zp_field_element &f2)
operator==
Definition Zp_field_shared.h:238
Gudhi::persistence_fields::Shared_Zp_field_element::Shared_Zp_field_element
Shared_Zp_field_element()
Default constructor. Sets the element to 0.
Definition Zp_field_shared.h:52
Gudhi::persistence_fields::Shared_Zp_field_element::operator=
Shared_Zp_field_element & operator=(const Integer_type &value)
Assign operator.
Definition Zp_field_shared.h:295
Gudhi::persistence_fields::Shared_Zp_field_element::operator==
friend bool operator==(const Integer_type &v, const Shared_Zp_field_element &f)
operator==
Definition Zp_field_shared.h:247
Gudhi::persistence_fields::Shared_Zp_field_element::operator=
Shared_Zp_field_element & operator=(Shared_Zp_field_element other)
Assign operator.
Definition Zp_field_shared.h:285
Gudhi::persistence_fields::Shared_Zp_field_element::operator+
friend Integer_type operator+(const Integer_type &v, Shared_Zp_field_element f)
operator+
Definition Zp_field_shared.h:145
Gudhi::persistence_fields::Shared_Zp_field_element::Characteristic
Element Characteristic
Definition Zp_field_shared.h:45
Gudhi::persistence_fields::Shared_Zp_field_element::operator-=
friend void operator-=(Shared_Zp_field_element &f1, const Shared_Zp_field_element &f2)
operator-=
Definition Zp_field_shared.h:153
Gudhi::persistence_fields::Shared_Zp_field_element::operator*
friend Integer_type operator*(const Integer_type &v, Shared_Zp_field_element f)
operator*
Definition Zp_field_shared.h:230
Gudhi::persistence_fields::Shared_Zp_field_element::operator+
friend Shared_Zp_field_element operator+(Shared_Zp_field_element f, const Integer_type &v)
operator+
Definition Zp_field_shared.h:135
Gudhi::persistence_fields::Shared_Zp_field_element::operator!=
friend bool operator!=(const Shared_Zp_field_element &f1, const Shared_Zp_field_element &f2)
operator!=
Definition Zp_field_shared.h:262
Gudhi::persistence_fields::Shared_Zp_field_element::operator*=
friend void operator*=(Shared_Zp_field_element &f1, const Shared_Zp_field_element &f2)
operator*=
Definition Zp_field_shared.h:195
Gudhi::persistence_fields::Shared_Zp_field_element::Shared_Zp_field_element
Shared_Zp_field_element(const Shared_Zp_field_element &toCopy)
Copy constructor.
Definition Zp_field_shared.h:66
Gudhi::persistence_fields::Shared_Zp_field_element::get_partial_multiplicative_identity
static Shared_Zp_field_element get_partial_multiplicative_identity(Characteristic productOfCharacteristics)
For interface purposes with multi-fields. Returns the multiplicative identity of the field.
Definition Zp_field_shared.h:344
Gudhi::persistence_fields::Shared_Zp_field_element::operator*
friend Shared_Zp_field_element operator*(Shared_Zp_field_element f, const Integer_type &v)
operator*
Definition Zp_field_shared.h:220
Gudhi::persistence_fields::Shared_Zp_field_element::get_additive_identity
static Shared_Zp_field_element get_additive_identity()
Returns the additive identity of the field.
Definition Zp_field_shared.h:331
Gudhi::persistence_fields::Shared_Zp_field_element::operator-=
friend void operator-=(Shared_Zp_field_element &f, const Integer_type &v)
operator-=
Definition Zp_field_shared.h:169
Gudhi::persistence_fields::Shared_Zp_field_element::Element
Unsigned_integer_type Element
Definition Zp_field_shared.h:44
Gudhi::persistence_fields::Shared_Zp_field_element::operator-
friend Shared_Zp_field_element operator-(Shared_Zp_field_element f1, const Shared_Zp_field_element &f2)
operator-
Definition Zp_field_shared.h:159
Gudhi::persistence_fields::Shared_Zp_field_element::operator+
friend Shared_Zp_field_element operator+(Shared_Zp_field_element f1, const Shared_Zp_field_element &f2)
operator+
Definition Zp_field_shared.h:116
Gudhi::persistence_fields::Shared_Zp_field_element::get_multiplicative_identity
static Shared_Zp_field_element get_multiplicative_identity()
Returns the multiplicative identity of the field.
Definition Zp_field_shared.h:337
Gudhi::persistence_fields::Shared_Zp_field_element::operator*=
friend void operator*=(Shared_Zp_field_element &f, const Integer_type &v)
operator*=
Definition Zp_field_shared.h:211
Gudhi::persistence_fields::Shared_Zp_field_element::swap
friend void swap(Shared_Zp_field_element &f1, Shared_Zp_field_element &f2)
Swap operator.
Definition Zp_field_shared.h:302
Gudhi::persistence_fields::Shared_Zp_field_element::get_characteristic
static Characteristic get_characteristic()
Returns the current characteristic.
Definition Zp_field_shared.h:353
Gudhi::persistence_fields::Shared_Zp_field_element::operator-
friend Shared_Zp_field_element operator-(Shared_Zp_field_element f, const Integer_type &v)
operator-
Definition Zp_field_shared.h:178
Gudhi::persistence_fields::Shared_Zp_field_element::operator*
friend Shared_Zp_field_element operator*(Shared_Zp_field_element f1, const Shared_Zp_field_element &f2)
operator*
Definition Zp_field_shared.h:201
Gudhi::persistence_fields::Shared_Zp_field_element::get_value
Element get_value() const
Returns the value of the element.
Definition Zp_field_shared.h:105
Gudhi::persistence_fields::Shared_Zp_field_element::Shared_Zp_field_element
Shared_Zp_field_element(Integer_type element)
Constructor setting the element to the given value.
Definition Zp_field_shared.h:60
Gudhi::persistence_fields::Shared_Zp_field_element::operator!=
friend bool operator!=(const Integer_type &v, const Shared_Zp_field_element &f)
operator!=
Definition Zp_field_shared.h:269
Gudhi::persistence_fields::Shared_Zp_field_element::get_partial_inverse
std::pair< Shared_Zp_field_element, Characteristic > get_partial_inverse(Characteristic productOfCharacteristics) const
For interface purposes with multi-fields. Returns the inverse together with the argument.
Definition Zp_field_shared.h:321
Gudhi::persistence_fields::Shared_Zp_field_element::operator-
friend Integer_type operator-(const Integer_type &v, const Shared_Zp_field_element &f)
operator-
Definition Zp_field_shared.h:188
Gudhi::persistence_fields::Shared_Zp_field_element::Shared_Zp_field_element
Shared_Zp_field_element(Shared_Zp_field_element &&toMove) noexcept
Move constructor.
Definition Zp_field_shared.h:72
Gudhi::persistence_fields::Shared_Zp_field_element::operator+=
friend void operator+=(Shared_Zp_field_element &f, const Integer_type &v)
operator+=
Definition Zp_field_shared.h:126
Gudhi::persistence_fields::Shared_Zp_field_element::operator!=
friend bool operator!=(const Shared_Zp_field_element &f, const Integer_type &v)
operator!=
Definition Zp_field_shared.h:278
Gudhi::persistence_fields::Shared_Zp_field_element::operator+=
friend void operator+=(Shared_Zp_field_element &f1, const Shared_Zp_field_element &f2)
operator+=
Definition Zp_field_shared.h:110
Gudhi::persistence_fields
Field namespace.
Definition Intro_field_elements_and_operators.h:16
Gudhi
Gudhi namespace.
Definition SimplicialComplexForAlpha.h:14