Macaulay2 Engine
Loading...
Searching...
No Matches
res-a2-gb.cpp
Go to the documentation of this file.
1// Copyright 1997 Michael E. Stillman
2
3#include "style.hpp"
4#include "res-a2.hpp"
5#include "hilb.hpp"
6#include "text-io.hpp"
7#include "comp-gb.hpp"
8#include "matrix-con.hpp"
9#include "interrupted.hpp"
10
12 stash *mi_stash0,
13 gb_node *ggens,
14 int lodeg,
15 int origsyz,
16 int lev,
17 int strategy)
18{
19 level = lev;
20 int i;
22 if (originalR == nullptr)
23 {
24 ERROR("internal error - ring is not a polynomial ring");
25 assert(0);
26 }
27 GR = originalR->get_gb_ring();
28 M = GR->get_flattened_monoid();
29 K = GR->get_flattened_coefficients();
30
31 mi_stash = mi_stash0;
32
33 F = const_cast<FreeModule *>(ggens->output_free_module());
34
35 gens = ggens;
36 syz = nullptr;
37
38 Fsyz = const_cast<FreeModule *>(FFsyz);
39
40 spairs = new s_pair_heap(M);
41
42 n_gb = n_mingens = n_subring = 0;
43 n_gb_first = 0;
48
49 orig_syz = origsyz; // Note: if orig_syz > 0, then Fsyz is
50 // completely set already.
51
52 this_degree = lodeg;
53
54 // We index into this using gbvector components (which are one greater than
55 // the
56 // FreeModule components
57 monideals.push_back(nullptr);
58 for (i = 0; i < F->rank(); i++)
59 {
61 monideals.push_back(p);
62 }
63
64 use_hilb = 0;
65 hf_numgens_F = F->rank();
66 hf_numgens_gb = 0; // This will enable the initial computation of HF,
67 // if use_hilb is set.
69 n_gb_syz = 0;
70
71 strategy_flags = strategy;
73}
74
76 stash *mi_stash0,
77 gb_node *gens0,
78 int lodegree,
79 int origsyz,
80 int level0,
81 int strat)
82{
83 setup(Fsyz0, mi_stash0, gens0, lodegree, origsyz, level0, strat);
84}
86{
87 syz = p;
88 use_hilb = (strategy_flags & STRATEGY_USE_HILB) && (syz != nullptr);
89}
91{
92 p->f = nullptr; // these are not used in res-a2-gb algorithm except for temp space
93 p->fsyz = nullptr; // ditto
94 p->first = nullptr;
95 p->second = nullptr;
96 p->next = nullptr;
97 M->remove(p->lcm);
98 freemem(p);
99 p = nullptr;
100}
101
103{
104 // remove all of the gbvector's in the gb_elems's and spairs.
105 for (int i = 0; i < gb.size(); i++)
106 {
107 gb_elem *g = gb[i];
108 GR->gbvector_remove(g->f);
109 GR->gbvector_remove(g->fsyz);
110 }
111 these_pairs = nullptr;
112}
113
115// s pair construction //////////////////////
117
119{
120 s_pair *result = new s_pair;
121 result->next = nullptr;
122 result->syz_type = SPAIR_RING;
123 result->degree = M->primary_degree(lcm) + F->primary_degree(p->f->comp - 1);
124 result->compare_num = 0;
125 result->first = p;
126 result->second = nullptr;
127 result->f = nullptr;
128 result->fsyz = nullptr;
129
130 result->lcm = M->make_new(lcm);
131 return result;
132}
133
135{
136 // p and q should have 'f' field defined.
137 s_pair *result = new s_pair;
138 result->next = nullptr;
139 result->syz_type = SPAIR_PAIR;
140 result->degree = M->primary_degree(lcm) + F->primary_degree(p->f->comp - 1);
141 result->compare_num = 0;
142 result->first = p;
143 result->second = q;
144 result->f = nullptr;
145 result->fsyz = nullptr;
146
147 result->lcm = M->make_new(lcm);
148 return result;
149}
150
152// sorting the Groebner basis ///////////////
154
156{
157 gb_elem *pivot = gb[lo];
158 const int *pivot_monom = pivot->f->monom;
159 int i = lo - 1;
160 int j = hi + 1;
161 for (;;)
162 {
163 do
164 {
165 j--;
166 }
167 while (M->compare(gb[j]->f->monom, pivot_monom) < 0);
168 do
169 {
170 i++;
171 }
172 while (M->compare(gb[i]->f->monom, pivot_monom) > 0);
173
174 if (i < j)
175 {
176 gb_elem *tmp = gb[j];
177 gb[j] = gb[i];
178 gb[i] = tmp;
179 }
180 else
181 return j;
182 }
183}
184
185void gb2_comp::gb_sort(int lo, int hi)
186{
187 if (lo < hi)
188 {
189 int q = gb_sort_partition(lo, hi);
190 gb_sort(lo, q);
191 gb_sort(q + 1, hi);
192 }
193}
194
196// compute min gen set of {m | m lead(p) is in (p1, ..., pr, f1, ..., fs)}
197// (includes cases m * lead(p) = 0).
198// Returns a list of new s_pair's.
199{
200 gc_vector<Bag*> elems;
201 gc_vector<int> vplcm;
202 monomial find_pairs_m = M->make_one();
203 monomial f_m = M->make_one();
204 int *find_pairs_lcm = newarray_atomic(int, M->n_vars());
205
206 GR->gbvector_get_lead_monomial(F, p->f, f_m);
207 if (GR->is_skew_commutative())
208 {
209 exponents_t find_pairs_exp = newarray_atomic(int, M->n_vars());
210 M->to_expvector(f_m, find_pairs_exp);
211
212 for (int v = 0; v < GR->n_skew_commutative_vars(); v++)
213 {
214 int w = GR->skew_variable(v);
215 if (find_pairs_exp[w] == 0) continue;
216
217 find_pairs_exp[w]++;
218 M->from_expvector(find_pairs_exp, find_pairs_lcm);
219 find_pairs_exp[w]--;
220
221 vplcm.resize(0);
222 M->to_varpower(find_pairs_lcm, vplcm);
223 s_pair *q = new_ring_pair(p, find_pairs_lcm);
224 elems.push_back(new Bag(q, vplcm));
225 }
226 freemem(find_pairs_exp);
227 }
228
229 // Add in syzygies arising from a base ring
230
231 if (originalR->is_quotient_ring())
232 {
233 for (int i = 0; i < originalR->n_quotients(); i++)
234 {
235 const Nterm *f = originalR->quotient_element(i);
236 M->lcm(f->monom, f_m, find_pairs_lcm);
237 vplcm.resize(0);
238 M->to_varpower(find_pairs_lcm, vplcm);
239 s_pair *q = new_ring_pair(p, find_pairs_lcm);
240 elems.push_back(new Bag(q, vplcm));
241 }
242 }
243
244 // Add in syzygies arising as s-pairs
245 MonomialIdeal *mi1 = monideals[p->f->comp]->mi;
246 for (Bag& a : *mi1)
247 {
248 M->from_varpower(a.monom().data(), find_pairs_m);
249 M->lcm(find_pairs_m, f_m, find_pairs_lcm);
250 vplcm.resize(0);
251 M->to_varpower(find_pairs_lcm, vplcm);
252 s_pair *q =
254 reinterpret_cast<gb_elem *>(a.basis_ptr()),
255 find_pairs_lcm);
256 elems.push_back(new Bag(q, vplcm));
257 }
258
259 // Add 'p' to the correct monideal
261 M->to_varpower(f_m, vp);
262 mi1->insert(new Bag(p, vp));
263
264 // Now minimalize these elements, and insert them into
265 // the proper degree.
266
267 VECTOR(Bag *) rejects;
268 MonomialIdeal *mi = new MonomialIdeal(originalR, elems, rejects, mi_stash);
269 for (auto& b : rejects)
270 {
271 s_pair *q = reinterpret_cast<s_pair *>(b->basis_ptr());
272 remove_pair(q);
273 delete b;
274 }
275
276 int is_ideal2 = (F->rank() == 1 && orig_syz == 0);
277 for (Bag& a : *mi)
278 {
279 n_pairs++;
280 s_pair *q = reinterpret_cast<s_pair *>(a.basis_ptr());
281 if (is_ideal2 && q->syz_type == SPAIR_PAIR)
282 {
283 // MES: the following line is suspect, for Schreyer orders
284 M->gcd(q->first->f->monom, q->second->f->monom, find_pairs_m);
285 if (M->is_one(find_pairs_m))
286 {
287 n_pairs_gcd++;
288 if (M2_gbTrace >= 8)
289 {
290 buffer o;
291 o << "removed pair[" << q->first->me << " " << q->second->me
292 << "]" << newline;
293 emit(o.str());
294 }
295 remove_pair(q);
296 }
297 else
298 spairs->insert(q);
299 }
300 else
301 spairs->insert(q);
302 }
303
304 delete mi;
305 // Remove the local variables
306 M->remove(find_pairs_m);
307 M->remove(f_m);
308 freemem(find_pairs_lcm);
309}
310
312{
313 if (p->f == nullptr)
314 {
315 monomial s = M->make_one();
316 GR->gbvector_get_lead_monomial(F, p->first->f, s);
317 M->divide(p->lcm, s, s);
318
319 GR->gbvector_mult_by_term(
320 F, Fsyz, GR->one(), s, p->first->f, p->first->fsyz, p->f, p->fsyz);
321 if (p->syz_type == SPAIR_PAIR)
322 GR->gbvector_reduce_lead_term(
323 F, Fsyz, nullptr, p->f, p->fsyz, p->second->f, p->second->fsyz);
324 M->remove(s);
325 }
326}
327
329{
331 {
332 gb_geo_reduce(f, fsyz);
333 return;
334 }
335 gbvector head;
336 gbvector *result = &head;
337 result->next = nullptr;
338
339 exponents_t div_totalexp = newarray_atomic(int, M->n_vars());
340 int count = 0;
341 if (M2_gbTrace == 10)
342 {
343 buffer o;
344 o << "reducing ";
345 GR->gbvector_text_out(o, F, f);
346 emit_line(o.str());
347 }
348 while (f != nullptr)
349 {
350 Bag *b;
351 GR->gbvector_get_lead_exponents(F, f, div_totalexp);
352 if (originalR->is_quotient_ring() &&
353 originalR->get_quotient_monomials()->search_expvector(div_totalexp,
354 b))
355 {
356 const gbvector *g = originalR->quotient_gbvector(b->basis_elem());
357 GR->gbvector_reduce_lead_term(F, Fsyz, head.next, f, fsyz, g, nullptr);
358 count++;
359 }
360 else if (monideals[f->comp]->mi_search->search_expvector(div_totalexp, b))
361 {
362 gb_elem *q = reinterpret_cast<gb_elem *>(b->basis_ptr());
363 GR->gbvector_reduce_lead_term(
364 F, Fsyz, head.next, f, fsyz, q->f, q->fsyz);
365 count++;
366 if (M2_gbTrace == 10)
367 {
368 buffer o;
369 o << " reduced by ";
370 GR->gbvector_text_out(o, F, q->f);
371 o << newline;
372 o << " giving ";
373 GR->gbvector_text_out(o, F, f);
374 o << newline;
375 emit(o.str());
376 }
377 }
378 else
379 {
380 result->next = f;
381 f = f->next;
382 result = result->next;
383 result->next = nullptr;
384 }
385 }
386
387 if (M2_gbTrace >= 4)
388 {
389 buffer o;
390 o << "." << count;
391 emit_wrapped(o.str());
392 }
393 f = head.next;
394 freemem(div_totalexp);
395}
396
398{
399 gbvector head;
400 gbvector *result = &head;
401 result->next = nullptr;
402
403 exponents_t div_totalexp = newarray_atomic(int, M->n_vars());
404 int count = 0;
405
406 gbvectorHeap fb(GR, F);
407 gbvectorHeap fsyzb(GR, Fsyz);
408 fb.add(f);
409 fsyzb.add(fsyz);
410 const gbvector *lead;
411 while ((lead = fb.get_lead_term()) != nullptr)
412 {
413 Bag *b;
414 GR->gbvector_get_lead_exponents(F, lead, div_totalexp);
415 if (originalR->is_quotient_ring() &&
416 originalR->get_quotient_monomials()->search_expvector(div_totalexp,
417 b))
418 {
419 const gbvector *g = originalR->quotient_gbvector(b->basis_elem());
420 GR->reduce_lead_term_heap(F,
421 Fsyz,
422 lead,
423 div_totalexp, // are these two needed
424 head.next,
425 fb,
426 fsyzb,
427 g,
428 nullptr);
429 count++;
430 }
431 else if (monideals[lead->comp]->mi_search->search_expvector(div_totalexp,
432 b))
433 {
434 gb_elem *q = reinterpret_cast<gb_elem *>(b->basis_ptr());
435 GR->reduce_lead_term_heap(
436 F, Fsyz, lead, div_totalexp, head.next, fb, fsyzb, q->f, q->fsyz);
437 count++;
438 }
439 else
440 {
441 result->next = fb.remove_lead_term();
442 result = result->next;
443 result->next = nullptr;
444 }
445 }
446
447 if (M2_gbTrace >= 4)
448 {
449 buffer o;
450 o << "." << count;
451 emit_wrapped(o.str());
452 }
453 f = head.next;
454
455 fsyz = fsyzb.value();
456 freemem(div_totalexp);
457}
458
459void gb2_comp::reduce(gbvector *&f, gbvector *&fsyz) { gb_reduce(f, fsyz); }
461{
462 while (these_pairs != nullptr)
463 {
464 n_pairs_hilb++;
466 these_pairs = p->next;
467 remove_pair(p);
468 }
469}
470
471#ifdef DEVELOPMENT
472#warning " schreyer append: wrong if not encoded order"
473#endif
475{
476 if (orig_syz < 0)
477 {
478 monomial d = originalR->degree_monoid()->make_one();
479 GR->gbvector_multidegree(F, f, d);
480 Fsyz->append_schreyer(d, f->monom, Fsyz->rank());
481 originalR->degree_monoid()->remove(d);
482 }
483}
484
485void gb2_comp::gb_insert(gbvector *f, gbvector *fsyz, int ismin)
486{
487 monomial f_m = M->make_one();
488 gbvector *bull = nullptr;
489 gb_elem *p = new gb_elem(f, fsyz, ismin);
490
491 if (orig_syz < 0 && ismin)
492 GR->gbvector_remove_content(p->f, bull);
493 else
494 GR->gbvector_remove_content(p->f, p->fsyz);
495
496 if (M2_gbTrace >= 10)
497 {
498 buffer o;
499 o << "inserting level " << level << " ";
500 GR->gbvector_text_out(o, F, p->f);
501 o << newline;
502 emit(o.str());
503 }
504 if (ismin) n_mingens++;
505 GR->gbvector_get_lead_monomial(F, p->f, f_m);
506
507 if (M->in_subring(1, f_m)) n_subring++;
508 // insert into p->f->comp->mi_search
510 M->to_varpower(f_m, vp);
511 monideals[p->f->comp]->mi_search->insert(new Bag(p, vp));
512 gb.push_back(p);
513
514 M->remove(f_m);
515
516 // Now do auto-reduction of previous elements using this one.
517 if (orig_syz >= 0 || !ismin)
518 for (int i = n_gb_first; i < n_gb; i++)
519 {
520 // Now compute gb(i) := gb(i) - c gb(j), where
521 // c in(gb(j)) is a term in gb(i).
522 // Also compute change(i) -= c change(j).
523
524 GR->gbvector_auto_reduce(F, Fsyz, gb[i]->f, gb[i]->fsyz, p->f, p->fsyz);
525 }
526
527 n_gb++;
528}
529
531{
532 int n = 0;
533 s_pair head;
534 s_pair *slast = &head;
535
536 for (;;)
537 {
538 s_pair *p = spairs->remove();
539 if (p == nullptr) break;
540 if (p->degree != this_degree)
541 {
542 spairs->put_back(p);
543 break;
544 }
545
546 slast->next = p;
547 slast = p;
548 n++;
549 }
550
551 slast->next = nullptr;
552 these_pairs = head.next;
553 total_pairs.push_back(this_degree);
554 total_pairs.push_back(n);
555 return n;
556}
558// If no s-pairs left in the current degree,
559// return false
560// Otherwise, compute the current s-pair, reduce it, and
561// dispatch the result. Return true.
562{
563 if (use_hilb && n_gb_syz == 0) flush_pairs();
564 if (these_pairs == nullptr) return false; // Done
566 these_pairs = these_pairs->next;
567
570
571 gbvector *f = p->f;
572 gbvector *fsyz = p->fsyz;
573 p->f = nullptr;
574 p->fsyz = nullptr;
575 remove_pair(p);
576
577 gb_reduce(f, fsyz);
578 if (f != nullptr)
579 {
580 gb_insert(f, fsyz, 0);
581 n_gb_syz--;
582 n_pairs_gb++;
583 if (M2_gbTrace >= 3) emit_wrapped("m");
584 }
585 else if (fsyz != nullptr && syz != nullptr)
586 {
587 if (syz->receive_generator(fsyz, n_syz++, GR->one()))
588 {
589 n_gb_syz--;
590 n_pairs_syz++;
591 if (M2_gbTrace >= 3) emit_wrapped("z");
592 }
593 else
594 {
595 n_pairs_usyz++;
596 if (M2_gbTrace >= 3) emit_wrapped("u");
597 }
598 }
599 else
600 {
601 if (fsyz != nullptr) GR->gbvector_remove(fsyz);
602 n_pairs_zero++;
603 if (M2_gbTrace >= 3) emit_wrapped("o");
604 }
605 return true;
606}
607
609// Hilbert function use ///
611
612//---- Completion testing -----------------------------
613
615{
616 bool isgen = false;
617 // It is our duty to free 'f'...
618
619 for (int i = monideals.size(); i <= F->rank(); i++)
620 {
622 monideals.push_back(p);
623 }
624
625 gbvector *fsyz = nullptr;
626 if (orig_syz >= 0)
627 {
628 if (orig_syz > n)
629 fsyz = GR->gbvector_term(
630 Fsyz, denom, n + 1); // Note the change in component number
631 gb_reduce(f, fsyz);
632 if (f == nullptr)
633 {
634 if (fsyz != nullptr && syz != nullptr)
635 syz->receive_generator(fsyz, n_syz++, GR->one());
636 }
637 else
638 {
639 isgen = true;
640 gb_insert(f, fsyz, 1);
641 }
642 }
643 else
644 {
645 gb_reduce(f, fsyz);
646 GR->gbvector_remove(fsyz);
647 GR->gbvector_remove_content(f, nullptr);
648 if (f != nullptr)
649 {
650 // schreyer_append(f);
651 isgen = true;
652 // gb_insert(f,Fsyz->e_sub_i(n_mingens),1);
653 // The fsyz part will be set at the end of the degree,
654 // after sorting takes place, and after auto-reduction in
655 // this degree.
656 gb_insert(f, nullptr, 1);
657 }
658 }
659 return isgen;
660}
661
663{
664 if ((strategy_flags & STRATEGY_SORT) != 0)
665 {
666 gb_sort(n_gb_first, n_gb - 1); // This is the range of elements to sort.
667 }
668 for (int j = n_gb_first; j < n_gb; j++) gb[j]->me = j;
669 if (orig_syz < 0)
670 {
671 for (int j = n_gb_first; j < n_gb; j++)
672 if (gb[j]->is_min)
673 {
674 schreyer_append(gb[j]->f);
675 gb[j]->fsyz = GR->gbvector_term(Fsyz, GR->one(), Fsyz->rank());
676 }
677 }
678
679 // Now set the state so that we know we have finished here
680 this_degree++;
682}
683
685{
687 if (this_degree > deg) return COMP_DONE;
688 if (state == STATE_DONE) return COMP_DONE; // This includes knowledge
689 // that there will be no new generators.
690 if (this_degree < deg)
691 {
692 // Now make sure that previous computations have been done:
693 ret = calc_gens(deg - 1);
694 if (ret != COMP_DONE) return ret;
695 }
696 // At this point, we have completely computed a GB with new gens
697 // in this degree. Depending on whether we stopped
698 // prematurely, our state will be one of STATE_NEW_DEGREE,
699 // STATE_GB, STATE_GENS.
700
701 buffer o1;
702
703 if (state == STATE_NEW_DEGREE)
704 {
705 if (use_hilb)
706 {
707 RingElement *hsyz;
708 const PolynomialRing *DR = originalR->get_degree_ring();
709 RingElement *h = RingElement::make_raw(DR, DR->zero());
710 if (syz != nullptr)
711 {
712 hsyz = syz->hilbertNumerator();
713 if (hsyz == nullptr) return COMP_INTERRUPTED;
714 // o1 << "hsyz = "; hsyz->text_out(o);
715 h = (*h) + (*hsyz);
716 }
718 if (hf1 == nullptr) return COMP_INTERRUPTED;
719 h = (*h) + (*hf1);
721 if (hF == nullptr) return COMP_INTERRUPTED;
722 h = (*h) - (*hF);
723
724#if 0
725// o1 << "\nhf = "; hf1->text_out(o1);
726// o1 << "\nhF = "; hF->text_out(o1);
727// o1 << "\nh = "; h->text_out(o1);
728// o1 << "\n";
729// emit(o1.str());
730// o1.reset();
731#endif
732 if (M2_gbTrace >= 1 && n_gb_syz != 0)
733 {
734 buffer o;
735 o << "<WARNING: remaining nsyz+ngb = " << n_gb_syz << ">";
736 emit(o.str());
737 }
738
740 if (error()) return COMP_ERROR;
741 }
742
743 // Compute new s-pairs
744 for (int i = n_gb_first; i < n_gb; i++) find_pairs(gb[i]);
745
746 state = STATE_GB;
748 int npairs = get_pairs();
749 if (M2_gbTrace >= 1 && npairs > 0)
750 {
751 buffer o;
752 // Should only display this if there are some pairs.
753 o << '[' << level << ',' << npairs;
754 if (use_hilb) o << ",e" << n_gb_syz; // << "," << n1 << "," << n2;
755 o << ']';
756 emit(o.str());
757 }
758 }
759
760 if (state == STATE_GB)
761 {
762 ret = COMP_COMPUTING;
763 // Now compute all the s-pairs here.
764 for (;;)
765 {
766 if (ret != COMP_COMPUTING) break;
767 if (system_interrupted())
768 {
769 ret = COMP_INTERRUPTED;
770 break;
771 }
772 // Check ending conditions...
773 if (!s_pair_step())
774 {
775 ret = COMP_DONE;
777 }
778 }
779 }
780
781 if (state == STATE_GENS && orig_syz > 0)
782 {
783 // Get the generators of the same degree, since these
784 // may produce syzygies of this degree.
785 ret = gens->calc_gb(deg);
786 if (ret == COMP_DONE)
787 {
788 // Cleanup, go to next degree.
789 end_degree();
790 }
791 }
792 // MES: put out an endl if M2_gbTrace >= 1?
793
794 // Is this where we should compute the HF again: for use by the
795 // previous node... Do we really have to compute it twice per degree/level
796 // node?
797
798 return ret;
799}
800
802{
803 enum ComputationStatusCode ret;
804 // First check whether we have done this:
805 if (this_degree > deg) return COMP_DONE;
806
807 // First make sure that we have a GB here:
808 ret = calc_gb(deg);
809 if (ret != COMP_DONE) return ret;
810
811 // Go get the generators:
812 ret = gens->calc_gb(deg);
813 if (ret != COMP_DONE) return ret;
814
815 end_degree();
816 return COMP_DONE;
817}
818
820{
821 return ((spairs->n_elems() == 0) && n_gb == n_gb_first);
822}
823
825// Hilbert function computing //
827
829{
830 MatrixConstructor result(F, gb.size());
831 for (int i = 0; i < gb.size(); i++)
832 {
833 gb_elem *g = gb[i];
834 gbvector *f = g->f;
835 if (f == nullptr) continue;
836 // Only grab the lead term, which should be non-null
837 gbvector *fnext = f->next;
838 f->next = nullptr;
839 vec v = originalR->translate_gbvector_to_vec(F, f);
840 f->next = fnext;
841 result.set_column(i, v);
842 }
843 return result.to_matrix();
844}
845
847{
848 if (hf_numgens_gb == n_gb && hf_numgens_F == F->rank())
849 {
850 return hf;
851 }
852
853 Matrix *hf_matrix = make_lead_term_matrix();
854 hf = hilb_comp::hilbertNumerator(hf_matrix);
855
856 // hf is NULL if the computation was interrupted
857 if (hf == nullptr) return nullptr;
858
859 hf_numgens_F = F->rank();
861
862 return hf;
863}
864
865//--- Obtaining matrices as output -------
867{
868 MatrixConstructor mat(F, Fsyz, nullptr);
869 int j = 0;
870 for (int i = 0; i < gb.size(); i++)
871 if (gb[i]->is_min)
872 mat.set_column(j++, originalR->translate_gbvector_to_vec(F, gb[i]->f));
873 return mat.to_matrix();
874}
876{
877 if (orig_syz > 0)
878 return gens->get_matrix();
879 else
880 return min_gens_matrix();
881}
882
884{
885 MatrixConstructor mat(F, 0);
886 for (int i = 0; i < gb.size(); i++)
887 {
888 gbvector *tmp = GR->gbvector_lead_term(n, F, gb[i]->f);
889 mat.append(originalR->translate_gbvector_to_vec(F, tmp));
890 GR->gbvector_remove(tmp);
891 }
892 return mat.to_matrix();
893}
894
896{
897 MatrixConstructor mat(F, 0);
898 for (int i = 0; i < gb.size(); i++)
899 mat.append(originalR->translate_gbvector_to_vec(F, gb[i]->f));
900 return mat.to_matrix();
901}
902
904{
905 MatrixConstructor mat(Fsyz, 0);
906 for (int i = 0; i < gb.size(); i++)
907 mat.append(originalR->translate_gbvector_to_vec(Fsyz, gb[i]->fsyz));
908 return mat.to_matrix();
909}
910
912{
913 buffer o;
914 debug_out(o, q);
915 emit(o.str());
916}
918{
919 if (q == nullptr) return;
920 o << "(" << q->compare_num << " ";
921 if (q->first != nullptr)
922 o << q->first->me;
923 else
924 o << ".";
925 o << " ";
926 if (q->second != nullptr)
927 o << q->second->me;
928 else
929 o << ".";
930 o << " ";
931 M->elem_text_out(o, q->lcm);
932 o << ") ";
933}
934
935// text_out and stats are the same routine, except that text_out returns
936// a string, essentially, and stats displays its result directly.
938{
939 if (M2_gbTrace >= 4 && n_gb > 0)
940 {
941 int nmonoms = 0;
942 int nchange = 0;
943 for (int i = 0; i < gb.size(); i++)
944 {
945 nmonoms += GR->gbvector_n_terms(gb[i]->f);
946 nchange += GR->gbvector_n_terms(gb[i]->fsyz);
947 }
948 o.put(n_gb, 5);
949 o.put(" ");
950 o.put(n_pairs, 5);
951 o.put(" ");
952 o.put(n_pairs_computed, 5);
953 o.put(" ");
954 o.put(n_pairs_gb, 5);
955 o.put(" ");
956 o.put(n_pairs_syz, 5);
957 o.put(" ");
958 o.put(n_pairs_zero, 5);
959 o.put(" ");
960 o.put(n_pairs_usyz, 5);
961 o.put(" ");
962 o.put(n_pairs_hilb, 5);
963 o.put(" ");
964 o.put(n_pairs_gcd, 5);
965 o.put(" ");
966 o.put(nmonoms, 5);
967 o.put(" ");
968 o.put(nchange, 5);
969 o.put(newline);
970 }
971
972 spairs->text_out(o);
973 if (M2_gbTrace >= 5 && M2_gbTrace % 2 == 1)
974 for (int i = 0; i < gb.size(); i++)
975 {
976 o << i << '\t';
977 GR->gbvector_text_out(o, F, gb[i]->f);
978 o << newline;
979 }
980}
981
982void gb2_comp::stats() const
983{
984 buffer o;
985 if (M2_gbTrace >= 4 && n_gb > 0)
986 {
987 int nmonoms = 0;
988 int nchange = 0;
989 for (int i = 0; i < gb.size(); i++)
990 {
991 nmonoms += GR->gbvector_n_terms(gb[i]->f);
992 nchange += GR->gbvector_n_terms(gb[i]->fsyz);
993 }
994 o.put(n_gb, 5);
995 o.put(" ");
996 o.put(n_pairs, 5);
997 o.put(" ");
998 o.put(n_pairs_computed, 5);
999 o.put(" ");
1000 o.put(n_pairs_gb, 5);
1001 o.put(" ");
1002 o.put(n_pairs_syz, 5);
1003 o.put(" ");
1004 o.put(n_pairs_zero, 5);
1005 o.put(" ");
1006 o.put(n_pairs_usyz, 5);
1007 o.put(" ");
1008 o.put(n_pairs_hilb, 5);
1009 o.put(" ");
1010 o.put(n_pairs_gcd, 5);
1011 o.put(" ");
1012 o.put(nmonoms, 5);
1013 o.put(" ");
1014 o.put(nchange, 5);
1015 o.put(newline);
1016 emit(o.str());
1017 o.reset();
1018 }
1019
1020 spairs->stats();
1021 if (M2_gbTrace >= 5 && M2_gbTrace % 2 == 1)
1022 {
1023 o << "free module is ";
1024 F->text_out(o);
1025 o << newline;
1026 for (int i = 0; i < gb.size(); i++)
1027 {
1028 o.reset();
1029 o << i << '\t';
1030 GR->gbvector_text_out(o, F, gb[i]->f);
1031 o << newline;
1032 emit(o.str());
1033 }
1034 }
1035 // dfree(F);
1036}
1037
1038// Local Variables:
1039// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
1040// indent-tabs-mode: nil
1041// End:
exponents::Exponents exponents_t
const Ring * get_ring() const
Definition freemod.hpp:102
Engine-side free module R^n over a Ring.
Definition freemod.hpp:66
Matrix * to_matrix()
void append(vec v)
void set_column(int c, vec v)
Mutable builder used to assemble an immutable Matrix one column (or one term) at a time.
int insert(Bag *b)
Definition monideal.cpp:622
Nmi_node * mi
Definition monideal.hpp:138
Engine-side monomial ideal: a decision tree of Nmi_nodes storing the (typically minimal) generators b...
Definition monideal.hpp:136
Abstract base for the engine's polynomial-ring hierarchy.
Definition polyring.hpp:96
ring_elem zero() const
Definition ring.hpp:359
virtual const PolynomialRing * cast_to_PolynomialRing() const
Definition ring.hpp:243
static RingElement * make_raw(const Ring *R, ring_elem f)
Definition relem.cpp:20
Front-end-visible "ring element" value: an engine ring_elem paired with the Ring* that gives it meani...
Definition relem.hpp:67
char * str()
Definition buffer.hpp:72
void reset()
Definition buffer.hpp:69
void put(const char *s)
Definition buffer.cpp:35
int n_syz
Definition res-a2.hpp:144
int n_pairs_computed
Definition res-a2.hpp:147
int n_gb_first
Definition res-a2.hpp:126
int n_subring
Definition res-a2.hpp:143
Matrix * change_matrix()
int n_pairs
Definition res-a2.hpp:146
RingElement * hf
Definition res-a2.hpp:165
int n_pairs_syz
Definition res-a2.hpp:149
int n_pairs_gb
Definition res-a2.hpp:151
s_pair * new_ring_pair(gb_elem *p, const int *lcm)
gb_node * syz
Definition res-a2.hpp:137
void setup(FreeModule *Fsyz, stash *mi_stash, gb_node *gens, int lodegree, int origsyz, int level, int strategy)
Definition res-a2-gb.cpp:11
int n_pairs_zero
Definition res-a2.hpp:152
FreeModule * Fsyz
Definition res-a2.hpp:121
Matrix * initial_matrix(int n)
gc_vector< int > total_pairs
Definition res-a2.hpp:131
void gb_insert(gbvector *f, gbvector *fsyz, int ismin)
enum ComputationStatusCode calc_gens(int deg)
enum ComputationStatusCode calc_gb(int deg)
void gb_sort(int lo, int hi)
int level
Definition res-a2.hpp:123
void remove_pair(s_pair *&p)
Definition res-a2-gb.cpp:90
int orig_syz
Definition res-a2.hpp:157
int hf_numgens_F
Definition res-a2.hpp:168
Matrix * min_gens_matrix()
s_pair * these_pairs
Definition res-a2.hpp:130
virtual void text_out(buffer &o) const
int get_pairs()
Matrix * gb_matrix()
int n_gb
Definition res-a2.hpp:141
Matrix * make_lead_term_matrix()
Matrix * get_matrix()
stash * mi_stash
Definition res-a2.hpp:118
int this_degree
Definition res-a2.hpp:125
void find_pairs(gb_elem *p)
void debug_out(s_pair *q) const
int state
Definition res-a2.hpp:124
int n_mingens
Definition res-a2.hpp:142
void end_degree()
void gb_geo_reduce(gbvector *&f, gbvector *&fsyz)
const Ring * K
Definition res-a2.hpp:117
int strategy_flags
Definition res-a2.hpp:160
void schreyer_append(gbvector *f)
FreeModule * F
Definition res-a2.hpp:120
gb2_comp(FreeModule *Fsyz, stash *mi_stash, gb_node *gens, int lodegree, int orig_syz, int level, int strategy)
Definition res-a2-gb.cpp:75
void stats() const
virtual void set_output(gb_node *p)
Definition res-a2-gb.cpp:85
s_pair_heap * spairs
Definition res-a2.hpp:129
int n_pairs_gcd
Definition res-a2.hpp:154
int n_pairs_usyz
Definition res-a2.hpp:150
void gb_reduce(gbvector *&f, gbvector *&fsyz)
const Monoid * M
Definition res-a2.hpp:115
char use_hilb
Definition res-a2.hpp:164
const PolynomialRing * originalR
Definition res-a2.hpp:113
void flush_pairs()
bool s_pair_step()
virtual RingElement * hilbertNumerator()
void compute_s_pair(s_pair *p)
int n_pairs_hilb
Definition res-a2.hpp:153
gb_node * gens
Definition res-a2.hpp:138
int hf_numgens_gb
Definition res-a2.hpp:166
int gb_sort_partition(int lo, int hi)
bool receive_generator(gbvector *f, int n, const ring_elem denom)
virtual void reduce(gbvector *&f, gbvector *&fsyz)
GBRing * GR
Definition res-a2.hpp:114
s_pair * new_s_pair(gb_elem *p, gb_elem *q, const int *lcm)
int n_gb_syz
Definition res-a2.hpp:169
bool is_done()
virtual const FreeModule * output_free_module() const =0
gbvector * remove_lead_term()
Definition gbring.cpp:1592
gbvector * value()
Definition gbring.cpp:1603
void add(gbvector *p)
Definition gbring.cpp:1532
const gbvector * get_lead_term()
Definition gbring.cpp:1551
static int coeff_of(const RingElement *h, int deg)
Definition hilb.cpp:704
static RingElement * hilbertNumerator(const Matrix *M)
Definition hilb.cpp:665
int basis_elem() const
Definition int-bag.hpp:66
void * basis_ptr() const
Definition int-bag.hpp:67
Definition mem.hpp:78
const int SPAIR_PAIR
Definition comp-gb.hpp:56
const int SPAIR_RING
Definition comp-gb.hpp:57
GBComputation — abstract base of every Groebner-basis algorithm in the engine.
@ STRATEGY_LONGPOLYNOMIALS
@ STRATEGY_USE_HILB
@ STRATEGY_SORT
ComputationStatusCode
Definition computation.h:53
@ COMP_DONE
Definition computation.h:60
@ COMP_ERROR
Definition computation.h:56
@ COMP_COMPUTING
Definition computation.h:71
@ COMP_INTERRUPTED
Definition computation.h:57
int error()
Definition error.c:48
#define Matrix
Definition factory.cpp:14
void gb(IntermediateBasis &F, int n)
#define monomial
Definition gb-toric.cpp:11
int p
Hilbert-series numerator via the Bigatti-Caboara-Robbiano recursion.
int_bag Bag
Definition int-bag.hpp:70
bool system_interrupted()
system_interrupted() — thread-safe polling predicate for Ctrl+C handling.
void freemem(void *s)
Definition m2-mem.cpp:103
void size_t s
Definition m2-mem.cpp:271
const int ERROR
Definition m2-mem.cpp:55
VALGRIND_MAKE_MEM_DEFINED & result(result)
char newline[]
Definition m2-types.cpp:49
int M2_gbTrace
Definition m2-types.cpp:52
MatrixConstructor — the mutable builder that produces an immutable Matrix.
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 VECTOR(T)
Definition newdelete.hpp:78
#define newarray_atomic(T, len)
Definition newdelete.hpp:91
#define STATE_GENS
Definition res-a2.hpp:16
#define STATE_DONE
Definition res-a2.hpp:12
#define STATE_NEW_DEGREE
Definition res-a2.hpp:13
#define STATE_GB
Definition res-a2.hpp:15
int monom[1]
Definition ringelem.hpp:160
Singly linked-list node carrying one term of a polynomial-ring element.
Definition ringelem.hpp:156
gbvector * fsyz
Definition spair.hpp:59
gbvector * f
Definition spair.hpp:58
int me
Definition spair.hpp:62
gbvector * next
Definition gbring.hpp:80
int monom[1]
Definition gbring.hpp:83
int comp
Definition gbring.hpp:82
int * lcm
Definition spair.hpp:95
gb_elem * second
Definition spair.hpp:97
int syz_type
Definition spair.hpp:92
s_pair * next
Definition spair.hpp:90
gb_elem * first
Definition spair.hpp:96
int compare_num
Definition spair.hpp:93
Engine-wide stylistic constants: LT / EQ / GT codes, INTSIZE, GEOHEAP_SIZE.
void emit_wrapped(const char *s)
Definition text-io.cpp:27
void emit_line(const char *s)
Definition text-io.cpp:47
void emit(const char *s)
Definition text-io.cpp:41
Text-formatting helpers layered on buffer: bignum print, line wrapping, M2_gbTrace-gated emit.