Macaulay2 Engine
Loading...
Searching...
No Matches
hilb.cpp
Go to the documentation of this file.
1// Copyright 1996 Michael E. Stillman
2
3#include "hilb.hpp"
4
5#include <assert.h> // for assert
6#include <stdio.h> // for fprintf, stderr
7#include <algorithm> // for max, stable_sort
8#include <cstdlib> // for NULL, abort
9#include <limits> // for numeric_limits
10#include <utility> // for pair, make_pair
11#include <vector> // for vector
12
13#include "ExponentList.hpp" // for index_varpower, varpower, const_v...
14#include "ExponentVector.hpp" // for exponents
15#include "interface/m2-mem.h" // for freemem
16#include "buffer.hpp" // for buffer
17#include "error.h" // for ERROR
18#include "freemod.hpp" // for FreeModule
19#include "int-bag.hpp" // for Bag, int_bag
20#include "interrupted.hpp" // for system_interrupted
21#include "matrix.hpp" // for Matrix
22#include "mem.hpp" // for stash
23#include "monideal.hpp" // for MonomialIdeal, operator!=, Nmi_node
24#include "monoid.hpp" // for Monoid
25#include "polyring.hpp" // for PolynomialRing
26#include "relem.hpp" // for RingElement
27#include "ring.hpp" // for Ring
28
30{
31 int i = x;
32 while (dad[i] >= 0) i = dad[i];
33 int j = x;
34 while (j != i)
35 {
36 int t = dad[j];
37 dad[j] = i;
38 j = t;
39 }
40 return i;
41}
42
44// Returns the label representative of the merge of the two sets
45{
46 int t, newtop;
47 int i = x;
48 int j = y;
49 while (dad[i] >= 0) i = dad[i];
50 while (dad[j] >= 0) j = dad[j];
51 if (i == j) return i;
52 n_sets--;
53 if (dad[i] > dad[j])
54 {
55 newtop = j;
56 dad[newtop] += dad[i];
57 dad[i] = newtop;
58 }
59 else
60 {
61 newtop = i;
62 dad[newtop] += dad[j];
63 dad[j] = newtop;
64 }
65 while (dad[x] >= 0)
66 {
67 t = x;
68 x = dad[x];
69 dad[t] = newtop;
70 }
71 while (dad[y] >= 0)
72 {
73 t = y;
74 y = dad[y];
75 dad[t] = newtop;
76 }
77
78 return newtop;
79}
80
82// merge in the varpower monomial 'm'.
83{
84 index_varpower i = m;
85 int var1 = i.var();
86 occurs[var1] = 1;
87 ++i;
88 for (; i.valid(); ++i)
89 {
90 var1 = merge_in(var1, i.var());
91 occurs[i.var()] = 1;
92 }
93}
94
96 : n_vars(nvars),
97 n_sets(nvars),
98 adad(nvars),
99 aoccurs(nvars),
100 mi_stash(mi_stash0)
101{
102 dad = adad.data();
103 occurs = aoccurs.data();
104 for (int i = 0; i < nvars; i++)
105 {
106 dad[i] = -1;
107 occurs[i] = 0;
108 }
109}
110
112{
113 n_vars = nvars;
114 n_sets = nvars;
115 for (int i = 0; i < nvars; i++)
116 {
117 dad[i] = -1;
118 occurs[i] = 0;
119 }
120}
123// consumes and frees I
124{
125 int k;
126 reset(I->topvar() + 1);
127 // Create the sets
128 for (Bag& a : *I)
129 if (n_sets > 1)
130 merge_in(a.monom().data());
131 else
132 break;
133
134 if (n_sets == 1)
135 {
136 result.push_back(I);
137 return;
138 }
139
140 int this_label = -1;
141 n_sets = 0;
142 for (k = 0; k < n_vars; k++)
143 if (occurs[k] && dad[k] < 0)
144 {
145 dad[k] = this_label--;
146 n_sets++;
147 }
148
149 if (n_sets == 1)
150 {
151 result.push_back(I);
152 return;
153 }
154
155 int first = result.size();
156 for (k = 0; k < n_sets; k++)
157 result.push_back(new MonomialIdeal(I->get_ring(), mi_stash));
158
159 // Now partition the monomials
160 Bag *b;
161 while (I->remove(b))
162 {
163 int v = varpower::topvar(b->monom().data());
164 int loc = -1 - dad[representative(v)];
165 result[first + loc]->insert_minimal(b);
166 }
167
168 delete I;
169}
170
171#define MAX_EXP (1 << (8 * sizeof(int) - 2))
172static int popular_var(const MonomialIdeal &I,
173 int &npure,
174 exponents_t pure,
175 int &nhits,
176 const_varpower &non_pure_power,
177 int &exp_of_popular)
178// Return the variable which occurs the most often in non pure monomials,
179// placing the number of monomials in which it occurs into 'nhits'.
180// At the same time, set 'pure' and 'npure'. If there is a non pure
181// power monomial, set non_pure_power to this varpower monomial.
182{
183 int k;
184 npure = 0;
185 int nvars = I.topvar() + 1;
186 for (k = 0; k < nvars; k++) pure[k] = -1;
187
188 exponents_t hits = newarray_atomic_clear(int, nvars);
189 exponents_t minnonzero = newarray_atomic(int, nvars);
190 for (k = 0; k < nvars; k++) hits[k] = 0;
191 for (k = 0; k < nvars; k++) minnonzero[k] = MAX_EXP;
192
193 non_pure_power = nullptr;
194
195 for (Bag& a : I)
196 {
197 const_varpower m = a.monom().data();
198 index_varpower j = m;
199 assert(j.valid()); // The monomial cannot be '1'.
200 int v = j.var();
201 int e = j.exponent();
202 ++j;
203 if (j.valid())
204 {
205 non_pure_power = m;
206 for (; j.valid(); ++j)
207 {
208 v = j.var();
209 e = j.exponent();
210 if (minnonzero[v] > e) minnonzero[v] = e;
211 hits[v]++;
212 }
213 }
214 else
215 {
216 if (pure[v] == -1)
217 {
218 npure++;
219 pure[v] = e;
220 }
221 else if (pure[v] > e)
222 pure[v] = e;
223 }
224 }
225
226 int popular = 0;
227 for (k = 1; k < nvars; k++)
228 if (hits[k] > hits[popular]) popular = k;
229 nhits = hits[popular];
230 exp_of_popular = minnonzero[popular];
231 freemem(hits);
232 freemem(minnonzero);
233 return popular;
234}
235
236static int find_pivot(const MonomialIdeal &I,
237 int &npure,
238 exponents_t pure,
240// If I has a single monomial which is a non pure power, return 0,
241// and set 'pure', and 'npure'. If I has at least two non pure
242// monomials, choose a monomial 'm', not in I, but at least of degree 1,
243// which is suitable for divide and conquer in Hilbert function
244// computation.
245{
246 int nhits;
247 int exp_of_v;
249 int v = popular_var(I, npure, pure, nhits, vp, exp_of_v);
250
251 // The following will take some tweaking...
252 // Some possibilities: take just this variable, take gcd of 2 or 3
253 // elements containing this variable (choose first 3, last 3, or randomly).
254
255 // For now, let's just take this variable, if there is more than one
256 // non pure power.
257 if (npure >= I.size() - 1)
258 {
259 assert(vp != NULL);
260 varpower::copy(vp, m);
261 return 0;
262 }
263 varpower::var(v, exp_of_v, m);
264 return 1;
265}
266
269 MonomialIdeal *&quot,
270 MonomialIdeal *&sum,
271 stash *mi_stash)
272{
273 gc_vector<Bag*> elems;
274 sum = new MonomialIdeal(I.get_ring(), mi_stash);
275 quot = new MonomialIdeal(I.get_ring(), mi_stash);
276 Bag *bmin = new Bag();
277 varpower::copy(m, bmin->monom());
278 sum->insert_minimal(bmin);
279 for (Bag& a : I)
280 {
281 Bag *b = new Bag();
282 varpower::quotient(a.monom().data(), m, b->monom());
283 if (varpower::divides(m, a.monom().data()))
284 quot->insert_minimal(b);
285 else
286 {
287 sum->insert_minimal(new Bag(0, a.monom()));
288 elems.push_back(b);
289 }
290 }
291
292 // Now we sort items in 'elems' so that we can insert as min gens into 'quot'
293 std::vector<std::pair<int, int>> degs_and_indices;
294 int count = 0;
295 for (auto& b : elems)
296 {
297 int deg = varpower::simple_degree(b->monom().data());
298 degs_and_indices.push_back(std::make_pair(deg, count));
299 ++count;
300 }
301 std::stable_sort(degs_and_indices.begin(), degs_and_indices.end());
302
303 for (auto p : degs_and_indices)
304 {
305 Bag* b = elems[p.second];
306 Bag* b1; // not used here...
307 if (quot->search(b->monom().data(), b1))
308 delete b;
309 else
310 quot->insert_minimal(b);
311 }
312}
313
315{
316 reset();
317 MonomialIdeal *I = input_mat->make_monideal(this_comp);
318 // The above line adds the squares of the variables which are skew variables
319 // into the monomial ideal. This allows Hilbert functions of such rings
320 // to be computed as usual.
321 part_table.partition(I, current->monids);
322 current->i = current->monids.size() - 1;
323 current->first_sum = current->i + 1; // This part is not used at top level
324}
326{
327 depth = 0;
328 if (current == nullptr)
329 {
330 current = new hilb_step;
331 current->up = current->down = nullptr;
332 current->h0 = R->from_long(0);
333 current->h1 = R->from_long(0);
334 }
335 else
336 while (current->up != nullptr) current = current->up;
337
338 R->remove(current->h0); // This line should not be needed...
339 R->remove(current->h1);
340 current->h0 = R->from_long(0); // This top level h0 is not used
341 current->h1 = R->from_long(1);
342}
344 : S(m->get_ring()->cast_to_PolynomialRing()),
345 R(RR),
346 M(S->getMonoid()),
347 D(S->degree_monoid()),
348 mi_stash(new stash("hilb mi", sizeof(Nmi_node))),
349 input_mat(m),
350 this_comp(0),
351 n_components(m->n_rows()),
352 current(nullptr),
353 part_table(std::max(1, S->n_vars()), mi_stash)
354{
355 assert(D == R->getMonoid());
356 one = R->getCoefficientRing()->from_long(1);
357 minus_one = R->getCoefficientRing()->from_long(-1);
358 LOCAL_deg1 = D->make_one();
359
360 result_poincare = R->from_long(0);
361 nsteps = 0;
362 maxdepth = 0;
363 nideal = 0;
364 nrecurse = 0;
365
366 // Collect the 'this_comp' monideal of the input matrix
367 // Set up the computation for that
369}
370
372 : S(I->get_ring()->cast_to_PolynomialRing()),
373 R(RR),
374 M(S->getMonoid()),
375 D(S->degree_monoid()),
376 mi_stash(new stash("hilb mi", sizeof(Nmi_node))),
377 input_mat(nullptr),
378 this_comp(0),
379 n_components(1),
380 current(nullptr),
381 part_table(S->n_vars(), mi_stash)
382{
383 assert(D == R->getMonoid());
384 one = R->getCoefficientRing()->from_long(1);
385 minus_one = R->getCoefficientRing()->from_long(-1);
386 LOCAL_deg1 = D->make_one();
387
388 result_poincare = R->from_long(0);
389 nsteps = 0;
390 maxdepth = 0;
391 nideal = 0;
392 nrecurse = 0;
393
394 reset();
395 MonomialIdeal *copyI = I->copy();
396 part_table.partition(copyI, current->monids);
397 current->i = current->monids.size() - 1;
398 current->first_sum = current->i + 1; // This part is not used at top level
399}
400
402{
403 // free 'current' (which is most of the stuff here...)
404 while (current != nullptr)
405 {
407 current = current->down;
408
409 R->remove(p->h0);
410 R->remove(p->h1);
411 for (int i = 0; i < p->monids.size(); i++) delete p->monids[i];
412 delete p;
413 }
414
415 R->remove(result_poincare);
416 R->getCoefficientRing()->remove(one);
417 R->getCoefficientRing()->remove(minus_one);
418 D->remove(LOCAL_deg1);
419 delete mi_stash;
420}
421
422int hilb_comp::calc(int n_steps)
423// Possible return values: COMP_DONE, COMP_INTERRUPTED.
424{
425 if (n_components == 0) return COMP_DONE;
426 if (n_steps >= 0)
427 {
428 int calc_nsteps = nsteps + n_steps;
429 while (calc_nsteps-- > 0)
430 {
431 int result = step();
432 if (result == COMP_DONE) return COMP_DONE;
434 }
435 return COMP_DONE_STEPS;
436 }
437 else
438 for (;;)
439 {
440 int result = step();
441 if (result == COMP_DONE) return COMP_DONE;
443 }
444}
445
447// Possible return values: COMP_DONE, COMP_COMPUTING
448{
449 nsteps++;
450 if (current->i == current->first_sum)
451 {
452 current->h0 = current->h1;
453 current->h1 = R->from_long(1);
454 }
455 if (current->i >= 0)
456 {
457 // If the i th monomial ideal is a 'special case', simply compute its
458 // value
459 // Otherwise, find pivot, and quotient/sum creating next level down
460 // (possibly make new hilb_step, and increment max_depth if needed)
461 // and set current = current->down
462 do_ideal(current->monids[current->i]); // consumes this monomial ideal
463 }
464 else
465 {
466 // At this point, all Hilbert functions at this level have been
467 // computed, so add the values, and place one step up
468 R->add_to(current->h0, current->h1);
469 ring_elem f = current->h0;
470 current->h0 = R->from_long(0);
471 current->h1 = R->from_long(0);
472 current->monids.clear();
473 if (current->up == nullptr)
474 {
475 if (input_mat)
476 {
477 ring_elem tmp =
478 R->make_flat_term(one, input_mat->rows()->degree(this_comp));
479 R->mult_to(f, tmp);
480 R->remove(tmp);
481 }
482 R->add_to(result_poincare, f);
483 this_comp++;
484
485 // Now check if we have any more components
486 if (this_comp >= n_components) return COMP_DONE;
487 // otherwise go on to the next component:
488
490 return COMP_COMPUTING;
491 }
492 current = current->up;
493 R->mult_to(current->h1, f);
494 current->i--;
495 R->remove(f);
496 }
497 return COMP_COMPUTING;
498}
499
501{
502 depth++;
503 if (depth > maxdepth) maxdepth = depth;
504 nrecurse++;
505 if (current->down == nullptr)
506 {
507 current->down = new hilb_step; // MES: is this ok?
508 current->down->up = current;
509 current->down->down = nullptr;
510 }
511 current = current->down;
512 current->h0 = R->from_long(0);
513 M->degree_of_varpower(pivot_vp, LOCAL_deg1);
514 current->h1 = R->make_flat_term(one, LOCAL_deg1); // t^(deg vp)
515 MonomialIdeal *quot, *sum;
516 iquotient_and_sum(*I, pivot_vp, quot, sum, mi_stash);
517 delete I;
518 part_table.partition(sum, current->monids);
519 current->first_sum = current->monids.size() - 1;
520 part_table.partition(quot, current->monids);
521 current->i = current->monids.size() - 1;
522}
523
525{
526 // This either will multiply to current->h1, or it will recurse down
527 // Notice that one, and minus_one are global in this class.
528 // LOCAL_deg1, LOCAL_vp are scratch variables defined in this class
529 nideal++;
530 ring_elem F = R->from_long(1);
531 ring_elem G;
532 int len = I->size();
533 if (len <= 2)
534 {
535 // len==1: set F to be 1 - t^(deg m), where m = this one element
536 // len==2: set F to be 1 - t^(deg m1) - t^(deg m2) + t^(deg lcm(m1,m2))
537 M->degree_of_varpower(I->first_elem(), LOCAL_deg1);
538 G = R->make_flat_term(minus_one, LOCAL_deg1);
539 R->add_to(F, G);
540
541 if (len == 2)
542 {
543 M->degree_of_varpower(I->second_elem(), LOCAL_deg1);
544 G = R->make_flat_term(minus_one, LOCAL_deg1);
545 R->add_to(F, G);
547 M->degree_of_varpower(LOCAL_vp.data(), LOCAL_deg1);
548 G = R->make_flat_term(one, LOCAL_deg1);
549 R->add_to(F, G);
550 }
551 delete I;
552 }
553 else
554 {
555 int npure;
556 gc_vector<int> pivot;
557 gc_vector<int> pure_a(I->topvar() + 1);
558 exponents_t pure = pure_a.data();
559 if (!find_pivot(*I, npure, pure, pivot))
560 {
561 // set F to be product(1-t^(deg x_i^e_i))
562 // - t^(deg pivot) product((1-t^(deg x_i^(e_i - m_i)))
563 // where e_i >= 1 is the smallest number s.t. x_i^(e_i) is in I,
564 // and m_i = exponent of x_i in pivot element (always < e_i).
565 M->degree_of_varpower(pivot.data(), LOCAL_deg1);
566 G = R->make_flat_term(one, LOCAL_deg1);
567 for (index_varpower i = pivot.data(); i.valid(); ++i)
568 if (pure[i.var()] != -1)
569 {
570 ring_elem H = R->from_long(1);
571 D->power(M->degree_of_var(i.var()), pure[i.var()], LOCAL_deg1);
572 ring_elem tmp = R->make_flat_term(minus_one, LOCAL_deg1);
573 R->add_to(H, tmp);
574 R->mult_to(F, H);
575 R->remove(H);
576
577 H = R->from_long(1);
578 D->power(M->degree_of_var(i.var()),
579 pure[i.var()] - i.exponent(),
580 LOCAL_deg1);
581 tmp = R->make_flat_term(minus_one, LOCAL_deg1);
582 R->add_to(H, tmp);
583 R->mult_to(G, H);
584 R->remove(H);
585 }
586 R->subtract_to(F, G);
587 delete I;
588 }
589 else
590 {
591 // This is the one case in which we recurse down
592 R->remove(F);
593 recurse(I, pivot.data());
594 return;
595 }
596 }
597 R->mult_to(current->h1, F);
598 R->remove(F);
599 current->i--;
600}
601
603{
604 return (current != nullptr && current->up == nullptr);
605}
606
608{
609 if (!is_done())
610 {
611 ERROR("Hilbert function computation not complete");
612 return nullptr;
613 }
615 return result;
616}
617
619{
620 buffer o;
621 o << "--- Hilbert Function Statistics---------------------" << newline;
622 o << "#steps = " << nsteps << newline;
623 o << "Max depth = " << maxdepth << newline;
624 o << "current depth = " << depth << newline;
625 o << "#ideal = " << nideal << newline;
626 o << "#recurse = " << nrecurse << newline;
627
629 int d = depth;
630 while (p != nullptr)
631 {
632 o << "----- depth " << d << " -------------" << newline;
633 o << " " << p->monids.size() << " monomial ideals total" << newline;
634 o << " " << p->i << " = current location" << newline;
635 o << " " << p->first_sum + 1 << " sum monomial ideals" << newline;
636 o << " h0 = ";
637 R->elem_text_out(o, p->h0);
638 o << newline;
639 o << " h1 = ";
640 R->elem_text_out(o, p->h1);
641 o << newline;
642 for (int i = 0; i < p->monids.size(); i++)
643 {
644 o << " ---- monomial ideal ---------------" << newline;
645 o << " ";
646 p->monids[i]->text_out(o);
647 o << newline;
648 }
649 p = p->up;
650 d--;
651 }
652}
653#if 0
654// int hilb_comp::hilbertSeries(const Matrix *M, RingElement *&result)
655// {
656// const PolynomialRing *P = M->get_ring()->get_degree_ring();
657// hilb_comp *hf = new hilb_comp(P,M);
658// int retval = hf->calc(-1);
659// if (retval != COMP_DONE) return 1;
660// result = hf->value();
661// freemem(hf);
662// return 0;
663// }
664#endif
666/* This routine computes the numerator of the Hilbert series
667 for coker leadterms(M), using the degrees of the rows of M.
668 NULL is returned if the ring is not appropriate for
669 computing Hilbert series, or the computation was interrupted. */
670{
671 const PolynomialRing *P = M->get_ring()->get_degree_ring();
672 if (P == nullptr) return nullptr;
673 hilb_comp *hf = new hilb_comp(P, M);
674 int retval = hf->calc(-1);
675 if (retval != COMP_DONE) return nullptr;
676 RingElement *result = hf->value();
677 delete hf;
678 return result;
679}
680
682{
683 const Matrix *Fmatrix = Matrix::make(F, 0, nullptr);
685 delete Fmatrix;
686 return result;
687}
688
690/* This routine computes the numerator of the Hilbert series
691 for coker I. NULL is returned if the ring is not appropriate for
692 computing Hilbert series, or the computation was interrupted. */
693{
694 const PolynomialRing *P = I->get_ring()->get_degree_ring();
695 if (P == nullptr) return nullptr;
696 hilb_comp *hf = new hilb_comp(P, I);
697 int retval = hf->calc(-1);
698 if (retval != COMP_DONE) return nullptr;
699 RingElement *result = hf->value();
700 delete hf;
701 return result;
702}
703
704int hilb_comp::coeff_of(const RingElement *h, int deg)
705{
706 // This is a bit of a kludge of a routine. The idea is to loop through
707 // all the terms of the polynomial h, expand out the exponent, and to add
708 // up the small integer values of the coefficients of those that have
709 // exp[0]=deg.
711
712 exponents_t exp = newarray_atomic(int, P->n_vars());
713 int result = 0;
714 for (Nterm& f : h->get_value())
715 {
716 P->getMonoid()->to_expvector(f.monom, exp);
717 if (exp[0] < deg)
718 {
719 ERROR("incorrect Hilbert function given");
720 fprintf(
721 stderr,
722 "internal error: incorrect Hilbert function given, aborting\n");
723 fprintf(
724 stderr,
725 "exp[0]: %d deg: %d\n", exp[0], deg);
726 abort();
727 }
728 else if (exp[0] == deg)
729 {
730 std::pair<bool, long> res =
732 assert(res.first &&
733 std::abs(res.second) < std::numeric_limits<int>::max());
734 int n = static_cast<int>(res.second);
735 result += n;
736 }
737 }
738 freemem(exp);
739 return result;
740}
741
742// Local Variables:
743// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
744// indent-tabs-mode: nil
745// End:
#define MAX_EXP
varpower::ConstExponents const_varpower
ExponentListIterator< int, true > index_varpower
Variable-length sparse (variable, exponent) encoding of monomials.
exponents::Exponents exponents_t
Dense exponent-vector template [e_0, ..., e_{nvars-1}] for monomial operations.
Append-only GC-backed byte buffer used throughout the engine for text output.
static void lcm(ConstExponents a, ConstExponents b, Vector &result)
static void quotient(ConstExponents a, ConstExponents b, Vector &result)
static Exponent topvar(ConstExponents a)
static Exponent simple_degree(ConstExponents m)
static void copy(ConstExponents vp, Vector &result)
static bool divides(ConstExponents a, ConstExponents b)
static void var(Exponent v, Exponent e, Vector &result)
Engine-side free module R^n over a Ring.
Definition freemod.hpp:66
void to_expvector(const_monomial m, exponents_t result_exp) const
Definition monoid.cpp:747
int search(const_varpower m, Bag *&b) const
Definition monideal.cpp:278
int remove(Bag *&b)
Definition monideal.cpp:451
void insert_minimal(Bag *b)
Definition monideal.hpp:333
int size() const
Definition monideal.hpp:186
MonomialIdeal * copy() const
Definition monideal.cpp:187
int topvar() const
Definition monideal.hpp:187
const_varpower second_elem() const
Definition monideal.cpp:182
const PolynomialRing * get_ring() const
Definition monideal.hpp:190
const_varpower first_elem() const
Definition monideal.cpp:177
Engine-side monomial ideal: a decision tree of Nmi_nodes storing the (typically minimal) generators b...
Definition monideal.hpp:136
Internal tree node of the MonomialIdeal decision tree.
Definition monideal.hpp:74
const Ring * getCoefficientRing() const
Definition polyring.hpp:200
virtual const Monoid * getMonoid() const
Definition polyring.hpp:282
int n_vars() const
Definition polyring.hpp:196
Abstract base for the engine's polynomial-ring hierarchy.
Definition polyring.hpp:96
virtual std::pair< bool, long > coerceToLongInteger(ring_elem a) const
Definition ring.cpp:236
virtual const PolynomialRing * cast_to_PolynomialRing() const
Definition ring.hpp:243
const PolynomialRing * get_degree_ring() const
Definition ring.hpp:161
ring_elem get_value() const
Definition relem.hpp:79
static RingElement * make_raw(const Ring *R, ring_elem f)
Definition relem.cpp:20
const Ring * get_ring() const
Definition relem.hpp:81
Front-end-visible "ring element" value: an engine ring_elem paired with the Ring* that gives it meani...
Definition relem.hpp:67
int nideal
Definition hilb.hpp:116
int calc(int nsteps)
Definition hilb.cpp:422
const Monoid * D
Definition hilb.hpp:97
void do_ideal(MonomialIdeal *I)
Definition hilb.cpp:524
ring_elem result_poincare
Definition hilb.hpp:103
int is_done() const
Definition hilb.cpp:602
ring_elem minus_one
Definition hilb.hpp:121
gc_vector< int > LOCAL_vp
Definition hilb.hpp:126
const Matrix * input_mat
Definition hilb.hpp:102
int nrecurse
Definition hilb.hpp:117
void stats() const
Definition hilb.cpp:618
const PolynomialRing * R
Definition hilb.hpp:95
int step()
Definition hilb.cpp:446
void next_monideal()
Definition hilb.cpp:314
const PolynomialRing * S
Definition hilb.hpp:94
monomial LOCAL_deg1
Definition hilb.hpp:125
hilb_comp(const PolynomialRing *R, const Matrix *M)
Definition hilb.cpp:343
void recurse(MonomialIdeal *&I, const_varpower pivot_vp)
Definition hilb.cpp:500
void reset()
Definition hilb.cpp:325
hilb_step * current
Definition hilb.hpp:110
int nsteps
Definition hilb.hpp:113
~hilb_comp()
Definition hilb.cpp:401
partition_table part_table
Definition hilb.hpp:127
int n_components
Definition hilb.hpp:106
int this_comp
Definition hilb.hpp:105
int depth
Definition hilb.hpp:114
int maxdepth
Definition hilb.hpp:115
RingElement * value()
Definition hilb.cpp:607
const Monoid * M
Definition hilb.hpp:96
static int coeff_of(const RingElement *h, int deg)
Definition hilb.cpp:704
static RingElement * hilbertNumerator(const Matrix *M)
Definition hilb.cpp:665
ring_elem one
Definition hilb.hpp:120
stash * mi_stash
Definition hilb.hpp:99
gc_vector< int > & monom()
Definition int-bag.hpp:60
partition_table(int nvars, stash *mi_stash0)
Definition hilb.cpp:95
int * occurs
Definition hilb.hpp:61
void partition(MonomialIdeal *&I, gc_vector< MonomialIdeal * > &result)
Definition hilb.cpp:121
gc_vector< int > adad
Definition hilb.hpp:58
stash * mi_stash
Definition hilb.hpp:67
int representative(int x)
Definition hilb.cpp:29
int merge_in(int x, int y)
Definition hilb.cpp:43
gc_vector< int > aoccurs
Definition hilb.hpp:59
void reset(int nvars)
Definition hilb.cpp:111
Definition mem.hpp:78
@ COMP_DONE_STEPS
Definition computation.h:69
@ COMP_DONE
Definition computation.h:60
@ COMP_COMPUTING
Definition computation.h:71
@ COMP_INTERRUPTED
Definition computation.h:57
Engine error-reporting primitives: ERROR, INTERNAL_ERROR, error, error_message.
#define Matrix
Definition factory.cpp:14
FreeModule — finite-rank free module R^n, the type-level anchor for every Matrix.
int p
static int find_pivot(const MonomialIdeal &I, int &npure, exponents_t pure, gc_vector< int > &m)
Definition hilb.cpp:236
static void iquotient_and_sum(MonomialIdeal &I, const_varpower m, MonomialIdeal *&quot, MonomialIdeal *&sum, stash *mi_stash)
Definition hilb.cpp:267
static int popular_var(const MonomialIdeal &I, int &npure, exponents_t pure, int &nhits, const_varpower &non_pure_power, int &exp_of_popular)
Definition hilb.cpp:172
Hilbert-series numerator via the Bigatti-Caboara-Robbiano recursion.
int_bag Bag
Definition int-bag.hpp:70
int_bag / Bag — minimal (payload, varpower monomial) carrier shared by monomial-ideal code.
bool system_interrupted()
system_interrupted() — thread-safe polling predicate for Ctrl+C handling.
void freemem(void *s)
Definition m2-mem.cpp:103
const int ERROR
Definition m2-mem.cpp:55
VALGRIND_MAKE_MEM_DEFINED & result(result)
Engine-wide GC allocator surface (getmem / getmem_atomic) and debug-allocation trap.
char newline[]
Definition m2-types.cpp:49
Matrix — the engine's immutable homomorphism F -> G between free modules.
stash and doubling_stash — legacy size-class allocator interfaces, now stubbed to plain GC allocation...
MonomialIdeal — exponent-vector-only representation of an ideal generated by monomials.
Monoid — variable count, naming, grading, and monomial order of a polynomial ring.
STL namespace.
#define newarray_atomic_clear(T, len)
Definition newdelete.hpp:93
typename std::vector< T, gc_allocator< T > > gc_vector
a version of the STL vector, which allocates its backing memory with gc.
Definition newdelete.hpp:76
#define newarray_atomic(T, len)
Definition newdelete.hpp:91
volatile int x
PolynomialRing — abstract polynomial-ring base, the engine's most-reused class.
#define max(a, b)
Definition polyroots.cpp:52
RingElement — tagged (Ring*, ring_elem) pair, the engine's universal element type.
tbb::flow::graph G
Ring — the legacy abstract base class for every coefficient and polynomial ring.
Singly linked-list node carrying one term of a polynomial-ring element.
Definition ringelem.hpp:156