Basic Polynomial Algebra Subprograms (BPAS)  v. 1.700
dmpolynomial.h
1 #ifndef _MMPolynomial_H_
2 #define _MMPolynomial_H_
3 
4 
5 #include "../polynomial.h"
6 #include "../Utils/TemplateHelpers.hpp"
7 #include "../Ring/BPASField.hpp"
8 
9 template <class Field>
10 inline void coef_add_mod(Field* c, Field a, Field b, Field p) {
11  *c = (a + b) % p;
12 }
13 template <class Field>
14 inline void coef_sub_mod(Field* c, Field a, Field b, Field p) {
15  *c = (a - b) % p;
16  if (*c < 0) { *c += p; }
17 }
18 template <class Field>
19 inline void coef_neg_mod(Field* c, Field a, Field p) {
20  *c = p - a;
21 }
22 template <class Field>
23 inline void coef_mul_mod(Field* c, Field a, Field b, Field p) {
24  *c = (a * b) % p;
25 }
26 
27 /**
28  * A multivariate polynomial with coefficients in an arbitrary finite field represented densely.
29  * The class is templated by a Field which should be a BPASField.
30  */
31 template <class Field>
32 class DistributedDenseMultivariateModularPolynomial : public BPASMultivariatePolynomial<Field,DistributedDenseMultivariateModularPolynomial<Field>>,
33  private Derived_from<Field, BPASField<Field>> {
34  private:
35  Symbol* names; // Variable names
36  int var; // Number of variables
37  int n; // Number of terms
38  Field* coefs; // Coefficients in Prime field
39  int* degs; // Partial size
40  Field p; // Prime
41 
42 
43  int* acc;
44 
45  inline void zeros() {
46  for (int i = 0; i < n; ++i)
47  coefs[i] = 0;
48  }
49 
50  inline bool isSameRing(const DistributedDenseMultivariateModularPolynomial& b) const {
51  if (var != b.var || names[0] != b.names[0])
52  return 0;
53  if (names[0] == "9") {
54  for (int i = 1; i <= var; ++i) {
55  if (names[i] != b.names[i])
56  return 0;
57  }
58  }
59  return 1;
60  }
61 
62  public:
63  static mpz_class characteristic;
64  // static bool isPrimeField;
65  // static bool isSmallPrimeField;
66  // static bool isComplexField;
67  /**
68  * Constructor using a default field
69  **/
71  coefs = new Field[1];
72  coefs[0] = 0;
73  degs = new int[1];
74  degs[0] = 0;
75  acc = new int[1];
76  acc[0] = 1;
77  names = new Symbol[1];
78  names[0] = "1";
79  }
80 
81  /**
82  * Constructor with the Field
83  *
84  * @param m: The prime
85  **/
86  DistributedDenseMultivariateModularPolynomial (const Field& m) : var(0), n(0), p(m) {
87  coefs = new Field[1];
88  coefs[0] = 0;
89  degs = new int[1];
90  degs[0] = 0;
91  acc = new int[1];
92  acc[0] = 1;
93  names = new Symbol[1];
94  names[0] = "1";
95  }
96 
97  /**
98  * Constructor with number of variables and terms
99  *
100  * @param v: Number of variables
101  * @param ds: Partial degrees
102  * @param m: The prime
103  **/
104  DistributedDenseMultivariateModularPolynomial(int v, int* ds, Field m) : var(v), p(m) {
105  degs = new int[var];
106  acc = new int[var];
107  acc[0] = 1;
108  for (int i = 0; i < var; ++i) {
109  degs[i] = ds[i];
110  if (i < var - 1)
111  acc[i+1] = acc[i] * (degs[i] + 1);
112  }
113  n = acc[var-1] * (degs[var-1] + 1);
114  coefs = new Field[n];
115  zeros();
116  //coefs[0] = 0;
117  names = new Symbol[var+1];
118  names[0] = "1";
119  for (int i = 1; i <= var; ++i) {
120  std::ostringstream convert;
121  convert << var - i + 1;
122  names[i] = "_";
123  names[i] += convert.str();
124  }
125  }
126 
127  /**
128  * Construct with a variable name
129  * such that f(x) = x;
130  *
131  * @param x: The variable name
132  * @param m: The prime
133  **/
134  DistributedDenseMultivariateModularPolynomial (const Symbol& x, const Field& m) : var(1), n(2), p(m) {
135  names = new Symbol[2];
136  names[0] = "9";
137  names[1] = x;
138  degs = new int[1];
139  degs[0] = 1;
140  acc = new int[1];
141  acc[0] = 1;
142  coefs = new Field[2];
143  coefs[0] = 0;
144  coefs[1] = 1;
145  }
146  /**
147  * Copy constructor
148  *
149  * @param b: A multivariate modular polynomial
150  **/
152  degs = new int[var];
153  std::copy(b.degs, b.degs+var, degs);
154  acc = new int[var];
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);
160  }
161  /**
162  * Deconstructor
163  *
164  * @param
165  **/
167  delete [] coefs;
168  delete [] degs;
169  delete [] names;
170  delete [] acc;
171  }
172  /**
173  * Overload operator =
174  *
175  * @param b: A multivariate modular polynomial
176  **/
178  if (this != &b) {
179  delete [] coefs;
180  delete [] degs;
181  delete [] names;
182  delete [] acc;
183 
184  var = b.var;
185  degs = new int[var];
186  std::copy(b.degs, b.degs+var, degs);
187  acc = new int[var];
188  std::copy(b.acc, b.acc+var, acc);
189  n = b.n;
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);
194  p = b.p;
195  }
196  return *this;
197  }
198 
199  /**
200  * Overload operator =. Assign this to a be a base Field element.
201  */
204  return *this;
205  }
206 
207  /**
208  * Is a zero polynomial
209  *
210  * @param
211  **/
212  inline bool isZero() const {
213  for (int i = 0; i < n; ++i) {
214  if (coefs[i] != 0)
215  return 0;
216  }
217  return 1;
218  }
219  /**
220  * Zero polynomial
221  *
222  * @param
223  **/
224  inline void zero() {
225  zeros();
226  }
227  /**
228  * Is polynomial 1
229  *
230  * @param
231  **/
232  inline bool isOne() const {
233  for (int i = 1; i < n; ++i) {
234  if (coefs[i] != 0)
235  return 0;
236  }
237  return (coefs[0] == 1);
238  }
239  /**
240  * Set polynomial to 1
241  *
242  * @param
243  **/
244  inline void one() {
245  coefs[0] = 1;
246  for (int i = 1; i < n; ++i)
247  coefs[i] = 0;
248  }
249  /**
250  * Is polynomial -1
251  *
252  * @param
253  **/
254  inline bool isNegativeOne() const {
255  for (int i = 1; i < n; ++i) {
256  if (coefs[i] != 0)
257  return 0;
258  }
259  return (coefs[0] == p - 1);
260  }
261  /**
262  * Set polynomial to -1
263  *
264  * @param
265  **/
266  inline void negativeOne() {
267  coefs[0] = p - 1;
268  for (int i = 1; i < n; ++i)
269  coefs[i] = 0;
270  }
271  /**
272  * Is a constant
273  *
274  * @param
275  **/
276  inline int isConstant() const {
277  for (int i = 1; i < n; ++i) {
278  if (coefs[i] != 0)
279  return 0;
280  }
281  if (coefs[0] < (p / 2)) { return 1; }
282  else { return -1; }
283  }
284  /**
285  * Get the number of variables
286  *
287  * @param
288  **/
289  inline int numberOfVariables() const {
290  return variables().size();
291  }
292 
293  /**
294  * Get the number of variables in this polynomial ring.
295  */
296  inline int numberOfRingVariables() const {
297  return ringVariables().size();
298  }
299 
300  /**
301  * Get the number of non-zero terms
302  *
303  * @param
304  **/
305  inline Integer numberOfTerms() const {
306  int k = 0;
307  for (int i = 0; i < n; ++i)
308  if (coefs[i] != 0) { k++; }
309  return k;
310  }
311  /**
312  * Get the size of the polynomial
313  *
314  * @param
315  **/
316  inline int size() const {
317  return n;
318  }
319 
320  /**
321  * Get the total degree.
322  */
323  inline Integer degree() const {
324  std::cerr << "DistributedDenseMultivariateModularPolynomial::degree() NOT YET IMPLEMENTED" << std::endl;
325  //TODO
326  return 0;
327  }
328 
329  /**
330  * Get a partial degree of variable x
331  *
332  * @param x: The variable name
333  **/
334  inline Integer degree(const Symbol& x) const {
335  int k = 0, d = 0;
336  for (int i = 1; i <= var; ++i) {
337  if (names[i] == x)
338  k = i;
339  }
340  if (k) {
341  k--;
342  for (int i = 0; i < n; ++i) {
343  int e = (i / acc[k]) % (degs[k] + 1);
344  if (coefs[i] != 0 && e > d)
345  d = e;
346  }
347  }
348  return d;
349  }
350 
351  /**
352  * Get the leading coefficient
353  *
354  * @param
355  **/
356  inline Field leadingCoefficient() const {
357  for (int i = n-1; i > -1; --i) {
358  if (coefs[i] != 0)
359  return coefs[i];
360  }
361  return 0;
362  }
363 
364  inline Field trailingCoefficient() const {
365  for (int i = 0; i < n; ++i) {
366  if (coefs[i] != 0) {
367  return coefs[i];
368  }
369  }
370  return 0;
371  }
372 
373  bool isConstantTermZero() const {
374  int d[var];
375  Field f = coefficient(var, d);
376  return (f == 0);
377  }
378 
381  Field lead = leadingCoefficient();
382  Field leadInv = lead.inverse();
383  DistributedDenseMultivariateModularPolynomial ret = *this * leadInv;
384  if (u != NULL) {
385  *u = lead;
386  }
387  if (v != NULL) {
388  *v = leadInv;
389  }
390  return ret;
391  }
392 
393  /**
394  * Get a coefficient
395  *
396  * @param v: Number of variables
397  * @param d: The exponent of each variable
398  **/
399  inline Field coefficient(int v, const int* d) const {
400  int k = 0;
401  for (int i = var-1, j = 0; i > -1 && j < v; --i, ++j) {
402  if (d[j] <= degs[i])
403  k += d[j] * acc[i];
404  else { return 0; }
405  }
406  for (int i = v-var-1; i > -1; --i)
407  if (d[i]) { return 0; }
408  return coefs[k];
409  }
410 
411  inline Field coefficient(const std::vector<int>& v) const {
412  return coefficient(v.size(), v.data());
413  }
414 
415  /**
416  * Set a coefficient
417  *
418  * @param v: Number of variables
419  * @param d: The exponent of each variable
420  * @param val: Value of the coefficient
421  **/
422  inline void setCoefficient(int v, const int* d, const Field& val) {
423  if (v != var) {
424  std::cout << "BPAS: error, DDMMP(" << var << "), but trying to setCoefficient with " << v << " variables." << std::endl;
425  exit(1);
426  }
427  int k = 0;
428  for (int i = var-1, j = 0; i > -1 && j < v; --i, ++j) {
429  if (d[j] <= degs[i])
430  k += d[j] * acc[i];
431  else {
432  std::cout << "BPAS: error, the degree of " << names[i+1] << " in DDMMP is " << degs[i] << "." << std::endl;
433  exit(1);
434  }
435  }
436  coefs[k] = val;
437  }
438 
439  inline void setCoefficient(const std::vector<int>& v, const Field& val) {
440  setCoefficient(v.size(), v.data(), val);
441  }
442 
443  /**
444  * Set a coefficient
445  *
446  * @param k: The offset in the coefficient array
447  * @param val: Value of the coefficient
448  **/
449  inline void setCoefficient(int k, 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;
452  exit(1);
453  }
454  coefs[k] = val;
455  }
456 
457  inline Field content() const {
458  //TODO
459  std::cerr << "BPAS ERROR: DistributedDenseMultivariateModularPolynomial::content() NOT YET IMPLEMENTED" << std::endl;
460  return Field(1);
461  }
462 
463  inline DistributedDenseMultivariateModularPolynomial primitivePart() const {
464  //TODO
465  std::cerr << "BPAS ERROR: DistributedDenseMultivariateModularPolynomial::primitivePart() NOT YET IMPLEMENTED" << std::endl;
466  return *this;
467  }
468 
469  /**
470  * Overload operator ==
471  *
472  * @param b: A multivariate modular polynomial
473  **/
475  if (var != b.var || p != b.p)
476  return 0;
477 
478  int prev = 0;
479  for (int i = 0; i < n; ++i) {
480  int k = 0;
481  for (int j = 0; j < var; ++j) {
482  int e = (i / acc[j]) % (degs[j] + 1);
483  if (e <= b.degs[j])
484  k += e * b.acc[j];
485  else if (coefs[i] != 0)
486  return 0;
487  }
488  for (int j = prev+1; j < k; ++j) {
489  if (b.coefs[j] != 0)
490  return 0;
491  }
492  if (coefs[i] != b.coefs[k])
493  return 0;
494  prev = k;
495  }
496  for (int i = n; i < b.n; ++i) {
497  if (b.coefs[i] != 0)
498  return 0;
499  }
500  return 1;
501  }
502  /**
503  * Overload operator !=
504  *
505  * @param b: A multivariate modular polynomial
506  **/
508  return !(*this == b);
509  }
510 
511  /**
512  * Overload operator +
513  *
514  * @param b: A multivariate modular polynomial
515  **/
517  if (p != b.p) {
518  std::cout << "BPAS: error, trying to add between Z/" << p << "Z and Z/" << b.p << "Z from DDMMP<Field>." << std::endl;
519  exit(1);
520  }
521  if (isConstant()) { return b + coefs[0]; }
522  if (b.isConstant()) { return *this + b.coefs[0]; }
523 
524  bool isSame = isSameRing(b);
525  if (!isSame) {
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];
529  if (i < var)
530  std::cout << ", ";
531  }
532  std::cout << "] and Z/" << b.p << "Z[";
533  for (int i = 1; i <= b.var; ++i) {
534  std::cout << b.names[i];
535  if (i < b.var)
536  std::cout << ", ";
537  }
538  std::cout << "] from DDMMP<Field>." << std::endl;
539  exit(1);
540  }
541 
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);
547 
548  //#pragma cilk_grainsize = 1024;
549  for (int i = 0; i < res.n; ++i) {
550  Field elem = 0;
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];
556  else
557  offseta = -1;
558  if (offsetb >= 0 && k <= b.degs[j])
559  offsetb += k * b.acc[j];
560  else
561  offsetb = -1;
562  }
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];
569  res.coefs[i] = elem;
570  }
571 
572  delete [] ds;
573  return res;
574  }
575 
576  /**
577  * Overload operator +=
578  *
579  * @param b: A multivariate modular polynomial
580  **/
582  *this = *this + b;
583  return *this;
584  }
585 
586  /**
587  * Overload operator +
588  *
589  * @param e: A constant
590  **/
593  return (r += e);
594  }
595 
597  return (f + e);
598  }
599 
600  /**
601  * Overload operator +=
602  *
603  * @param e: A constant
604  **/
606  coef_add_mod(&coefs[0], coefs[0], e, p);
607  return *this;
608  }
609 
610  /**
611  * Overload operator -
612  *
613  * @param b: A multivariate modular polynomial
614  **/
616  if (p != b.p) {
617  std::cout << "BPAS: error, trying to subtract between Z/" << p << "Z and Z/" << b.p << "Z from DDMMP<Field>." << std::endl;
618  exit(1);
619  }
620  if (isConstant()) { return -b + coefs[0]; }
621  if (b.isConstant()) { return *this - b.coefs[0]; }
622 
623  bool isSame = isSameRing(b);
624  if (!isSame) {
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];
628  if (i < var)
629  std::cout << ", ";
630  }
631  std::cout << "] and Z/" << b.p << "Z[";
632  for (int i = 1; i <= b.var; ++i) {
633  std::cout << b.names[i];
634  if (i < b.var)
635  std::cout << ", ";
636  }
637  std::cout << "] from DDMMP<Field>." << std::endl;
638  exit(1);
639  }
640 
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);
646 
647  for (int i = 0; i < res.n; ++i) {
648  Field elem = 0;
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; }
658  }
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);
665  res.coefs[i] = elem;
666  }
667  delete [] ds;
668  return res;
669  }
670 
671  /**
672  * Overload operator -=
673  *
674  * @param b: A multivariate modular polynomial
675  **/
677  *this = *this - b;
678  return *this;
679  }
680 
681  /**
682  * Overload operator -, negate
683  *
684  * @param
685  **/
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);
691  return res;
692  }
693 
694  /**
695  * Overload operator -
696  *
697  * @param e: A constant
698  **/
701  return (r -= e);
702  }
703 
705  return (-f + e);
706  }
707 
708  /**
709  * Overload operator -=
710  *
711  * @param e: A constant
712  **/
714  coef_sub_mod(&coefs[0], coefs[0], e, p);
715  return *this;
716  }
717 
718  /**
719  * Negate, f(-x)
720  *
721  * @param
722  **/
723  inline void negate() {
724  for (int i = 0; i < n; ++i)
725  coef_neg_mod(&coefs[i], coefs[i], p);
726  }
727 
728  /**
729  * Overload operator *
730  *
731  * @param b: A multivariate modular polynomial
732  **/
734  if (p != b.p) {
735  std::cout << "BPAS: error, trying to multiply between Z/" << p << "Z and Z/" << b.p << "Z from DDMMP<Field>." << std::endl;
736  exit(1);
737  }
738  if (isConstant()) { return b * coefs[0]; }
739  if (b.isConstant()) { return *this * b.coefs[0]; }
740 
741  bool isSame = isSameRing(b);
742  if (!isSame) {
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];
746  if (i < var)
747  std::cout << ", ";
748  }
749  std::cout << "] and Z/" << b.p << "Z[";
750  for (int i = 1; i <= b.var; ++i) {
751  std::cout << b.names[i];
752  if (i < b.var)
753  std::cout << ", ";
754  }
755  std::cout << "] from DDMMP<Field>." << std::endl;
756  exit(1);
757  }
758 
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);
764 
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) {
769  int k = 0;
770  for (int v = 0; v < b.var; ++v) {
771  int e = (j / b.acc[v]) % (b.degs[v] + 1);
772  if (v < var)
773  k += (ds[v] + e) * res.acc[v];
774  else
775  k += e * res.acc[v];
776  }
777  for (int v = b.var; v < var; ++v)
778  k += ds[v] * res.acc[v];
779  // res.coefs[k] += coefs[i] * b.coefs[j];
780  Field t;
781  coef_mul_mod(&t, coefs[i], b.coefs[j], p);
782  coef_add_mod(&res.coefs[k], res.coefs[k], t, p);
783  }
784  }
785 
786  delete [] ds;
787  return res;
788  }
789 
790  /**
791  * Overload operator *=
792  *
793  * @param b: A multivariate modular polynomial
794  **/
796  *this = *this * b;
797  return *this;
798  }
799 
800  /**
801  * Overload operator *
802  *
803  * @param e: A constant
804  **/
807  return (r *= e);
808  }
809 
811  return (f * e);
812  }
813 
814  /**
815  * Overload operator *=
816  *
817  * @param e: A constant
818  **/
820  if (f != 0 && f != 1) {
821  Field e(f);
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);
825  }
826  else if (f == 0) { zero(); }
827  return *this;
828  }
829 
830  inline DistributedDenseMultivariateModularPolynomial<Field> operator^ (long long int e) const {
831  //TODO
832  std::cerr << "BPAS ERROR: DistributedDenseMultivariateModularPolynomial::operator^ NOT YET IMPLEMENTED" << std::endl;
833  return *this;
834  }
835 
836  inline DistributedDenseMultivariateModularPolynomial<Field>& operator^= (long long int e) {
837  //TODO
838  std::cerr << "BPAS ERROR: DistributedDenseMultivariateModularPolynomial::operator^= NOT YET IMPLEMENTED" << std::endl;
839  return *this;
840  }
841 
844  ret /= p;
845  return ret;
846  }
847 
849  //TODO
850  std::cerr << "BPAS ERROR: DistributedDenseMultivariateModularPolynomial::operator/=(DistributedDenseMultivariateModularPolynomial) NOT YET IMPLEMENTED" << std::endl;
851  return *this;
852  }
853 
854  inline DistributedDenseMultivariateModularPolynomial<Field> operator/ (const Field& e) const {
856  ret /= e;
857  return ret;
858  }
859 
860  inline DistributedDenseMultivariateModularPolynomial<Field>& operator/= (const Field& e) {
861  //TODO
862  std::cerr << "BPAS ERROR: DistributedDenseMultivariateModularPolynomial::operator/= NOT YET IMPLEMENTED" << std::endl;
863  return *this;
864  }
865 
866  /**
867  * Set variable names
868  *
869  * @param xs: Variable names
870  **/
871  inline void setRingVariables (const std::vector<Symbol>& xs) {
872  int ns = xs.size();
873  if (ns != var) {
874  std::cerr << "BPAS ERROR: DDMMP shrinking and expanding polynomial ring NOT YET IMPLEMENTED" << std::endl;
875  return;
876  }
877  names[0] = "9";
878  for (int i = var, j = 0; i > 0 && j < ns; --i, ++j)
879  names[i] = xs[j];
880  }
881 
882  /**
883  * Get variable names
884  *
885  * @param
886  **/
887  inline std::vector<Symbol> ringVariables() const {
888  std::vector<Symbol> xs;
889  for (int i = var; i > 0; --i)
890  xs.push_back(names[i]);
891  return xs;
892  }
893 
894  inline std::vector<Symbol> variables() const {
895  std::cerr << "BPAS ERROR: DDMMP::variables() NOT YET IMPLEMENTED" << std::endl;
896  return ringVariables();
897  }
898 
899 
900  /**
901  * Overload stream operator <<
902  *
903  * @param out: Stream object
904  * @param b: The multivariate modular polynomial
905  **/
906  inline void print(std::ostream &out) const {
907  bool isFirst = 0;
908  for (int i = 0; i < this->n; ++i) {
909  if (this->coefs[i] != 0) {
910  if (isFirst) {
911  if (this->coefs[i] >= 0)
912  out << "+";
913  else if (this->coefs[i] == -1)
914  out << "-";
915  if (this->coefs[i] != 1 && this->coefs[i] != -1)
916  out << this->coefs[i];
917  bool isIt = 1;
918  for (int j = 0; j < this->var; ++j) {
919  int exp = (i / this->acc[j]) % (this->degs[j] + 1);
920  if (exp) {
921  if ((this->coefs[i] != 1 && this->coefs[i] != -1 && isIt) || !isIt)
922  out << "*";
923  out << this->names[j+1];
924  if (exp > 1)
925  out << "^" << exp;
926  isIt = 0;
927  }
928  }
929  }
930  else { out << this->coefs[i]; }
931  isFirst = 1;
932  }
933  }
934  if (!isFirst) { out << "0"; }
935  }
936 
937  /**
938  * Convert *this to an expression tree
939  */
941  //TODO
942  std::cerr << "DistributedDenseMultivariateModularPolynomial::convertToExpressionTree() NOT YET IMPLEMENTED" << std::endl;
943  return ExpressionTree();
944  }
945 
946  inline void differentiate(const Symbol& s, int k) {
947  std::cerr << "DistributedDenseMultivariateModularPolynomial::differentiate NOT YET IMPLEMENTED" << std::endl;
948  //TODO
949  }
950 
951  inline void differentiate(const Symbol& s) {
952  differentiate(s, 1);
953  }
954 
955  inline DistributedDenseMultivariateModularPolynomial<Field> derivative(const Symbol& s, int k) const {
957  ret.differentiate(s, k);
958  return ret;
959  }
960 
961  inline DistributedDenseMultivariateModularPolynomial<Field> derivative(const Symbol& s) const {
962  return derivative(s, 1);
963  }
964 
965  inline DistributedDenseMultivariateModularPolynomial<Field> evaluate(const std::vector<Symbol>& syms, const std::vector<Field>& vals) const {
966  //TODO
967  std::cerr << "BPAS ERROR: DistributedDenseMultivariateModularPolynomial::evaluate NOT YET IMPLEMENTED" << std::endl;
968  return *this;
969  }
970 
971  inline DistributedDenseMultivariateModularPolynomial<Field> evaluate(int n, const Symbol* syms, const Field* vals) const {
972  //TODO
973  std::cerr << "BPAS ERROR: DistributedDenseMultivariateModularPolynomial::evaluate NOT YET IMPLEMENTED" << std::endl;
974  return *this;
975  }
976 
978  //TODO
979  std::cerr << "BPAS ERROR: DistributedDenseMultivariateModularPolynomial::gcd NOT YET IMPLEMENTED" << std::endl;
980  return *this;
981  }
982 
983  /**
984  * Compute squarefree factorization of *this
985  */
987  std::cerr << "DistributedDenseMultivariateModularPolynomial::squareFree NOT YET IMPLEMENTED" << std::endl;
988  //TODO
989  std::vector<DistributedDenseMultivariateModularPolynomial> ret;
990  ret.push_back(*this);
991  return ret;
992  }
993 
994 
995 
996 
997 
998 
999 
1000 };
1001 
1002 #endif
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