Macaulay2 Engine
Loading...
Searching...
No Matches
res-a2.cpp
Go to the documentation of this file.
1// Copyright 1997 Michael E. Stillman
2
3#include "res-a2.hpp"
4#include "hilb.hpp"
5#include "text-io.hpp"
6#include "matrix-con.hpp"
7#include "interrupted.hpp"
8extern ring_elem hilb(const Matrix &M, const Ring *RR);
9
11 : gens(m), g(nullptr), n_left(m->n_cols()), n_i(0)
12{
13 originalR = m->get_ring()->cast_to_PolynomialRing();
14 assert(originalR != 0);
15 GR = originalR->get_gb_ring();
17 n_gens = 0; // Also needs to be set at that time.
19}
20
23{
24 assert(0); // This routine should NEVER be called
25 return nullptr;
26}
28{
29 // This is when we ship off the elements in this degree. This should NEVER
30 // be called if elements of lower degree have not been sent.
31 if (this_degree != degree)
32 {
33 start_degree(degree);
34 }
35 for (;;)
36 {
38 if (n_i >= n_gens) return COMP_DONE;
39 if (g != nullptr)
40 {
41 ring_elem denom;
42 gbvector *v = originalR->translate_gbvector_from_vec(
43 gens->rows(), (*gens)[these[n_i]], denom);
44 g->receive_generator(v, these[n_i], denom);
45 }
46 n_i++;
47 n_left--;
48 }
49}
51{
52 return calc_gb(degree);
53}
54
56{
57 this_degree = deg;
58 n_gens = 0;
59 n_i = 0;
60 for (int i = 0; i < gens->n_cols(); i++)
61 {
62 if (gens->cols()->primary_degree(i) == this_degree) these[n_gens++] = i;
63 }
64 return n_gens;
65}
66
68{
69 n_left -= (n_gens - n_i);
70 n_gens = 0;
71 n_i = 0;
72}
73
74bool gb_emitter::is_done() { return (n_left == 0); }
75void gb_emitter::stats() const {}
76void gb_emitter::text_out(buffer &o) const { (void) o; }
78
79void gbres_comp::setup(const Matrix *m, int length, int origsyz, int strategy)
80{
81 int i;
83 if (originalR == nullptr) assert(0);
84 GR = originalR->get_gb_ring();
85 mi_stash = new stash("res mi nodes", sizeof(Nmi_node));
86
87 FreeModule *Fsyz = originalR->make_Schreyer_FreeModule();
88 if (length <= 0)
89 {
90 ERROR("resolution length must be at least 1");
91 length = 1;
92 }
93
94 // If origsyz, and length>1, create Fsyz as a Schreyer free
95 // if origsyz is smaller, truncate this module...
96
97 if (length > 1 && origsyz > 0)
98 {
99 if (origsyz > m->n_cols()) origsyz = m->n_cols();
100 monomial one = originalR->getMonoid()->make_one();
101 const int *mon;
102 for (i = 0; i < origsyz; i++)
103 {
104 if ((*m)[i] == nullptr)
105 mon = one;
106 else
107 {
108 Nterm *t = (*m)[i]->coeff;
109 mon = t->monom;
110 }
111 Fsyz->append_schreyer(m->cols()->degree(i), mon, i);
112 }
113 originalR->getMonoid()->remove(one);
114 }
115
118
119 n_nodes = length + 1;
121
122 nodes[0] = new gb_emitter(m);
123 nodes[1] =
124 new gb2_comp(Fsyz, mi_stash, nodes[0], lo_degree, origsyz, 1, strategy);
125 nodes[0]->set_output(nodes[1]);
126 if (n_nodes == 2)
127 {
128 // Don't compute syzygies at all.
129 nodes[1]->set_output(nullptr);
130 }
131 else if (n_nodes >= 3)
132 {
133 // Compute a resolution to length 'length', with last being
134 // a gb node.
135 int deg = lo_degree + 1;
136 if (origsyz > 0) deg--;
137 for (i = 2; i < n_nodes - 1; i++)
138 {
139 FreeModule *F = originalR->make_Schreyer_FreeModule();
140 nodes[i] =
141 new gb2_comp(F, mi_stash, nodes[i - 1], deg++, -1, i, strategy);
142 nodes[i - 1]->set_output(nodes[i]);
143 }
144 FreeModule *F = originalR->make_Schreyer_FreeModule();
145 nodes[n_nodes - 1] = new gb2_comp(
146 F, mi_stash, nodes[n_nodes - 2], deg++, 0, n_nodes - 1, strategy);
147 nodes[n_nodes - 1]->set_output(nullptr);
148 }
149 strategy_flags = strategy;
150}
151
152gbres_comp::gbres_comp(const Matrix *m, int length, int origsyz, int strategy)
153{
154 setup(m, length, origsyz, strategy);
155}
156
158 int length,
159 int origsyz,
160 const RingElement * /*hf*/,
161 int strategy)
162{
163 // MES: check homogeneity
164 setup(m, length, origsyz, strategy);
165 // nodes[0]->set_HF(hf);
166}
167
169{
170 for (int i = 0; i < n_nodes; i++)
171 {
172 nodes[i]->set_output(nullptr);
173 delete nodes[i];
174 }
175
176 delete mi_stash;
177}
178
179//---- state machine (roughly) for the computation ----
180
182{
183 if (stop_.length_limit != nullptr && stop_.length_limit->len > 0)
184 {
185 ERROR("cannot change length of resolution using this algorithm");
186 return false;
187 }
188 return true;
189}
190
192{
193 // int old_compare_type = compare_type;
194 // compare_type = (strategy_flags >> 10);
195 // if (M2_gbTrace >= 4)
196 // {
197 // buffer o;
198 // o << "compare=" << compare_type << newline;
199 // emit(o.str());
200 // }
201 for (int i = lo_degree; !is_done(); i++)
202 {
203 if (stop_.stop_after_degree && stop_.degree_limit->array[0] < i)
204 {
206 // compare_type = old_compare_type;
207 return;
208 }
209 if (M2_gbTrace >= 1)
210 {
211 buffer o;
212 o << "{" << i << "}";
213 emit(o.str());
214 }
215 enum ComputationStatusCode ret =
216 nodes[n_nodes - 1]->calc_gens(i + n_nodes - 3);
217 if (ret != COMP_DONE)
218 {
219 set_status(ret);
220 // compare_type = old_compare_type;
221 return;
222 }
224 }
225 // compare_type = old_compare_type;
227}
228
230{
231 for (int i = 0; i < n_nodes; i++)
232 if (!nodes[i]->is_done()) return false;
233 return true;
234}
235
237//--- Reduction --------------------------
238
240{
241 const FreeModule *F = nodes[0]->output_free_module();
242 if (m->n_rows() != F->rank())
243 {
244 ERROR("expected matrices to have same number of rows");
245 return nullptr;
246 }
247 MatrixConstructor mat_red(m->rows(), m->cols(), m->degree_shift());
248 MatrixConstructor mat_lift(nodes[1]->output_free_module(), m->cols(), nullptr);
249
250 for (int i = 0; i < m->n_cols(); i++)
251 {
252 const FreeModule *Fsyz = nodes[1]->output_free_module();
253
254 ring_elem denom;
255 gbvector *f = originalR->translate_gbvector_from_vec(F, (*m)[i], denom);
256 gbvector *fsyz = GR->gbvector_zero();
257
258 nodes[1]->reduce(f, fsyz);
259
260 vec fv = originalR->translate_gbvector_to_vec_denom(F, f, denom);
261 GR->get_flattened_coefficients()->negate_to(denom);
262 vec fsyzv = originalR->translate_gbvector_to_vec_denom(Fsyz, fsyz, denom);
263 mat_red.set_column(i, fv);
264 mat_lift.set_column(i, fsyzv);
265 }
266 lift = mat_lift.to_matrix();
267 return mat_red.to_matrix();
268}
269
271// Obtaining matrices as output //
273
274const FreeModule *gbres_comp::free_module(int level) const
275{
276 if (level >= 0 && level <= n_nodes - 1)
277 return const_cast<FreeModule *>(nodes[level]->output_free_module());
278 return nodes[0]->output_free_module()->get_ring()->make_FreeModule();
279}
281{
282 if (level <= 0 || level >= n_nodes)
283 return Matrix::zero(free_module(level - 1), free_module(level));
284 return nodes[level]->min_gens_matrix();
285}
287{
288 if (level <= 0 || level >= n_nodes)
289 return Matrix::zero(free_module(level - 1), free_module(level));
290 return nodes[level]->get_matrix();
291}
292
293const Matrix *gbres_comp::initial_matrix(int n, int level)
294{
295 if (level <= 0 || level >= n_nodes)
296 return Matrix::zero(free_module(level - 1), free_module(level));
297 return nodes[level]->initial_matrix(n);
298}
299
301{
302 if (level <= 0 || level >= n_nodes)
303 return Matrix::zero(free_module(level - 1), free_module(level));
304 return nodes[level]->gb_matrix();
305}
306
308{
309 if (level <= 0 || level >= n_nodes)
310 return Matrix::zero(free_module(level - 1), free_module(level));
311 return nodes[level]->change_matrix();
312}
313
315{
316 emit_line(
317 " #gb #pair #comp m z o u #hilb #gcd #mons #chg");
318 for (int i = 1; i < n_nodes; i++) nodes[i]->stats();
319}
321{
322 o << " #gb #pair #comp m z o u #hilb #gcd #mons #chg";
323 for (int i = 1; i < n_nodes; i++) nodes[i]->text_out(o);
324}
325
327// Negative numbers represent upper bounds
328{
329 int lev, i, d;
330 int lo = nodes[0]->output_free_module()->lowest_primary_degree();
331 if (n_nodes >= 2)
332 {
333 int lo1 = nodes[1]->output_free_module()->lowest_primary_degree() - 1;
334 if (lo1 < lo) lo = lo1;
335 }
336 if (n_nodes >= 3)
337 {
338 int lo2 = nodes[2]->output_free_module()->lowest_primary_degree() - 2;
339 if (lo2 < lo) lo = lo2;
340 }
341 int hi = lo;
342 int len = 1;
343
344 // Set the hi degree, and len
345 for (lev = 0; lev < n_nodes; lev++)
346 {
347 const FreeModule *F = free_module(lev);
348 if (F->rank() > 0) len = lev;
349
350 for (i = 0; i < F->rank(); i++)
351 {
352 d = F->primary_degree(i) - lev;
353 if (d > hi) hi = d;
354 }
355 }
356
357 int *bettis;
358 betti_init(lo, hi, len, bettis);
359
360 for (lev = 0; lev <= len; lev++)
361 {
362 const FreeModule *F = free_module(lev);
363
364 for (i = 0; i < F->rank(); i++)
365 {
366 d = F->primary_degree(i) - lev - lo;
367 bettis[lev + (len + 1) * d]++;
368 }
369 }
370 M2_arrayint result = betti_make(lo, hi, len, bettis);
371 freemem(bettis);
372 return result;
373}
374
376// Only type = 0 (minimal) is supported by this type.
377// Should we do the other types as well?
378// type is documented under rawResolutionBetti, in engine.h
379{
380 if (type == 0) return betti_minimal();
381 if (type == 4)
382 {
383 ERROR(
384 "cannot use Minimize=>true unless res(...,FastNonminimal=>true) was "
385 "used");
386 return nullptr;
387 }
388
389 ERROR("received unsupported betti type for this algorithm");
390 return nullptr;
391}
392
393// Local Variables:
394// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
395// indent-tabs-mode: nil
396// End:
enum ComputationStatusCode set_status(enum ComputationStatusCode)
Definition comp.cpp:66
StopConditions stop_
Definition comp.hpp:75
const_monomial degree(int i) const
Definition freemod.hpp:104
int primary_degree(int i) const
Definition freemod.cpp:440
int lowest_primary_degree() const
Definition freemod.cpp:447
void append_schreyer(const_monomial d, const_monomial base_monom, int compare_num)
Definition freemod.cpp:137
int rank() const
Definition freemod.hpp:105
Engine-side free module R^n over a Ring.
Definition freemod.hpp:66
const_monomial degree_shift() const
Definition matrix.hpp:149
const Ring * get_ring() const
Definition matrix.hpp:134
int n_cols() const
Definition matrix.hpp:147
int n_rows() const
Definition matrix.hpp:146
const FreeModule * rows() const
Definition matrix.hpp:144
const FreeModule * cols() const
Definition matrix.hpp:145
Matrix * to_matrix()
void set_column(int c, vec v)
Mutable builder used to assemble an immutable Matrix one column (or one term) at a time.
Internal tree node of the MonomialIdeal decision tree.
Definition monideal.hpp:74
static void betti_init(int lo, int hi, int len, int *&bettis)
Definition comp-res.cpp:151
static M2_arrayint betti_make(int lo, int hi, int len, int *bettis)
Definition comp-res.cpp:157
virtual const PolynomialRing * cast_to_PolynomialRing() const
Definition ring.hpp:243
Front-end-visible "ring element" value: an engine ring_elem paired with the Ring* that gives it meani...
Definition relem.hpp:67
xxx xxx xxx
Definition ring.hpp:102
char * str()
Definition buffer.hpp:72
int n_gens
Definition res-a2.hpp:73
int start_degree(int deg)
Definition res-a2.cpp:55
int n_left
Definition res-a2.hpp:71
void flush()
Definition res-a2.cpp:67
GBRing * GR
Definition res-a2.hpp:67
virtual void text_out(buffer &o) const
Definition res-a2.cpp:76
const Matrix * gens
Definition res-a2.hpp:68
int * these
Definition res-a2.hpp:74
int this_degree
Definition res-a2.hpp:70
gb_emitter(const Matrix *m)
Definition res-a2.cpp:10
virtual bool is_done()
Definition res-a2.cpp:74
virtual enum ComputationStatusCode calc_gens(int degree)
Definition res-a2.cpp:50
virtual RingElement * hilbertNumerator()
Definition res-a2.cpp:22
~gb_emitter()
Definition res-a2.cpp:21
gb_node * g
Definition res-a2.hpp:69
virtual enum ComputationStatusCode calc_gb(int degree)
Definition res-a2.cpp:27
virtual void stats() const
Definition res-a2.cpp:75
const PolynomialRing * originalR
Definition res-a2.hpp:66
void start_computation()
Definition res-a2.cpp:191
gbres_comp(const Matrix *m, int length, int orig_syz, int strategy)
Definition res-a2.cpp:152
int n_nodes
Definition res-a2.hpp:253
const Matrix * change_matrix(int level)
Definition res-a2.cpp:307
int lo_degree
Definition res-a2.hpp:256
const Matrix * get_matrix(int level)
Definition res-a2.cpp:286
gb_node ** nodes
Definition res-a2.hpp:254
stash * mi_stash
Definition res-a2.hpp:251
int strategy_flags
Definition res-a2.hpp:258
void text_out(buffer &o) const
Definition res-a2.cpp:320
M2_arrayint get_betti(int type) const
Definition res-a2.cpp:375
const FreeModule * free_module(int level) const
Definition res-a2.cpp:274
const Matrix * min_gens_matrix(int level)
Definition res-a2.cpp:280
bool is_done()
Definition res-a2.cpp:229
bool stop_conditions_ok()
Definition res-a2.cpp:181
void setup(const Matrix *m, int length, int origsyz, int strategy)
Definition res-a2.cpp:79
const PolynomialRing * originalR
Definition res-a2.hpp:250
virtual ~gbres_comp()
Definition res-a2.cpp:168
void stats() const
Definition res-a2.cpp:314
Matrix * reduce(const Matrix *m, Matrix *&lift)
Definition res-a2.cpp:239
M2_arrayint betti_minimal() const
Definition res-a2.cpp:326
const Matrix * gb_matrix(int level)
Definition res-a2.cpp:300
const Matrix * initial_matrix(int n, int level)
Definition res-a2.cpp:293
GBRing * GR
Definition res-a2.hpp:252
int complete_thru_degree() const
Definition res-a2.cpp:236
int last_completed_degree
Definition res-a2.hpp:257
Definition mem.hpp:78
ComputationStatusCode
Definition computation.h:53
@ COMP_DONE
Definition computation.h:60
@ COMP_DONE_DEGREE_LIMIT
Definition computation.h:61
@ COMP_INTERRUPTED
Definition computation.h:57
#define Matrix
Definition factory.cpp:14
#define monomial
Definition gb-toric.cpp:11
Hilbert-series numerator via the Bigatti-Caboara-Robbiano recursion.
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)
int M2_gbTrace
Definition m2-types.cpp:52
MatrixConstructor — the mutable builder that produces an immutable Matrix.
#define newarray_atomic_clear(T, len)
Definition newdelete.hpp:93
#define newarray(T, len)
Definition newdelete.hpp:82
ring_elem hilb(const Matrix &M, const Ring *RR)
gb_node * gb_node_ptr
Definition res-a2.cpp:77
ring_elem coeff
Definition ringelem.hpp:158
int monom[1]
Definition ringelem.hpp:160
Singly linked-list node carrying one term of a polynomial-ring element.
Definition ringelem.hpp:156
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.