Basic Polynomial Algebra Subprograms (BPAS)  v. 1.700
mrpolynomial.h
1 #ifndef _SMQPALTARRAY_H_
2 #define _SMQPALTARRAY_H_
3 
4 #include "../polynomial.h"
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 mpz_class characteristic;
202  static RingProperties properties;
203  // static bool isPrimeField;
204  // static bool isSmallPrimeField;
205  // static bool isComplexField;
206 
207  /**
208  * Is this polynomial zero.
209  * returns true iff this polynomial encodes 0.
210  */
211  bool isZero() const;
212 
213  /**
214  * Set this polynomial to zero. Maintains existing variable ordering.
215  */
216  void zero();
217 
218  /**
219  * Is this polynomial one.
220  * return true iff this polynomial encodes 1.
221  */
222  bool isOne() const;
223 
224  /**
225  * Sets this polynomial to one. Maintains existing variable ordering.
226  */
227  void one();
228 
229  /**
230  * Is this polynomial negative one.
231  * returns true iff this polynomial encodes -1.
232  */
233  bool isNegativeOne() const;
234 
235  /**
236  * Sets this polynomial to -1. Maintains existing variable ordering.
237  */
238  void negativeOne();
239 
240  /**
241  * Determine if this polynomial encodes a constant.
242  * returns 0 if not a constant, 1 if a constant >= 0, -1 if a negative contstant.
243  */
244  int isConstant() const;
245 
246  /**
247  * Obtain the unit normal (a.k.a canonical associate) of an element.
248  * If either parameters u, v, are non-NULL then the units are returned such that
249  * b = ua, v = u^-1. Where b is the unit normal of a, and is the returned value.
250  */
253  RationalNumber leadInv = lead.inverse();
254  if (u != NULL) {
255  *u = leadInv;
256  }
257  if (v != NULL) {
258  *v = lead;
259  }
260  return (*this * leadInv);
261  }
262 
263  /* BPASPolynomial interface */
264 
265  /**
266  * Assign this polynomail to equal the specified.
267  */
269 
270  /**
271  * Movement assignment: move b to be this polynomail.
272  */
274 
275  /**
276  * Assign this polynomial to be equal to the constant ring element.
277  */
279 
280  /**
281  * Add two SMQP polynomials together, *this and the specified.
282  */
285 
286  // /**
287  // * Add the polynomails a and b and return the sum.
288  // */
289  // friend SparseMultivariateRationalPolynomial operator+ (SparseMultivariateRationalPolynomial&& a, const SparseMultivariateRationalPolynomial& b);
290 
291  /**
292  * Update *this by adding the specified polynomail to it.
293  */
295 
296  /**
297  * Subtract the specified polynomail from *this
298  */
301 
302  // /**
303  // * Subtract the polynomial b from a and return the difference.
304  // */
305  // friend SparseMultivariateRationalPolynomial operator- (SparseMultivariateRationalPolynomial&& a, const SparseMultivariateRationalPolynomial& b);
306 
307  /**
308  * Unary operation, return *this * -1.
309  */
311 
312  /**
313  * Update *this by subtracting the specified polynomial from it.
314  */
316 
317  /**
318  * Multiply *this by the specified polynomail.
319  */
322 
323  // /**
324  // * Multiply the polynomials a and b, returning their product.
325  // */
326  // friend SparseMultivariateRationalPolynomial operator* (SparseMultivariateRationalPolynomial&& a, const SparseMultivariateRationalPolynomial& b);
327 
328  /**
329  * Update this by multiplying by the specified polynomail.
330  */
332 
333  /**
334  * Divide *this by the specified polynomial.
335  */
338 
339  // friend SparseMultivariateRationalPolynomial operator/ (SparseMultivariateRationalPolynomial&& a, const SparseMultivariateRationalPolynomial& b);
340 
341  /**
342  * Update *this by dividing by the specified polynomial.
343  */
345 
346  /**
347  * Exponentiate *this by the input exponent integer.
348  * Treats negative exponents as positive.
349  */
350  SparseMultivariateRationalPolynomial operator^ (long long int e) const;
351 
352  /**
353  * Update *this by exponentiating this to the input integer.
354  * Treats negative exponents as positive.
355  */
357 
358  /**
359  * Determine if *this is equal to the specified polynomial.
360  * This takes into account the variable ordering on both poylnomials
361  * in such a way that the same polynomial under different variable orderings
362  * are NOT equal.
363  */
365 
366  /**
367  * Determine if *this is not equal to the specified polynomial.
368  * This takes into account the variable ordering on both poylnomials
369  * in such a way that the same polynomial under different variable orderings
370  * are NOT equal.
371  */
373 
374  /**
375  * Output the string representation of *this to the input ostream.
376  */
377  void print(std::ostream& os) const;
378 
379  /**
380  * Parse polynomial from in stream. Exactly one line is parsed.
381  */
382  friend std::istream& operator>>(std::istream& in, SparseMultivariateRationalPolynomial& p);
383 
384  /**
385  * Parse a polynomial from string str and place in *this.
386  */
387  void fromString(const std::string& str);
388 
389  /**
390  * Given a polynomial q, compute the subresultant chain between this and q, viewing both polynomial
391  * recursively with main variable v.
392  *
393  * @note, if this and q do not exist in the same ambient space, the space of p will define the ordering of the subresultants.
394  *
395  * @param q, the other polynomial for which to compute the subresultant chain.
396  * @param v, the main variable to be used when computing the subresultant chain.
397  * @param filled, if false, degenerative cases are not returned and so indices in the returned chain do not necessarily match subresultant degrees
398  *
399  * @return a vector containing the subresultant chain whereby index 0 is resultant and subresultant degrees increase with index.
400  *
401  */
402  std::vector<SparseMultivariateRationalPolynomial> subresultantChain(const SparseMultivariateRationalPolynomial& q, const Symbol& v, bool filled = 1) const;
403 
404  /**
405  * Subresultant Chain with respect to the leaving variable of this.
406  * Return the list of subresultants
407  **/
408  std::vector<SparseMultivariateRationalPolynomial> subresultantChain (const SparseMultivariateRationalPolynomial& q, int filled = 1) const;
409 
410  /**
411  * Given a polynomial q, compute the subresultant of index idx between this and q, viewing both polynomial
412  * recursively with main variable v. This function in fact computes the subresultant of index idx and idx+1
413  * and so both are returned, unless idx+1 does not exist (e.g. idx = this->degree(v)).
414  *
415  * Optionally, this function also returns the principleCoefs of the subresultants of index i to this->degree(v).
416  *
417  * @note, if the subresultant of index idx+1 is degenerative then many subresultants will be returned until the first non-degenerative one is found.
418  * @note, if this and q do not exist in the same ambient space, the space of p will define the ordering of the subresultants.
419  *
420  * @param q, the other polynomial for which to compute the subresultant chain.
421  * @param v, the main variable to be used when computing the subresultant chain.
422  *
423  * @return a vector containing the subresultant chain whereby index 0 is requested subresultant idx subresultant degrees increase with index.
424  *
425  */
426  std::vector<SparseMultivariateRationalPolynomial> subresultantChainAtIdx (const SparseMultivariateRationalPolynomial& q, const Symbol& v, int idx = 0, std::vector<SparseMultivariateRationalPolynomial>* principleCoefs = NULL) const;
427 
428  /**
429  * Extended Subresultant Chain
430  * Return the list of subresultants with Besout Coefficients
431  **/
432  std::vector<std::vector<SparseMultivariateRationalPolynomial>> exSubresultantChain (const SparseMultivariateRationalPolynomial& q, const Symbol& v) const;
433 
435 
436  /**
437  * Get GCD between *this and b.
438  */
440 
441  /**
442  * Get the GCD between *this and b as a primitive polynomial.
443  */
445 
446  /**
447  * Compute squarefree factorization of *this with respect to all of its variables.
448  */
450 
451  /**
452  * Compute squarefree factorization of *this with respect to the list of variables, vars.
453  */
454  Factors<SparseMultivariateRationalPolynomial> squareFree(const std::vector<Symbol>& vars) const;
455 
456  /**
457  * Computes the square free part of this polynomail. That is, the polynomial of this
458  * divided by all square factors. This is with respect to all variables.
459  */
461 
462  /**
463  * Computes the square free part of this polynomail. That is, the polynomial of this
464  * divided by all square factors. This is with respect to all variables.
465  */
466  SparseMultivariateRationalPolynomial squareFreePart(std::vector<Symbol>& vars) const;
467 
468  /**
469  * Get the content with respect to all variables. That is, a single
470  * rational number. The content here is one such that this/content is
471  * an integer polynomial with content of 1.
472  *
473  * Moreover, the content is one such that the leading coefficient
474  * of the corresponding primitive part is positive.
475  */
476  RationalNumber content() const;
477 
478  /**
479  * Get the content of this polynomial with respect to the variables in
480  * the input vector v.
481  *
482  * Moreover, the content is one such that the leading coefficient
483  * of the corresponding primitive part is positive.
484  */
485  SparseMultivariateRationalPolynomial content(const std::vector<Symbol>& v) const;
486 
487  /**
488  * Get the primitive part with respect to all variables, returned as an SMZP.
489  * This is equivalent to this / content();
490  */
491  SparseMultivariateIntegerPolynomial primitivePartSMZP() const;
492 
493  /**
494  * Get the primitive part with respect to all variables, returned as an SMZP.
495  * This is equivalent to this / content();
496  *
497  * Simultaneously returns the rational number content in the parameter content.
498  */
499  SparseMultivariateIntegerPolynomial primitivePartSMZP(RationalNumber& content) const;
500 
501  /**
502  * Get the primitive part with respect to all variables.
503  * This is equivalent to this / content().
504  */
506 
507  /**
508  * Get the primitive part with respect to the variable s.
509  * This is equivalent to this / content(s).
510  */
512 
513  /**
514  * Get the primitive part with respect to all variables.
515  * This is equivalent to this / content().
516  *
517  * Simultaneously returns the rational number content in the parameter content.
518  */
520 
521  /**
522  * Get the primitive part with respect to the variables in the vector v.
523  *
524  * returns the primitive part.
525  */
526  SparseMultivariateRationalPolynomial primitivePart(const std::vector<Symbol>& v) const;
527 
528  /**
529  * Get the primitive part with respect to the variables in the vector v.
530  * Returns the corresponding content in the content reference.
531  * returns the primitive part.
532  */
533  SparseMultivariateRationalPolynomial primitivePart(const std::vector<Symbol>& v, SparseMultivariateRationalPolynomial& content) const;
534 
535  SparseMultivariateRationalPolynomial mainPrimitivePart() const;
536 
538 
539  /**
540  * Get the leading coefficient of *this with respect to the main variable.
541  *
542  * returns the initial.
543  */
545 
546  /**
547  * Get the main variable. That is, the highest-ordered variable with
548  * positive degree.
549  *
550  * returns the main variable.
551  */
552  inline Symbol mainVariable() const {
553  return leadingVariable();
554  }
555 
556  /**
557  * Get the degree of the main variable.
558  *
559  * returns the degree.
560  */
561  int mainDegree() const;
562 
563  /**
564  * Get the rank of this polynomial.
565  * That is, the main variable raised to the main degree.
566  *
567  * returns the rank.
568  */
570 
571  /**
572  * Get the head of this polynomial. That is, the initial multiplied
573  * by the rank.
574  *
575  * returns the head.
576  */
578 
579  /**
580  * Get the tail of this polynomial. That is, This - this.head().
581  *
582  * returns the tail.
583  */
585 
586  SparseMultivariateRationalPolynomial separant() const;
587 
588  /* BPASMultivariatePolynomial interface */
589 
590  /**
591  * Get the number of variables in this polynomial.
592  */
593  int numberOfVariables() const;
594 
595  /**
596  * Get the number of variables in this polynomial ring.
597  */
598  inline int numberOfRingVariables() const {
599  return ringVariables().size();
600  }
601 
602  /**
603  * Get the number of non-zero terms
604  */
605  Integer numberOfTerms() const;
606 
607  /**
608  * Total degree.
609  */
610  Integer degree() const;
611 
612  /**
613  * Get the degree of a variable
614  */
615  Integer degree(const Symbol&) const;
616 
617  /**
618  * Get the leading coefficient
619  */
621 
622  /**
623  * Get the trailing coefficient.
624  */
626 
627  /**
628  * Get a coefficient, given the exponent of each variable
629  */
630  RationalNumber coefficient(int, const int*) const;
631 
632  inline RationalNumber coefficient(const std::vector<int>& v) const {
633  return coefficient(v.size(), v.data());
634  }
635 
636  /**
637  * Set a coefficient, given the exponent of each variable
638  */
639  void setCoefficient(int, const int*, const RationalNumber&);
640 
641  inline void setCoefficient(const std::vector<int>& v, const RationalNumber& r) {
642  setCoefficient(v.size(), v.data(), r);
643  }
644 
645 
646  /**
647  * Set variables' names.
648  *
649  * This method can be used to shrink, expand, re-order, and re-name the variables
650  * of the polynomial ring in which this polynomial belongs.
651  *
652  * Any symbol in the input vector that matches the current variables
653  * is considered a re-order. Non-matching symbols are considered a re-name
654  * and this renames is done in the order they appear by increasing index.
655  * For example: Q[x,y,z] -> Q[y,s,t] will have y reordered to be the
656  * first variable, x renamed to s, and z renamed to t.
657  *
658  * If the size of the input vector is greater than the current number of variables
659  * then the polynomial ring is being expanded. Matching variables from this
660  * polynomial are re-ordered as they appear in the input vector. Current variables
661  * that have no match in the input vector are re-named in order of increasing index
662  * of unused variables from the input vector.
663  * For example: Q[x,y,z] -> Q[s,t,z,x] will have y named to s, t a new variable,
664  * and z and x re-ordered accordingly.
665  *
666  * If the size of the input vector is less than the current number of variables
667  * then the polynomial ring is shrink to remove variables. Variables in the
668  * input vector that are also found to be in the current polynomial ring
669  * are matched and re-ordered as necessary.
670  *
671  * It is invalid to remove a variable which is non-zero in this polynomial.
672  */
673  void setRingVariables (const std::vector<Symbol>&);
674 
675  /**
676  * Get variable names of all variables available to this polynomial,
677  * even those that have zero degree.
678  */
679  std::vector<Symbol> ringVariables() const;
680 
681  /**
682  * Get variable names of variables with non-zero degree;
683  */
684  std::vector<Symbol> variables() const;
685 
686 
687  /* SMQP-specific */
688 
689  /**
690  * Determine if *this is equal to b.
691  * This takes into account the variable ordering on both poylnomials
692  * in such a way that the same polynomial under different variable orderings
693  * are NOT equal.
694  */
695  bool isEqual(const SparseMultivariateRationalPolynomial& b) const;
696 
697  /**
698  * Convert current object to its k-th derivative
699  *
700  * @param s: Symbol to differentiate with respect to
701  * @param k: Order of the derivative, k > 0
702  **/
703  inline void differentiate(const Symbol& s, int k) {
704  *this = this->derivative(s, k);
705  }
706 
707  /**
708  * Convert current object to its derivative
709  *
710  * @param s: Symbol to differentiate with respect to
711  **/
712  inline void differentiate(const Symbol& s) {
713  this->differentiate(s,1);
714  }
715 
716  /**
717  * Return k-th derivative
718  *
719  * @param s: Symbol to differentiate with respect to
720  * @param k: Order of the k-th derivative, k > 0
721  **/
723 
724  /**
725  * Compute derivative
726  *
727  * @param s: Symbol to differentiate with respect to
728  **/
730  return this->derivative(s,1);
731  }
732 
733  /**
734  * Convert current object to its k-th integral
735  *
736  * @param s: Symbol to differentiate with respect to
737  * @param k: Order of the derivative, k > 0
738  **/
739  inline void integrate(const Symbol& s, int k) {
740  *this = this->integral(s, k);
741  }
742 
743  /**
744  * Convert current object to its derivative
745  *
746  * @param s: Symbol to differentiate with respect to
747  **/
748  inline void integrate(const Symbol& s) {
749  this->integrate(s,1);
750  }
751 
752  /**
753  * Return k-th integral. If Symbol s is not a symbol contained in this
754  * polynomial then it becomes the main variable of the result and
755  * integration proceeds as expected.
756  *
757  * @param s: Symbol to differentiate with respect to
758  * @param k: Order of the k-th derivative, k > 0
759  **/
760  SparseMultivariateRationalPolynomial integral(const Symbol& s, int k) const;
761 
762  /**
763  * Compute integral
764  *
765  * @param s: Symbol to differentiate with respect to
766  **/
768  return this->integral(s,1);
769  }
770 
771  /**
772  * Evaluate f(x)
773  *
774  * @param syms: Array of Symbols to evaluate at corresponding xs
775  * @param xs: Evaluation points
776  **/
777  inline SparseMultivariateRationalPolynomial evaluate(int n, const Symbol* syms, const RationalNumber* xs) const {
778  std::vector<Symbol> vecSyms;
779  std::vector<RationalNumber> vecRats;
780  vecSyms.reserve(n);
781  vecRats.reserve(n);
782  for (int i = 0; i < n; ++i) {
783  vecSyms.push_back(syms[i]);
784  vecRats.push_back(xs[i]);
785  }
786  return evaluate(vecSyms, vecRats);
787  }
788 
789  /**
790  * Evaluate *this polynomial given the variables and their values in vars, and values.
791  * vars must be a list of variables which are a (not necessarily proper) subset.
792  * vars and values should have matching indices. i.e. the values of vars[i] is values[i].
793  *
794  * returns a new SMQP where all variables in vars have been evaluated using the values given.
795  */
796  SparseMultivariateRationalPolynomial evaluate(const std::vector<Symbol>& vars, const std::vector<RationalNumber>& values) const;
797 
798  /**
799  * Find the interpolating polynomial for the points and values specified by each vector, respectively.
800  * The points vector is a vector of vectors, where each element of the outer vector represents a multi-dimensional point.
801  * Each multi-dimensional point should have the same number of dimensions and in the same order.
802  *
803  * returns the interpolating polynomial.
804  */
805  static SparseMultivariateRationalPolynomial interpolate(const std::vector<std::vector<RationalNumber>>& points, const std::vector<RationalNumber>& vals);
806 
807  /**
808  * Divide this by polynomial b, returning the quotient and remainder in q and r, respectively.
809  *
810  * returns a boolean indicating if the division was exact.
811  */
813 
814  /**
815  * Get the remainder of *this divided by b.
816  */
818 
819  /**
820  * Update *this by setting it to the remainder of *this divided by b.
821  */
823 
824 
827  ret %= i;
828  return ret;
829  }
830 
832  if (!this->isZero()) {
833  applyModuloSymmetricPrimPart_AA_inp(this->poly, i.get_mpz_t());
834  }
835  return *this;
836  }
837 
838  /**
839  * Pseudo divide this by b. The remainder is returned.
840  * if parameter quo is not null then the quotient is returned in quo.
841  * if parameter mult is not null then the multiplier is set to the initial of b
842  * raised to the power of degree(c, mvar(c)) - degree(b, mvar(c)) + 1.
843  *
844  * returns the pseudo remainder.
845  */
847 
848  /**
849  * Pseudo divide this by b. The remainder is returned.
850  * This function assumes that both this and b are primitive, and thus
851  * can be viewed as integer polynomials. The psuedo-division is then performed
852  * over the integers and the quotient and remainder returned also so they are primitive.
853  *
854  * If parameter quo is not null then the quotient is returned in quo.
855  * If parameter mult is not null then the multiplier is set to the initial of b
856  * raised to the power of degree(c, mvar(c)) - degree(b, mvar(c)) + 1.
857  *
858  * @return the pseudo remainder.
859  */
861 
862 
863  /**
864  * Add *this and a ratNum_t.
865  */
866  inline SparseMultivariateRationalPolynomial operator+ (const ratNum_t& r) const {
867  return (*this + RationalNumber(r));
868  }
869 
870  /**
871  * Add *this and the RationalNumber r.
872  */
874 
875  /**
876  * Add ratNum_t r and SMQP b.
877  */
879  return (b + r);
880  }
881 
882  /**
883  * Update *this by adding r
884  */
886  return (*this += RationalNumber(r));
887  }
888 
889  /**
890  * Add RationalNumber r and SMQP b.
891  */
893  return (b + r);
894  }
895 
896  /**
897  * Update *this by adding the RationalNumber r to it.
898  */
900 
901  /**
902  * Subtract the ratNum_t r from *this.
903  */
904  inline SparseMultivariateRationalPolynomial operator- (const ratNum_t& r) const {
905  return (*this - RationalNumber(r));
906  }
907 
908  /**
909  * Subtract the RationalNumber r from *this.
910  */
912 
913  /**
914  * Subtract SMQP b from ratNum_t r.
915  */
917  return (-b + r);
918  }
919 
920  /**
921  * Subtract SMQP b from ratNum_t r.
922  */
924  return (-b + r);
925  }
926 
927  /**
928  * Update *this by subtracting ratNum_t r.
929  */
931  return (*this -= RationalNumber(r));
932  }
933 
934  /**
935  * Update *this by subtracting RationalNumber r.
936  */
938 
939  /**
940  * Multiply *this by ratNum_t r.
941  */
942  inline SparseMultivariateRationalPolynomial operator* (const ratNum_t& r) const {
943  return (*this * RationalNumber(r));
944  }
945 
946  /**
947  * Multiply *this by RationalNumber r.
948  */
950 
951  /**
952  * Multiply ratNum_t r and SMQP b.
953  */
955  return (b * r);
956  }
957 
958  /**
959  * Update *this by multiplying by ratNum_t r.
960  */
962  return (*this *= RationalNumber(r));
963  }
964 
965  /**
966  * Multiply RationalNumber r and SMQP b.
967  */
969  return (b * r);
970  }
971 
972  /**
973  * Update *this by multiplying by RationalNumber r.
974  */
976 
977  /**
978  * Divide *this by ratNum_t r.
979  */
980  inline SparseMultivariateRationalPolynomial operator/ (const ratNum_t& r) const {
981  return (*this / RationalNumber(r));
982  }
983 
984  /**
985  * Divide *this by RationalNumber r.
986  */
988 
989  /**
990  * Divide ratNum_t r by SMQP b.
991  */
993 
994  /**
995  * Update *this by dividing by ratNum_t r.
996  */
998  return (*this /= RationalNumber(r));
999  }
1000  /**
1001  * Divide RationalNumber r by SMQP b.
1002  */
1004  ratNum_t t;
1005  mpq_init(t);
1006  mpq_set(t, r.get_mpq_t());
1008  mpq_clear(t);
1009  return ret;
1010  }
1011 
1012  /**
1013  * Update *this by dividing by RationalNumber r.
1014  */
1016 
1017  /**
1018  * Get the polynomial term at index. Returns 0 if index is beyond the
1019  * number of terms in this polynomial.
1020  */
1022 
1023  /**
1024  * Get the leading variable, that is, the highest-order variable with positive degree
1025  * of this polynomial.
1026  * returns the leading variable or the empty string if this polynomial has zero variables.
1027  */
1028  Symbol leadingVariable() const;
1029 
1030  /**
1031  * Get the degree of this polynomial w.r.t the leading variable.
1032  */
1034  degree_t leadingVariableDegree_tmp() const;
1035  /**
1036  * Is the contant term zero.
1037  */
1038  bool isConstantTermZero() const;
1039 
1040  /**
1041  * Get the leading coefficient w.r.t the input variable 'x'.
1042  * Returns the leading exponent as e.
1043  *
1044  * returns the coefficient as a new SMQP.
1045  */
1047 
1048  /**
1049  * Convert to a SUP<SMQP> given the variable 'x'.
1050  *
1051  * returns the SUP<SMQP>.
1052  */
1054 
1055  /**
1056  * Negate all the coefficients of *this. Note, that due to the
1057  * sharing nature of underling nodes, this may alter the Nodes of
1058  * other SMQP.
1059  */
1060  void negate();
1061 
1062  /**
1063  * Get a copy of this such that all underlying memory is NOT shared.
1064  * Note, any following arithmetic operations on the returned result
1065  * will result in possibly making the underlying memory shared again.
1066  */
1068 
1069  /**
1070  * Factors this polynomial into irreducible factors.
1071  * The Factors may include a common numerical (rational) factor.
1072  * See also, Factors.
1073  */
1075 
1076  /**
1077  * SLP representation of the polynomial
1078  **/
1079  void straightLineProgram();
1080 
1081  /**
1082  * Print SLP representation
1083  **/
1084  void printSLP(std::ostream& out = std::cout) const;
1085 
1086  /* Real Root Isolation */
1087  private:
1089  int refineSleeveUnivariateIntervals(Intervals*, Intervals*, Intervals*, DenseUnivariateRationalPolynomial*, DenseUnivariateRationalPolynomial*, lfixq);
1090  void sleeveBoundURPolynomials(DenseUnivariateRationalPolynomial*, DenseUnivariateRationalPolynomial*, Intervals&, int, int);
1091  public:
1092  /**
1093  * Given one real root for x_1, .., x_{n-1},
1094  * isolate positive roots for x_n
1095  *
1096  * @param mpIs: Roots of x_n (Output)
1097  * @param apIs: A root of previous polynomials
1098  * @param s: deal with 0: positive roots; 1: negative roots
1099  * @param check: 1: check the leading or tail coefficient; 0: do not
1100  * @param width: Interval's right - left < width
1101  * @param ts: Taylor Shift option
1102  *
1103  * Return
1104  * 1: Need to refine preious polynomials
1105  * 0: Found positive real roots
1106  **/
1107  int positiveRealRootIsolation(Intervals* pIs, Intervals& apIs, mpq_class width, int ts=-1, bool s=0, bool check=1);
1108 
1109  /**
1110  * Change *this to be a random non-zero polynomial.
1111  * numvar: number of variables
1112  * nterms: number of terms
1113  * coefBound: limit on the number of bits encoding the coefficients.
1114  * sparsity: succesive terms are at most sparsity away from each other
1115  * includeNeg: a bool to say if coefs can be randomly negative or all positive
1116  */
1117  void randomPolynomial(int numvar, int nterms, unsigned long int coefBound, degree_t sparsity, bool includeNeg);
1118 
1119  /**
1120  * Change *this to be a random non-zero polynomial. The number of variables will
1121  * be equal to the size of the maxDegs vector. The term whose monomial
1122  * has exponents equal to those in maxDegs is guaranteed to exist in the
1123  * resulting polynomial.
1124  * A sparsity of 0 produces a dense polynomial. A sparsity of 1 produces only
1125  * one term; one whose monomial has exponents equal to maxDegs.
1126  *
1127  * coefBound: limit on the number of bits encoding the coefficients.
1128  * sparsity: a percentage of zero-terms between term with maxDegs and the constant term.
1129  * includeNeg: a bool to say if coefs can be randomly negative or all positive
1130  */
1131  void randomPolynomial(std::vector<int> maxDegs, unsigned long int coefBound, float sparsity, bool includeNeg);
1132 
1133  /**
1134  * Convert *this to an ExpressionTree.
1135  *
1136  * returns the new ExpressionTree.
1137  */
1139 
1140 
1141 /****************
1142 * Multi-Divisor Division
1143 *****************/
1144 
1145 /**
1146  * Normal Form (or Multi-Divisor Division (MDD))
1147  * Given the dividend, f, and a divisor-set of polynomials of size s,
1148  * G[s] = {g_0, ..., g_{s-1}} to compute the reduce polynomial (remainder) r with respect to the G[s],
1149  * Return (by reference) the remainder and the quotient set Q[s] = {q_0, ..., q_{s-1}},
1150  * such that f = q_0*g_0 + ... + q_{s-1}*g_{s-1} + r.
1151  */
1152  SparseMultivariateRationalPolynomial lexNormalForm(const std::vector<Symbol>& superNames,
1153  const std::vector<SparseMultivariateRationalPolynomial>& ts, std::vector<SparseMultivariateRationalPolynomial>* quoSet = NULL) const;
1154 
1155  SparseMultivariateRationalPolynomial lexNormalizeDim0 (const std::vector<Symbol>& superNames,
1156  const std::vector<SparseMultivariateRationalPolynomial>& ts, SparseMultivariateRationalPolynomial* A) const;
1157 
1158  /**
1159  * Multi-Divisor Division (MDD) where the divisor-set is a Triangular Set
1160  * Given the dividend, f, and a divisor-set of polynomials of size s,
1161  * G[s] = {g_0, ..., g_{s-1}} to compute the reduce polynomial (remainder) r with respect to the G[s],
1162  * Return (by reference) the remainder and the quotient set Q[s] = {q_0, ..., q_{s-1}}.
1163  */
1164  SparseMultivariateRationalPolynomial triangularSetNormalForm(const TriangularSet<RationalNumber,SparseMultivariateRationalPolynomial>& ts, std::vector<SparseMultivariateRationalPolynomial>* quoSet) const;
1165 
1166 /**
1167  * Do the pseudo division of c by the triangular-set (divisor set) of B in the naive principle
1168  * such that hPow*f = quoSet_0 * B_0 + ... + quoSet_{nSet-1} * B_{nSet-1} + rem.
1169  * Quotients are returned in quoSet, and remainder in rem.
1170  * If hPow is not NULL then *hPow is set to the initial of b to the power of
1171  * the exact number of division steps which occurred..
1172  * nvar : size of exponent vectors
1173  * nSet : the size of the divisor set
1174  */
1176  std::vector<SparseMultivariateRationalPolynomial>* quoSet, SparseMultivariateRationalPolynomial* h) const;
1177 
1178 /**
1179  * Specialized Normal Form where the divisor-set is a Triangular Set
1180  * Given the dividend, f, and a divisor-set of polynomials of size s,
1181  * G[s] = {g_0, ..., g_{s-1}} to compute the reduce polynomial (remainder) r with respect to the G[s].
1182  */
1184 
1185 
1186 
1187 
1188 
1189 
1190 
1191 
1192 /*
1193 
1194 ***/
1195 
1198 
1199 
1200 };
1201 
1202 
1203 
1204 
1205 
1206 #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:777
void differentiate(const Symbol &s)
Convert current object to its derivative.
Definition: mrpolynomial.h:712
A univariate polynomial over an arbitrary BPASRing represented sparsely.
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.
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:729
Integer leadingCoefficient() const
Get the leading coefficient.
Symbol mainVariable() const
Get the main variable.
Definition: mrpolynomial.h:552
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:748
SparseMultivariateIntegerPolynomial evaluate(int n, const Symbol *syms, const Integer *xs) const
Evaluate f(x)
Definition: mzpolynomial.hpp:759
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:9
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:598
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:15
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:661
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.
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:739
SparseMultivariateIntegerPolynomial squareFreePart() const
Computes the square free part of this polynomail.
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:392
SparseMultivariateRationalPolynomial unitCanonical(SparseMultivariateRationalPolynomial *u, SparseMultivariateRationalPolynomial *v) const
Obtain the unit normal (a.k.a canonical associate) of an element.
Definition: mrpolynomial.h:251
void integrate(const Symbol &s, int k)
Convert current object to its k-th integral.
Definition: mzpolynomial.hpp:697
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:33
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:767
void differentiate(const Symbol &s, int k)
Convert current object to its k-th derivative.
Definition: mrpolynomial.h:703
An abstract class defining the interface of a multivariate polynomial that can be viewed recursively...
Definition: polynomial.h:166
bool operator==(const SparseMultivariateIntegerPolynomial &b) const
Determine if *this is equal to the specified polynomial.