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