abstract fields and polynomials

parent 2d60585f
#ifndef __FIELD_H__
#define __FIELD_H__
#include <type_traits>
namespace tinygb {
// AbstractField and AbstractFieldElement are the API for fields and their
// elements. Concrete implementations of fields are implemented in subclasses
// via static polymorphism.
template <typename T> // CRTP
class AbstractField {
public:
std::string description() const {
return static_cast<T*>(this)->description();
}
};
template <typename Field, typename T> // T is the CRTP parameter
class AbstractFieldElement {
static_assert(std::is_base_of<AbstractField<Field>, Field>::value,
"Field should be derived from AbstractField");
public:
typedef Field Parent;
void operator+=(const AbstractFieldElement<Field, T>& e) {
static_cast<T*>(this)->operator+=(e);
}
void operator-=(const AbstractFieldElement<Field, T>& e) {
static_cast<T*>(this)->operator-=(e);
}
void operator*=(const AbstractFieldElement<Field, T>& e) {
static_cast<T*>(this)->operator*=(e);
}
void operator/=(const AbstractFieldElement<Field, T>& e) {
static_cast<T*>(this)->operator/=(e);
}
void inv() {
static_cast<T*>(this)->inv();
}
bool IsZero() const {
return static_cast<T*>(this)->isZero();
}
};
} // namespace tinygb
#endif
#ifndef __ABSTRACT_POLYNOMIAL_H__
#define __ABSTRACT_POLYNOMIAL_H__
#include <type_traits>
#include "./abstract_field.h"
namespace tinygb {
// AbstractPolynomial is the global API for multivariate polynomials. Concrete
// implementations of polynomials are implemented in subclasses via static
// polymorphism.
template <class FieldElement, class T> // T is the CRTP parameter
class AbstractPolynomial {
static_assert(std::is_base_of<AbstractFieldElement<typename FieldElement::Parent, FieldElement>,
FieldElement>::value,
"Field should be derived from AbstractField");
public:
Monomial LeadingMonomial() const {
return static_cast<T*>(this)->LeadingMonomial();}
FieldElement LeadingCoefficient() const {
return static_cast<T*>(this)->LeadingCoefficient();}
void DivideByLeadingCoefficient() {
static_cast<T*>(this)->DivideByLeadingCoefficient();}
};
} // namespace tinygb
#endif
......@@ -6,9 +6,18 @@
#include <givaro/modular-integer.h>
#pragma GCC diagnostic pop
#include "./abstract_field.h"
namespace tinygb {
class GivaroWrapper {
class GFp : public AbstractField<GFp> {
public:
std::string description() const {
return "Finite field of prime cardinality p";}
};
class GivaroWrapper : public AbstractFieldElement<GFp, GivaroWrapper> {
public:
typedef Givaro::Integer elt_t;
typedef Givaro::Modular<Givaro::Integer> ring_t;
......
......@@ -5,6 +5,7 @@ namespace tinygb {
// static member definition
Monomial_pool Monomial::m_pool;
// Acknowledgements to Jeremie Detrey for this SSE/AVX code
// AVX code disabled
// TODO(pj): enable AVX
//#ifdef __MONOMIAL_ORDERING
......
// Acknowledgements to Jeremie Detrey for the SSE/AVX code
#ifndef __MONOMIAL_H__
#define __MONOMIAL_H__
......
......@@ -5,11 +5,12 @@
#include <utility>
#include "./common.h"
#include "./monomial.h"
#include "./abstract_polynomial.h"
#include "finite_field_arithmetic/givaro_wrapper.h"
namespace tinygb {
class Polynomial {
class Polynomial : public AbstractPolynomial<GivaroWrapper, Polynomial> {
public:
typedef std::pair<Monomial, GivaroWrapper> Term;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment