1 #ifndef _MMPolynomial_H_     2 #define _MMPolynomial_H_     5 #include "../Polynomial/BPASMultivarPolynomial.hpp"     6 #include "../Utils/TemplateHelpers.hpp"     7 #include "../Ring/BPASField.hpp"    10 inline void coef_add_mod(Field* c, Field a, Field b, Field p) {
    13 template <
class Field>
    14 inline void coef_sub_mod(Field* c, Field a, Field b, Field p) {
    16     if (*c < 0) { *c += p; }
    18 template <
class Field>
    19 inline void coef_neg_mod(Field* c, Field a, Field p) {
    22 template <
class Field>
    23 inline void coef_mul_mod(Field* c, Field a, Field b, Field p) {
    31 template <
class Field>
    33                                                       private Derived_from<Field, BPASField<Field>> {
    46             for (
int i = 0; i < n; ++i)
    51             if (var != b.var || names[0] != b.names[0])
    53             if (names[0] == 
"9") {
    54                 for (
int i = 1; i <= var; ++i) {
    55                     if (names[i] != b.names[i])
    63         static mpz_class characteristic;
   108             for (
int i = 0; i < var; ++i) {
   111                     acc[i+1] = acc[i] * (degs[i] + 1);
   113             n = acc[var-1] * (degs[var-1] + 1);
   114             coefs = 
new Field[n];
   117             names = 
new Symbol[var+1];
   119             for (
int i = 1; i <= var; ++i) {
   120                 std::ostringstream convert;
   121                 convert << var - i + 1;
   123                 names[i] += convert.str();
   142             coefs = 
new Field[2];
   153             std::copy(b.degs, b.degs+var, degs);
   155             std::copy(b.acc, b.acc+var, acc);
   156             coefs = 
new Field[n];
   157             std::copy(b.coefs, b.coefs+n, coefs);
   158             names = 
new Symbol[var+1];
   159             std::copy(b.names, b.names+var+1, names);
   186                 std::copy(b.degs, b.degs+var, degs);
   188                 std::copy(b.acc, b.acc+var, acc);
   190                 coefs = 
new Field[n];
   191                 std::copy(b.coefs, b.coefs+n, coefs);
   192                 names = 
new Symbol[var+1];
   193                 std::copy(b.names, b.names+var+1, names);
   222             for (
int i = 0; i < n; ++i) {
   242             for (
int i = 1; i < n; ++i) {
   246             return (coefs[0] == 1);
   255             for (
int i = 1; i < n; ++i)
   264             for (
int i = 1; i < n; ++i) {
   268             return (coefs[0] == p - 1);
   277             for (
int i = 1; i < n; ++i)
   286             for (
int i = 1; i < n; ++i) {
   290             if (coefs[0] < (p / 2)) { 
return 1; }
   316             for (
int i = 0; i < n; ++i)
   317                 if (coefs[i] != 0) { k++; }
   334             for (
int i = 0; i < var; ++i) {
   347             for (
int i = 1; i <= var; ++i) {
   353                 for (
int i = 0; i < n; ++i) {
   354                     int e = (i / acc[k]) % (degs[k] + 1);
   355                     if (coefs[i] != 0 && e > d)
   368             for (
int i = n-1; i > -1; --i) {
   375         inline Field trailingCoefficient()
 const {
   376             for (
int i = 0; i < n; ++i) {
   384         bool isConstantTermZero()
 const {
   393             Field leadInv = lead.inverse();
   412             for (
int i = var-1, j = 0; i > -1 && j < v; --i, ++j) {
   417             for (
int i = v-var-1; i > -1; --i)
   418                 if (d[i]) { 
return 0; }
   435                 std::cout << 
"BPAS: error, DDMMP(" << var << 
"), but trying to setCoefficient with " << v << 
" variables." << std::endl;
   439             for (
int i = var-1, j = 0; i > -1 && j < v; --i, ++j) {
   443                     std::cout << 
"BPAS: error, the degree of " << names[i+1] << 
" in DDMMP is " << degs[i] << 
"." << std::endl;
   461             if (k >= n || k < 0) {
   462                 std::cout << 
"BPAS: error, trying to access a non-exist coefficient in DDMMP<Field>." << std::endl;
   468         inline Field content()
 const {
   470             std::cerr << 
"BPAS ERROR: DistributedDenseMultivariateModularPolynomial::content() NOT YET IMPLEMENTED" << std::endl;
   476             std::cerr << 
"BPAS ERROR: DistributedDenseMultivariateModularPolynomial::primitivePart() NOT YET IMPLEMENTED" << std::endl;
   486             if (var != b.var || p != b.p)
   490             for (
int i = 0; i < n; ++i) {
   492                 for (
int j = 0; j < var; ++j) {
   493                     int e = (i / acc[j]) % (degs[j] + 1);
   496                     else if (coefs[i] != 0)
   499                 for (
int j = prev+1; j < k; ++j) {
   503                 if (coefs[i] != b.coefs[k])
   507             for (
int i = n; i < b.n; ++i) {
   519             return !(*
this == b);
   529                 std::cout << 
"BPAS: error, trying to add between Z/" << p << 
"Z and Z/" << b.p << 
"Z from DDMMP<Field>." << std::endl;
   533             if (b.isConstant()) { 
return *
this + b.coefs[0]; }
   535             bool isSame = isSameRing(b);
   537                 std::cout << 
"BPAS: error, trying to add between Z/" << p << 
"Z[";
   538                 for (
int i = 1; i <= var; ++i) {
   539                     std::cout << names[i];
   543                 std::cout << 
"] and Z/" << b.p << 
"Z[";
   544                 for (
int i = 1; i <= b.var; ++i) {
   545                     std::cout << b.names[i];
   549                 std::cout << 
"] from DDMMP<Field>." << std::endl;
   553             int* ds = 
new int[var];
   554             for (
int i = 0; i < var; ++i)
   555                 ds[i] = (degs[i] >= b.degs[i])? degs[i] : b.degs[i];
   557             std::copy(names, names+var+1, res.names);
   560             for (
int i = 0; i < res.n; ++i) {
   562                 int offseta = 0, offsetb = 0;
   563                 for (
int j = 0; j < var; ++j) {
   564                     int k = (i / res.acc[j]) % (res.degs[j] + 1);
   565                     if (offseta >= 0 && k <= degs[j])
   566                         offseta += k * acc[j];
   569                     if (offsetb >= 0 && k <= b.degs[j])
   570                         offsetb += k * b.acc[j];
   574                 if (offseta >= 0 && offsetb >= 0)
   575                     coef_add_mod(&elem, coefs[offseta], b.coefs[offsetb], p);
   576                 else if (offseta >= 0)
   577                     elem = coefs[offseta];
   578                 else if (offsetb >= 0)
   579                     elem = b.coefs[offsetb];
   617             coef_add_mod(&coefs[0], coefs[0], e, p);
   628                 std::cout << 
"BPAS: error, trying to subtract between Z/" << p << 
"Z and Z/" << b.p << 
"Z from DDMMP<Field>." << std::endl;
   632             if (b.isConstant()) { 
return *
this - b.coefs[0]; }
   634             bool isSame = isSameRing(b);
   636                 std::cout << 
"BPAS: error, trying to subtract between Z/" << p << 
"Z[";
   637                 for (
int i = 1; i <= var; ++i) {
   638                     std::cout << names[i];
   642                 std::cout << 
"] and Z/" << b.p << 
"Z[";
   643                 for (
int i = 1; i <= b.var; ++i) {
   644                     std::cout << b.names[i];
   648                 std::cout << 
"] from DDMMP<Field>." << std::endl;
   652             int* ds = 
new int[var];
   653             for (
int i = 0; i < var; ++i)
   654                 ds[i] = (degs[i] >= b.degs[i])? degs[i] : b.degs[i];
   656             std::copy(names, names+var+1, res.names);
   658             for (
int i = 0; i < res.n; ++i) {
   660                 int offseta = 0, offsetb = 0;
   661                 for (
int j = 0; j < var; ++j) {
   662                     int k = (i / res.acc[j]) % (res.degs[j] + 1);
   663                     if (offseta >= 0 && k <= degs[j])
   664                         offseta += k * acc[j];
   665                     else { offseta = -1; }
   666                     if (offsetb >= 0 && k <= b.degs[j])
   667                         offsetb += k * b.acc[j];
   668                     else { offsetb = -1; }
   670                 if (offseta >= 0 && offsetb >= 0)
   671                     coef_sub_mod(&elem, coefs[offseta], b.coefs[offsetb], p);
   672                 else if (offseta >= 0)
   673                     elem = coefs[offseta];
   674                 else if (offsetb >= 0)
   675                     coef_neg_mod(&elem, b.coefs[offsetb], p);
   699             std::copy(names, names+var+1, res.names);
   700             for (
int i = 0; i < res.n; ++i)
   701                 coef_neg_mod(&res.coefs[i], coefs[i], p);
   725             coef_sub_mod(&coefs[0], coefs[0], e, p);
   735             for (
int i = 0; i < n; ++i)
   736                 coef_neg_mod(&coefs[i], coefs[i], p);
   746                 std::cout << 
"BPAS: error, trying to multiply between Z/" << p << 
"Z and Z/" << b.p << 
"Z from DDMMP<Field>." << std::endl;
   750             if (b.isConstant()) { 
return *
this * b.coefs[0]; }
   752             bool isSame = isSameRing(b);
   754                 std::cout << 
"BPAS: error, trying to multiply between Z/" << p << 
"Z[";
   755                 for (
int i = 1; i <= var; ++i) {
   756                     std::cout << names[i];
   760                 std::cout << 
"] and Z/" << b.p << 
"Z[";
   761                 for (
int i = 1; i <= b.var; ++i) {
   762                     std::cout << b.names[i];
   766                 std::cout << 
"] from DDMMP<Field>." << std::endl;
   770             int* ds = 
new int[var];
   771             for (
int i = 0; i < var; ++i)
   772                 ds[i] = degs[i] + b.degs[i];
   774             std::copy(names, names+var+1, res.names);
   776             for (
int i = 0; i < n; ++i) {
   777                 for (
int v = 0; v < var; ++v)
   778                     ds[v] = (i / acc[v]) % (degs[v] + 1);
   779                 for (
int j = 0; j < b.n; ++j) {
   781                     for (
int v = 0; v < b.var; ++v) {
   782                         int e = (j / b.acc[v]) % (b.degs[v] + 1);
   784                             k += (ds[v] + e) * res.acc[v];
   788                     for (
int v = b.var; v < var; ++v)
   789                         k += ds[v] * res.acc[v];
   792                     coef_mul_mod(&t, coefs[i], b.coefs[j], p);
   793                     coef_add_mod(&res.coefs[k], res.coefs[k], t, p);
   831             if (f != 0 && f != 1) {
   833                 if (e < 0) { e = e % p + p; }
   834                 for (
int i = 0; i < n; ++i)
   835                     coef_mul_mod(&coefs[i], coefs[i], e, p);
   837             else if (f == 0) { 
zero(); }
   843             std::cerr << 
"BPAS ERROR: DistributedDenseMultivariateModularPolynomial::operator^ NOT YET IMPLEMENTED" << std::endl;
   849             std::cerr << 
"BPAS ERROR: DistributedDenseMultivariateModularPolynomial::operator^= NOT YET IMPLEMENTED" << std::endl;
   861             std::cerr << 
"BPAS ERROR: DistributedDenseMultivariateModularPolynomial::operator/=(DistributedDenseMultivariateModularPolynomial) NOT YET IMPLEMENTED" << std::endl;
   873             std::cerr << 
"BPAS ERROR: DistributedDenseMultivariateModularPolynomial::operator/= NOT YET IMPLEMENTED" << std::endl;
   885                 std::cerr << 
"BPAS ERROR: DDMMP shrinking and expanding polynomial ring NOT YET IMPLEMENTED" << std::endl;
   889             for (
int i = var, j = 0; i > 0 && j < ns; --i, ++j)
   899                 std::vector<Symbol> xs;
   900                 for (
int i = var; i > 0; --i)
   901                         xs.push_back(names[i]);
   906             std::cerr << 
"BPAS ERROR: DDMMP::variables() NOT YET IMPLEMENTED" << std::endl;
   917         inline void print(std::ostream &out)
 const {
   919             for (
int i = 0; i < this->n; ++i) {
   920                 if (this->coefs[i] != 0) {
   922                         if (this->coefs[i] >= 0)
   924                         else if (this->coefs[i] == -1)
   926                         if (this->coefs[i] != 1 && this->coefs[i] != -1)
   927                             out << this->coefs[i];
   929                         for (
int j = 0; j < this->var; ++j) {
   930                             int exp = (i / this->acc[j]) % (this->degs[j] + 1);
   932                                 if ((this->coefs[i] != 1 && this->coefs[i] != -1 && isIt) || !isIt)
   934                                 out << this->names[j+1];
   941                     else { out << this->coefs[i]; }
   945             if (!isFirst) { out << 
"0"; }
   953             std::cerr << 
"DistributedDenseMultivariateModularPolynomial::convertToExpressionTree() NOT YET IMPLEMENTED" << std::endl;
   958             std::cerr << 
"DistributedDenseMultivariateModularPolynomial::differentiate NOT YET IMPLEMENTED" << std::endl;
   978             std::cerr << 
"BPAS ERROR: DistributedDenseMultivariateModularPolynomial::evaluate NOT YET IMPLEMENTED" << std::endl;
   984             std::cerr << 
"BPAS ERROR: DistributedDenseMultivariateModularPolynomial::evaluate NOT YET IMPLEMENTED" << std::endl;
   990             std::cerr << 
"BPAS ERROR: DistributedDenseMultivariateModularPolynomial::gcd NOT YET IMPLEMENTED" << std::endl;
   998             std::cerr << 
"DistributedDenseMultivariateModularPolynomial::squareFree NOT YET IMPLEMENTED" << std::endl;
  1000             std::vector<DistributedDenseMultivariateModularPolynomial> ret;
  1001             ret.push_back(*
this);
 DistributedDenseMultivariateModularPolynomial(const DistributedDenseMultivariateModularPolynomial< Field > &b)
Copy constructor. 
Definition: dmpolynomial.h:151
void negate()
Negate, f(-x) 
Definition: dmpolynomial.h:734
Field coefficient(const std::vector< int > &v) const
Get the coefficient of this polynomial with respect to the monomial defined by exponent vector exps...
Definition: dmpolynomial.h:422
DistributedDenseMultivariateModularPolynomial< Field > derivative(const Symbol &s, int k) const
Differentiate this polynomial k times, with respect to a particular variable, setting itself to its d...
Definition: dmpolynomial.h:966
ExpressionTree convertToExpressionTree() const
Convert *this to an expression tree. 
Definition: dmpolynomial.h:951
DistributedDenseMultivariateModularPolynomial< Field > operator+(const DistributedDenseMultivariateModularPolynomial< Field > &b) const
Overload operator +. 
Definition: dmpolynomial.h:527
Field leadingCoefficient() const
Get the leading coefficient. 
Definition: dmpolynomial.h:367
int numberOfRingVariables() const
Get the number of variables in this polynomial ring. 
Definition: dmpolynomial.h:305
Integer degree(const Symbol &x) const
Get a partial degree of variable x. 
Definition: dmpolynomial.h:345
DistributedDenseMultivariateModularPolynomial< Field > & operator-=(const DistributedDenseMultivariateModularPolynomial< Field > &b)
Overload operator -=. 
Definition: dmpolynomial.h:687
Integer numberOfTerms() const
Get the number of non-zero terms. 
Definition: dmpolynomial.h:314
DistributedDenseMultivariateModularPolynomial(int v, int *ds, Field m)
Constructor with number of variables and terms. 
Definition: dmpolynomial.h:104
void print(std::ostream &out) const
Overload stream operator <<. 
Definition: dmpolynomial.h:917
mpz_class getCharacteristic() const override
The characteristic of this ring class. 
Definition: dmpolynomial.h:211
DistributedDenseMultivariateModularPolynomial()
Constructor using a default field. 
Definition: dmpolynomial.h:70
An ExpressionTree encompasses various forms of data that can be expressed generically as a binary tre...
Definition: ExpressionTree.hpp:17
DistributedDenseMultivariateModularPolynomial< Field > operator*(const DistributedDenseMultivariateModularPolynomial< Field > &b) const
Overload operator *. 
Definition: dmpolynomial.h:744
Factors< DistributedDenseMultivariateModularPolynomial > squareFree() const
Compute squarefree factorization of *this. 
Definition: dmpolynomial.h:997
Integer degree() const
Get the total degree. 
Definition: dmpolynomial.h:332
void negativeOne()
Set polynomial to -1. 
Definition: dmpolynomial.h:275
std::vector< Symbol > ringVariables() const
Get variable names. 
Definition: dmpolynomial.h:898
int size() const
Get the size of the polynomial. 
Definition: dmpolynomial.h:325
void setCoefficient(const std::vector< int > &v, const Field &val)
Set the coefficient of this polynomial for the monomial defined by exponent vector exps to r...
Definition: dmpolynomial.h:450
bool isOne() const
Is polynomial 1. 
Definition: dmpolynomial.h:241
Field coefficient(int v, const int *d) const
Get a coefficient. 
Definition: dmpolynomial.h:410
DistributedDenseMultivariateModularPolynomial< Field > evaluate(int n, const Symbol *syms, const Field *vals) const
Evaluate this polynomial by substituting the input ring elements elems for the variables vars...
Definition: dmpolynomial.h:982
DistributedDenseMultivariateModularPolynomial< Field > evaluate(const std::vector< Symbol > &syms, const std::vector< Field > &vals) const
Evaluate this polynomial by substituting the input ring elements elems for the variables vars...
Definition: dmpolynomial.h:976
DistributedDenseMultivariateModularPolynomial(const Symbol &x, const Field &m)
Construct with a variable name such that f(x) = x;. 
Definition: dmpolynomial.h:134
DistributedDenseMultivariateModularPolynomial< Field > & operator=(const DistributedDenseMultivariateModularPolynomial< Field > &b)
Overload operator =. 
Definition: dmpolynomial.h:177
An abstract class defining the interface of a multivariate polynomial over an arbitrary BPASRing...
Definition: BPASMultivarPolynomial.hpp:17
DistributedDenseMultivariateModularPolynomial(const Field &m)
Constructor with the Field. 
Definition: dmpolynomial.h:86
std::vector< Symbol > variables() const
Get all the variables in this polynomial with positive degree. 
Definition: dmpolynomial.h:905
bool isZero() const
Is a zero polynomial. 
Definition: dmpolynomial.h:221
A simple data structure for encapsulating a collection of Factor elements. 
Definition: Factors.hpp:95
~DistributedDenseMultivariateModularPolynomial()
Deconstructor. 
Definition: dmpolynomial.h:166
DistributedDenseMultivariateModularPolynomial< Field > operator-() const
Overload operator -, negate. 
Definition: dmpolynomial.h:697
void differentiate(const Symbol &s, int k)
Differentiate this polynomial k times, with respect to a particular variable, setting itself to its d...
Definition: dmpolynomial.h:957
An arbitrary-precision Integer. 
Definition: Integer.hpp:22
void zero()
Zero polynomial. 
Definition: dmpolynomial.h:233
bool operator!=(const DistributedDenseMultivariateModularPolynomial< Field > &b) const
Overload operator !=. 
Definition: dmpolynomial.h:518
void one()
Set polynomial to 1. 
Definition: dmpolynomial.h:253
DistributedDenseMultivariateModularPolynomial< Field > & operator+=(const DistributedDenseMultivariateModularPolynomial< Field > &b)
Overload operator +=. 
Definition: dmpolynomial.h:592
int numberOfVariables() const
Get the number of variables. 
Definition: dmpolynomial.h:298
DistributedDenseMultivariateModularPolynomial< Field > derivative(const Symbol &s) const
Differentiate this polynomial, with respect to a particular variable, setting itself to its derivativ...
Definition: dmpolynomial.h:972
void setCoefficient(int v, const int *d, const Field &val)
Set a coefficient. 
Definition: dmpolynomial.h:433
An encapsulation of a mathematical symbol. 
Definition: Symbol.hpp:23
int isConstant() const
Is a constant. 
Definition: dmpolynomial.h:285
A multivariate polynomial with coefficients in an arbitrary finite field represented densely...
Definition: dmpolynomial.h:32
DistributedDenseMultivariateModularPolynomial< Field > & operator*=(const DistributedDenseMultivariateModularPolynomial< Field > &b)
Overload operator *=. 
Definition: dmpolynomial.h:806
bool operator==(const DistributedDenseMultivariateModularPolynomial< Field > &b) const
Overload operator ==. 
Definition: dmpolynomial.h:485
void setRingVariables(const std::vector< Symbol > &xs)
Set variable names. 
Definition: dmpolynomial.h:882
void setCoefficient(int k, const Field &val)
Set a coefficient. 
Definition: dmpolynomial.h:460
bool isNegativeOne() const
Is polynomial -1. 
Definition: dmpolynomial.h:263
void differentiate(const Symbol &s)
Differentiate this polynomial, with respect to a particular variable, setting itself to its derivativ...
Definition: dmpolynomial.h:962