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