1 #ifndef _MMPolynomial_H_ 2 #define _MMPolynomial_H_ 5 #include "../polynomial.h" 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);
213 for (
int i = 0; i < n; ++i) {
233 for (
int i = 1; i < n; ++i) {
237 return (coefs[0] == 1);
246 for (
int i = 1; i < n; ++i)
255 for (
int i = 1; i < n; ++i) {
259 return (coefs[0] == p - 1);
268 for (
int i = 1; i < n; ++i)
277 for (
int i = 1; i < n; ++i) {
281 if (coefs[0] < (p / 2)) {
return 1; }
290 return variables().size();
307 for (
int i = 0; i < n; ++i)
308 if (coefs[i] != 0) { k++; }
324 std::cerr <<
"DistributedDenseMultivariateModularPolynomial::degree() NOT YET IMPLEMENTED" << std::endl;
336 for (
int i = 1; i <= var; ++i) {
342 for (
int i = 0; i < n; ++i) {
343 int e = (i / acc[k]) % (degs[k] + 1);
344 if (coefs[i] != 0 && e > d)
357 for (
int i = n-1; i > -1; --i) {
364 inline Field trailingCoefficient()
const {
365 for (
int i = 0; i < n; ++i) {
373 bool isConstantTermZero()
const {
382 Field leadInv = lead.inverse();
401 for (
int i = var-1, j = 0; i > -1 && j < v; --i, ++j) {
406 for (
int i = v-var-1; i > -1; --i)
407 if (d[i]) {
return 0; }
411 inline Field
coefficient(
const std::vector<int>& v)
const {
424 std::cout <<
"BPAS: error, DDMMP(" << var <<
"), but trying to setCoefficient with " << v <<
" variables." << std::endl;
428 for (
int i = var-1, j = 0; i > -1 && j < v; --i, ++j) {
432 std::cout <<
"BPAS: error, the degree of " << names[i+1] <<
" in DDMMP is " << degs[i] <<
"." << std::endl;
439 inline void setCoefficient(
const std::vector<int>& v,
const Field& val) {
450 if (k >= n || k < 0) {
451 std::cout <<
"BPAS: error, trying to access a non-exist coefficient in DDMMP<Field>." << std::endl;
457 inline Field content()
const {
459 std::cerr <<
"BPAS ERROR: DistributedDenseMultivariateModularPolynomial::content() NOT YET IMPLEMENTED" << std::endl;
465 std::cerr <<
"BPAS ERROR: DistributedDenseMultivariateModularPolynomial::primitivePart() NOT YET IMPLEMENTED" << std::endl;
475 if (var != b.var || p != b.p)
479 for (
int i = 0; i < n; ++i) {
481 for (
int j = 0; j < var; ++j) {
482 int e = (i / acc[j]) % (degs[j] + 1);
485 else if (coefs[i] != 0)
488 for (
int j = prev+1; j < k; ++j) {
492 if (coefs[i] != b.coefs[k])
496 for (
int i = n; i < b.n; ++i) {
508 return !(*
this == b);
518 std::cout <<
"BPAS: error, trying to add between Z/" << p <<
"Z and Z/" << b.p <<
"Z from DDMMP<Field>." << std::endl;
522 if (b.isConstant()) {
return *
this + b.coefs[0]; }
524 bool isSame = isSameRing(b);
526 std::cout <<
"BPAS: error, trying to add between Z/" << p <<
"Z[";
527 for (
int i = 1; i <= var; ++i) {
528 std::cout << names[i];
532 std::cout <<
"] and Z/" << b.p <<
"Z[";
533 for (
int i = 1; i <= b.var; ++i) {
534 std::cout << b.names[i];
538 std::cout <<
"] from DDMMP<Field>." << std::endl;
542 int* ds =
new int[var];
543 for (
int i = 0; i < var; ++i)
544 ds[i] = (degs[i] >= b.degs[i])? degs[i] : b.degs[i];
546 std::copy(names, names+var+1, res.names);
549 for (
int i = 0; i < res.n; ++i) {
551 int offseta = 0, offsetb = 0;
552 for (
int j = 0; j < var; ++j) {
553 int k = (i / res.acc[j]) % (res.degs[j] + 1);
554 if (offseta >= 0 && k <= degs[j])
555 offseta += k * acc[j];
558 if (offsetb >= 0 && k <= b.degs[j])
559 offsetb += k * b.acc[j];
563 if (offseta >= 0 && offsetb >= 0)
564 coef_add_mod(&elem, coefs[offseta], b.coefs[offsetb], p);
565 else if (offseta >= 0)
566 elem = coefs[offseta];
567 else if (offsetb >= 0)
568 elem = b.coefs[offsetb];
606 coef_add_mod(&coefs[0], coefs[0], e, p);
617 std::cout <<
"BPAS: error, trying to subtract between Z/" << p <<
"Z and Z/" << b.p <<
"Z from DDMMP<Field>." << std::endl;
621 if (b.isConstant()) {
return *
this - b.coefs[0]; }
623 bool isSame = isSameRing(b);
625 std::cout <<
"BPAS: error, trying to subtract between Z/" << p <<
"Z[";
626 for (
int i = 1; i <= var; ++i) {
627 std::cout << names[i];
631 std::cout <<
"] and Z/" << b.p <<
"Z[";
632 for (
int i = 1; i <= b.var; ++i) {
633 std::cout << b.names[i];
637 std::cout <<
"] from DDMMP<Field>." << std::endl;
641 int* ds =
new int[var];
642 for (
int i = 0; i < var; ++i)
643 ds[i] = (degs[i] >= b.degs[i])? degs[i] : b.degs[i];
645 std::copy(names, names+var+1, res.names);
647 for (
int i = 0; i < res.n; ++i) {
649 int offseta = 0, offsetb = 0;
650 for (
int j = 0; j < var; ++j) {
651 int k = (i / res.acc[j]) % (res.degs[j] + 1);
652 if (offseta >= 0 && k <= degs[j])
653 offseta += k * acc[j];
654 else { offseta = -1; }
655 if (offsetb >= 0 && k <= b.degs[j])
656 offsetb += k * b.acc[j];
657 else { offsetb = -1; }
659 if (offseta >= 0 && offsetb >= 0)
660 coef_sub_mod(&elem, coefs[offseta], b.coefs[offsetb], p);
661 else if (offseta >= 0)
662 elem = coefs[offseta];
663 else if (offsetb >= 0)
664 coef_neg_mod(&elem, b.coefs[offsetb], p);
688 std::copy(names, names+var+1, res.names);
689 for (
int i = 0; i < res.n; ++i)
690 coef_neg_mod(&res.coefs[i], coefs[i], p);
714 coef_sub_mod(&coefs[0], coefs[0], e, p);
724 for (
int i = 0; i < n; ++i)
725 coef_neg_mod(&coefs[i], coefs[i], p);
735 std::cout <<
"BPAS: error, trying to multiply between Z/" << p <<
"Z and Z/" << b.p <<
"Z from DDMMP<Field>." << std::endl;
739 if (b.isConstant()) {
return *
this * b.coefs[0]; }
741 bool isSame = isSameRing(b);
743 std::cout <<
"BPAS: error, trying to multiply between Z/" << p <<
"Z[";
744 for (
int i = 1; i <= var; ++i) {
745 std::cout << names[i];
749 std::cout <<
"] and Z/" << b.p <<
"Z[";
750 for (
int i = 1; i <= b.var; ++i) {
751 std::cout << b.names[i];
755 std::cout <<
"] from DDMMP<Field>." << std::endl;
759 int* ds =
new int[var];
760 for (
int i = 0; i < var; ++i)
761 ds[i] = degs[i] + b.degs[i];
763 std::copy(names, names+var+1, res.names);
765 for (
int i = 0; i < n; ++i) {
766 for (
int v = 0; v < var; ++v)
767 ds[v] = (i / acc[v]) % (degs[v] + 1);
768 for (
int j = 0; j < b.n; ++j) {
770 for (
int v = 0; v < b.var; ++v) {
771 int e = (j / b.acc[v]) % (b.degs[v] + 1);
773 k += (ds[v] + e) * res.acc[v];
777 for (
int v = b.var; v < var; ++v)
778 k += ds[v] * res.acc[v];
781 coef_mul_mod(&t, coefs[i], b.coefs[j], p);
782 coef_add_mod(&res.coefs[k], res.coefs[k], t, p);
820 if (f != 0 && f != 1) {
822 if (e < 0) { e = e % p + p; }
823 for (
int i = 0; i < n; ++i)
824 coef_mul_mod(&coefs[i], coefs[i], e, p);
826 else if (f == 0) {
zero(); }
832 std::cerr <<
"BPAS ERROR: DistributedDenseMultivariateModularPolynomial::operator^ NOT YET IMPLEMENTED" << std::endl;
838 std::cerr <<
"BPAS ERROR: DistributedDenseMultivariateModularPolynomial::operator^= NOT YET IMPLEMENTED" << std::endl;
850 std::cerr <<
"BPAS ERROR: DistributedDenseMultivariateModularPolynomial::operator/=(DistributedDenseMultivariateModularPolynomial) NOT YET IMPLEMENTED" << std::endl;
862 std::cerr <<
"BPAS ERROR: DistributedDenseMultivariateModularPolynomial::operator/= NOT YET IMPLEMENTED" << std::endl;
874 std::cerr <<
"BPAS ERROR: DDMMP shrinking and expanding polynomial ring NOT YET IMPLEMENTED" << std::endl;
878 for (
int i = var, j = 0; i > 0 && j < ns; --i, ++j)
888 std::vector<Symbol> xs;
889 for (
int i = var; i > 0; --i)
890 xs.push_back(names[i]);
894 inline std::vector<Symbol> variables()
const {
895 std::cerr <<
"BPAS ERROR: DDMMP::variables() NOT YET IMPLEMENTED" << std::endl;
906 inline void print(std::ostream &out)
const {
908 for (
int i = 0; i < this->n; ++i) {
909 if (this->coefs[i] != 0) {
911 if (this->coefs[i] >= 0)
913 else if (this->coefs[i] == -1)
915 if (this->coefs[i] != 1 && this->coefs[i] != -1)
916 out << this->coefs[i];
918 for (
int j = 0; j < this->var; ++j) {
919 int exp = (i / this->acc[j]) % (this->degs[j] + 1);
921 if ((this->coefs[i] != 1 && this->coefs[i] != -1 && isIt) || !isIt)
923 out << this->names[j+1];
930 else { out << this->coefs[i]; }
934 if (!isFirst) { out <<
"0"; }
942 std::cerr <<
"DistributedDenseMultivariateModularPolynomial::convertToExpressionTree() NOT YET IMPLEMENTED" << std::endl;
946 inline void differentiate(
const Symbol& s,
int k) {
947 std::cerr <<
"DistributedDenseMultivariateModularPolynomial::differentiate NOT YET IMPLEMENTED" << std::endl;
951 inline void differentiate(
const Symbol& s) {
957 ret.differentiate(s, k);
962 return derivative(s, 1);
967 std::cerr <<
"BPAS ERROR: DistributedDenseMultivariateModularPolynomial::evaluate NOT YET IMPLEMENTED" << std::endl;
973 std::cerr <<
"BPAS ERROR: DistributedDenseMultivariateModularPolynomial::evaluate NOT YET IMPLEMENTED" << std::endl;
979 std::cerr <<
"BPAS ERROR: DistributedDenseMultivariateModularPolynomial::gcd NOT YET IMPLEMENTED" << std::endl;
987 std::cerr <<
"DistributedDenseMultivariateModularPolynomial::squareFree NOT YET IMPLEMENTED" << std::endl;
989 std::vector<DistributedDenseMultivariateModularPolynomial> ret;
990 ret.push_back(*
this);
DistributedDenseMultivariateModularPolynomial(const DistributedDenseMultivariateModularPolynomial< Field > &b)
Copy constructor.
Definition: dmpolynomial.h:151
void negate()
Negate, f(-x)
Definition: dmpolynomial.h:723
ExpressionTree convertToExpressionTree() const
Convert *this to an expression tree.
Definition: dmpolynomial.h:940
DistributedDenseMultivariateModularPolynomial< Field > operator+(const DistributedDenseMultivariateModularPolynomial< Field > &b) const
Overload operator +.
Definition: dmpolynomial.h:516
Field leadingCoefficient() const
Get the leading coefficient.
Definition: dmpolynomial.h:356
int numberOfRingVariables() const
Get the number of variables in this polynomial ring.
Definition: dmpolynomial.h:296
Integer degree(const Symbol &x) const
Get a partial degree of variable x.
Definition: dmpolynomial.h:334
DistributedDenseMultivariateModularPolynomial< Field > & operator-=(const DistributedDenseMultivariateModularPolynomial< Field > &b)
Overload operator -=.
Definition: dmpolynomial.h:676
Integer numberOfTerms() const
Get the number of non-zero terms.
Definition: dmpolynomial.h:305
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:906
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:733
Factors< DistributedDenseMultivariateModularPolynomial > squareFree() const
Compute squarefree factorization of *this.
Definition: dmpolynomial.h:986
Integer degree() const
Get the total degree.
Definition: dmpolynomial.h:323
void negativeOne()
Set polynomial to -1.
Definition: dmpolynomial.h:266
std::vector< Symbol > ringVariables() const
Get variable names.
Definition: dmpolynomial.h:887
int size() const
Get the size of the polynomial.
Definition: dmpolynomial.h:316
bool isOne() const
Is polynomial 1.
Definition: dmpolynomial.h:232
Field coefficient(int v, const int *d) const
Get a coefficient.
Definition: dmpolynomial.h:399
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: polynomial.h:117
DistributedDenseMultivariateModularPolynomial(const Field &m)
Constructor with the Field.
Definition: dmpolynomial.h:86
bool isZero() const
Is a zero polynomial.
Definition: dmpolynomial.h:212
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:686
An arbitrary-precision Integer.
Definition: Integer.hpp:22
void zero()
Zero polynomial.
Definition: dmpolynomial.h:224
bool operator!=(const DistributedDenseMultivariateModularPolynomial< Field > &b) const
Overload operator !=.
Definition: dmpolynomial.h:507
void one()
Set polynomial to 1.
Definition: dmpolynomial.h:244
DistributedDenseMultivariateModularPolynomial< Field > & operator+=(const DistributedDenseMultivariateModularPolynomial< Field > &b)
Overload operator +=.
Definition: dmpolynomial.h:581
int numberOfVariables() const
Get the number of variables.
Definition: dmpolynomial.h:289
void setCoefficient(int v, const int *d, const Field &val)
Set a coefficient.
Definition: dmpolynomial.h:422
An encapsulation of a mathematical symbol.
Definition: Symbol.hpp:23
int isConstant() const
Is a constant.
Definition: dmpolynomial.h:276
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:795
bool operator==(const DistributedDenseMultivariateModularPolynomial< Field > &b) const
Overload operator ==.
Definition: dmpolynomial.h:474
void setRingVariables(const std::vector< Symbol > &xs)
Set variable names.
Definition: dmpolynomial.h:871
void setCoefficient(int k, const Field &val)
Set a coefficient.
Definition: dmpolynomial.h:449
bool isNegativeOne() const
Is polynomial -1.
Definition: dmpolynomial.h:254