Gröbner basis project
Codebase for research into Gröbner basis computation
monomial_ideal.hpp
1 #ifndef __MONOMIAL_IDEAL_HPP_
2 #define __MONOMIAL_IDEAL_HPP_
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 <cstddef>
22 #include <iostream>
23 using std::cout; using std::endl;
24 #include <map>
25 using std::map;
26 #include <list>
27 using std::list;
28 #include <vector>
29 using std::vector;
30 
31 #include "system_constants.hpp"
32 
33 #include "betti.hpp"
34 #include "monomial.hpp"
35 #include "hilbert_functions.hpp"
36 #include "polynomial.hpp"
37 #include "skeleton.hpp"
38 
46 class Monomial_Ideal_Variables_Exception : public std::exception {
47  virtual const char * what() const throw() {
48  return "Monomials in list for monomial ideal need same number of variables";
49  }
50 };
51 
63 list<Monomial> colon_ideal_without_ideals(
64  const list<Monomial> & U, const Monomial & t
65 );
66 
79 public:
81 
85  Monomial_Ideal(NVAR_TYPE nvars) {
86  n = nvars; hPol = nullptr;
87  hNum = hRedNum = hGradNum = hGradRedNum = nullptr;
88  current_grading = nullptr;
89  }
96  NVAR_TYPE nvars, const list<Monomial> & G,
97  const Dense_Univariate_Integer_Polynomial * h_old = nullptr,
98  const WT_TYPE * h_grading = nullptr
99  ) {
100  n = nvars;
101  for (const Monomial & g : G) {
102  if (g.num_vars() != n)
104  gens.push_back(g);
105  }
106  hPol = nullptr;
107  if (h_grading == nullptr) {
108  hNum = (h_old == nullptr) ? nullptr
110  hRedNum = hGradNum = hGradRedNum = nullptr;
111  } else {
112  hGradNum = (h_old == nullptr) ? nullptr
114  hNum = hRedNum = hGradRedNum = nullptr;
115  }
116  current_grading = h_grading;
117  }
124  NVAR_TYPE nvars, const vector<Monomial> & G,
125  const Dense_Univariate_Integer_Polynomial * h_old = nullptr,
126  const WT_TYPE * h_grading = nullptr
127  ) {
128  n = nvars;
129  for (const Monomial & g : G) {
130  if (g.num_vars() != n)
132  gens.push_back(g);
133  }
134  hPol = nullptr;
135  if (h_grading == nullptr) {
136  hNum = (h_old == nullptr) ? nullptr
138  hRedNum = hGradNum = hGradRedNum = nullptr;
139  } else {
140  hGradNum = (h_old == nullptr) ? nullptr
142  hNum = hRedNum = hGradRedNum = nullptr;
143  }
144  current_grading = h_grading;
145  }
148  : n(I.n), gens(I.gens)
149  {
150  hNum = (I.hNum == nullptr) ? nullptr
152  hRedNum = (I.hRedNum == nullptr) ? nullptr
154  hGradNum = (I.hGradNum == nullptr) ? nullptr
156  hGradRedNum = (I.hGradRedNum == nullptr) ? nullptr
158  hPol = (I.hPol == nullptr) ? nullptr
160  current_grading = I.current_grading;
161  }
163 
164 
169  if (hPol != nullptr) delete hPol;
170  if (hNum != nullptr) delete hNum;
171  if (hRedNum != nullptr) delete hRedNum;
172  if (hGradNum != nullptr) delete hGradNum;
173  if (hGradRedNum != nullptr) delete hGradRedNum;
174  }
176 
180 
182  NVAR_TYPE number_of_variables() const { return n; }
184  unsigned size() const { return gens.size(); }
186  const list<Monomial> & generators() const { return gens; }
190  unsigned dimension() {
191  return ideal_dimension(
192  number_of_variables(), hilbert_numerator(), reduced_hilbert_numerator()
193  );
194  }
198  const map<DEG_TYPE, unsigned long> & inc_betti(
199  const WT_TYPE * grading = nullptr
200  ) {
201  if (grading == nullptr) {
202  if (current_grading == nullptr and ibmap.size() > 0) {
203  // nothing to do
204  }
205  else {
206  ibmap = incremental_betti(gens, grading);
207  current_grading = nullptr;
208  }
209  } else {
210  if (current_grading == grading and ibmap.size() > 0) {
211  // nothing to do
212  } else{
213  ibmap = incremental_betti(gens, grading);
214  current_grading = grading;
215  }
216  }
217  return ibmap;
218  }
228  const WT_TYPE * grading = nullptr
229  ) {
231  if (grading == nullptr) {
232  if (hNum == nullptr)
233  hNum = hilbert_numerator_bigatti(gens);
234  else if (grading != current_grading) {
235  delete hNum;
236  hNum = hilbert_numerator_bigatti(gens);
237  }
238  result = hNum;
239  } else {
240  if (hGradNum == nullptr or grading != current_grading) {
241  if (grading != current_grading)
242  delete hGradNum;
243  hGradNum = hilbert_numerator_bigatti(gens, grading);
244  current_grading = grading;
245  }
246  result = hGradNum;
247  }
248  //cout << "Hilbert numerator requested: " << *result << endl;
249  return result;
250  }
260  const WT_TYPE * grading = nullptr
261  ) {
263  if (grading == nullptr) {
264  if (hRedNum == nullptr)
265  hRedNum = hilbert_second_numerator(
266  number_of_variables(), hilbert_numerator()
267  );
268  result = hRedNum;
269  } else {
270  if (hGradRedNum == nullptr or grading != current_grading) {
271  if (grading != current_grading)
272  delete hGradRedNum;
273  hGradRedNum = hilbert_second_numerator(
274  number_of_variables(), hilbert_numerator(grading)
275  );
276  current_grading = grading;
277  }
278  result = hGradRedNum;
279  }
280  //cout << "Hilbert reduced numerator requested: " << *result << endl;
281  return result;
282  }
292  if (hPol == nullptr) {
293  hPol = hilbert_polynomial(
294  number_of_variables(),
296  number_of_variables(),
297  hilbert_numerator(), reduced_hilbert_numerator()
298  ),
299  gens,
300  hilbert_numerator(),
301  reduced_hilbert_numerator()
302  );
303  }
304  /*cout << "Ideal of ";
305  for (auto t : gens) cout << t << ", ";
306  cout << endl;
307  cout << "Hilbert polynomial: " << *hPol << endl;*/
308  return hPol;
309  }
311 
312 
321  Monomial_Ideal * colon(const Monomial & t) const {
322  return new Monomial_Ideal(n, colon_ideal_without_ideals(gens, t));
323  }
331  void colon_with(const Monomial & t) {
332  if (t.num_vars() != n)
334  gens = colon_ideal_without_ideals(gens, t);
335  hNum = hRedNum = nullptr;
336  hPol = nullptr;
337  }
339 
340 
342  void add_generator(const Monomial & t) {
343  if (hNum != nullptr) {
345  Dense_Univariate_Integer_Polynomial * hn_new = J.hilbert_numerator();
346  J.forget_hilbert_numerator();
348  hn_new->negate();
349  hn_new->add(*hNum);
350  delete hNum;
351  hNum = hn_new;
352  if (hRedNum != nullptr) delete hRedNum;
353  if (hPol != nullptr) delete hPol;
354  }
355  gens.push_back(t);
356  }
358  void remove_newest() { gens.pop_back(); }
360  void forget_hilbert_numerator() { hNum = nullptr; }
363  hNum = h;
364  }
366 
367  friend ostream & operator << (ostream &, const Monomial_Ideal &);
370 protected:
372  NVAR_TYPE n;
374  list<Monomial> gens;
376  map<DEG_TYPE, unsigned long> ibmap;
393  const WT_TYPE * current_grading;
394 };
395 
396 #endif
const map< DEG_TYPE, unsigned long > & inc_betti(const WT_TYPE *grading=nullptr)
incremental Betti numbers when adding the last Monomial in this ideal
Monomial_Ideal(NVAR_TYPE nvars, const vector< Monomial > &G, const Dense_Univariate_Integer_Polynomial *h_old=nullptr, const WT_TYPE *h_grading=nullptr)
Copies basis. If you supply a Hilbert function that is not computed according to the standard grading...
DEG_TYPE total_degree(NVAR_TYPE m=0) const
Sum of exponents of the first m variables.
Definition: monomial.cpp:190
Dense_Univariate_Integer_Polynomial * hGradNum
the ideal&#39;s Hilbert numerator, according to current_grading
A class for monomial ideals.
void multiply_by_monomial_of_degree(DEG_TYPE)
a hopefully efficient multiplication algorithm
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
map< DEG_TYPE, unsigned long > ibmap
the ideal&#39;s incremental Betti numbers
Dense_Univariate_Rational_Polynomial * hPol
the ideal&#39;s Hilbert polynomial – standard grading only
NVAR_TYPE number_of_variables() const
number of variables in each Monomial
const WT_TYPE * current_grading
the most recent grading for the Hilbert functions; nullptr implies standard grading ...
void remove_newest()
removes the newest monomial from the basis
unsigned size() const
number of generators
Dense_Univariate_Integer_Polynomial * hRedNum
the ideal&#39;s reduced Hilbert numerator, standard grading
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 )
~Monomial_Ideal()
destroys the Hilbert data, but not the grading.
Monomial_Ideal * colon(const Monomial &t) const
returns the ideal , where is this
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
map< DEG_TYPE, unsigned long > incremental_betti(const list< Monomial > &T, const WT_TYPE *grading)
Incremental Betti numbers for monomial ideals.
Definition: betti.cpp:30
Dense_Univariate_Integer_Polynomial * hNum
the ideal&#39;s Hilbert numerator, standard grading
Dense_Univariate_Rational_Polynomial * hilbert_poly()
Dense_Univariate_Integer_Polynomial * hilbert_numerator(const WT_TYPE *grading=nullptr)
NVAR_TYPE n
number of variables the monomials of this ideal have
NVAR_TYPE num_vars() const
number of variables
Definition: monomial.hpp:130
list< Monomial > gens
the ideal&#39;s generators
Implementation of monomials.
Definition: monomial.hpp:69
unsigned dimension()
returns the dimension of the ideal
void forget_hilbert_numerator()
sets numerator to nullptr
void add_generator(const Monomial &t)
adds t to the basis
Dense_Univariate_Integer_Polynomial * hGradRedNum
the ideal&#39;s reduced Hilbert numerator, according to current_grading
void colon_with(const Monomial &t)
replaces the generators of this with those of the ideal , where is this
Monomial_Ideal(NVAR_TYPE nvars)
Creates a zero ideal.
Monomial_Ideal(NVAR_TYPE nvars, const list< Monomial > &G, const Dense_Univariate_Integer_Polynomial *h_old=nullptr, const WT_TYPE *h_grading=nullptr)
Copies basis. If you supply a Hilbert function that is not computed according to the standard grading...
void set_hilbert_numerator(Dense_Univariate_Integer_Polynomial *h)
sets numerator to given value; only use when you know this is true!
const list< Monomial > & generators() const
returns the list of generators
quick-’n-dirty Dense_Univariate rational polynomial class
list< Monomial > colon_ideal_without_ideals(const list< Monomial > &U, const Monomial &t)
Computes the generators of an ideal and a new generator, given the ideal&#39;s generators. No monomial ideal machinery required.
Monomial_Ideal(const Monomial_Ideal &I)
copy constructor
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
exceptions for Monomial Ideals
Dense_Univariate_Integer_Polynomial * reduced_hilbert_numerator(const WT_TYPE *grading=nullptr)
the reduced Hilbert Numerator