1 #ifndef __ALGORITHM_BUCHBERGER_DYNAMIC_CPP_ 2 #define __ALGORITHM_BUCHBERGER_DYNAMIC_CPP_ 21 #include "system_constants.hpp" 23 #include "algorithm_buchberger_basic.hpp" 24 #include "algorithm_buchberger_dynamic.hpp" 26 #include "skeleton.hpp" 27 #include "dynamic_engine.hpp" 28 #include "particular_orderings.hpp" 29 #include "reduction_support.hpp" 33 #define ORDERING_TYPE WGrevlex 37 const list<Abstract_Polynomial *>G
43 bool very_verbose =
false;
47 if (very_verbose) s->println();
48 if ((g =
find_reducer<list<Abstract_Polynomial *>>(s, G))) {
50 if (very_verbose) { cout <<
"\tyes! by "; g->println(); }
61 s->
strategy()->pre_reduction_tasks(t, *g);
64 cout <<
"\tresults in ";
70 if (verbose and not s->
is_zero())
73 if (verbose or very_verbose) cout <<
"no!\n";
100 list<Critical_Pair_Dynamic *> & P,
101 list<Abstract_Polynomial *> & G,
104 ORDERING_TYPE * ordering
107 list<Critical_Pair_Dynamic *> C;
112 list<Critical_Pair_Dynamic *> D;
113 while (C.size() != 0) {
127 list<Critical_Pair_Dynamic *> E;
128 while (D.size() != 0) {
140 list<Critical_Pair_Dynamic *> Q;
141 while (P.size() != 0) {
166 bool none_others_divide(
const list<Monomial> & U,
const Monomial & t) {
169 if (not u.is_like(t) and u | t) {
177 list<list<Monomial>> recursive_select(list<list<Monomial>> & Ms) {
178 list<list<Monomial>> result;
179 if (Ms.size() == 0) {
185 auto lower = recursive_select(Ms);
187 if (none_others_divide(M, t)) {
188 for (
auto S : lower) {
191 result.push_back(tmp);
199 void initial_analysis(
200 const list<Abstract_Polynomial *> & F,
204 NVAR_TYPE n = (*F.begin())->leading_monomial().num_vars();
207 list<list<Monomial>> mons;
208 list<list<Monomial>> saved_mons;
221 for (
auto t : T) W.push_back(t);
223 saved_mons.push_back(W);
225 list<list<Monomial>> mon_chains = recursive_select(mons);
229 vector<constraint> all_constraints;
230 for (
auto M : mon_chains) {
232 list<Abstract_Polynomial *> G;
233 list<Critical_Pair_Dynamic *> P;
240 if (not (win_hn ==
nullptr or
hilbertCmp(*win_hn, *win_hp, *T_hn, *T_hp) > 0))
247 set<constraint> tmp_cnstr;
248 bool consistent =
true;
251 for (
auto N : saved_mons) {
254 while (consistent and fi != N.end()) {
256 for (NVAR_TYPE i = 0; i < n; ++i)
257 w[i] = t.
degree(i) - fi->degree(i);
259 consistent = tmp_lp->
solve(c);
260 if (consistent) tmp_cnstr.emplace(c);
270 all_constraints.clear();
271 for (
auto c : tmp_cnstr)
272 all_constraints.push_back(c);
273 if (win_hn !=
nullptr) {
282 solver->
solve(all_constraints);
283 cout <<
"prefer ordering with " << solver->
get_rays().size() <<
" rays: ";
285 cout << interior_ray << endl;
286 auto wt_ptr = interior_ray.
weights();
287 for (NVAR_TYPE i = 0; i < n; ++i) weights[i] = wt_ptr[i];
290 mord =
new ORDERING_TYPE(n, weights);
294 const list<Abstract_Polynomial *> &F,
297 WT_TYPE * strategy_weights,
302 unsigned number_of_spolys = 0;
303 list<Abstract_Polynomial *> G;
304 list<Critical_Pair_Dynamic *> P;
306 list<Monomial> currentLPPs;
308 NVAR_TYPE n = (*(F.begin()))->base_ring().number_of_variables();
309 WT_TYPE * weights =
new WT_TYPE [n];
310 for (NVAR_TYPE i = 0; i < n; ++i) weights[i] = 1;
311 ORDERING_TYPE * curr_ord =
new ORDERING_TYPE(n, weights);
312 list<ORDERING_TYPE *> all_orderings_used;
313 all_orderings_used.push_front(curr_ord);
314 const WT_TYPE * wt_ptr;
317 switch (solver_type) {
318 case SKELETON_SOLVER: solver =
new skeleton(n);
break;
319 case GLPK_SOLVER: solver =
new GLPK_Solver(n);
break;
320 case PPL_SOLVER: solver =
new PPL_Solver(n);
break;
321 default: solver =
new skeleton(n);
break;
328 case StrategyFlags::SUGAR_STRATEGY:
331 case StrategyFlags::WSUGAR_STRATEGY:
336 bool new_world_order =
false;
338 SelectMonomial(g, currentLPPs, &hNum, G, P, solver, new_world_order, heuristic);
341 if (new_world_order) {
342 weights =
new WT_TYPE [n];
343 cout <<
"new ordering from " << solver->
get_rays().size() <<
" rays: ";
345 cout << interior_ray << endl;
346 wt_ptr = interior_ray.
weights();
347 for (NVAR_TYPE i = 0; i < n; ++i) weights[i] = wt_ptr[i];
348 curr_ord =
new ORDERING_TYPE(n, weights);
349 all_orderings_used.push_front(curr_ord);
357 if (f != *(F.begin())) {
362 bool verbose =
false;
363 bool very_verbose =
false;
368 cout <<
"current ordering: " << *curr_ord << endl;
369 sort_pairs_by_strategy<Critical_Pair_Dynamic>(P);
373 report_front_pair(p, strategy);
387 cout <<
"\treduced to zero\n";
397 very_verbose =
false;
398 if (very_verbose) { cout <<
"\tadded "; r->println(); }
399 very_verbose =
false;
402 bool new_world_order =
false;
403 SelectMonomial(r, currentLPPs, &hNum, G, P, solver, new_world_order, heuristic);
404 if (new_world_order) {
405 cout <<
"new ordering from " << solver->
get_rays().size() <<
" rays: ";
407 cout << interior_ray << endl;
410 wt_ptr = interior_ray.
weights();
411 weights =
new WT_TYPE [n];
412 for (NVAR_TYPE i = 0; i < n; ++i) weights[i] = wt_ptr[i];
413 curr_ord =
new ORDERING_TYPE(n, weights);
415 all_orderings_used.push_front(curr_ord);
428 cout << number_of_spolys <<
" s-polynomials computed and reduced\n";
430 cout << G.size() <<
" polynomials before interreduction\n";
433 cout << G.size() <<
" polynomials after interreduction\n";
436 list<Constant_Polynomial *> B;
437 unsigned long num_mons = 0;
438 unsigned long max_mons = 0;
441 unsigned long glen = g->
length();
443 if (glen > max_mons) max_mons = glen;
449 cout <<
"tot # monomials: " << num_mons << endl;
450 cout <<
"max # monomials: " << max_mons << endl;
451 cout <<
"avg # monomials: " << num_mons / B.size() << endl;
453 all_orderings_used.pop_front();
455 while (all_orderings_used.size() != 0) {
456 ORDERING_TYPE * bye_bye_ordering = all_orderings_used.front();
457 all_orderings_used.pop_front();
458 delete [] bye_bye_ordering->order_weights();
459 delete bye_bye_ordering;
461 if (hNum !=
nullptr)
delete hNum;
The general class of a polynomial.
ray ray_sum(const set< ray > &rs)
Add all the rays in a set.
virtual bool is_zero() const =0
is this polynomial zero?
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.
const Monomial_Ordering * monomial_ordering() const
reports leading monomial’s monomial ordering
DEG_TYPE weighted_degree(const WT_TYPE *weights, NVAR_TYPE m=0) const
A Constant_Polynomial is a polynomial that should not change.
void change_ordering(Weighted_Ordering *new_order)
change the ordering associated with this pair
approximate skeleton of a polyhedral cone, using PPL linear solver
void reduce_over_basis_dynamic(Mutable_Polynomial **sp, const list< Abstract_Polynomial *>G)
Reduce the polynomial r over the basis G.
Dense_Univariate_Rational_Polynomial * hilbert_polynomial(NVAR_TYPE n, unsigned int pole_order, const list< Monomial > T, Dense_Univariate_Integer_Polynomial *hn, Dense_Univariate_Integer_Polynomial *hn2)
computes the Hilbert polynomial for an ideal
virtual void moveRight()=0
Moves right in the polynomial, to the next smaller monomial.
const Abstract_Polynomial * second() const
second polynomial in pair
virtual Mutable_Polynomial * s_polynomial(SPolyCreationFlags method, StrategyFlags strategy)
creates the s-polynomial for first() and second()
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()!
virtual Prime_Field_Element leading_coefficient() const =0
leading coefficient – call after sort_by_order()!
const Monomial & lcm() const
lcm of leading monomials of polynomials
virtual Mutable_Polynomial * zero_polynomial() const =0
zero polynomial of this type
Controls the creation of s-polynomials, specialized for the dynamic algorithm.
Dense_Univariate_Integer_Polynomial * hilbert_second_numerator(NVAR_TYPE n, Dense_Univariate_Integer_Polynomial *first, const WT_TYPE *grading)
computes the second Hilbert numerator (after reduction by )
approximate skeleton of a polyhedral cone, using GLPK linear solver
Dense_Univariate_Integer_Polynomial * hilbert_numerator_bigatti(const list< Monomial > &T, const WT_TYPE *grading)
the Bigatti algorithm to compute the Hilbert numerator
quick-’n-dirty Dense_Univariate integer polynomial class
StrategyFlags
flag indicating which strategy to use for computation
list< Abstract_Polynomial * > reduce_basis(list< Abstract_Polynomial *>G)
Remove redundant polynomials from G.
SPolyCreationFlags
flag indicating which structure to use for an s-polynomial
skeleton of a polyhedral cone, with methods allowing definition and refinement
virtual void add_last(const Prime_Field_Element &, const Monomial &)=0
Attach a new monomial to the tail – check that it belongs at tail!
void compatiblePP(Monomial currentLPP, const set< Monomial > &allPPs, const set<::ray > &bndrys, set< Monomial > &result, set< Monomial > &boundary_mons, LP_Solver *skel)
bool lcm_alike(const Monomial &t, const Monomial &u, const Critical_Pair_Basic *p)
Checks if the lcm of t and u is like the lcm stored in p.
exact or approximate polyhedral cone solution, with methods allowing definition and refinement ...
virtual bool fellOff() const =0
Polynomials that need arithmetic typically descend from this class.
const Abstract_Polynomial * first() const
first polynomial in pair
polynomial-related data for a weighted sugar strategy
Implementation of monomials.
Element of a field of prime characteristic.
interface to a monomial ordering
virtual Mutable_Polynomial * detach_head()=0
Remove and return the head.
virtual void set_monomial_ordering(const Monomial_Ordering *order, bool sort_anew=true)=0
set the monomial ordering and sort the polynomials (optionally, but by default)
polynomial-related data for a sugar strategy
bool is_coprime(const Monomial &other) const
true iff this has no common factor with other.
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)
DEG_TYPE degree(NVAR_TYPE i) const
Degree of th variable.
virtual void set_monomial_ordering(const Monomial_Ordering *order, bool sort_anew=true) override
sets the ordering of monomials in this polynomial
virtual void add_polynomial_multiple(const Prime_Field_Element &, const Monomial &, const Abstract_Polynomial &, bool subtract=false)=0
add monomial multiple of other
DynamicSolver
used by buchberger_dynamic() to decide which solver to use
void set_strategy(Poly_Strategy_Data *psd)
sets the polynomial’s strategy to psd
list< Constant_Polynomial * > buchberger_dynamic(const list< Abstract_Polynomial *> &F, SPolyCreationFlags method, StrategyFlags strategy, WT_TYPE *strategy_weights, DynamicHeuristic heuristic, DynamicSolver solver_type, bool analyze_inputs)
implementation of the dynamic Buchberger algorithm
Used to iterate through a polynomial.
void gm_update_dynamic(list< Critical_Pair_Dynamic *> &P, list< Abstract_Polynomial *> &G, Abstract_Polynomial *r, StrategyFlags strategy, ORDERING_TYPE *ordering)
implementation of Gebauer-Möller algorithm, adjusted for dynamic computation
virtual const Monomial & currMonomial() const =0
Reports the monomial at the current position.
bool no_triplet(const T *p, const list< T *>C)
Checks whether p is in danger of forming a Buchberger triple with some pair listed in C...
quick-’n-dirty Dense_Univariate rational polynomial class
bool is_like(const Monomial &other) const
Have same variables, same powers? Synonymous with operator==().
virtual bool solve(constraint &)=0
Adds the indicated constraint (singular!) and re-computes the solution.
void report_critical_pairs(const list< T *>P, bool verbose=false)
A brief report on the number of critical pairs. If verbose is true, also lists them.
unsigned ideal_dimension(NVAR_TYPE n, const Dense_Univariate_Integer_Polynomial *h1, const Dense_Univariate_Integer_Polynomial *h2)
computes the dimension of the ideal by subtracting the Hilbert numerators
const RAYENT_TYPE * weights() const
Returns the weights.
virtual unsigned length() const =0
number of monomials
virtual bool solve(constraint &)
Adds the indicated constraint (singular!) and re-computes the solution.
Abstract_Polynomial * find_reducer(Abstract_Polynomial *r, const T &G)
Find a polynomial in the basis G that can reduce r.
a ray defined by nonnegative coordinates
virtual Poly_Strategy_Data * strategy() const
strategy related information