Basic Polynomial Algebra Subprograms (BPAS)  v. 1.791
mzpolynomial.hpp
1 #ifndef _SMZPALTARRAY_H_
2 #define _SMZPALTARRAY_H_
3 
4 #include "../Ring/Integer.hpp"
5 #include "../Polynomial/BPASRecursivePolynomial.hpp"
6 #include "uzpolynomial.h"
7 #include "../RingPolynomial/upolynomial.h"
8 #include "../RationalNumberPolynomial/mrpolynomial.h"
9 #include "SMZP_CppSupport.hpp"
10 #include "SMZP_Support.h"
11 #include "SMZP_Support_Test.h"
12 #include "SMZP_Support_Recursive.h"
13 #include <gmpxx.h>
14 #include "../ExpressionTree/ExpressionTree.hpp"
15 #include "../DataStructures/Factors.hpp"
16 
17 #if defined(WITH_BLAD) && WITH_BLAD
18 #include "../BLADInterface/bladinterface.h"
19 #endif
20 
21 #if defined(WITH_MAPLE) && WITH_MAPLE
22 #include "../MapleInterface/MapleInterfaceStream.hpp"
23 #endif
24 
26 
27 /**
28  * An element of the SLP of an integer polynomial.
29  */
31 
32  public:
33  union CoefOrInt {
34  Integer* c;
35  int i;
36  };
37 
38  int op; // 0: '+'; 1: '*'.
39  int type; // 0: coef & variate;
40  // 1: coef & result;
41  // 2: variate & result;
42  // 3: result & result;
43  // 4: coef (constant);
44  CoefOrInt a; // variate or result or coef position
45  int b; // variate or result or coef position
46  Interval res; // Storing the result
47 
49  a.c = NULL;
50  }
51 
53  op = r.op;
54  type = r.type;
55  b = r.b;
56  res = r.res;
57  if (type == 0 || type == 1 || type == 4) {
58  a.c = new Integer(*(r.a.c));
59  } else {
60  a.i = r.a.i;
61  }
62  }
63 
65  if (type == 0 || type == 1) {
66  delete a.c;
67  }
68  }
69 };
70 
71 /**
72  * A multivariate polynomial with Integer coefficients using a
73  * sparse representation. Only non-zero coefficients are encoded.
74  */
75 class SparseMultivariateIntegerPolynomial: public BPASRecursivelyViewedPolynomial<Integer,SparseMultivariateIntegerPolynomial> {
76 
77  private:
78  mutable AltArrZ_t* poly;
79  int nvar; //number of variables
80  Symbol* names; //list of strings representing the variables.
81  //names[0] is 1 if "system-generated" variables
82  //names[0] is 9 if "user-specified" variables
83 
85  friend class MapleInterface;
86 
87  /**
88  * Construct an SMZP given the alternating array.
89  */
90  SparseMultivariateIntegerPolynomial(AltArrZ_t* aa, int vars, Symbol* varNames);
91 
92  /**
93  * Attempt to construct an SMZP given the rational number alternating array.
94  */
95  SparseMultivariateIntegerPolynomial(const RationalNumber& r, AltArr_t* aa, int vars, Symbol* varNames);
96 
97  /**
98  * Determine if *this and b have compatible variable orderings.
99  * xs returns the mapping of both *this and b to the compatible superset
100  * returns true iff compatible.
101  */
102  bool isOrderedRing(const SparseMultivariateIntegerPolynomial& b, std::vector<int>& xs) const;
103 
104  /**
105  * Rearrange exponent vectors in place and then re-sort the polynomial.
106  */
107  void reorderVarsInPlace(int varmap[]);
108 
109  /**
110  * Rearrange exponent vectors, expanding as needed, and then re-sort the polynomial.
111  */
112  void expandVarsInPlace(int vars, Symbol* newvars, int varmap[]);
113 
114  /**
115  * Returns a copy of *this under the new variable ordering supplied.
116  * varmap is such that this.names[i] = newvars[varmap[i]]
117  * Returns an SMQP equal to *this but expended to newvars.
118  */
119  SparseMultivariateIntegerPolynomial expandVariables(int vars, Symbol* newvars, int varmap[]) const;
120 
121  public:
122 
124 
125  std::vector<SparseMultivariateIntegerPolynomial> subresultantChain (const SparseMultivariateIntegerPolynomial& q, int filled = 0) const;
126 
128 
129  std::vector<SLPZRepresentation> slp;
130 
131  /* Constructors */
132 
133  /**
134  * Construct a multivariate polynomial
135  *
136  **/
138 
139  /**
140  * Construct a multivariate polynomial with specific number of variables
141  *
142  * @param v: Number of variables
143  **/
145 
146  /**htop
147 
148  * Construct with a variable name such that f(x) = x;
149  *
150  * @param x: The variable name
151  **/
153 
154  /**
155  * Construct a polynomial by parsing the string str.
156  */
157  SparseMultivariateIntegerPolynomial (const std::string& str);
158 
159  /**
160  * Copy Constructor.
161  *
162  * Does not reuse underlying memory allocated by b.
163  *
164  * @param b: A sparse multivariate polynomial
165  **/
167 
168  /**
169  * Move Constructor.
170  *
171  * @params b: The r-value reference polynomial.
172  */
174 
175  /**
176  * Create a SMZP from an SMQP.
177  */
179 
180  /**
181  * Create a SMZP from an Integer.
182  */
183  SparseMultivariateIntegerPolynomial(const Integer& r, int nvar = 0);
184 
185  /**
186  * Create a SMZP from a RationalNumber.
187  */
188  SparseMultivariateIntegerPolynomial(const RationalNumber& r, int nvar = 0);
189 
190  /**
191  * Create a SMZP from a univariate rational polynomial.
192  *
193  * @param p: A SUZP polynomial.
194  **/
196 
197  /**
198  * Construct from a SUP<SMZP> polynomial such that the resulting SMZP
199  * has main variable equal to the variable of s.
200  *
201  * @param s: The SUP<SMZP> polynomial
202  **/
204 
205  /**
206  * Destroy the polynomial and underlying node memory.
207  **/
209 
210 
211  /* BPASRing interface */
212  // static bool isPrimeField;
213  // static bool isSmallPrimeField;
214  // static bool isComplexField;
215 
216  /**
217  * Is this polynomial zero.
218  * returns true iff this polynomial encodes 0.
219  */
220  bool isZero() const;
221 
222  /**
223  * Set this polynomial to zero. Maintains existing variable ordering.
224  */
225  void zero();
226 
227  /**
228  * Is this polynomial one.
229  * return true iff this polynomial encodes 1.
230  */
231  bool isOne() const;
232 
233  /**
234  * Sets this polynomial to one. Maintains existing variable ordering.
235  */
236  void one();
237 
238  /**
239  * Is this polynomial negative one.
240  * returns true iff this polynomial encodes -1.
241  */
242  bool isNegativeOne() const;
243 
244  /**
245  * Sets this polynomial to -1. Maintains existing variable ordering.
246  */
247  void negativeOne();
248 
249  /**
250  * Determine if this polynomial encodes a constant.
251  * returns 0 if not a constant, 1 if a constant >= 0, -1 if a negative contstant.
252  */
253  int isConstant() const;
254 
255  /**
256  * Obtain the unit normal (a.k.a canonical associate) of an element.
257  * If either parameters u, v, are non-NULL then the units are returned such that
258  * b = ua, v = u^-1. Where b is the unit normal of a, and is the returned value.
259  */
261  if (isZero()) {
262  return *this;
263  }
264 
265  if (mpz_cmp_si(this->poly->elems->coef, 0l) < 0) {
267  if (u != NULL) {
269  }
270  if (v != NULL) {
271  *v = *u;
272  }
273  return ret;
274  }
275 
276  if (u != NULL) {
277  (*u).one();
278  }
279  if (v != NULL) {
280  (*v).one();
281  }
282  return *this;
283  }
284 
285  /* BPASPolynomial interface */
286 
287  /**
288  * Assign this polynomail to equal the specified.
289  */
291 
292  /**
293  * Movement assignment: move b to be this polynomail.
294  */
296 
297  /**
298  * Assign this polynomial to be equal to the constant ring element.
299  */
300  SparseMultivariateIntegerPolynomial& operator= (const Integer& r);
301 
302  /**
303  * Add two SMQP polynomials together, *this and the specified.
304  */
307 
308  /**
309  * Add the polynomails a and b and return the sum.
310  */
311  // friend SparseMultivariateIntegerPolynomial operator+ (SparseMultivariateIntegerPolynomial&& a, const SparseMultivariateIntegerPolynomial& b);
312 
313  /**
314  * Update *this by adding the specified polynomail to it.
315  */
317 
318  /**
319  * Subtract the specified polynomail from *this
320  */
323 
324  /**
325  * Subtract the polynomial b from a and return the difference.
326  */
327  // friend SparseMultivariateIntegerPolynomial operator- (SparseMultivariateIntegerPolynomial&& a, const SparseMultivariateIntegerPolynomial& b);
328 
329  /**
330  * Unary operation, return *this * -1.
331  */
332  SparseMultivariateIntegerPolynomial operator- () const;
333 
334  /**
335  * Update *this by subtracting the specified polynomial from it.
336  */
338 
339  /**
340  * Multiply *this by the specified polynomail.
341  */
344 
345  /**
346  * Multiply the polynomials a and b, returning their product.
347  */
348  // friend SparseMultivariateIntegerPolynomial operator* (SparseMultivariateIntegerPolynomial&& a, const SparseMultivariateIntegerPolynomial& b);
349 
350  /**
351  * Update this by multiplying by the specified polynomail.
352  */
354 
355  /**
356  * Divide *this by the specified polynomial.
357  */
360 
361  // friend SparseMultivariateIntegerPolynomial operator/ (SparseMultivariateIntegerPolynomial&& a, const SparseMultivariateIntegerPolynomial& b);
362 
363  /**
364  * Update *this by dividing by the specified polynomial.
365  */
367 
368  /**
369  * Exponentiate *this by the input exponent integer.
370  * Treats negative exponents as positive.
371  */
372  SparseMultivariateIntegerPolynomial operator^ (long long int e) const;
373 
374  /**
375  * Update *this by exponentiating this to the input integer.
376  * Treats negative exponents as positive.
377  */
378  SparseMultivariateIntegerPolynomial& operator^= (long long int e);
379 
380  /**
381  * Determine if *this is equal to the specified polynomial.
382  * This takes into account the variable ordering on both poylnomials
383  * in such a way that the same polynomial under different variable orderings
384  * are NOT equal.
385  */
386  bool operator== (const SparseMultivariateIntegerPolynomial& b) const;
387 
388  /**
389  * Determine if *this is not equal to the specified polynomial.
390  * This takes into account the variable ordering on both poylnomials
391  * in such a way that the same polynomial under different variable orderings
392  * are NOT equal.
393  */
394  bool operator!= (const SparseMultivariateIntegerPolynomial& b) const;
395 
396  /**
397  * Output the string representation of *this to the input ostream.
398  */
399  void print(std::ostream& os) const;
400 
401  /**
402  * Parse a polynomial from the in stream. Exactly one line is parsed.
403  */
404  friend std::istream& operator>>(std::istream& in, SparseMultivariateIntegerPolynomial& p);
405 
406  /**
407  * Parse a polynomial from the string str and place it in *this.
408  */
409  void fromString(const std::string& str);
410 
411  /**
412  * Get GCD between *this and b.
413  */
415 
416  /**
417  * Get the GCD between *this and b as a primitive polynomial.
418  */
420 
421  /**
422  * Compute squarefree factorization of *this with respect to all of its variables.
423  */
425 
426  /**
427  * Compute squarefree factorization of *this with respect to the list of variables, vars.
428  */
429  Factors<SparseMultivariateIntegerPolynomial> squareFree(const std::vector<Symbol>& vars) const;
430 
431  /**
432  * Computes the square free part of this polynomail. That is, the polynomial of this
433  * divided by all square factors. This is with respect to all variables.
434  */
435  SparseMultivariateIntegerPolynomial squareFreePart() const;
436 
437  /**
438  * Computes the square free part of this polynomail. That is, the polynomial of this
439  * divided by all square factors. This is with respect to all variables.
440  */
441  SparseMultivariateIntegerPolynomial squareFreePart(std::vector<Symbol>& vars) const;
442 
443  /**
444  * Get the content with respect to all variables. That is, a single
445  * integer which is the GCD of all coefficients.
446  * The content here is one such that this/content is
447  * an integer polynomial with content of 1.
448  *
449  * Moreover, the content is one such that the leading coefficient
450  * of the corresponding primitive part is positive.
451  */
452  Integer content() const;
453 
454  /**
455  * Get the content of this polynomial with respect to the variables in
456  * the input vector v. That is, viewing the polynomial recursively
457  * such that the variables in v are the polynomial variables and all
458  * other variables belong to the coefficient ring.
459  *
460  * In this case, the content does not necessarily make the leading
461  * coefficient of the corresponding primitive part positive.
462  */
463  SparseMultivariateIntegerPolynomial content(const std::vector<Symbol>& v) const;
464 
465  /**
466  * Get the primitive part with respect to all variables.
467  * This is equivalent to this / content().
468  */
469  SparseMultivariateIntegerPolynomial primitivePart() const;
470 
471  /**
472  * Get the primitive part with respect to all variables.
473  * This is equivalent to this / content().
474  *
475  * Simultaneously returns the rational number content in the parameter content.
476  */
477  SparseMultivariateIntegerPolynomial primitivePart(Integer& content) const;
478 
479  /**
480  * Get the primitive part with respect to the variables in the vector v.
481  *
482  * returns the primitive part.
483  */
484  SparseMultivariateIntegerPolynomial primitivePart(const std::vector<Symbol>& v) const;
485 
486  /**
487  * Get the primitive part with respect to the variables in the vector v.
488  * Returns the corresponding content in the content reference.
489  * returns the primitive part.
490  */
491  SparseMultivariateIntegerPolynomial primitivePart(const std::vector<Symbol>& v, SparseMultivariateIntegerPolynomial& content) const;
492 
493  /**
494  * Get the leading coefficient of *this with respect to the main variable.
495  *
496  * returns the initial.
497  */
498  SparseMultivariateIntegerPolynomial initial() const;
499 
500  /**
501  * Get the main variable. That is, the highest-ordered variable with
502  * positive degree.
503  *
504  * returns the main variable.
505  */
506  inline Symbol mainVariable() const {
507  return leadingVariable();
508  }
509 
510  /**
511  * Get the degree of the main variable.
512  *
513  * returns the degree.
514  */
515  int mainDegree() const;
516 
517  /**
518  * Get the rank of this polynomial.
519  * That is, the main variable raised to the main degree.
520  *
521  * returns the rank.
522  */
524 
525  /**
526  * Get the head of this polynomial. That is, the initial multiplied
527  * by the rank.
528  *
529  * returns the head.
530  */
532 
533  /**
534  * Get the tail of this polynomial. That is, This - this.head().
535  *
536  * returns the tail.
537  */
539 
540  SparseMultivariateIntegerPolynomial separant() const;
541 
542  /* BPASMultivariatePolynomial interface */
543 
544  /**
545  * Get the number of variables in this polynomial.
546  */
547  int numberOfVariables() const;
548 
549  /**
550  * Get the number of variables in this polynomial ring.
551  */
552  inline int numberOfRingVariables() const {
553  return ringVariables().size();
554  }
555 
556  /**
557  * Get the number of non-zero terms
558  */
559  Integer numberOfTerms() const;
560 
561  /**
562  * Total degree.
563  */
564  Integer degree() const;
565 
566  /**
567  * Get the degree of a variable
568  */
569  Integer degree(const Symbol&) const;
570 
571  /**
572  * Get the leading coefficient
573  */
574  Integer leadingCoefficient() const;
575 
576  /**
577  * Set the leading coefficient.
578  */
579  void setLeadingCoefficient(const Integer& it);
580 
581  /**
582  * Get the trailing coefficient.
583  */
584  Integer trailingCoefficient() const;
585 
586  /**
587  * Get a coefficient, given the exponent of each variable
588  */
589  Integer coefficient(int, const int*) const;
590 
591  inline Integer coefficient(const std::vector<int>& v) const {
592  return coefficient(v.size(), v.data());
593  }
594 
595  /**
596  * Set a coefficient, given the exponent of each variable
597  */
598  void setCoefficient(int, const int*, const Integer&);
599 
600  inline void setCoefficient(const std::vector<int>& v, const Integer& r) {
601  setCoefficient(v.size(), v.data(), r);
602  }
603 
604 
605  /**
606  * Set variables' names.
607  *
608  * This method can be used to shrink, expand, re-order, and re-name the variables
609  * of the polynomial ring in which this polynomial belongs.
610  *
611  * Any symbol in the input vector that matches the current variables
612  * is considered a re-order. Non-matching symbols are considered a re-name
613  * and this renames is done in the order they appear by increasing index.
614  * For example: Q[x,y,z] -> Q[y,s,t] will have y reordered to be the
615  * first variable, x renamed to s, and z renamed to t.
616  *
617  * If the size of the input vector is greater than the current number of variables
618  * then the polynomial ring is being expanded. Matching variables from this
619  * polynomial are re-ordered as they appear in the input vector. Current variables
620  * that have no match in the input vector are re-named in order of increasing index
621  * of unused variables from the input vector.
622  * For example: Q[x,y,z] -> Q[s,t,z,x] will have y named to s, t a new variable,
623  * and z and x re-ordered accordingly.
624  *
625  * If the size of the input vector is less than the current number of variables
626  * then the polynomial ring is shrink to remove variables. Variables in the
627  * input vector that are also found to be in the current polynomial ring
628  * are matched and re-ordered as necessary.
629  *
630  * It is invalid to remove a variable which is non-zero in this polynomial.
631  */
632  void setRingVariables (const std::vector<Symbol>&);
633 
634  /**
635  * Get variable names of all variables available to this polynomial,
636  * even those that have zero degree.
637  */
638  std::vector<Symbol> ringVariables() const;
639 
640  /**
641  * Get variable names of variables with non-zero degree;
642  */
643  std::vector<Symbol> variables() const;
644 
645 
646  /* SMQP-specific */
647 
648  /**
649  * Determine if *this is equal to b.
650  * This takes into account the variable ordering on both poylnomials
651  * in such a way that the same polynomial under different variable orderings
652  * are NOT equal.
653  */
654  bool isEqual(const SparseMultivariateIntegerPolynomial& b) const;
655 
656  /**
657  * Convert current object to its k-th derivative
658  *
659  * @param s: Symbol to differentiate with respect to
660  * @param k: Order of the derivative, k > 0
661  **/
662  inline void differentiate(const Symbol& s, int k) {
663  *this = this->derivative(s, k);
664  }
665 
666  /**
667  * Convert current object to its derivative
668  *
669  * @param s: Symbol to differentiate with respect to
670  **/
671  inline void differentiate(const Symbol& s) {
672  this->differentiate(s,1);
673  }
674 
675  /**
676  * Return k-th derivative
677  *
678  * @param s: Symbol to differentiate with respect to
679  * @param k: Order of the k-th derivative, k > 0
680  **/
681  SparseMultivariateIntegerPolynomial derivative(const Symbol& s, int k) const;
682 
683  /**
684  * Compute derivative
685  *
686  * @param s: Symbol to differentiate with respect to
687  **/
689  return this->derivative(s,1);
690  }
691 
692  /**
693  * Convert current object to its k-th integral
694  *
695  * @param s: Symbol to differentiate with respect to
696  * @param k: Order of the derivative, k > 0
697  **/
698  inline void integrate(const Symbol& s, int k) {
699  *this = this->integral(s, k);
700  }
701 
702  /**
703  * Convert current object to its derivative
704  *
705  * @param s: Symbol to differentiate with respect to
706  **/
707  inline void integrate(const Symbol& s) {
708  this->integrate(s,1);
709  }
710 
711  /**
712  * Return k-th integral. If Symbol s is not a symbol contained in this
713  * polynomial then it becomes the main variable of the result and
714  * integration proceeds as expected.
715  *
716  * If the integral of this polynomial cannot be represented as an integer
717  * polynomial then an error occurs. See rationalIntegral().
718  *
719  * @param s: Symbol to differentiate with respect to
720  * @param k: Order of the k-th derivative, k > 0
721  **/
722  SparseMultivariateIntegerPolynomial integral(const Symbol& s, int k) const;
723 
724  /**
725  * Return k-th integral. If Symbol s is not a symbol contained in this
726  * polynomial then it becomes the main variable of the result and
727  * integration proceeds as expected.
728  *
729  * This method returns a rational number polynomial and therefore works
730  * regardless of the coefficients of this polynomial.
731  *
732  * @param s: Symbol to differentiate with respect to
733  * @param k: Order of the k-th derivative, k > 0
734  **/
735  SparseMultivariateRationalPolynomial rationalIntegral(const Symbol& s, int k) const;
736 
737  /**
738  * Compute integral
739  *
740  * @param s: Symbol to differentiate with respect to
741  **/
743  return this->integral(s,1);
744  }
745 
746  /**
747  * Return the integral of this, with respect to Symbol s, as a rational number polynomial.
748  *
749  * @param s: the symbol to integrate with respect to
750  * returns the integral
751  */
752  SparseMultivariateRationalPolynomial rationalIntegral(const Symbol& s) const;
753 
754  /**
755  * Evaluate f(x)
756  *
757  * @param syms: Array of Symbols to evaluate at corresponding xs
758  * @param xs: Evaluation points
759  **/
760  inline SparseMultivariateIntegerPolynomial evaluate(int n, const Symbol* syms, const Integer* xs) const {
761  std::vector<Symbol> vecSyms;
762  std::vector<Integer> vecRats;
763  vecSyms.reserve(n);
764  vecRats.reserve(n);
765  for (int i = 0; i < n; ++i) {
766  vecSyms.push_back(syms[i]);
767  vecRats.push_back(xs[i]);
768  }
769  return evaluate(vecSyms, vecRats);
770  }
771 
772  /**
773  * Evaluate *this polynomial given the variables and their values in vars, and values.
774  * vars must be a list of variables which are a (not necessarily proper) subset.
775  * vars and values should have matching indices. i.e. the values of vars[i] is values[i].
776  *
777  * returns a new SMQP where all variables in vars have been evaluated using the values given.
778  */
779  SparseMultivariateIntegerPolynomial evaluate(const std::vector<Symbol>& vars, const std::vector<Integer>& values) const;
780 
781  /**
782  * Find the interpolating polynomial for the integer points and values specified by each vector, respectively.
783  * The points vector is a vector of vectors, where each element of the outer vector represents a multi-dimensional point.
784  * Each multi-dimensional point should have the same number of dimensions and in the same order.
785  *
786  * An error will occur if the resulting interpolating polynomial cannot be represented as an integer polynomial.
787  *
788  * returns the interpolating polynomial.
789  */
790  static SparseMultivariateIntegerPolynomial interpolate(const std::vector<std::vector<Integer>>& points, const std::vector<Integer>& vals);
791 
792  /**
793  * Find the interpolating polynomial for the rational number points and values specified by each vector, respectively.
794  * The points vector is a vector of vectors, where each element of the outer vector represents a multi-dimensional point.
795  * Each multi-dimensional point should have the same number of dimensions and in the same order.
796  *
797  * An error will occur if the resulting interpolating polynomial cannot be represented as an integer polynomial.
798  *
799  * returns the interpolating polynomial.
800  */
801  static SparseMultivariateIntegerPolynomial interpolate(const std::vector<std::vector<RationalNumber>>& points, const std::vector<RationalNumber>& vals);
802 
803 
804  /**
805  * Divide this by polynomial b, returning the quotient and remainder in q and r, respectively.
806  *
807  * returns a boolean indicating if the division was exact.
808  */
810 
811  /**
812  * Divide this by polynomial b, return the quotient and remainder in q and r as rational number polynomials.
813  * This differs from the normal divide function where divisibility of coefficients does not matter as the result
814  * belongs to the polynomial ring over the rational numbers.
815  *
816  * returns a boolean indicating if the division was exact.
817  */
819 
820  /**
821  * Get the remainder of *this divided by b.
822  */
824 
825  /**
826  * Update *this by setting it to the remainder of *this divided by b.
827  */
829 
830  /**
831  * Pseudo divide this by b. The remainder is returned.
832  * if parameter quo is not null then the quotient is returned in quo.
833  * if parameter mult is not null then the multiplier is set to the initial of b
834  * raised to the power of degree(c, mvar(c)) - degree(b, mvar(c)) + 1.
835  *
836  * returns the pseudo remainder.
837  */
839 
840 
841  /**
842  * Add *this and a mpz_t.
843  */
844  inline SparseMultivariateIntegerPolynomial operator+ (const mpz_t r) const {
845  return (*this + mpz_class(r));
846  }
847 
848  /**
849  * Add *this and the mpz_class r.
850  */
851  SparseMultivariateIntegerPolynomial operator+ (const mpz_class& r) const;
852 
853  inline SparseMultivariateIntegerPolynomial operator+ (const Integer& r) const {
854  return (*this + r.get_mpz());
855  }
856 
857  /**
858  * Add mpz_t r and SMQP b.
859  */
860  inline friend SparseMultivariateIntegerPolynomial operator+ (const mpz_t r, const SparseMultivariateIntegerPolynomial& b) {
861  return (b + r);
862  }
863 
864  /**
865  * Update *this by adding r
866  */
867  inline SparseMultivariateIntegerPolynomial& operator+= (const mpz_t r) {
868  return (*this += mpz_class(r));
869  }
870 
871 
872  /**
873  * Add mpz_class r and SMQP b.
874  */
875  inline friend SparseMultivariateIntegerPolynomial operator+ (const mpz_class& r, const SparseMultivariateIntegerPolynomial& b) {
876  return (b + r);
877  }
878 
879  /**
880  * Update *this by adding the mpz_class r to it.
881  */
882  SparseMultivariateIntegerPolynomial& operator+= (const mpz_class& r);
883 
884  /**
885  * Update *this by adding the Integer r to it.
886  */
887  inline SparseMultivariateIntegerPolynomial& operator+= (const Integer& r) {
888  *this += r.get_mpz();
889  return *this;
890  }
891 
892  /**
893  * Subtract the mpz_t r from *this.
894  */
895  inline SparseMultivariateIntegerPolynomial operator- (const mpz_t r) const {
896  return (*this - mpz_class(r));
897  }
898 
899  /**
900  * Subtract the mpz_class r from *this.
901  */
902  SparseMultivariateIntegerPolynomial operator- (const mpz_class& r) const;
903 
904  /**
905  * Subtract the Integer r from *this.
906  */
907  inline SparseMultivariateIntegerPolynomial operator- (const Integer& r) const {
908  return (*this - r.get_mpz());
909  }
910 
911  /**
912  * Subtract SMQP b from mpz_t r.
913  */
914  inline friend SparseMultivariateIntegerPolynomial operator- (const mpz_t r, const SparseMultivariateIntegerPolynomial& b) {
915  return (-b + r);
916  }
917 
918  /**
919  * Update *this by subtracting mpz_t r.
920  */
921  inline SparseMultivariateIntegerPolynomial& operator-= (const mpz_t r) {
922  return (*this -= mpz_class(r));
923  }
924 
925 
926  /**
927  * Subtract SMQP b from mpz_class r.
928  */
929  inline friend SparseMultivariateIntegerPolynomial operator- (const mpz_class& r, const SparseMultivariateIntegerPolynomial& b) {
930  return (-b + r);
931  }
932 
933  /**
934  * Update *this by subtracting mpz_class r.
935  */
936  SparseMultivariateIntegerPolynomial& operator-= (const mpz_class& r);
937 
938  /**
939  * Update *this by subtracting Integer r.
940  */
941  inline SparseMultivariateIntegerPolynomial& operator-= (const Integer& r) {
942  *this -= r.get_mpz();
943  return *this;
944  }
945 
946  /**
947  * Multiply *this by mpz_t r.
948  */
949  inline SparseMultivariateIntegerPolynomial operator* (const mpz_t r) const {
950  return (*this * mpz_class(r));
951  }
952 
953  /**
954  * Multiply *this by mpz_class r.
955  */
956  SparseMultivariateIntegerPolynomial operator* (const mpz_class& r) const;
957 
958  /**
959  * Multiply *this by Integer r.
960  */
961  inline SparseMultivariateIntegerPolynomial operator* (const Integer& r) const {
962  return (*this * r.get_mpz());
963  }
964 
965  /**
966  * Multiply mpz_t r and SMQP b.
967  */
968  inline friend SparseMultivariateIntegerPolynomial operator* (const mpz_t r, const SparseMultivariateIntegerPolynomial& b) {
969  return (b * r);
970  }
971 
972  /**
973  * Update *this by multiplying by mpz_t r.
974  */
975  inline SparseMultivariateIntegerPolynomial& operator*= (const mpz_t r) {
976  return (*this *= mpz_class(r));
977  }
978 
979  /**
980  * Multiply mpz_class r and SMQP b.
981  */
982  inline friend SparseMultivariateIntegerPolynomial operator* (const mpz_class& r, const SparseMultivariateIntegerPolynomial& b) {
983  return (b * r);
984  }
985 
986  /**
987  * Update *this by multiplying by mpz_class r.
988  */
989  SparseMultivariateIntegerPolynomial& operator*= (const mpz_class& r);
990 
991  /**
992  * Update *this by multiplying by Integer r.
993  */
994  inline SparseMultivariateIntegerPolynomial& operator*= (const Integer& r) {
995  *this *= r.get_mpz();
996  return *this;
997  }
998 
999  /**
1000  * Divide *this by mpz_t r.
1001  */
1002  inline SparseMultivariateIntegerPolynomial operator/ (const mpz_t r) const {
1003  return (*this / mpz_class(r));
1004  }
1005 
1006  /**
1007  * Divide *this by mpz_class r.
1008  */
1009  SparseMultivariateIntegerPolynomial operator/ (const mpz_class& r) const;
1010 
1011  /**
1012  * Divide *this by Integer r.
1013  */
1014  inline SparseMultivariateIntegerPolynomial operator/ (const Integer& r) const {
1015  return (*this / r.get_mpz());
1016  }
1017 
1018  /**
1019  * Divide mpz_t r by SMQP b.
1020  */
1021  friend SparseMultivariateIntegerPolynomial operator/ (const mpz_t r, const SparseMultivariateIntegerPolynomial& b) ;
1022 
1023  /**
1024  * Update *this by dividing by mpz_t r.
1025  */
1026  inline SparseMultivariateIntegerPolynomial& operator/= (const mpz_t r) {
1027  return (*this /= mpz_class(r));
1028  }
1029  /**
1030  * Divide mpz_class r by SMQP b.
1031  */
1032  inline friend SparseMultivariateIntegerPolynomial operator/ (const mpz_class& r, const SparseMultivariateIntegerPolynomial& b) {
1033  mpz_t t;
1034  mpz_init(t);
1035  mpz_set(t, r.get_mpz_t());
1037  mpz_clear(t);
1038  return ret;
1039  }
1040 
1041  /**
1042  * Update *this by dividing by mpz_class r.
1043  */
1044  SparseMultivariateIntegerPolynomial& operator/= (const mpz_class& r);
1045  /**
1046  * Update *this by dividing by Integer r.
1047  */
1048  inline SparseMultivariateIntegerPolynomial& operator/= (const Integer& r) {
1049  *this /= r.get_mpz();
1050  return *this;
1051  }
1052 
1053  /**
1054  * Get the polynomial term at index. Returns 0 if index is beyond the
1055  * number of terms in this polynomial.
1056  */
1057  SparseMultivariateIntegerPolynomial operator[] (int index) const;
1058 
1059  /**
1060  * Get the leading variable, that is, the highest-order variable with positive degree
1061  * of this polynomial.
1062  * returns the leading variable or the empty string if this polynomial has zero variables.
1063  */
1064  Symbol leadingVariable() const;
1065 
1066  /**
1067  * Get the degree of this polynomial w.r.t the leading variable.
1068  */
1069  Integer leadingVariableDegree() const;
1070 
1071  /**
1072  * Is the contant term zero.
1073  */
1074  bool isConstantTermZero() const;
1075 
1076  /**
1077  * Get the leading coefficient w.r.t the input variable 'x'.
1078  * Returns the leading exponent as e.
1079  *
1080  * returns the coefficient as a new SMQP.
1081  */
1082  SparseMultivariateIntegerPolynomial leadingCoefficientInVariable (const Symbol& x, int* e = NULL) const;
1083 
1084  /**
1085  * Convert to a SUP<SMQP> given the variable 'x'.
1086  *
1087  * returns the SUP<SMQP>.
1088  */
1090 
1091  /**
1092  * Negate all the coefficients of *this. Note, that due to the
1093  * sharing nature of underling nodes, this may alter the Nodes of
1094  * other SMQP.
1095  */
1096  void negate();
1097 
1098  /**
1099  * Get a copy of this such that all underlying memory is NOT shared.
1100  * Note, any following arithmetic operations on the returned result
1101  * will result in possibly making the underlying memory shared again.
1102  */
1103  SparseMultivariateIntegerPolynomial deepCopy() const;
1104 
1105  /**
1106  * Factors this polynomial into irreducible factors.
1107  * The Factors may include a common numerical (integer) factor.
1108  * See also, Factors.
1109  */
1111 
1112  /**
1113  * SLP representation of the polynomial
1114  **/
1115  void straightLineProgram();
1116 
1117  /**
1118  * Print SLP representation
1119  **/
1120  void printSLP(std::ostream& out = std::cout) const;
1121 
1122  /**
1123  * Change *this to be a random non-zero polynomial.
1124  * numvar: number of variables
1125  * nterms: number of terms
1126  * coefBound: limit on the number of bits encoding the coefficients.
1127  * sparsity: succesive terms are at most sparsity away from each other
1128  * includeNeg: a bool to say if coefs can be randomly negative or all positive
1129  */
1130  void randomPolynomial(int numvar, int nterms, unsigned long int coefBound, degree_t sparsity, bool includeNeg);
1131 
1132  /**
1133  * Change *this to be a random non-zero polynomial. The number of variables will
1134  * be equal to the size of the maxDegs vector. The term whose monomial
1135  * has exponents equal to those in maxDegs is guaranteed to exist in the
1136  * resulting polynomial.
1137  * A sparsity of 0 produces a dense polynomial. A sparsity of 1 produces only
1138  * one term; one whose monomial has exponents equal to maxDegs.
1139  *
1140  * coefBound: limit on the number of bits encoding the coefficients.
1141  * sparsity: a percentage of zero-terms between term with maxDegs and the constant term.
1142  * includeNeg: a bool to say if coefs can be randomly negative or all positive
1143  */
1144  void randomPolynomial(std::vector<int> maxDegs, unsigned long int coefBound, float sparsity, bool includeNeg);
1145 
1146  /**
1147  * Convert *this to an ExpressionTree.
1148  *
1149  * returns the new ExpressionTree.
1150  */
1151  ExpressionTree convertToExpressionTree() const;
1152 };
1153 
1154 
1155 
1156 
1157 
1158 #endif //_SMQPLINKEDLIST_H_
A multivariate polynomial with Integer coefficients using a sparse representation.
Definition: mzpolynomial.hpp:75
A sparsely represented univariate polynomial over an arbitrary ring.
Definition: BigPrimeField.hpp:21
A multivariate polynomial with RationalNumber coefficients represented sparely.
Definition: mrpolynomial.h:71
int numberOfRingVariables() const
Get the number of variables in this polynomial ring.
Definition: mzpolynomial.hpp:552
Definition: mzpolynomial.hpp:33
SparseMultivariateIntegerPolynomial evaluate(int n, const Symbol *syms, const Integer *xs) const
Evaluate f(x)
Definition: mzpolynomial.hpp:760
An ExpressionTree encompasses various forms of data that can be expressed generically as a binary tre...
Definition: ExpressionTree.hpp:17
Data Structure for interval [a, b].
Definition: interval.h:11
SparseMultivariateIntegerPolynomial unitCanonical(SparseMultivariateIntegerPolynomial *u, SparseMultivariateIntegerPolynomial *v) const
Obtain the unit normal (a.k.a canonical associate) of an element.
Definition: mzpolynomial.hpp:260
A univariate polynomial with Integer coefficients using a dense representation.
Definition: uzpolynomial.h:14
Symbol mainVariable() const
Get the main variable.
Definition: mzpolynomial.hpp:506
Integer coefficient(const std::vector< int > &v) const
Get the coefficient of this polynomial with respect to the monomial defined by exponent vector exps...
Definition: mzpolynomial.hpp:591
SparseMultivariateIntegerPolynomial integral(const Symbol &s) const
Compute integral.
Definition: mzpolynomial.hpp:742
void differentiate(const Symbol &s, int k)
Convert current object to its k-th derivative.
Definition: mzpolynomial.hpp:662
A simple data structure for encapsulating a collection of Factor elements.
Definition: Factors.hpp:95
void setCoefficient(const std::vector< int > &v, const Integer &r)
Set the coefficient of this polynomial for the monomial defined by exponent vector exps to r...
Definition: mzpolynomial.hpp:600
An arbitrary-precision Integer.
Definition: Integer.hpp:22
An encapsulation of a mathematical symbol.
Definition: Symbol.hpp:23
An arbitrary-precision rational number.
Definition: RationalNumber.hpp:24
An element of the SLP of an integer polynomial.
Definition: mzpolynomial.hpp:30
void one()
Sets this polynomial to one.
void integrate(const Symbol &s)
Convert current object to its derivative.
Definition: mzpolynomial.hpp:707
SparseMultivariateIntegerPolynomial derivative(const Symbol &s) const
Compute derivative.
Definition: mzpolynomial.hpp:688
void integrate(const Symbol &s, int k)
Convert current object to its k-th integral.
Definition: mzpolynomial.hpp:698
void differentiate(const Symbol &s)
Convert current object to its derivative.
Definition: mzpolynomial.hpp:671
An abstract class defining the interface of a multivariate polynomial that can be viewed recursively...
Definition: BPASRecursivePolynomial.hpp:12