Gröbner basis project
Codebase for research into Gröbner basis computation
critical_pair.cpp
1 #ifndef __CRITICAL_PAIR_CPP_
2 #define __CRITICAL_PAIR_CPP_
3 
4 /*****************************************************************************\
5 * This file is part of DynGB. *
6 * *
7 * DynGB is free software: you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation, either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * Foobar is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with DynGB. If not, see <http://www.gnu.org/licenses/>. *
19 \*****************************************************************************/
20 
21 #include "critical_pair.hpp"
22 
23 #include "polynomial.hpp"
24 #include "strategies.hpp"
25 #include "sugar_strategy.hpp"
26 #include "weighted_sugar_strategy.hpp"
27 #include "particular_orderings.hpp"
28 
29 ostream & operator<<(ostream & os, const Critical_Pair_Basic & p) {
30  os << "(";
31  p.p->leading_monomial().print(false, os, p.p->base_ring().name_list());
32  os << ',';
33  if (p.q == nullptr) cout << 0;
34  else p.q->leading_monomial().print(false, os, p.q->base_ring().name_list());
35  os << ';';
36  p.tpq.print(false, os, p.p->base_ring().name_list());
37  os << ')';
38  return os;
39 }
40 
41 ostream & operator<<(ostream & os, const Critical_Pair_Dynamic & p) {
42  os << static_cast<const Critical_Pair_Basic &>(p);
43  os << p.ordering;
44  return os;
45 }
46 
49  StrategyFlags strategy
50 ) : tpq(f->leading_monomial()), p(f), q(nullptr), s(nullptr),
51  tp(tpq.num_vars()), tq(tpq.num_vars())
52 {
56  switch(strategy) {
57  case StrategyFlags::NORMAL_STRATEGY:
58  key = new Normal_Strategy(*this);
59  break;
60  case StrategyFlags::SUGAR_STRATEGY :
61  key = new Pair_Sugar_Data(*this);
62  break;
63  case StrategyFlags::WSUGAR_STRATEGY:
64  key = new Pair_WSugar_Strategy(*this);
65  break;
66  default: key = new Normal_Strategy(*this); break;
67  }
68 }
69 
73  StrategyFlags strategy
74 ) : tpq(f->leading_monomial().lcm(g->leading_monomial())),
75  p((f->leading_monomial().larger_than(g->leading_monomial())) ? f : g ),
76  q((f->leading_monomial().larger_than(g->leading_monomial())) ? g : f ),
77  s(nullptr),
78  tp(tpq),
79  tq(tpq)
80 {
84  tp /= p->leading_monomial();
85  tq /= q->leading_monomial();
86  switch(strategy) {
87  case StrategyFlags::NORMAL_STRATEGY:
88  key = new Normal_Strategy(*this);
89  break;
90  case StrategyFlags::SUGAR_STRATEGY :
91  key = new Pair_Sugar_Data(*this);
92  break;
93  case StrategyFlags::WSUGAR_STRATEGY:
94  key = new Pair_WSugar_Strategy(*this);
95  break;
96  default: key = new Normal_Strategy(*this); break;
97  }
98 }
99 
101  SPolyCreationFlags method, StrategyFlags strategy
102 ) {
103  if (s != nullptr) return s;
104  if (key != nullptr) key->pre_spolynomial_tasks();
105  // create multiple of first() according to the indicated method
106  switch (method) {
107  case SPolyCreationFlags::LINKED_LST:
108  s = new Polynomial_Linked_List(*p);
109  break;
110  case SPolyCreationFlags::GEOBUCKETS:
111  s = new Polynomial_Geobucket(*p);
112  break;
113  case SPolyCreationFlags::DOUBLE_BUF:
114  s = new Double_Buffered_Polynomial(*p);
115  break;
116  default:
117  s = new Polynomial_Geobucket(*p);
118  break;
119  }
120  //cout << "s-poly: " << *s << endl;
121  switch(strategy) {
122  case StrategyFlags::NORMAL_STRATEGY:
123  break; /* nothing to do */
124  case StrategyFlags::SUGAR_STRATEGY :
125  s->set_strategy(new Poly_Sugar_Data(s)); break;
126  case StrategyFlags::WSUGAR_STRATEGY: {
127  Poly_WSugar_Data * sd = static_cast<Poly_WSugar_Data *>(p->strategy());
128  const WT_TYPE * w;
129  if (sd == nullptr) w = nullptr;
130  else
131  w = (static_cast<const Weighted_Ordering *>(p->monomial_ordering()))
132  ->order_weights();
133  s->set_strategy(new Poly_WSugar_Data(s, w));
134  break;
135  }
136  default: break; /* default to normal strategy */
137  }
138  if (s->strategy() != nullptr) { s->strategy()->at_generation_tasks(tp); }
140  //cout << "after multiply by monomial " << tp << " : " << *s << endl;
141  if (q != nullptr) {
143  if (not q->leading_coefficient().is_one())
145  if (s->strategy() != nullptr) { s->strategy()->pre_reduction_tasks(tq, *q); }
146  s->add_polynomial_multiple(a, tq, *q, true);
147  }
148  //cout << "after adding other poly: " << *s << endl;
149  return s;
150 }
151 
153  SPolyCreationFlags method, StrategyFlags strategy
154 ) {
155  if (s != nullptr) return s;
156  if (p->monomial_ordering() != ordering)
157  p->set_monomial_ordering(ordering);
158  if (q != nullptr and q->monomial_ordering() != ordering)
159  q->set_monomial_ordering(ordering);
160  switch(strategy) {
161  case StrategyFlags::NORMAL_STRATEGY: break; /* nothing to do */
162  case StrategyFlags::SUGAR_STRATEGY: break; /* nothing to do? */
163  case StrategyFlags::WSUGAR_STRATEGY: {
164  if (p->strategy() == nullptr)
165  p->set_strategy(new Poly_WSugar_Data(p, ordering->order_weights()));
166  else {
167  Poly_WSugar_Data * sd = static_cast<Poly_WSugar_Data *>(p->strategy());
168  sd->change_weights(ordering->order_weights());
169  }
170  if (q != nullptr and q->strategy() == nullptr)
171  q->set_strategy(new Poly_WSugar_Data(q, ordering->order_weights()));
172  else if (q != nullptr) {
173  Poly_WSugar_Data * sd = static_cast<Poly_WSugar_Data *>(q->strategy());
174  sd->change_weights(ordering->order_weights());
175  }
176  }
177  default: break; /* default to normal strategy */
178  }
179  return Critical_Pair_Basic::s_polynomial(method, strategy);
180 };
181 
182 #endif
The general class of a polynomial.
Definition: polynomial.hpp:101
Implementation of geobuckets.
const Monomial_Ordering * monomial_ordering() const
reports leading monomial’s monomial ordering
Definition: polynomial.hpp:130
Critical_Pair_Basic(Abstract_Polynomial *f, StrategyFlags strategy)
create critical pair (f,0) for initial polynomial
Monomial tq
monomial multiple of that produces -polynomial
virtual void pre_spolynomial_tasks() const
hook called immediately before computing a new s-polynomiald
Definition: strategies.cpp:74
Mutable_Polynomial * s
S-polynomial.
ordering critical pairs using the weighted sugar strategy
void set_monomial_ordering(const Monomial_Ordering *mord)
sets the Monomial_Ordering associated with this Monomial
Definition: monomial.cpp:211
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
Controls the creation of s-polynomials, specialized for the dynamic algorithm.
Monomial tpq
lcm of leading monomials of and
ordering critical pairs using the sugar strategy
Abstract_Polynomial * q
second polynomial in the critical pair
void print(bool=true, ostream &=cout, const string *names=nullptr) const
prints the monomial to the give stream with the given names; adds a newline if the boolean is true ...
Definition: monomial.cpp:439
virtual void at_generation_tasks()
hook called while first generating polynomial
Definition: strategies.hpp:88
StrategyFlags
flag indicating which strategy to use for computation
Definition: strategies.hpp:34
SPolyCreationFlags
flag indicating which structure to use for an s-polynomial
virtual void multiply_by_monomial(const Monomial &t)
multiply by monomial
Definition: polynomial.cpp:75
Polynomials that need arithmetic typically descend from this class.
Definition: polynomial.hpp:305
Weighted_Ordering * ordering
the Monomial_Ordering assigned to this pair — might disagree with that of polynomials; they must be ...
polynomial-related data for a weighted sugar strategy
Element of a field of prime characteristic.
Definition: fields.hpp:137
bool is_one() const
Is this the multiplicative identity?
Definition: fields.cpp:88
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
virtual Mutable_Polynomial * s_polynomial()
to use only if s-polynomial is already computed by another method
virtual void multiply_by_scalar(const Prime_Field_Element &a)
multiply by scalar
Definition: polynomial.cpp:65
ordering critical pairs using the normal strategy
void change_weights(const WT_TYPE *w)
changes the weights used to compute the sugar to w
Pair_Strategy_Data * key
strategy used to sort critical pairs
interface to a weighted monomial ordering
virtual void add_polynomial_multiple(const Prime_Field_Element &, const Monomial &, const Abstract_Polynomial &, bool subtract=false)=0
add monomial multiple of other
void set_strategy(Poly_Strategy_Data *psd)
sets the polynomial’s strategy to psd
Definition: polynomial.cpp:36
Polynomials represented as a doubly linked list.
virtual const string * name_list() const
names of all the variabiles
Polynomials implemented using double buffers.A double-buffered polynomial maintains at all times two ...
Controls the creation of s-polynomials.
Polynomial_Ring & base_ring() const
ring in which this polynomial resides
Definition: polynomial.cpp:25
Monomial tp
monomial multiple of that produces -polynomial
Abstract_Polynomial * p
first polynomial in the critical pair
virtual Poly_Strategy_Data * strategy() const
strategy related information
Definition: polynomial.hpp:144