Macaulay2 Engine
Loading...
Searching...
No Matches
comp-res.cpp
Go to the documentation of this file.
1// Copyright 2004 Michael E. Stillman.
2
3#include "text-io.hpp"
4#include "comp-res.hpp"
5#include "res-a1.hpp"
6#include "res-a0.hpp"
7#include "res-a2.hpp"
8#include "finalize.hpp"
11
12#include <iostream>
13
17 const Matrix *m,
18 M2_bool resolve_cokernel,
19 int max_level,
20 M2_bool use_max_slanted_degree,
21 int max_slanted_degree,
22 int algorithm,
23 int strategy,
24 int numThreads, // only used for algorithms supporting parallelism. 0 means use TBB default.
25 M2_bool parallelizeByDegree) // only used for algorithms supporting parallelism. 0 means use TBB default.
26{
27 // The following modification is because some algorithms do not work if
28 // max_level is 0.
29 // github issue (crash, #368).
30 if (max_level <= 0) max_level = 1;
31
32 const Ring *R = m->get_ring();
33 ResolutionComputation *C = nullptr;
34 int origsyz;
35 // First, we need to check that m is homogeneous, and that
36 // the heft values of the variables are all positive.
37 // All of these algorithms also assume that R is a polynomial ring.
38
40 if (NCP != nullptr)
41 {
42 if (M2_gbTrace > 0) emit_line("NC resolution");
43 C = createNCRes(m, max_level, strategy);
44 return C;
45 }
47 if (P == nullptr)
48 {
49 ERROR("engine resolution strategies all require a polynomial base ring");
50 return nullptr;
51 }
52 const Ring* K = P->getCoefficientRing();
53 if (K->get_precision() != 0)
54 {
55 ERROR("free resolutions over polynomial rings with RR or CC coefficients not yet implemented");
56 return nullptr;
57 }
59 {
60 ERROR(
61 "engine resolution strategies all require a Heft vector which is "
62 "positive for all variables");
63 return nullptr;
64 }
65 if (algorithm < 4 and !m->is_homogeneous())
66 {
67 ERROR("engine resolution strategies require a homogeneous module");
68 return nullptr;
69 }
70
71 switch (algorithm)
72 {
73 case 1:
74 if (!resolve_cokernel)
75 {
76 ERROR(
77 "resolution Strategy=>1 cannot resolve a cokernel with a given "
78 "presentation: use Strategy=>2 or Strategy=>3 instead");
79 return nullptr;
80 }
81 if (!R->is_commutative_ring())
82 {
83 ERROR(
84 "use resolution Strategy=>2 or Strategy=>3 for non commutative "
85 "polynomial rings");
86 return nullptr;
87 }
88 if (M2_gbTrace > 0) emit_line("resolution Strategy=>1");
89 C = new res_comp(m, max_level, strategy);
90 break;
91 case 0:
92 if (!resolve_cokernel)
93 {
94 ERROR(
95 "resolution Strategy=>0 cannot resolve a cokernel with a given "
96 "presentation: use Strategy=>2 or Strategy=>3 instead");
97 return nullptr;
98 }
99 if (!R->is_commutative_ring())
100 {
101 ERROR(
102 "use resolution Strategy=>2 or Strategy=>3 for non commutative "
103 "polynomial rings");
104 return nullptr;
105 }
106 if (M2_gbTrace > 0) emit_line("resolution Strategy=>0");
107 C = new res2_comp(
108 m, max_level, use_max_slanted_degree, max_slanted_degree, strategy);
109 break;
110 case 2:
111 origsyz = m->n_cols();
112 if (M2_gbTrace > 0) emit_line("resolution Strategy=>2");
113 C = new gbres_comp(m, max_level + 1, origsyz, strategy);
114 break;
115 case 3:
116 origsyz = m->n_cols();
117 if (M2_gbTrace > 0) emit_line("resolution Strategy=>3");
118 C = new gbres_comp(
119 m, max_level + 1, origsyz, strategy | STRATEGY_USE_HILB);
120 break;
121 case 4:
122 case 5:
123 if (!resolve_cokernel)
124 {
125 ERROR(
126 "resolution Strategy=>4 cannot resolve a cokernel with a given "
127 "presentation: use Strategy=>2 or Strategy=>3 instead");
128 return nullptr;
129 }
130 if (!P->is_skew_commutative() and !R->is_commutative_ring())
131 {
132 ERROR(
133 "use resolution Strategy=>2 or Strategy=>3 for non commutative "
134 "polynomial rings");
135 return nullptr;
136 }
137 if (M2_gbTrace > 0) emit_line("resolution Strategy=>4 (res-f4)");
138 C = createF4Res(m, max_level, strategy, numThreads, parallelizeByDegree);
139 if (C == nullptr) return nullptr;
140 break;
141 }
142 if (C == nullptr)
143 {
144 ERROR("unknown resolution algorithm");
145 return nullptr;
146 }
147 intern_res(C);
148 return C;
149}
150
151void ResolutionComputation::betti_init(int lo, int hi, int len, int *&bettis)
152{
153 int z = (hi - lo + 1) * (len + 1);
154 bettis = newarray_atomic_clear(int, z);
155}
156
158 int hi,
159 int len,
160 int *bettis)
161{
162 int d, lev;
163 int hi1 = hi + 1;
164 int len1 = len + 1;
165
166 // Reset 'hi1' to reflect the top degree that occurs
167 for (d = hi; d >= lo; d--)
168 {
169 for (lev = 0; lev <= len; lev++)
170 if (bettis[lev + (len + 1) * (d - lo)] > 0)
171 {
172 hi1 = d;
173 break;
174 }
175 if (hi1 <= hi) break;
176 }
177 if (hi1 > hi) hi1 = hi;
178
179 // Reset 'len1' to reflect the top level that occurs
180 for (lev = len; lev >= 0; lev--)
181 {
182 for (d = lo; d <= hi1; d++)
183 if (bettis[lev + (len + 1) * (d - lo)] > 0)
184 {
185 len1 = lev;
186 break;
187 }
188 if (len1 <= len) break;
189 }
190 if (len1 > len) len1 = len;
191
192 int totallen = (hi1 - lo + 1) * (len1 + 1);
193 M2_arrayint result = M2_makearrayint(3 + totallen);
194
195 result->array[0] = lo;
196 result->array[1] = hi1;
197 result->array[2] = len1;
198
199 int next = 3;
200 for (d = lo; d <= hi1; d++)
201 for (lev = 0; lev <= len1; lev++)
202 result->array[next++] = bettis[lev + (len + 1) * (d - lo)];
203
204 return result;
205}
206
208{
209 int *a = ar->array;
210 int total_sum = 0;
211 int lo = a[0];
212 int hi = a[1];
213 int len = a[2] + 1;
214 o << "total ";
215 for (int lev = 0; lev < len; lev++)
216 {
217 int sum = 0;
218 for (int d = lo; d <= hi; d++) sum += a[len * (d - lo) + lev + 3];
219 total_sum += sum;
220 o.put(sum, 6);
221 o << ' ';
222 }
223 o << " [" << total_sum << "]" << newline;
224 for (int d = lo; d <= hi; d++)
225 {
226 o.put(d, 5);
227 o << ": ";
228 for (int lev = 0; lev < len; lev++)
229 {
230 int c = a[len * (d - lo) + lev + 3];
231 if (c != 0)
232 o.put(c, 6);
233 else
234 o << " -";
235 o << " ";
236 }
237 o << newline;
238 }
239}
240
242 int degree)
243{
244 (void) level;
245 (void) degree;
246 // the default version gives an error that it isn't defined
247 ERROR("this function not defined for this resolution type");
248 return nullptr;
249}
250
251// Local Variables:
252// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
253// indent-tabs-mode: nil
254// End:
Abstract Ring subclass that lifts either a FreeAlgebra or a FreeAlgebraQuotient into the engine's Rin...
const Ring * get_ring() const
Definition matrix.hpp:134
int n_cols() const
Definition matrix.hpp:147
bool primary_degrees_of_vars_positive() const
Definition monoid.cpp:298
Abstract base class for mutable matrices over an arbitrary engine Ring, the in-place counterpart of t...
Definition mat.hpp:79
const Ring * getCoefficientRing() const
Definition polyring.hpp:200
virtual const Monoid * getMonoid() const
Definition polyring.hpp:282
bool is_skew_commutative() const
Definition polyring.hpp:237
Abstract base for the engine's polynomial-ring hierarchy.
Definition polyring.hpp:96
static void betti_display(buffer &o, M2_arrayint a)
Definition comp-res.cpp:207
static void betti_init(int lo, int hi, int len, int *&bettis)
Definition comp-res.cpp:151
virtual const Matrix * get_matrix(int level)=0
static ResolutionComputation * choose_res(const Matrix *m, M2_bool resolve_cokernel, int max_level, M2_bool use_max_slanted_degree, int max_slanted_degree, int algorithm, int strategy, int numThreads, M2_bool parallelizeByDegree)
Definition comp-res.cpp:16
static M2_arrayint betti_make(int lo, int hi, int len, int *bettis)
Definition comp-res.cpp:157
virtual ~ResolutionComputation()
Definition comp-res.cpp:15
virtual const M2FreeAlgebraOrQuotient * cast_to_M2FreeAlgebraOrQuotient() const
Definition ring.hpp:266
virtual bool is_commutative_ring() const
Definition ring.hpp:189
virtual unsigned long get_precision() const
Definition ring.cpp:438
virtual const PolynomialRing * cast_to_PolynomialRing() const
Definition ring.hpp:243
xxx xxx xxx
Definition ring.hpp:102
void put(const char *s)
Definition buffer.cpp:35
One of the Resolution computations, based on computing step by step.
Definition res-a2.hpp:248
One of the Resolution computations, based on Schreyer and Lascala.
Definition res-a0.hpp:120
One of the Resolution computations, based on Schreyer and Lascala.
Definition res-a1.hpp:76
void intern_res(ResolutionComputation *G)
Definition finalize.cpp:144
ResolutionComputation — abstract base for every free-resolution algorithm in the engine.
@ STRATEGY_USE_HILB
#define Matrix
Definition factory.cpp:14
intern_* helpers that register long-lived engine objects with bdwgc finalisers.
const int ERROR
Definition m2-mem.cpp:55
VALGRIND_MAKE_MEM_DEFINED & result(result)
M2_arrayint M2_makearrayint(int n)
Definition m2-types.cpp:6
char newline[]
Definition m2-types.cpp:49
int M2_gbTrace
Definition m2-types.cpp:52
char M2_bool
Definition m2-types.h:82
ResolutionComputation * createNCRes(const Matrix *gbModuleMatrix, int max_level, int strategy)
NCResComputation — placeholder free-resolution driver for modules over a FreeAlgebraQuotient.
#define newarray_atomic_clear(T, len)
Definition newdelete.hpp:93
res2_comp — original (1996) free-resolution engine using explicit pair processing.
ResolutionComputation * createF4Res(const Matrix *groebnerBasisMatrix, int max_level, int strategy, int numThreads, bool parallelizeByDegree)
F4ResComputation — top-level Schreyer-frame F4 free-resolution driver.
void emit_line(const char *s)
Definition text-io.cpp:47
Text-formatting helpers layered on buffer: bignum print, line wrapping, M2_gbTrace-gated emit.