1 #ifndef __DYNAMIC_ENGINE_C__ 2 #define __DYNAMIC_ENGINE_C__ 24 using std::cout;
using std::endl;
28 #include "monomial.hpp" 29 #include "polynomial.hpp" 30 #include "dynamic_engine.hpp" 46 for (; i <= hn1.
degree() and i <= hn2.
degree() and hn1[i] == hn2[i]; i++)
48 if (i > hn1.degree()) {
54 if (i > hn2.
degree()) result = 1;
56 if (hn1[i] < hn2[i]) result = -1;
77 if (hilcheck == -1) result =
true;
99 const vector<Monomial>
I(T.begin(), T.end());
101 bool * keepers =
new bool [m];
102 for (
int i = 0; i < m; ++i) keepers[i] =
true;
104 for (
int i = 0; i < m; ++i)
109 bool has_divisor =
false;
110 for (
int j=0; (not has_divisor) and j < m; ++j)
112 if (i != j and keepers[j])
116 for (
int k=1; has_divisor and k <= n; ++k)
118 (((
t[k] >
I[i][k]) ?
t[k] :
I[i][k])
119 < ((
t[k] >
I[j][k]) ?
t[k] :
I[j][k]))
123 if (has_divisor) keepers[i] =
false;
127 for (
int i = 0; i < m; ++i)
133 for (
int k=1; k <= n; ++k)
134 new_deg += (
t[k] >
I[i][k]) ?
t[k] :
I[i][k];
137 min_deg = new_deg; num_new_pairs = 1;
153 for (
int k=1; k <= n; ++k) new_deg += u[k];
159 bool has_divisor =
true;
161 bool all_equal =
true;
162 const Monomial & p1 = p->first()->leading_monomial();
163 const Monomial & p2 = (p->second() ==
nullptr) ?
164 p->first()->leading_monomial()
165 : p->second()->leading_monomial();
166 for (
int k=1; has_divisor and all_equal and k <= n; ++k)
168 if (
t[k] > u[k]) has_divisor =
false;
172 int a = (
t[k] > p1[k]) ?
t[k] : p1[k];
173 int b = (
t[k] > p2[k]) ?
t[k] : p2[k];
174 int c = (p1[k] > p2[k]) ? p1[k] : p2[k];
175 all_equal = (a == c) and (b == c);
178 if (not has_divisor or all_equal)
182 min_deg = new_deg; num_new_pairs = 1;
227 if (hilcheck == -1) result =
true;
228 else if (hilcheck == 1) result =
false;
250 if (hilcheck == -1) result =
true;
251 else if (hilcheck == 1) result =
false;
252 else if (hilcheck == 0) {
287 i <= h1->
degree() and i <= h2->
degree() and (*h1)[i] == (*h2)[i];
295 while (i < n and a.
getPP()[i] == b.
getPP()[i]) ++i;
296 if (i == n) result =
false;
305 if (i > h2->
degree()) result =
false;
306 else result = (*h1)[i] < (*h2)[i];
337 i <= h1->
degree() and i <= h2->
degree() and (*h1)[i] == (*h2)[i];
345 while (i < n and a.
getPP()[i] == b.
getPP()[i]) ++i;
346 if (i == n) result =
false;
355 if (i > h2->
degree()) result =
false;
356 else result = (*h1)[i] < (*h2)[i];
386 i <= h1->
degree() and i <= h2->
degree() and (*h1)[i] == (*h2)[i];
394 while (i < n and a.
getPP()[i] == b.
getPP()[i]) ++i;
395 if (i == n) result =
false;
403 if (i > h2->
degree()) result =
false;
404 else result = (*h1)[i] < (*h2)[i];
413 const map<DEG_TYPE, unsigned long> & Ba = a.
getIncBetti();
414 const map<DEG_TYPE, unsigned long> & Bb = b.
getIncBetti();
415 auto Bai = Ba.begin();
416 auto Bbi = Bb.begin();
418 Bai != Ba.end() and Bbi != Bb.end()
419 and (Bai->first == Bbi->first and Bai->second == Bbi->second);
422 if (Bai == Ba.end()) {
424 result = LessByHilbertThenDegree(a, b);
428 if (Bbi == Bb.end()) {
431 if (Bai->first < Bbi->first)
433 else if (Bai->first > Bbi->first)
435 else if (Bai->second < Bbi->second)
446 const map<DEG_TYPE, unsigned long> & Ba = a.
getIncBetti();
447 const map<DEG_TYPE, unsigned long> & Bb = b.
getIncBetti();
451 Bai != Ba.begin() and Bbi != Bb.begin()
452 and (Bai->first == Bbi->first and Bai->second == Bbi->second);
455 if (Bai == Ba.begin()) {
456 if (Bbi == Bb.begin())
457 result = LessByHilbertThenDegree(a, b);
461 if (Bbi == Bb.begin()) {
464 if (Bai->first < Bbi->first)
466 else if (Bai->first > Bbi->first)
468 else if (Bai->second < Bbi->second)
479 const map<DEG_TYPE, unsigned long> & Ba = a.
getIncBetti(
true);
480 const map<DEG_TYPE, unsigned long> & Bb = b.
getIncBetti(
true);
481 auto Bai = Ba.begin();
482 auto Bbi = Bb.begin();
484 Bai != Ba.end() and Bbi != Bb.end()
485 and (Bai->first == Bbi->first and Bai->second == Bbi->second);
488 if (Bai == Ba.end()) {
490 result = LessByGradHilbertThenDegree(a, b);
494 if (Bbi == Bb.end()) {
497 if (Bai->first < Bbi->first)
499 else if (Bai->first > Bbi->first)
501 else if (Bai->second < Bbi->second)
512 const set<Monomial> &allPPs,
514 const set<::ray> &bndrys,
515 set<Monomial> &result,
517 set<Monomial> &boundary_mons,
522 NVAR_TYPE n = currentLPP.
num_vars();
524 set<Monomial> initial_candidates;
525 initial_candidates.insert(currentLPP);
559 initial_candidates.insert(b);
560 for (
const Monomial &
t : initial_candidates)
565 for (
const Monomial &
t : initial_candidates)
568 bool good_constraints =
true;
575 for (
const Monomial & u : initial_candidates)
578 good_constraints =
false;
581 if (good_constraints)
583 boundary_mons.insert(
t);
624 const list<Abstract_Polynomial *> ¤tPolys
627 bool consistent =
true;
631 RAYENT_TYPE *entries =
new RAYENT_TYPE [n];
632 CONSTR_TYPE *coefficients =
new CONSTR_TYPE [n];
635 auto piter = currentPolys.begin(); piter != currentPolys.end(); ++piter
643 for (NVAR_TYPE i = 0; i < n; ++i) entries[i] = t[i];
650 consistent and not ti->
fellOff();
657 for (NVAR_TYPE i = 0; i < n; ++i) entries[i] = ti->
currMonomial()[i];
663 if (coefficients ==
nullptr)
664 coefficients =
new CONSTR_TYPE[n];
665 for (NVAR_TYPE i = 0; i < n; ++i)
666 coefficients[i] = a[i] - b[i];
669 if (dynamic_cast<skeleton *>(skel) !=
nullptr)
670 newskel =
new skeleton(*static_cast<skeleton *>(skel));
671 else if (dynamic_cast<GLPK_Solver *>(skel) !=
nullptr) {
672 newskel =
new GLPK_Solver(*static_cast<GLPK_Solver *>(skel));
675 else if (dynamic_cast<PPL_Solver *>(skel) !=
nullptr)
676 newskel =
new PPL_Solver(*static_cast<PPL_Solver *>(skel));
677 consistent = newskel->
solve(new_constraint);
681 if (consistent and a*w > b*w)
687 else consistent =
false;
696 delete [] coefficients;
703 const set<Monomial> &monomialsForComparison,
704 vector<constraint> &result
711 const EXP_TYPE * a, * b;
712 CONSTR_TYPE *c =
new CONSTR_TYPE[n];
715 for (
const Monomial &
t : monomialsForComparison)
721 for (NVAR_TYPE i = 0; i < n; ++i) c[i] = a[i] - b[i];
732 list<Monomial> & CurrentLPPs,
734 const list<Abstract_Polynomial *> & CurrentPolys,
735 const list<Critical_Pair_Dynamic *> & crit_pairs,
737 bool & ordering_changed,
749 for (NVAR_TYPE i = 0; i < w.
get_dimension(); ++i) { ord.push_back(w[i]); }
752 set<Monomial> allPPs, boundaryPPs, compatiblePPs;
764 cout << allPPs.size() <<
" possible monomials\n";
766 cout << compatiblePPs.size() <<
" compatible monomials\n";
770 list<PPWithIdeal> possibleIdealsBasic;
773 PPWithIdeal newIdeal(
t, CurrentLPPs, w, crit_pairs, *current_hilbert_numerator);
774 possibleIdealsBasic.push_back(newIdeal);
779 case DynamicHeuristic::ORD_HILBERT_THEN_LEX:
780 possibleIdealsBasic.sort(LessByHilbert);
782 case DynamicHeuristic::ORD_HILBERT_THEN_DEG:
783 possibleIdealsBasic.sort(LessByHilbertThenDegree);
785 case DynamicHeuristic::DEG_THEN_ORD_HILBERT:
786 possibleIdealsBasic.sort(LessByDegreeThenHilbert);
788 case DynamicHeuristic::GRAD_HILB_THEN_DEG:
789 possibleIdealsBasic.sort(LessByGradHilbertThenDegree);
791 case DynamicHeuristic::DEG_THEN_GRAD_HILB:
792 possibleIdealsBasic.sort(LessByDegreeThenGradHilbert);
794 case DynamicHeuristic::SMOOTHEST_DEGREES:
795 possibleIdealsBasic.sort(LessBySmoothestDegrees);
797 case DynamicHeuristic::LARGEST_MAX_COMPONENT:
798 possibleIdealsBasic.sort(LessByLargestMaxComponent);
800 case DynamicHeuristic::MIN_CRIT_PAIRS:
801 possibleIdealsBasic.sort(LessByNumCritPairs);
803 case DynamicHeuristic::BETTI_HILBERT_DEG:
804 possibleIdealsBasic.sort(LessByBetti);
806 case DynamicHeuristic::GRAD_BETTI_HILBERT_DEG:
807 possibleIdealsBasic.sort(LessByGradBetti);
809 default: possibleIdealsBasic.sort(LessByHilbert);
811 PPWithIdeal * winner = & possibleIdealsBasic.front();
812 bool searching =
true;
813 if (possibleIdealsBasic.size() != 1)
817 set<Monomial> PPunion;
825 if (src_skel !=
nullptr)
826 newSkeleton =
new skeleton(*src_skel);
827 else if (src_GLPK !=
nullptr)
829 else if (src_PPL !=
nullptr)
831 vector<constraint> newvecs;
834 if (newSkeleton->
solve(newvecs))
840 if (src_skel !=
nullptr)
841 src_skel -> copy(newSkeleton);
842 else if (src_GLPK !=
nullptr)
843 src_GLPK -> copy(newSkeleton);
844 else if (src_PPL !=
nullptr)
845 src_PPL -> copy(newSkeleton);
856 compatiblePPs.erase(
I.getPP());
861 else if (possibleIdealsBasic.size() == 1 and compatiblePPs.size() != 1)
863 vector<constraint> newvecs;
865 currSkel->
solve(newvecs);
870 CurrentLPPs.push_back(winner->
getPP());
871 if (*current_hilbert_numerator !=
nullptr)
delete *current_hilbert_numerator;
872 *current_hilbert_numerator
880 not ordering_changed and i < (int )(new_weight.
get_dimension());
884 ordering_changed = ordering_changed or (new_weight[i] != w[i]);
886 cout <<
"ordering changed? " << ordering_changed << endl;
DEG_TYPE total_degree(NVAR_TYPE m=0) const
Sum of exponents of the first m variables.
The general class of a polynomial.
ray ray_sum(const set< ray > &rs)
Add all the rays in a set.
void SelectMonomial(Abstract_Polynomial *r, list< Monomial > &CurrentLPPs, Dense_Univariate_Integer_Polynomial **current_hilbert_numerator, const list< Abstract_Polynomial *> &CurrentPolys, const list< Critical_Pair_Dynamic *> &crit_pairs, LP_Solver *currSkel, bool &ordering_changed, DynamicHeuristic method)
Selects a leading power product for a polynomial.
MPZCOEF_TYPE numerator(DEG_TYPE k) const
returns the th numerator
const Monomial_Ideal & getIdeal() const
the old ideal of leading monomials
DEG_TYPE weighted_degree(const WT_TYPE *weights, NVAR_TYPE m=0) const
int howManyNewPairs() const
estimate of the number of new critical pairs generated by adding the monomial to the ideal ...
approximate skeleton of a polyhedral cone, using PPL linear solver
virtual Polynomial_Iterator * new_iterator() const =0
An iterator that poses no risk of modifying the polynomial.
virtual void moveRight()=0
Moves right in the polynomial, to the next smaller monomial.
bool is_zero() const
indicates whether the polynomial is zero
int getDifferenceInDegree()
computes the difference in degree between the first and last monomials of the ideal ...
int num_new_pairs
estimate of number of new pairs
NVAR_TYPE number_of_variables() const
number of variables in each Monomial
const list< Critical_Pair_Dynamic * > & pairs
the list of critical pairs of at this point in the algorithm
const map< DEG_TYPE, unsigned long > & getIncBetti(bool graded=false)
the incremental Betti numbers obtained by adding the monomial to the ideal
Dense_Univariate_Rational_Polynomial * getHilbertPolynomial()
the Hilbert polynomial obtained by adding the monomial to the ideal
unsigned size() const
number of generators
virtual const set< ray > & get_rays()
Returns the rays that define the skeleton.
virtual Monomial & leading_monomial() const =0
leading monomial – call after sort_by_order()!
Monomial_Ideal I
the ideal of leading terms
Controls the creation of s-polynomials, specialized for the dynamic algorithm.
approximate skeleton of a polyhedral cone, using GLPK linear solver
quick-’n-dirty Dense_Univariate integer polynomial class
inline ::ray getOrdering()
the current monomial ordering
skeleton of a polyhedral cone, with methods allowing definition and refinement
int min_deg
minimum weighted degree of monomials in ideal
void compatiblePP(Monomial currentLPP, const set< Monomial > &allPPs, const set<::ray > &bndrys, set< Monomial > &result, set< Monomial > &boundary_mons, LP_Solver *skel)
exact or approximate polyhedral cone solution, with methods allowing definition and refinement ...
NVAR_TYPE num_vars() const
number of variables
Dense_Univariate_Integer_Polynomial * getHilbertNumerator(bool graded=false)
the Hilbert numerator obtained by adding the monomial to the ideal (numerator is not reduced) ...
virtual bool fellOff() const =0
virtual bool makes_consistent_constraint(const Monomial &t, const Monomial &u, bool show_data=false)
tests for consistency of a constraint generated by two monomials.
Implementation of monomials.
bool verifyAndModifyIfNecessary(LP_Solver *skel, const list< Abstract_Polynomial *> ¤tPolys)
bool is_coprime(const Monomial &other) const
true iff this has no common factor with other.
NVAR_TYPE get_dimension() const
Returns the dimension of this ray.
int hilbertCmp(const Dense_Univariate_Integer_Polynomial &hn1, const Dense_Univariate_Rational_Polynomial &hp1, const Dense_Univariate_Integer_Polynomial &hn2, const Dense_Univariate_Rational_Polynomial &hp2)
Monomial lcm(const Monomial &u) const
Least common multiple: largest exponents.
const EXP_TYPE * log() const
Direct access to the exponents, for whatever reason.
const Monomial & getPP() const
the leading monomial being added to the ideal
void computeNumberNewPairs()
Computes the number of critical pairs the monomial would add.
const list< Monomial > & generators() const
returns the list of generators
Used to iterate through a polynomial.
DEG_TYPE degree() const
the polynomial’s degree (exponent of largest nonzero term)
void ConstraintsForNewPP(const PPWithIdeal &I, const set< Monomial > &monomialsForComparison, vector< constraint > &result)
virtual const Monomial & currMonomial() const =0
Reports the monomial at the current position.
quick-’n-dirty Dense_Univariate rational polynomial class
Monomial t
the last monomial added to
bool is_like(const Monomial &other) const
Have same variables, same powers? Synonymous with operator==().
DEG_TYPE degree() const
returns the polynomial’s degree
virtual bool solve(constraint &)=0
Adds the indicated constraint (singular!) and re-computes the solution.
void simplify_ray()
Simplifies the ray by dividing its components by the least common denominator.
const RAYENT_TYPE * weights() const
Returns the weights.
a ray defined by nonnegative coordinates