Macaulay2 Engine
Loading...
Searching...
No Matches
res-f4-m2-interface.cpp
Go to the documentation of this file.
1// Copyright 2016 Michael E. Stillman
2
3#include "m2tbb.hpp" // Needs to occur earlier than ffpack.
5#include "ZZ.hpp" // for RingZZ
6#include "aring-RRR.hpp" // for ARingRRR
7#include "aring-zz-gmp.hpp" // for ARingZZGMP
8#include "aring-zzp-ffpack.hpp" // for ARingZZpFFPACK
9#include "aring-zzp-flint.hpp" // for ARingZZpFlint
10#include "aring.hpp" // for ring_RR
11#include "coeffrings.hpp" // for Coefficient...
12#include "comp.hpp" // for Computation
13#include "mat-linalg.hpp" // for DMatLinAlg
14#include "dmat.hpp" // for DMat
15#include "interface/m2-types.h" // for M2_arrayint
16#include "error.h" // for ERROR
17#include "exceptions.hpp" // for engine_error
18#include "freemod.hpp" // for FreeModule
19#include "gauss.hpp" // for GaussElimCo...
20#include "gbring.hpp" // for gbvector
21#include "interface/groebner.h" // for rawMinimalB...
22#include "mat.hpp" // for MutableMatrix
23#include "matrix-con.hpp" // for MatrixConst...
24#include "matrix.hpp" // for Matrix
25#include "monoid.hpp" // for Monoid
26#include "newdelete.hpp" // for newarray
27#include "polyring.hpp" // for PolynomialRing
28#include "ring.hpp" // for Ring, globalZZ
29#include "schreyer-resolution/res-f4-computation.hpp" // for F4ResComput...
30#include "schreyer-resolution/res-moninfo.hpp" // for ResMonoid
31#include "schreyer-resolution/res-monomial-types.hpp" // for res_monomia...
32#include "schreyer-resolution/res-poly-ring.hpp" // for ResPolynomialIterator
33#include "schreyer-resolution/res-schreyer-frame.hpp" // for SchreyerFrame
34#include "schreyer-resolution/res-schreyer-order.hpp" // for ResSchreyer...
35#include "timing.hpp" // for timer, seconds
36#include <cstdlib> // for exit, size_t
37#include <chrono> // for common_type...
38#include <iostream> // for operator<<
39#include <type_traits> // for move
40#include <vector> // for vector, vec...
41
43 const FreeModule* F,
44 vec v,
46{
47 const PolynomialRing* origR = F->get_ring()->cast_to_PolynomialRing();
48 const Monoid* M = origR->getMonoid();
49
50 ring_elem denom;
51 gbvector* f = origR->translate_gbvector_from_vec(F, v, denom);
52 GBRing* GR = origR->get_gb_ring();
53 int n = GR->gbvector_n_terms(f);
54
55#if 0
56 buffer o;
57 o << "input: ";
58 GR->gbvector_text_out(o,F,f,-1);
59 o << newline;
60 emit(o.str());
61#endif
62
63 int* exp = new int[M->n_vars()];
64
66
67 // all these pointers (or values) are still in the element f.
68 // auto monoms = std::unique_ptr<res_monomial_word[]>(new res_monomial_word[n
69 // * R.monoid().max_monomial_size()]);
70 std::vector<res_monomial_word> monoms(n * R.monoid().max_monomial_size());
71 n = 0;
72 res_monomial_word* nextmonom = monoms.data();
73 for (gbvector* t = f; t != nullptr; t = t->next)
74 {
76 coeffs, t->coeff, f->coeff); // note: f->coeff is assumed to be 1 for
77 // finite fields, but for QQ both of
78 // these are integers
79
80 M->to_expvector(t->monom, exp);
82 exp,
83 t->comp - 1,
84 nextmonom); // gbvector components are shifted up by one
85 nextmonom += R.monoid().monomial_size(nextmonom);
86 n++;
87 }
88
90 GR->gbvector_remove(f);
91 delete[] exp;
92}
93
95 const ResPolynomial& f,
96 const FreeModule* F)
97{
98 const PolynomialRing* origR = F->get_ring()->cast_to_PolynomialRing();
99 const Monoid* M = origR->getMonoid();
100
101 monomial m1 = M->make_one();
102
103 Nterm** comps = newarray(Nterm*, F->rank());
104 Nterm** last = newarray(Nterm*, F->rank());
105 for (int i = 0; i < F->rank(); i++)
106 {
107 comps[i] = nullptr;
108 last[i] = nullptr;
109 }
110
111 int* exp = new int[M->n_vars()];
112
113 const res_monomial_word* w = f.monoms.data();
114 for (int i = 0; i < f.len; i++)
115 {
116 component_index comp;
117 R.monoid().to_expvector(w, exp, comp);
118 w = w + R.monoid().monomial_size(w);
119 M->from_expvector(exp, m1);
120 ring_elem a =
122 Nterm* g = origR->make_flat_term(a, m1);
123 g->next = nullptr;
124 if (last[comp] == nullptr)
125 {
126 comps[comp] = g;
127 last[comp] = g;
128 }
129 else
130 {
131 last[comp]->next = g;
132 last[comp] = g;
133 }
134 }
135 vec result = nullptr;
136 for (int i = 0; i < F->rank(); i++)
137 {
138 if (comps[i] != nullptr)
139 {
140 vec v = origR->make_vec(i, comps[i]);
141 origR->add_vec_to(result, v);
142 comps[i] = nullptr;
143 last[i] = nullptr;
144 }
145 }
146
147 delete[] exp;
148 return result;
149}
150
152 SchreyerFrame& C,
153 int lev)
154{
155 FreeModule* result = new FreeModule(R, 0, true);
156 if (lev < 0 or lev > C.maxLevel())
157 {
158 return result;
159 }
160 const Monoid* M = R->getMonoid();
161 auto& thislevel = C.level(lev);
162 const ResSchreyerOrder& S = C.schreyerOrder(lev);
163 int* exp = new int[M->n_vars()];
164 for (auto i = 0; i < thislevel.size(); ++i)
165 {
166 int d[1];
167 d[0] = thislevel[i].mDegree;
168 monomial deg = M->degree_monoid()->make_one();
169 M->degree_monoid()->from_expvector(d, deg);
170 // Now grab the Schreyer info
171 // unpack to exponent vector, then repack into monoid element
172 monomial totalmonom = M->make_one();
173 component_index comp;
174 C.monoid().to_expvector(S.mTotalMonom[i], exp, comp);
175 M->from_expvector(exp, totalmonom);
176 result->append_schreyer(
177 deg, totalmonom, static_cast<int>(S.mTieBreaker[i]));
178 }
179 delete[] exp;
180 return result;
181}
182
184 const FreeModule* F,
185 SchreyerFrame& C,
186 int lev)
187// The input F must be the original freemodule of level=0.
188// assumption: lev >= 0.
189{
190 if (lev < 0 or lev > C.maxLevel())
191 {
192 ERROR("expected level in the range %d..%d",1,C.maxLevel());
193 return nullptr;
194 }
195 FreeModule* result = new FreeModule(R, 0, true);
196 const Monoid* M = R->getMonoid();
197 auto& thislevel = C.level(lev);
198 const ResSchreyerOrder& S = C.schreyerOrder(lev);
199 int* exp = new int[M->n_vars()];
200 monomial deg1 = M->degree_monoid()->make_one();
201 for (auto i = 0; i < thislevel.size(); ++i)
202 {
203 component_index comp;
204 C.monoid().to_expvector(S.mTotalMonom[i], exp, comp);
205 monomial deg = M->degree_monoid()->make_new(F->degree(comp)); // resulting degree of this element
206 M->degree_of_expvector(exp, deg1);
207 M->degree_monoid()->mult(deg, deg1, deg);
208 // Now grab the Schreyer info
209 // unpack to exponent vector, then repack into monoid element
210 monomial totalmonom = M->make_one();
211 M->from_expvector(exp, totalmonom);
212 result->append_schreyer(
213 deg, totalmonom, static_cast<int>(S.mTieBreaker[i]));
214 }
215 delete[] exp;
216 M->degree_monoid()->remove(deg1);
217 return result;
218}
219
221 int lev,
222 const FreeModule* tar,
223 const FreeModule* src)
224{
225 if (lev < 0 or lev > C.maxLevel())
226 {
227 MatrixConstructor zero(tar, src);
228 return zero.to_matrix();
229 }
230 auto& thislevel = C.level(lev);
231 MatrixConstructor result(tar, src);
232 int j = 0;
233 for (auto i = thislevel.cbegin(); i != thislevel.cend(); ++i, ++j)
234 {
235 vec v = to_M2_vec(C.ring(), i->mSyzygy, tar);
236 result.set_column(j, v);
237 }
238 return result.to_matrix();
239}
240
241// NEW
243 const Ring* R,
244 int lev)
245{
246 // Ring will be R, which should be a polynomial ring with the same monoid as
247 // ring of C.
248 const PolynomialRing* RP = R->cast_to_PolynomialRing();
249 const Monoid* M = RP->getMonoid();
250
251 if (lev <= 0 or lev > C.maxLevel())
252 {
254 R,
255 0, // TODO: set this correctly?
256 0, // TODO: set this correctly? i.e. one of these might be in range,
257 // so getting the rank correct might be good.
258 true);
259 }
260
261 auto& thislevel = C.level(lev);
262 int ncols = static_cast<int>(thislevel.size());
263 int nrows = static_cast<int>(C.level(lev - 1).size());
264
265 // create the mutable matrix
266 MutableMatrix* result = MutableMatrix::zero_matrix(R, nrows, ncols, true);
267
268 // Nterm **comps = newarray(Nterm *, nrows);
269 Nterm** comps = newarray(Nterm*, nrows);
270 Nterm** last = newarray(Nterm*, nrows);
271
272 monomial m1 = M->make_one();
273 // FIXME: is exp a monomial or exponent vector?
274 int* exp = new int[M->n_vars() + 1];
275
276 int j = 0;
277 for (auto j1 = thislevel.cbegin(); j1 != thislevel.cend(); ++j1, ++j)
278 {
279 // Now we create the polynomials for column j
280 // into 'comps', 'last'.
281 const ResPolynomial& f = (*j1).mSyzygy;
282 for (int i = 0; i < nrows; i++)
283 {
284 comps[i] = nullptr;
285 last[i] = nullptr; // used to easily place monomials in the correct
286 // bin, at the end of the polynomials.
287 }
288 const res_monomial_word* w = f.monoms.data();
289 for (int i = 0; i < f.len; i++)
290 {
291 component_index comp;
292 C.ring().monoid().to_expvector(w, exp, comp);
293 w = w + C.ring().monoid().monomial_size(w);
294 M->from_expvector(exp, m1);
296 Nterm* g = RP->make_flat_term(a, m1);
297 if (g == nullptr) continue;
298 g->next = nullptr;
299 if (last[comp] == nullptr)
300 {
301 comps[comp] = g;
302 last[comp] = g;
303 }
304 else
305 {
306 last[comp]->next = g;
307 last[comp] = g;
308 }
309 }
310 // Now we have run through the entire vector, so put it into result
311 for (int r = 0; r < nrows; r++) result->set_entry(r, j, comps[r]);
312 }
313
314 delete[] exp;
315 freemem(comps);
316 freemem(last);
317 return result;
318}
319
321 const Ring* K,
322 int lev,
323 int degree)
324{
325 // The ring K should be the coefficient ring of the poly ring of C,
326 // OR: if the coefficient ring is QQ, then it can be RR, or a finite field.
327
328 // Now we loop through the elements of degree 'degree' at level 'lev'
329 auto& thislevel = C.level(lev);
330 int n = 0;
331 for (auto p = thislevel.begin(); p != thislevel.end(); ++p)
332 {
333 if (p->mDegree == degree) n++;
334 }
335
336 auto& prevlevel = C.level(lev - 1);
337 int* newcomps = new int[prevlevel.size()];
338 int nextcomp = 0;
339 for (int i = 0; i < prevlevel.size(); i++)
340 if (prevlevel[i].mDegree == degree)
341 newcomps[i] = nextcomp++;
342 else
343 newcomps[i] = -1;
344
345 // create the mutable matrix
346 MutableMatrix* result = MutableMatrix::zero_matrix(K, nextcomp, n, true);
347 // Now loop through the elements at thislevel,
348 // and for each, loop through the terms of mSyzygy.
349 // if the component x satisfies newcomps[x] >= 0, then place
350 // this coeff into the mutable matrix.
351 int col = 0;
352
353 for (auto p = thislevel.begin(); p != thislevel.end(); ++p)
354 {
355 if (p->mDegree != degree) continue;
356 auto& f = p->mSyzygy;
357 auto end = ResPolynomialIterator(C.ring(), f, 1);
358 auto i = ResPolynomialIterator(C.ring(), f);
359 for (; i != end; ++i)
360 {
361 long comp = C.monoid().get_component(i.monomial());
362 if (newcomps[comp] >= 0)
363 {
365 f.coeffs, i.coefficient_index());
366 result->set_entry(newcomps[comp], col, a);
367 }
368 }
369 ++col;
370 }
371
372 delete[] newcomps;
373 return result;
374}
375
376// One way to organize this:
377// Create an iterator, such that: i->components() is a std::vector of sorted indices
378// and i->coefficients() is a std::vector of ring_elem's.
379// or: take a function as input, that knows how to consume this info.
380//
381
398{
399public:
400 DegreeZeroMapGenerator(SchreyerFrame& C, int slanted_degree, int lev)
401 : mSchreyerFrame(C),
402 mThisLevel(C.level(lev)),
403 mDegree(slanted_degree+lev),
404 mLevel(lev),
405 mNumRows(0),
406 mNumColumns(0)
407 {
408 if (lev <= 0 or lev > C.maxLevel())
409 {
410 return;
411 }
412 int degree = slanted_degree + lev;
413 for (auto p = mThisLevel.begin(); p != mThisLevel.end(); ++p)
414 {
415 if (p->mDegree == degree) mNumColumns++;
416 }
417
418 auto& prevlevel = C.level(lev - 1);
419 mComponentTranslation.resize(prevlevel.size());
420 for (int i = 0; i < prevlevel.size(); i++)
421 {
422 if (prevlevel[i].mDegree == mDegree)
424 else
425 mComponentTranslation[i] = -1;
426 }
427 }
428
429 const Ring* ring() const { return mSchreyerFrame.vectorArithmetic().ring(); }
430
431 int numRows() const { return mNumRows; }
432
433 int numColumns() const { return mNumColumns; }
434
435 long numNonzero() const
436 {
437 long nnonzeros = 0;
438 auto& thislevel = mSchreyerFrame.level(mLevel);
439 for (auto p = thislevel.begin(); p != thislevel.end(); ++p)
440 {
441 if (p->mDegree != mDegree) continue;
442 auto& f = p->mSyzygy;
443 auto end = ResPolynomialIterator(mSchreyerFrame.ring(), f, 1);
444 auto i = ResPolynomialIterator(mSchreyerFrame.ring(), f);
445
446 for (; i != end; ++i)
447 {
448 auto comp = mSchreyerFrame.monoid().get_component(i.monomial());
449 if (mComponentTranslation[comp] >= 0)
450 nnonzeros++;
451 }
452 }
453 return nnonzeros;
454 }
455
469 {
470 public:
472 : mGenerator(D),
473 mColumn(-1),
476 mEnd(D.mThisLevel.end())
477 {
478 increment();
479 }
480
482
483 bool operator==(const iterator& sentinel) const
484 {
485 // Do we need to check that these refer to the same object?
486 return mColumn == sentinel.mColumn;
487 }
488
489 bool operator!=(const iterator& sentinel) const
490 {
491 // Do we need to check that these refer to the same object?
492 return mColumn != sentinel.mColumn;
493 }
494
496 {
497 increment();
498 return *this;
499 }
500
501 int column() const { return mColumn; }
502
503 const std::vector<int>& components() const { return mComponents; }
504
505 const std::vector<long>& coefficients() const { return mCoefficients; }
506
507 private:
509 {
510 ++mColumn;
511 mComponents.clear();
512 mCoefficients.clear();
513 if (mColumn == mNumColumns) return;
514 for (; mIter != mEnd; ++mIter)
515 {
516 if (mIter->mDegree == mGenerator.mDegree) break;
517 }
518 auto& f = mIter->mSyzygy;
519 auto end = ResPolynomialIterator(mGenerator.mSchreyerFrame.ring(), f, 1);
520 auto i = ResPolynomialIterator(mGenerator.mSchreyerFrame.ring(), f);
521
522 for (; i != end; ++i)
523 {
524 auto comp = mGenerator.mSchreyerFrame.monoid().get_component(i.monomial());
525 auto new_comp = mGenerator.mComponentTranslation[comp];
526 if (new_comp >= 0)
527 {
528 mComponents.push_back(new_comp);
529 long val =
530 mGenerator.mSchreyerFrame.vectorArithmetic().to_modp_long(f.coeffs, i.coefficient_index());
531 mCoefficients.push_back(val);
532 }
533 }
534 ++mIter;
535 }
536 private:
537 using Iter = std::vector<SchreyerFrameTypes::FrameElement>::iterator;
543 std::vector<int> mComponents;
544 std::vector<long> mCoefficients;
545 };
546
548
549 iterator begin() { return iterator(*this); }
550 iterator end() { return iterator(*this, 1); }
551
552private:
554 std::vector<SchreyerFrameTypes::FrameElement>& mThisLevel;
559 std::vector<int> mComponentTranslation; // indices of the rows. -1 means not present.
560};
561
562template<typename Gen>
564{
565 const Ring* R = G.ring();
566 MatrixConstructor M(R->make_FreeModule(G.numRows()), R->make_FreeModule(G.numColumns()), nullptr);
567 for (auto i = G.begin(); i != G.end(); ++i)
568 {
569 for (int j=i.components().size()-1; j>=0; --j)
570 {
571 M.set_entry(i.components()[j], i.column(), R->from_long(i.coefficients()[j]));
572 }
573 }
574 return M.to_matrix();
575}
576
577template<typename RingType, typename Gen>
579{
580 M.resize(G.numRows(), G.numColumns());
581
582 for (auto i = G.begin(); i != G.end(); ++i)
583 {
584 for (int j=0; j<i.components().size(); ++j)
585 {
586 M.ring().set_from_long(M.entry(i.components()[j], i.column()), i.coefficients()[j]);
587 }
588 }
589}
590
591template<typename RingType, typename Gen>
593{
594 M.resize(G.numColumns(), G.numRows());
595
596 for (auto i = G.begin(); i != G.end(); ++i)
597 {
598 for (int j=0; j<i.components().size(); ++j)
599 {
600 M.ring().set_from_long(M.entry(i.column(), i.components()[j]), i.coefficients()[j]);
601 }
602 }
603}
604
605
606template<typename Gen>
608{
610 // std::cout << "--- sparse matrix ----" << std::endl;
611 // dmatrix(M);
612 // std::cout << "----------------------" << std::endl;
613 auto timeA = timer();
614 GaussElimComputation comp { M, 0, 0 };
615 comp.set_stop_conditions(false, nullptr, -1, -1, -1, -1, -1, false, nullptr);
616 comp.start_computation();
617 // const Matrix* gbM = comp.get_gb();
618 // std::cout << "--- gb of matrix ----" << std::endl;
619 // dmatrix(gbM);
620 // std::cout << "----------------------" << std::endl;
621
622 int rk = comp.get_initial(-1)->n_cols();
623 auto timeB = timer();
624 double nsecs = seconds(timeB - timeA);
625
626 timeComputeSparseRanks += nsecs;
627
628 if (M2_gbTrace >= 2)
629 {
630 if (M->n_rows() > 0 and M->n_cols() > 0)
631 std::cout << " sparse rank = " << rk
632 << " time = " << nsecs << " sec"
633 << std::endl;
634 }
635
636 return rk;
637}
638
639template<typename Gen>
640int SchreyerFrame::rankUsingDenseMatrix(Gen& D, bool transposed)
641{
642 unsigned int charac =
643 static_cast<unsigned int>(vectorArithmetic().ring()->characteristic());
644 M2::ARingZZpFFPACK R(charac);
645 DMat<M2::ARingZZpFFPACK> M(R, 0, 0);
646 if (!transposed)
648 else
651 // std::cout << "---- dense matrix ----" << std::endl;
652 // displayMat(M);
653 // std::cout << "----------------------" << std::endl;
654 auto timeA = timer();
655 int rk = static_cast<int>(a.rank());
656 auto timeB = timer();
657 double nsecs = seconds(timeB - timeA);
658
659 timeComputeRanks += nsecs;
660
661 if (M2_gbTrace >= 2)
662 {
663 if (M.numRows() > 0 and M.numColumns() > 0)
664 std::cout << " dense rank = " << rk
665 << " time = " << nsecs << " sec"
666 << std::endl;
667 }
668
669 return rk;
670}
671
672template<typename Gen>
674{
675 unsigned int charac =
676 static_cast<unsigned int>(vectorArithmetic().ring()->characteristic());
677 M2::ARingZZpFlint R(charac);
678 DMat<M2::ARingZZpFlint> M(R, 0, 0);
679 if (!transposed)
681 else
684 // std::cout << "---- dense matrix ----" << std::endl;
685 // displayMat(M);
686 // std::cout << "----------------------" << std::endl;
687 auto timeA = timer();
688 int rk = static_cast<int>(a.rank());
689 auto timeB = timer();
690 double nsecs = seconds(timeB - timeA);
691
692 timeComputeRanks += nsecs;
693
694 if (M2_gbTrace >= 2)
695 {
696 if (M.numRows() > 0 and M.numColumns() > 0)
697 std::cout << " dense rank = " << rk
698 << " time = " << nsecs << " sec"
699 << std::endl;
700 }
701
702 return rk;
703}
704
705int SchreyerFrame::rank(int slanted_degree, int lev)
706{
707 DegreeZeroMapGenerator D(*this, slanted_degree, lev);
708 long nnonzero = D.numNonzero();
709 long nelements = static_cast<long>(D.numRows()) * static_cast<long>(D.numColumns());
710 double nnonzeroD = static_cast<double>(nnonzero);
711 double nelementsD = static_cast<double>(nelements);
712 double frac_nonzero = (nelements > 0 ? nnonzeroD/nelementsD : 1.0);
713
714 if (M2_gbTrace >= 2)
715 {
716 std::cout << " rank(" << lev << "," << slanted_degree << ") size = "
717 << D.numRows() << " x " << D.numColumns()
718 << " frac non-zero= " << frac_nonzero << std::endl << std::flush;
719 }
720 int rkSparse = -1;
721 int rkDense = -1;
722 if (frac_nonzero <= .007)
723 {
724 rkSparse = rankUsingSparseMatrix(D);
725 return rkSparse;
726 }
727 else
728 {
729 rkDense = rankUsingDenseMatrix(D);
730 return rkDense;
731 }
732}
733
735 M2_arrayint slanted_degree_limit,
736 M2_arrayint length_limit)
737{
738 try
739 {
740 F4ResComputation* G = dynamic_cast<F4ResComputation*>(C);
741 if (G != nullptr)
742 return G->minimal_betti(slanted_degree_limit,
743 length_limit); // Computes it if needed
744 ERROR("expected resolution computed via res(...,FastNonminimal=>true)");
745 return nullptr;
746 } catch (const exc::engine_error& e)
747 {
748 ERROR(e.what());
749 return nullptr;
750 }
751}
752
753// Local Variables:
754// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
755// End:
static const int nelements
Legacy RingZZ — a Ring-derived integer ring backed by GMP mpz_t.
M2::ARingRRR — arbitrary-precision real numbers backed by MPFR.
M2::ARingZZGMP — aring integer ring backed straight by GMP mpz_t.
M2::ARingZZpFFPACK — Z/p via FFLAS-FFPACK's Givaro::Modular<double> field.
M2::ARingZZpFlint — Z/p via FLINT's nmod_t precomputed-reciprocal reduction.
Shared base of the aring framework (namespace M2) that unifies the engine's coefficient rings.
Computation * set_stop_conditions(M2_bool always_stop, M2_arrayint degree_limit, int basis_element_limit, int syzygy_limit, int pair_limit, int codim_limit, int subring_limit, M2_bool just_min_gens, M2_arrayint length_limit)
Definition comp.cpp:11
Abstract base for long-running, resumable engine computations (GBComputation, ResolutionComputation,...
Definition comp.hpp:70
size_t numRows() const
Definition dmat.hpp:144
ElementType & entry(size_t row, size_t column)
Definition dmat.hpp:148
void resize(size_t new_nrows, size_t new_ncols)
Definition dmat.hpp:157
const ACoeffRing & ring() const
Definition dmat.hpp:143
size_t numColumns() const
Definition dmat.hpp:145
Definition dmat.hpp:62
const std::vector< long > & coefficients() const
const std::vector< int > & components() const
bool operator!=(const iterator &sentinel) const
iterator(DegreeZeroMapGenerator &D)
bool operator==(const iterator &sentinel) const
std::vector< SchreyerFrameTypes::FrameElement >::iterator Iter
iterator(DegreeZeroMapGenerator &D, int)
Column iterator over the parent DegreeZeroMapGenerator's degree-zero submap.
std::vector< SchreyerFrameTypes::FrameElement > & mThisLevel
std::vector< int > mComponentTranslation
friend class DegreeZeroMapGenerator::iterator
DegreeZeroMapGenerator(SchreyerFrame &C, int slanted_degree, int lev)
View of one cell of a SchreyerFrame as the degree-zero (scalar) part of the differential between two ...
Type-erased owning handle to a dense coefficient vector held by a ConcreteVectorArithmetic<Ring>.
ResolutionComputation subclass that drives the F4 resolution engine (SchreyerFrame + F4Res) from the ...
const Ring * get_ring() const
Definition freemod.hpp:102
const_monomial degree(int i) const
Definition freemod.hpp:104
int rank() const
Definition freemod.hpp:105
Engine-side free module R^n over a Ring.
Definition freemod.hpp:66
void gbvector_remove(gbvector *f)
Definition gbring.cpp:288
void gbvector_text_out(buffer &o, const FreeModule *F, const gbvector *f, int nterms=-1) const
Definition gbring.cpp:779
int gbvector_n_terms(const gbvector *f) const
Definition gbring.cpp:392
Polynomial-ring view tuned for the inner loop of classical Buchberger Groebner-basis computations.
Definition gbring.hpp:120
virtual void start_computation()
Definition gauss.cpp:216
virtual const Matrix * get_initial(int nparts)
Definition gauss.cpp:278
Gaussian elimination class. To be rewritten.
Definition gauss.hpp:59
wrapper for the FFPACK::ModularBalanced<double> field implementation
aring-style adapter for Z/p with p a word-size prime, backed by FLINT's nmod_* routines.
int n_cols() const
Definition matrix.hpp:147
int n_rows() const
Definition matrix.hpp:146
Matrix * to_matrix()
void set_entry(int r, int c, ring_elem a)
Mutable builder used to assemble an immutable Matrix one column (or one term) at a time.
void to_expvector(const_monomial m, exponents_t result_exp) const
Definition monoid.cpp:747
void degree_of_expvector(const T *expvector, monomial result) const
Definition monoid.hpp:293
int n_vars() const
Definition monoid.hpp:207
monomial make_one() const
Definition monoid.cpp:455
void remove(monomial d) const
Definition monoid.cpp:462
const Monoid * degree_monoid() const
Definition monoid.hpp:175
void mult(const_monomial m, const_monomial n, monomial result) const
Definition monoid.cpp:363
monomial make_new(const_monomial d) const
Definition monoid.cpp:448
void from_expvector(const_exponents exp, monomial result) const
Definition monoid.cpp:742
Engine-side commutative monomial monoid: variable names, ordering, multidegree machinery,...
Definition monoid.hpp:89
static MutableMatrix * zero_matrix(const Ring *R, size_t nrows, size_t ncols, bool dense)
Definition mat.cpp:54
Abstract base class for mutable matrices over an arbitrary engine Ring, the in-place counterpart of t...
Definition mat.hpp:79
virtual GBRing * get_gb_ring() const
Definition polyring.hpp:276
virtual const Monoid * getMonoid() const
Definition polyring.hpp:282
virtual ring_elem make_flat_term(const ring_elem a, const_monomial m) const =0
virtual gbvector * translate_gbvector_from_vec(const FreeModule *F, const vec v, ring_elem &result_denominator) const =0
Abstract base for the engine's polynomial-ring hierarchy.
Definition polyring.hpp:96
static vec to_M2_vec(const ResPolyRing &R, const ResPolynomial &f, const FreeModule *F)
static FreeModule * to_M2_freemodule(const PolynomialRing *R, SchreyerFrame &C, int lev)
static MutableMatrix * to_M2_MutableMatrix(SchreyerFrame &C, const Ring *R, int lev)
static void from_M2_vec(const ResPolyRing &R, const FreeModule *F, vec v, ResPolynomial &result)
static Matrix * to_M2_matrix(SchreyerFrame &C, int lev, const FreeModule *tar, const FreeModule *src)
int max_monomial_size() const
component_index get_component(res_const_packed_monomial m) const
bool from_expvector(res_const_ntuple_monomial e, component_index comp, res_packed_monomial result) const
bool to_expvector(res_const_packed_monomial m, res_ntuple_monomial result, component_index &result_comp) const
int monomial_size(res_const_packed_monomial m) const
const ResMonoid & monoid() const
const VectorArithmetic & vectorArithmetic() const
The polynomial-ring view the F4 resolution engine reduces against: coefficient arithmetic plus the en...
std::vector< res_monomial_word > monoms
ElementArray coeffs
static void setPolyFromArrays(ResPolynomial &result, int len, ElementArray &coeffs, std::vector< res_monomial_word > &monoms)
Polynomial type used by the F4 resolution engine: parallel coefficient vector and concatenated monomi...
Forward iterator over the terms of a ResPolynomial.
virtual FreeModule * make_FreeModule() const
Definition ring.cpp:53
vec make_vec(int r, ring_elem a) const
Definition ring-vecs.cpp:60
virtual ring_elem from_long(long n) const =0
virtual const PolynomialRing * cast_to_PolynomialRing() const
Definition ring.hpp:243
long characteristic() const
Definition ring.hpp:159
void add_vec_to(vec &v, vec &w) const
xxx xxx xxx
Definition ring.hpp:102
int rankUsingDenseMatrixFlint(Gen &D, bool transposed=true)
int rankUsingSparseMatrix(Gen &D)
int rank(int slanted_degree, int lev)
const ResMonoid & monoid() const
std::vector< FrameElement > & level(int lev)
const ResPolyRing & ring() const
const VectorArithmetic & vectorArithmetic() const
int rankUsingDenseMatrix(Gen &D, bool transposed=true)
ResSchreyerOrder & schreyerOrder(int lev)
State container for the in-progress free resolution built by the F4 resolution engine.
ElementArray allocateElementArray(ComponentIndex nelems) const
Create a coefficient vector with room for nelems coefficients.
ring_elem ringElemFromElementArray(const ElementArray &coeffs, int index) const
void from_ring_elem(ElementArray &coeffs, ring_elem numer, ring_elem denom_not_used_except_QQ) const
const Ring * ring() const
char * str()
Definition buffer.hpp:72
Two SimpleARing-style coefficient adapters: CoefficientRingZZp and CoefficientRingR.
Abstract Computation base class — stop-condition machinery for incremental engine work.
DMat<ACoeffRing> — dense-matrix template plus the umbrella that wires in every per-ring specialisatio...
Engine error-reporting primitives: ERROR, INTERNAL_ERROR, error, error_message.
namespace exc — internal C++ exception types and the TRY / CATCH macro pair.
#define Matrix
Definition factory.cpp:14
FreeModule — finite-rank free module R^n, the type-level anchor for every Matrix.
GaussElimComputation — Gaussian elimination GB / submodule strategy over a field.
#define monomial
Definition gb-toric.cpp:11
GBRing and gbvector — the GB-tuned polynomial-ring view used by classical Buchberger code.
int p
int zero
Engine-boundary C API for Gröbner basis, resolution, and Hilbert-series computations.
void freemem(void *s)
Definition m2-mem.cpp:103
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
Engine-to-interpreter type vocabulary across the C++ / .dd boundary.
Engine TBB shim — single point of inclusion for every parallel primitive.
Templated DMat<R> linear algebra: LU, rank, determinant, solve, inverse, nullSpace.
MutableMatrix — abstract base of every mutable matrix the engine hands across the boundary.
MatrixConstructor — the mutable builder that produces an immutable Matrix.
Matrix — the engine's immutable homomorphism F -> G between free modules.
Monoid — variable count, naming, grading, and monomial order of a polynomial ring.
#define newarray(T, len)
Definition newdelete.hpp:82
our_new_delete — per-class opt-in routing of new / delete through bdwgc.
PolynomialRing — abstract polynomial-ring base, the engine's most-reused class.
F4ResComputation — top-level Schreyer-frame F4 free-resolution driver.
M2_arrayint rawMinimalBetti(Computation *C, M2_arrayint slanted_degree_limit, M2_arrayint length_limit)
Matrix * matrixFromSparseMatrixGenerator(Gen &G)
void setDMatFromSparseMatrixGeneratorTransposed(Gen &G, DMat< RingType > &M)
void setDMatFromSparseMatrixGenerator(Gen &G, DMat< RingType > &M)
Conversion layer between engine Matrix / vec types and the F4-resolution internal types.
ResMonoid dispatcher — single typedef switch between ResMonoidDense and ResMonoidSparse.
myword component_index
myword res_monomial_word
Typed-monomial vocabulary shared by ResMonoid, ResPolyRing, SchreyerFrame, and F4Res.
ResPolyRing and ResPolynomial — resolution-tuned polynomial-ring view and value type.
SchreyerFrame — in-progress representation of a free resolution organised by (level,...
ResSchreyerOrder — per-free-module-summand data implementing the Schreyer order on the next level.
tbb::flow::graph G
Ring — the legacy abstract base class for every coefficient and polynomial ring.
TermIterator< Nterm > end(Nterm *)
Definition ringelem.cpp:5
Nterm * next
Definition ringelem.hpp:157
Singly linked-list node carrying one term of a polynomial-ring element.
Definition ringelem.hpp:156
std::vector< res_packed_monomial > mTotalMonom
std::vector< component_index > mTieBreaker
Per-level Schreyer-order data attached to a SchreyerFrame::Level.
ring_elem coeff
Definition gbring.hpp:81
gbvector * next
Definition gbring.hpp:80
void emit(const char *s)
Definition text-io.cpp:41
std::chrono::steady_clock::time_point timer()
Definition timing.hpp:35
double seconds(DurationType time_diff)
Definition timing.hpp:59
Inline std::chrono::steady_clock wrappers and elapsed-time conversion helpers.