Macaulay2 Engine
Loading...
Searching...
No Matches
gauss.cpp
Go to the documentation of this file.
1// Copyright 1997-2005 Michael E. Stillman
2
3#include "style.hpp"
4#include "gauss.hpp"
5#include "text-io.hpp"
6#include "matrix-con.hpp"
7#include "newdelete.hpp"
8#include "interrupted.hpp"
9
10#include <iostream>
11extern RingZZ *globalZZ;
12
14// The computation is complete up through this degree.
15{
16 if (status() == COMP_DONE) return 0;
17 return -1;
18}
19
21{
22 gm_elem *result = new gm_elem;
23 result->f = R->copy_vec(gens->elem(i));
24
25 if (i < n_comps_per_syz)
26 result->fsyz = R->make_vec(i, R->one());
27 else
28 result->fsyz = nullptr;
29 result->next = nullptr;
30 return result;
31}
33{
34 if (p->f == nullptr)
35 {
36 if (p->fsyz != nullptr && collect_syz)
37 {
38 syz_list.push_back(p->fsyz);
39 n_syz++;
40 }
41 freemem(p);
42 }
43 else
44 {
45 ring_elem leadinv = R->invert(p->f->coeff);
46 R->mult_vec_to(p->f, leadinv, false);
47 R->mult_vec_to(p->fsyz, leadinv, false);
48 p->nterms = R->n_nonzero_terms(p->f);
49 int i = p->f->comp;
50 if (gb_list[i] == nullptr)
51 {
52 gb_list[i] = p;
53 n_gb++;
54 }
55 else
56 {
57 if (p->nterms < gb_list[i]->nterms)
58 {
59 gm_elem *q = p;
60 p = gb_list[i];
61 gb_list[i] = q;
62 }
63 p->next = reduce_list[i];
64 reduce_list[i] = p;
65 }
66 }
67}
68
70 int collsyz,
71 int nsyz)
72 : row(m->n_rows() - 1),
73 R(m->get_ring()),
74 gens(m),
75 n_gb(0),
76 n_pairs(0),
77 n_syz(0),
78 collect_syz(collsyz)
79{
80 int i;
81
82 typedef struct gm_elem *gm_elem_ptr;
83 reduce_list = newarray(gm_elem_ptr, m->n_rows());
84 gb_list = newarray(gm_elem_ptr, m->n_rows());
85
86 for (i = 0; i < m->n_rows(); i++)
87 {
88 reduce_list[i] = nullptr;
89 gb_list[i] = nullptr;
90 }
91
92 if (nsyz < 0 || nsyz > m->n_cols()) nsyz = m->n_cols();
93 n_comps_per_syz = nsyz;
94 Fsyz = m->cols()->sub_space(nsyz);
95
96 for (i = 0; i < m->n_cols(); i++)
97 {
98 gm_elem *p = new_gen(i);
99 insert(p);
100 }
101}
102
104{
105 if (p != nullptr)
106 {
107 R->remove_vec(p->f);
108 R->remove_vec(p->fsyz);
109 freemem(p);
110 p = nullptr;
111 }
112}
113
115{
116 for (int i = 0; i < gens->n_rows(); i++)
117 {
118 // remove the gm_elem list
119 gm_elem *p = reduce_list[i];
120 while (p != nullptr)
121 {
122 gm_elem *tmp = p;
123 p = p->next;
124 remove_gm_elem(tmp);
125 }
127 }
128}
129
131{
132 // MES: rewrite.
133 // Reduce q by p. This is a single step reduction.
134 // The element is then inserted further down.
135
136 ring_elem c1 = p->f->coeff;
137 ring_elem c2 = q->f->coeff;
138 ring_elem d2 = R->negate(c2);
139 vec v1 = R->mult_vec(c1, q->f);
140 vec v2 = R->mult_vec(d2, p->f);
141 vec s1 = R->mult_vec(c1, q->fsyz);
142 vec s2 = R->mult_vec(d2, p->fsyz);
143 R->remove_vec(q->f);
144 R->remove_vec(q->fsyz);
145 R->remove(d2);
146 R->add_vec_to(v1, v2);
147 R->add_vec_to(s1, s2);
148 q->f = v1;
149 q->fsyz = s1;
150}
151
153{
154 vecterm head;
155 vecterm *result = &head;
156
157 while (f != nullptr)
158 {
159 int r = f->comp;
160 if (gb_list[r] != nullptr)
161 {
162 // Reduce w.r.t. this term
163 ring_elem c = f->coeff;
164 c = R->negate(c);
165 vec g = R->mult_vec(c, gb_list[r]->f);
166 R->add_vec_to(f, g);
167 }
168 else
169 {
170 result->next = f;
171 f = f->next;
172 result = result->next;
173 }
174 }
175
176 result->next = nullptr;
177 f = head.next;
178}
179void GaussElimComputation::reduce(vec &f, vec &fsyz, bool tail_only)
180{
181 if (f == nullptr) return;
182 vecterm head;
183 vecterm *result = &head;
184
185 if (tail_only)
186 {
187 // Don't reduce the head term.
188 result->next = f;
189 f = f->next;
190 result = result->next;
191 }
192 while (f != nullptr)
193 {
194 int r = f->comp;
195 if (gb_list[r] != nullptr)
196 {
197 // Reduce w.r.t. this term
198 ring_elem c = f->coeff;
199 c = R->negate(c);
200 vec gsyz = R->mult_vec(c, gb_list[r]->fsyz);
201 vec g = R->mult_vec(c, gb_list[r]->f);
202 R->add_vec_to(f, g);
203 R->add_vec_to(fsyz, gsyz);
204 }
205 else
206 {
207 result->next = f;
208 f = f->next;
209 result = result->next;
210 }
211 }
212
213 result->next = nullptr;
214 f = head.next;
215}
217{
218 if (status() == COMP_DONE) return;
219 for (; row >= 0; row--)
220 {
221 if (gb_list[row] == nullptr) continue;
222 while (reduce_list[row] != nullptr)
223 {
225 reduce_list[row] = p->next;
226 p->next = nullptr;
227 reduce(gb_list[row], p); // replaces p
228 if (M2_gbTrace >= 3)
229 {
230 if (p->f == nullptr)
231 {
232 if (p->fsyz == nullptr)
233 emit_wrapped("o");
234 else
235 emit_wrapped("z");
236 }
237 else
238 emit_wrapped("r");
239 }
240 else
241 {
242 }
243 insert(p);
244 n_pairs++;
245 if (system_interrupted())
246 {
248 return;
249 }
250 if (n_pairs == stop_.pair_limit)
251 {
253 return;
254 }
255 if (n_syz == stop_.syzygy_limit)
256 {
258 return;
259 }
260 }
261 }
262 // Now auto reduce these
263 for (int r = 1; r < gens->n_rows(); r++)
264 {
265 if (gb_list[r] == nullptr) continue;
266 reduce(gb_list[r]->f, gb_list[r]->fsyz, true);
267 }
268 if (M2_gbTrace >= 10)
269 {
270 buffer o;
271 text_out(o);
272 emit(o.str());
273 }
275}
276
279{
280 (void) nparts;
281 MatrixConstructor mat(gens->rows(), 0);
282 for (int i = 0; i < gens->n_rows(); i++)
283 if (gb_list[i] != nullptr)
284 {
285 vec v = gb_list[i]->f;
286 mat.append(R->make_vec(v->comp, v->coeff));
287 }
288 return mat.to_matrix();
289}
290
292{
293 MatrixConstructor mat(gens->rows(), 0);
294 for (int i = 0; i < gens->n_rows(); i++)
295 if (gb_list[i] != nullptr) mat.append(R->copy_vec(gb_list[i]->f));
296 return mat.to_matrix();
297}
298
300{
301 MatrixConstructor mat(Fsyz, 0);
302 for (int i = 0; i < gens->n_rows(); i++)
303 if (gb_list[i] != nullptr) mat.append(R->copy_vec(gb_list[i]->fsyz));
304 return mat.to_matrix();
305}
306
308{
309 MatrixConstructor mat(Fsyz, 0);
310 for (int i = 0; i < syz_list.size(); i++)
311 mat.append(R->copy_vec(syz_list[i]));
312 return mat.to_matrix();
313}
314
316{
317 o << newline;
318 for (int i = 0; i < gens->n_rows(); i++)
319 {
320 if (gb_list[i] != nullptr)
321 {
322 o << "--- component " << i << " -----" << newline;
323 o << "gb elem = ";
324 R->vec_text_out(o, gb_list[i]->f);
325 o << newline;
326 }
327 else if (reduce_list[i] != nullptr)
328 o << "--- component " << i << " -----" << newline;
329 for (gm_elem *p = reduce_list[i]; p != nullptr; p = p->next)
330 {
331 o << p->nterms;
332 o << " ## ";
333 R->vec_text_out(o, p->f);
334 o << " ## ";
335 R->vec_text_out(o, p->fsyz);
336 o << newline;
337 }
338 }
339 o << newline;
340 for (int i = 0; i < syz_list.size(); i++) R->vec_text_out(o, syz_list[i]);
341 o << newline;
342}
343
345 const Matrix *m)
346{
347 if (m->get_ring() != R)
348 {
349 ERROR("encountered different rings");
350 return nullptr;
351 }
352 if (m->n_rows() != gens->rows()->rank())
353 {
354 ERROR("expected matrices to have same number of rows");
355 return nullptr;
356 }
357 MatrixConstructor mat_remainder(m->rows(), m->cols(), m->degree_shift());
358 for (int i = 0; i < m->n_cols(); i++)
359 {
360 vec f = R->copy_vec(m->elem(i));
361
362 reduce(f);
363 mat_remainder.set_column(i, f);
364 }
365 return mat_remainder.to_matrix();
366}
367
369 const Matrix *m,
370 const Matrix /* or null */ **result_remainder,
371 const Matrix /* or null */ **result_quotient)
372{
373 if (m->get_ring() != R)
374 {
375 ERROR("encountered different rings");
376 *result_remainder = nullptr;
377 *result_quotient = nullptr;
378 return false;
379 }
380 if (m->n_rows() != gens->rows()->rank())
381 {
382 ERROR("expected matrices to have same number of rows");
383 *result_remainder = nullptr;
384 *result_quotient = nullptr;
385 return false;
386 }
387 MatrixConstructor mat_remainder(m->rows(), m->cols(), m->degree_shift());
388 MatrixConstructor mat_quotient(Fsyz, m->cols(), nullptr);
389 bool all_zeroes = true;
390 for (int i = 0; i < m->n_cols(); i++)
391 {
392 vec f = R->copy_vec(m->elem(i));
393 vec fsyz = nullptr;
394
395 reduce(f, fsyz);
396 R->negate_vec_to(fsyz);
397 if (f != nullptr) all_zeroes = false;
398 mat_remainder.set_column(i, f);
399 mat_quotient.set_column(i, fsyz);
400 }
401 *result_remainder = mat_remainder.to_matrix();
402 *result_quotient = mat_quotient.to_matrix();
403 return all_zeroes;
404}
405
407// Return -1 if every column of 'm' reduces to zero.
408// Otherwise return the index of the first column that
409// does not reduce to zero.
410{
411 if (m->get_ring() != R)
412 {
413 ERROR("encountered different ring");
414 return -1;
415 }
416 // Reduce each column of m one by one.
417 for (int i = 0; i < m->n_cols(); i++)
418 {
419 vec f = R->copy_vec(m->elem(i));
420 reduce(f);
421 if (f != nullptr)
422 {
423 R->remove_vec(f);
424 return i;
425 }
426 }
427 return -1;
428}
429
430// Local Variables:
431// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
432// indent-tabs-mode: nil
433// End:
enum ComputationStatusCode status() const
Definition comp.hpp:100
enum ComputationStatusCode set_status(enum ComputationStatusCode)
Definition comp.cpp:66
StopConditions stop_
Definition comp.hpp:75
FreeModule * sub_space(int n) const
Definition freemod.cpp:197
virtual const Matrix * get_mingens()
Definition gauss.cpp:277
void remove_gm_elem(gm_elem *&p)
Definition gauss.cpp:103
virtual int complete_thru_degree() const
Definition gauss.cpp:13
gm_elem * new_gen(int i)
Definition gauss.cpp:20
virtual M2_bool matrix_lift(const Matrix *m, const Matrix **result_remainder, const Matrix **result_quotient)
Definition gauss.cpp:368
virtual const Matrix * get_change()
Definition gauss.cpp:299
gm_elem ** reduce_list
Definition gauss.hpp:62
gm_elem ** gb_list
Definition gauss.hpp:63
virtual const Matrix * get_syzygies()
Definition gauss.cpp:307
const Matrix * gens
Definition gauss.hpp:67
GaussElimComputation(const Matrix *m, int collect_syz, int n_syz)
Definition gauss.cpp:69
virtual const Matrix * get_gb()
Definition gauss.cpp:291
void reduce(gm_elem *&p, gm_elem *q)
Definition gauss.cpp:130
virtual void start_computation()
Definition gauss.cpp:216
virtual const Matrix * matrix_remainder(const Matrix *m)
Definition gauss.cpp:344
const Ring * R
Definition gauss.hpp:66
void insert(gm_elem *p)
Definition gauss.cpp:32
virtual void text_out(buffer &o) const
Definition gauss.cpp:315
const FreeModule * Fsyz
Definition gauss.hpp:68
virtual const Matrix * get_initial(int nparts)
Definition gauss.cpp:278
virtual int contains(const Matrix *m)
Definition gauss.cpp:406
virtual const Ring * get_ring() const
Definition gauss.hpp:99
const_monomial degree_shift() const
Definition matrix.hpp:149
const Ring * get_ring() const
Definition matrix.hpp:134
ring_elem elem(int i, int j) const
Definition matrix.cpp:307
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 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.
Engine-side ring of integers, backed by GMP mpz_ptr elements.
Definition ZZ.hpp:77
char * str()
Definition buffer.hpp:72
@ COMP_DONE_PAIR_LIMIT
Definition computation.h:64
@ COMP_DONE
Definition computation.h:60
@ COMP_DONE_SYZYGY_LIMIT
Definition computation.h:63
@ COMP_INTERRUPTED
Definition computation.h:57
#define Matrix
Definition factory.cpp:14
RingZZ * globalZZ
Definition relem.cpp:13
GaussElimComputation — Gaussian elimination GB / submodule strategy over a field.
int p
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)
char newline[]
Definition m2-types.cpp:49
int M2_gbTrace
Definition m2-types.cpp:52
char M2_bool
Definition m2-types.h:82
MatrixConstructor — the mutable builder that produces an immutable Matrix.
#define newarray(T, len)
Definition newdelete.hpp:82
our_new_delete — per-class opt-in routing of new / delete through bdwgc.
vec fsyz
Definition gauss.hpp:46
vec f
Definition gauss.hpp:45
Engine-wide stylistic constants: LT / EQ / GT codes, INTSIZE, GEOHEAP_SIZE.
void emit_wrapped(const char *s)
Definition text-io.cpp:27
void emit(const char *s)
Definition text-io.cpp:41
Text-formatting helpers layered on buffer: bignum print, line wrapping, M2_gbTrace-gated emit.