1 #ifndef __HILBERT_FUNCTIONS_CPP_ 2 #define __HILBERT_FUNCTIONS_CPP_ 11 using std::set;
using std::list;
using std::vector;
13 #include "system_constants.hpp" 16 #include "monomial.hpp" 17 #include "polynomial_linked_list.hpp" 19 #include "hilbert_functions.hpp" 22 const list<Monomial> &,
30 bool * d =
new bool [n] {
false};
33 for (NVAR_TYPE k = 0; result and k < n; ++k) {
35 if (found) { result =
false; }
38 if (d[k]) { result =
false; }
49 const list<Monomial> & T
51 DEG_TYPE n = T.front().total_degree() + 1;
61 const list<Monomial> & T
63 DEG_TYPE n = T.front().total_degree() + 1;
65 list<Monomial>::const_iterator ti = T.begin();
66 for (++ti; ti != T.end(); ++ti)
68 n += ti->total_degree();
69 if (ti->total_degree() + 1 > d)
70 d = ti->total_degree() + 1;
78 for (ti = T.begin(); ti != T.end(); ++ti) {
88 list<Monomial>::const_iterator result = T.end();
90 list<Monomial>::const_iterator ti = T.begin();
91 (result != T.end()) and ti != T.end();
96 if (not u.is_like(*ti))
105 const list<Monomial> & T, list<Monomial>::const_iterator ui
116 bool found_index =
false;
118 for ( ; not found_index and j < u.num_vars(); ++j)
119 if (u.degree(j) != 0)
122 DEG_TYPE e = (u.degree(j) > p.
degree(j)) ?
123 u.degree(j) - p.
degree(j) : 0;
132 fac->set_coefficient(0, 1);
137 for (; k < u.num_vars() and u.degree(k) == 0; ++k) {
141 fac->set_coefficient(u.degree(k) - p.
degree(k), -1);
143 fac->set_coefficient(u.degree(k) - p.
degree(k), 0);
154 list<Monomial>::const_iterator result = T.end();
156 list<Monomial>::const_iterator ti = T.begin();
157 result == T.end() and ti != T.end();
161 bool relprime =
true;
163 list<Monomial>::const_iterator ui = T.begin();
164 relprime and ui != T.end();
168 relprime = ti->is_coprime(*ui);
177 const list<Monomial> & T, list<Monomial>::const_iterator ui
180 for (list<Monomial>::const_iterator ti = T.begin(); ti != T.end(); ++ti)
193 NVAR_TYPE n = T.front().num_vars();
194 unsigned * xcount =
new unsigned [n] {0};
196 for (NVAR_TYPE k = 0; k < n; ++k)
197 if (t.degree(k) != 0)
200 for (NVAR_TYPE k = 1; k < n; ++k)
201 if (xcount[k] > xcount[i])
204 unsigned * td =
new unsigned [T.size()];
207 if (t.degree(i) != 0)
208 td[j++] = t.degree(i);
210 std::sort(td, td + m);
211 j = (m == 2) ? 0 : m / 2;
219 const list<Monomial> & T,
const WT_TYPE * grading
221 bool verbose =
false;
224 for (
const Monomial & t : T) cout << t <<
" ,";
229 list<Monomial>::const_iterator ti;
231 result = solve_one_monomial_case(T);
240 if (verbose) cout <<
"pivot = " << p << endl;
243 while (p.
degree(pi) == 0) { ++pi; }
246 if (not t.divisible_by(p))
253 for (
const Monomial & u : U) cout << u <<
" ,";
278 for (
const Monomial & v : V) cout << v <<
" ,";
282 if (verbose) cout <<
"result from V: " << *result << endl;
286 if (verbose) cout <<
"result from U: " << *other << endl;
296 const WT_TYPE * grading
303 for (; r == 0 and i < n; ++i) {
307 for (
unsigned j = hn->
degree() - 1; j < hn->
degree(); --j) {
308 COEF_TYPE b = hn->
coeff(j);
312 if ((r = hn->
coeff(0)) != 0) {
317 for (
unsigned j = 0; j < hn->
degree(); ++j)
334 COEF_TYPE a, COEF_TYPE b
348 for (
unsigned i = 1; i < b; ++i) {
364 unsigned int pole_order,
365 const list<Monomial> T,
369 bool own_hn1 =
false;
370 bool own_hn2 =
false;
387 if (pole_order != 0) {
388 DEG_TYPE d = hn2->
degree();
389 COEF_TYPE d1 = pole_order - 1;
390 for (DEG_TYPE i = 0; i <= d; ++i) {
399 if (pole_order % 2 != n % 2)
401 if (own_hn1)
delete hn;
402 if (own_hn2)
delete hn2;
DEG_TYPE total_degree(NVAR_TYPE m=0) const
Sum of exponents of the first m variables.
void set_coefficient(DEG_TYPE k, COEF_TYPE a)
set the coefficient of to
list< Monomial >::const_iterator is_one_base_case(const list< Monomial > &T)
test for the 1-base case
void negate()
negates the coefficients
void set_coefficient(DEG_TYPE k, long a, unsigned long b)
set the coefficient of to
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
void multiply_by(const Dense_Univariate_Rational_Polynomial &)
highly inefficient polynomial multiplication ( )
list< Monomial >::const_iterator is_splitting_case(const list< Monomial > &T)
test for the “splitting case”
Dense_Univariate_Rational_Polynomial * polynomial_binomial(long long a, long long b)
computes the number of combinations
Dense_Univariate_Integer_Polynomial * solve_one_base_case(const list< Monomial > &T, list< Monomial >::const_iterator ui, const WT_TYPE *grading)
applies Bigatti’s algorithm for the 1-base case
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 )
void set_exponent(NVAR_TYPE i, DEG_TYPE e)
change th exponent to
void negate()
negates the numerators
COEF_TYPE coeff(DEG_TYPE k) const
the th coefficient
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
void multiply_by(const Dense_Univariate_Integer_Polynomial &)
highly inefficient polynomial multiplication ( )
NVAR_TYPE num_vars() const
number of variables
Dense_Univariate_Integer_Polynomial * solve_zero_base_case(const list< Monomial > &T, const WT_TYPE *grading)
computes Hilbert numerator when the 0-base case applies
Implementation of monomials.
DEG_TYPE degree(NVAR_TYPE i) const
Degree of th variable.
Monomial choose_hilbert_pivot(const list< Monomial > &T)
chooses a pivot for the Bigatti algorithm
void add(const Dense_Univariate_Integer_Polynomial &q)
reasonably efficient, given our dense representation
DEG_TYPE degree() const
the polynomial’s degree (exponent of largest nonzero term)
void scale_by(COEF_TYPE a)
multiplies every monomial by a constant integer
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's generators. No monomial ideal machinery required.
Dense_Univariate_Integer_Polynomial * solve_splitting_case(const list< Monomial > &T, list< Monomial >::const_iterator ui, const WT_TYPE *grading)
applies Bigatti’s algorithm for the 1-base case
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
bool is_zero_base_case(const list< Monomial > &T)
test for the 0-base case