1 #ifndef __HILBERT_FUNCTIONS_CPP_ 2 #define __HILBERT_FUNCTIONS_CPP_ 28 using std::set;
using std::list;
using std::vector;
30 #include "system_constants.hpp" 33 #include "monomial.hpp" 34 #include "polynomial_linked_list.hpp" 36 #include "hilbert_functions.hpp" 39 const list<Monomial> &,
47 bool * d =
new bool [n] {
false};
50 for (NVAR_TYPE k = 0; result and k < n; ++k) {
52 if (found) { result =
false; }
55 if (d[k]) { result =
false; }
66 const list<Monomial> & T,
67 const WT_TYPE * grading
69 DEG_TYPE n = T.front().weighted_degree(grading) + 1;
79 const list<Monomial> & T,
80 const WT_TYPE * grading
82 DEG_TYPE n = T.front().weighted_degree(grading) + 1;
84 list<Monomial>::const_iterator ti = T.begin();
85 for (++ti; ti != T.end(); ++ti)
87 n += ti->weighted_degree(grading);
88 if (ti->weighted_degree(grading) + 1 > d)
89 d = ti->weighted_degree(grading) + 1;
97 for (ti = T.begin(); ti != T.end(); ++ti) {
107 list<Monomial>::const_iterator result = T.end();
109 list<Monomial>::const_iterator ti = T.begin();
110 (result != T.end()) and ti != T.end();
115 if (not u.is_like(*ti))
124 const list<Monomial> & T, list<Monomial>::const_iterator ui,
125 const WT_TYPE * grading
136 bool found_index =
false;
138 for ( ; not found_index and j < u.num_vars(); ++j)
139 if (u.degree(j) != 0)
142 DEG_TYPE e = (u.degree(j) > p.
degree(j)) ?
143 u.degree(j) - p.
degree(j) : 0;
144 d += (grading ==
nullptr) ? e : grading[j] * e;
152 fac->set_coefficient(0, 1);
157 for (; k < u.num_vars() and u.degree(k) == 0; ++k) {
161 if (grading ==
nullptr) {
162 fac->set_coefficient(u.degree(k) - p.
degree(k), -1);
164 fac->set_coefficient(u.degree(k) - p.
degree(k), 0);
166 WT_TYPE d = grading[k];
167 fac->set_coefficient(d*(u.degree(k) - p.
degree(k)), -1);
169 fac->set_coefficient(d*(u.degree(k) - p.
degree(k)), 0);
181 list<Monomial>::const_iterator result = T.end();
183 list<Monomial>::const_iterator ti = T.begin();
184 result == T.end() and ti != T.end();
188 bool relprime =
true;
190 list<Monomial>::const_iterator ui = T.begin();
191 relprime and ui != T.end();
195 relprime = ti->is_coprime(*ui);
204 const list<Monomial> & T, list<Monomial>::const_iterator ui,
205 const WT_TYPE * grading
208 for (list<Monomial>::const_iterator ti = T.begin(); ti != T.end(); ++ti)
221 NVAR_TYPE n = T.front().num_vars();
222 unsigned * xcount =
new unsigned [n] {0};
224 for (NVAR_TYPE k = 0; k < n; ++k)
225 if (t.degree(k) != 0)
228 for (NVAR_TYPE k = 1; k < n; ++k)
229 if (xcount[k] > xcount[i])
232 unsigned * td =
new unsigned [T.size()];
235 if (t.degree(i) != 0)
236 td[j++] = t.degree(i);
238 std::sort(td, td + m);
239 j = (m == 2) ? 0 : m / 2;
247 const list<Monomial> & T,
const WT_TYPE * grading
249 bool verbose =
false;
252 for (
const Monomial & t : T) cout << t <<
" ,";
254 if (grading !=
nullptr) {
256 for (NVAR_TYPE i = 0; i < T.front().num_vars(); ++i)
257 cout << grading[i] <<
", ";
263 list<Monomial>::const_iterator ti;
265 result = solve_one_monomial_case(T, grading);
274 if (verbose) cout <<
"pivot = " << p << endl;
277 while (p.
degree(pi) == 0) { ++pi; }
280 if (not t.divisible_by(p))
287 for (
const Monomial & u : U) cout << u <<
" ,";
292 for (
const Monomial & v : V) cout << v <<
" ,";
296 if (verbose) cout <<
"result from V: " << *result << endl;
300 if (verbose) cout <<
"result from U: " << *other << endl;
310 const WT_TYPE * grading
315 if (grading ==
nullptr) {
318 for (; r == 0 and i < n; ++i) {
322 for (DEG_TYPE j = hn->
degree(); j != 0; --j) {
323 COEF_TYPE b = hn->
coeff(j - 1);
327 if ((r = hn->
coeff(0)) != 0) {
332 for (
unsigned j = 0; j < hn->
degree(); ++j)
340 WT_TYPE curr_grad = grading[0];
341 NVAR_TYPE curr_grad_index = 0;
342 for (
unsigned k = 1; k < n; ++k)
343 if (grading[k] > curr_grad) {
344 curr_grad = grading[k];
348 for (NVAR_TYPE i = 1; hn->
degree() != 0 and i < n; ++i) {
353 for (DEG_TYPE j = hn->
degree(); j > curr_grad - 1; --j) {
354 COEF_TYPE a = hn->
coeff(j);
363 delete tmp;
delete hn;
367 WT_TYPE tmp_grad = grading[0];
368 NVAR_TYPE tmp_grad_index = 0;
369 bool searching =
true;
370 for (
unsigned k = 0; searching and k < n; ++k) {
371 if (grading[k] == curr_grad and k > curr_grad_index) {
375 else if (grading[k] > tmp_grad and grading[k] < curr_grad)
377 tmp_grad = grading[k];
381 curr_grad = tmp_grad;
382 curr_grad_index = tmp_grad_index;
397 COEF_TYPE a, COEF_TYPE b
411 for (
unsigned i = 1; i < b; ++i) {
427 unsigned int pole_order,
428 const list<Monomial> T,
432 bool own_hn1 =
false;
433 bool own_hn2 =
false;
442 if (hn2 ==
nullptr) {
450 if (pole_order != 0) {
451 DEG_TYPE d = hn2->
degree();
452 COEF_TYPE d1 = pole_order - 1;
453 for (DEG_TYPE i = 0; i <= d; ++i) {
462 if (pole_order % 2 != n % 2)
464 if (own_hn1)
delete hn;
465 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
DEG_TYPE weighted_degree(const WT_TYPE *weights, NVAR_TYPE m=0) const
void multiply_by_monomial_of_degree(DEG_TYPE)
a hopefully efficient multiplication algorithm
Dense_Univariate_Rational_Polynomial * polynomial_binomial(long long a, long long b)
computes the number of combinations
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_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() const
returns True if and only if every valid coefficient is zero
bool is_zero_base_case(const list< Monomial > &T)
test for the 0-base case