Macaulay2 Engine
Loading...
Searching...
No Matches
schorder.cpp
Go to the documentation of this file.
1#include <algorithm>
2#include <iostream>
3
4#include "schorder.hpp"
5#include "matrix.hpp"
6#include "comb.hpp"
7#include "polyring.hpp"
8#include "Eschreyer.hpp"
9#include "finalize.hpp"
10
17
18void SchreyerOrder::remove() { _order.clear(); _order.shrink_to_fit(); }
19void SchreyerOrder::append(int compare_num0, const_monomial baseMonom)
20{
21 auto end = _order.size();
22 _order.resize(end + _nslots);
23 int *me = _order.data() + end;
24 *me++ = compare_num0;
25 for (int i = 1; i < _nslots; i++) *me++ = *baseMonom++;
26 _rank++;
27}
28
30{
31 int i;
32 const Ring *R = m->get_ring();
33 const SchreyerOrder *S = m->rows()->get_schreyer_order();
35 if (P == nullptr)
36 {
37 throw exc::engine_error("expected polynomial ring");
38 }
39 const Monoid *M = P->getMonoid();
41 int rk = m->n_cols();
42 if (rk == 0) return result;
43 monomial base = M->make_one();
44 int *tiebreaks = newarray_atomic(int, rk);
45 int *ties = newarray_atomic(int, rk);
46 for (i = 0; i < rk; i++)
47 {
48 vec v = (*m)[i];
49 if (v == nullptr || S == nullptr)
50 tiebreaks[i] = i;
51 else
52 tiebreaks[i] = i + rk * S->compare_num(v->comp);
53 }
54 // Now sort tiebreaks in increasing order.
55 std::sort<int *>(tiebreaks, tiebreaks + rk);
56 for (i = 0; i < rk; i++) ties[tiebreaks[i] % rk] = i;
57 for (i = 0; i < rk; i++)
58 {
59 vec v = (*m)[i];
60 if (v == nullptr)
61 M->one(base);
62 else if (S == nullptr)
63 M->copy(P->lead_flat_monomial(v->coeff), base);
64 else
65 {
66 int x = v->comp;
67 M->mult(P->lead_flat_monomial(v->coeff), S->base_monom(x), base);
68 }
69
70 result->append(ties[i], base);
71 }
72
74 M->remove(base);
75 freemem(tiebreaks);
76 freemem(ties);
77 return result;
78}
79
81{
82#ifdef DEVELOPMENT
83#warning "the logic in SchreyerOrder creation is WRONG!"
84#endif
85 int i;
86 const FreeModule *F = m->get_free_module();
87 const Ring *R = F->get_ring();
88 const SchreyerOrder *S = F->get_schreyer_order();
90 const Monoid *M = P->getMonoid();
92 int rk = INTSIZE(m->elems);
93 if (rk == 0) return result;
94
95 monomial base = M->make_one();
96 int *tiebreaks = newarray_atomic(int, rk);
97 int *ties = newarray_atomic(int, rk);
98 for (i = 0; i < rk; i++)
99 {
100 gbvector *v = m->elems[i];
101 if (v == nullptr || S == nullptr)
102 tiebreaks[i] = i;
103 else
104 tiebreaks[i] = i + rk * S->compare_num(v->comp - 1);
105 }
106 // Now sort tiebreaks in increasing order.
107 std::sort<int *>(tiebreaks, tiebreaks + rk);
108 for (i = 0; i < rk; i++) ties[tiebreaks[i] % rk] = i;
109 for (i = 0; i < rk; i++)
110 {
111 gbvector *v = m->elems[i];
112 if (v == nullptr)
113 M->one(base);
114 else // if (S == NULL)
115 M->copy(v->monom, base);
116#ifdef DEVELOPMENT
117#warning "Schreyer unencoded case not handled here"
118#endif
119#if 0
120// else
121// M->mult(v->monom, S->base_monom(i), base);
122#endif
123 result->append(ties[i], base);
124 }
125
127 M->remove(base);
128 freemem(tiebreaks);
129 freemem(ties);
130 return result;
131}
132
134// A schreyer order is never equal to a non-Schreyer order, even
135// if the monomials are all ones.
136{
137 if (G == nullptr) return false;
138 for (int i = 0; i < rank(); i++)
139 {
140 if (compare_num(i) != G->compare_num(i)) return false;
141 if (M->compare(base_monom(i), G->base_monom(i)) != 0) return false;
142 }
143 return true;
144}
145
147{
149 for (int i = 0; i < rank(); i++)
150 result->append(compare_num(i), base_monom(i));
151 return result;
152}
153
155{
156 if (n < 0 || n > rank())
157 {
158 ERROR("sub schreyer order: index out of bounds");
159 return nullptr;
160 }
162 for (int i = 0; i < n; i++) result->append(compare_num(i), base_monom(i));
163 return result;
164}
165
167{
168 // Since this is called only from FreeModule::sub_space,
169 // the elements of 'a' are all in bounds, and do not need to be checked...
170 // BUT, we check anyway...
172 for (unsigned int i = 0; i < a->len; i++)
173 if (a->array[i] >= 0 && a->array[i] < rank())
174 result->append(compare_num(a->array[i]), base_monom(a->array[i]));
175 else
176 {
177 ERROR("schreyer order subspace: index out of bounds");
179 return nullptr;
180 }
181 return result;
182}
183
185{
186 for (int i = 0; i < G->rank(); i++)
187 append(G->compare_num(i), G->base_monom(i));
188}
189
191{
193 result->append_order(this);
194 result->append_order(G);
195 return result;
196}
197
199// tensor product
200{
201 // Since this is called only from FreeModule::tensor,
202 // we assume that 'this', 'G' have the same monoid 'M'.
203
205 monomial base = M->make_one();
206
207 int next = 0;
208 for (int i = 0; i < rank(); i++)
209 for (int j = 0; j < G->rank(); j++)
210 {
211 M->mult(base_monom(i), G->base_monom(j), base);
212 result->append(next++, base);
213 }
214
215 M->remove(base);
216 return result;
217}
218
220// p th exterior power
221{
222 // This routine is only called from FreeModule::exterior.
223 // Therefore: p is in the range 0 < p <= rk.
225 int rk = rank();
226
227 assert(pp > 0);
228 assert(pp <= rk);
229 size_t p = static_cast<size_t>(pp);
230
231 Subset a(p, 0);
232 for (size_t i = 0; i < p; i++) a[i] = i;
233
234 monomial base = M->make_one();
235 int next = 0;
236 do
237 {
238 M->one(base);
239 for (size_t r = 0; r < p; r++)
240 M->mult(base, base_monom(static_cast<int>(a[r])), base);
241
242 result->append(next++, base);
243 }
244 while (Subsets::increment(rk, a));
245
246 M->remove(base);
247 return result;
248}
249
264{
265 const SchreyerOrder *S; // original one
266 int n;
267 const Monoid *M;
268
269 SchreyerOrder *symm1_result; // what is being computed
270 monomial symm1_base; // used in recursion
271 int symm1_next; // used in recursion
272
273 void symm1(int lastn, // can use lastn..rank()-1 in product
274 int pow) // remaining power to take
275 {
276 if (pow == 0)
278 else
279 {
280 for (int i = lastn; i < S->rank(); i++)
281 {
282 // increase symm1_base with e_i
283 M->mult(symm1_base, S->base_monom(i), symm1_base);
284
285 symm1(i, pow - 1);
286
287 // decrease symm1_base back
288 M->divide(symm1_base, S->base_monom(i), symm1_base);
289 }
290 }
291 }
292
294 : S(S0),
295 n(n0),
296 M(S0->getMonoid()),
297 symm1_result(nullptr),
298 symm1_base(nullptr),
299 symm1_next(0)
300 {
301 }
302
304 {
305 if (symm1_result == nullptr)
306 {
308 if (n >= 0)
309 {
310 symm1_base = M->make_one();
311 symm1(0, n);
312 M->remove(symm1_base);
313 }
314 }
315 return symm1_result;
316 }
317};
318
320// n th symmetric power
321{
322 SchreyerOrder_symm S(this, n);
323 return S.value();
324}
325
327{
328 for (int i = 0; i < _rank; i++)
329 {
330 if (i != 0) o << ' ';
331 M->elem_text_out(o, base_monom(i));
332 o << '.';
333 o << compare_num(i);
334 }
335}
336
338 int m_comp,
340 int n_comp) const
341{
342 const_monomial ms = base_monom(m_comp);
343 const_monomial ns = base_monom(n_comp);
344 for (int i = M->monomial_size(); i > 0; --i)
345 {
346 int cmp = *ms++ + *m++ - *ns++ - *n++;
347 if (cmp < 0) return LT;
348 if (cmp > 0) return GT;
349 }
350 int cmp = compare_num(m_comp) - compare_num(n_comp);
351 if (cmp < 0) return LT;
352 if (cmp > 0) return GT;
353 return EQ;
354}
355
357 int m_comp,
359 int n_comp) const
360{
361 int cmp = M->compare(m, n);
362 if (cmp != EQ) return cmp;
363 cmp = compare_num(m_comp) - compare_num(n_comp);
364 if (cmp < 0) return LT;
365 if (cmp > 0) return GT;
366 return EQ;
367}
368
369// Local Variables:
370// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
371// indent-tabs-mode: nil
372// End:
Older Schreyer-style kernel computation, predecessor of schreyer-resolution/.
const Ring * get_ring() const
Definition freemod.hpp:102
const SchreyerOrder * get_schreyer_order() const
Definition freemod.hpp:103
Engine-side free module R^n over a Ring.
Definition freemod.hpp:66
const Ring * get_ring() const
Definition matrix.hpp:134
int n_cols() const
Definition matrix.hpp:147
const FreeModule * rows() const
Definition matrix.hpp:144
Engine-side commutative monomial monoid: variable names, ordering, multidegree machinery,...
Definition monoid.hpp:89
virtual const Monoid * getMonoid() const
Definition polyring.hpp:282
virtual const_monomial lead_flat_monomial(const ring_elem f) const =0
Abstract base for the engine's polynomial-ring hierarchy.
Definition polyring.hpp:96
virtual const PolynomialRing * cast_to_PolynomialRing() const
Definition ring.hpp:243
xxx xxx xxx
Definition ring.hpp:102
void append_order(const SchreyerOrder *G)
Definition schorder.cpp:184
void text_out(buffer &o) const
Definition schorder.cpp:326
int schreyer_compare_encoded(const_monomial m, int m_comp, const_monomial n, int n_comp) const
Definition schorder.cpp:356
bool is_equal(const SchreyerOrder *G) const
Definition schorder.cpp:133
SchreyerOrder * exterior(int p) const
Definition schorder.cpp:219
void append(int compare_num, const_monomial base_monom)
Definition schorder.cpp:19
SchreyerOrder * symm(int n) const
Definition schorder.cpp:319
SchreyerOrder * sub_space(int n) const
Definition schorder.cpp:154
static SchreyerOrder * create(const Monoid *m)
Definition schorder.cpp:11
const Monoid * M
Definition schorder.hpp:69
SchreyerOrder(const Monoid *m)
Definition schorder.hpp:77
int schreyer_compare(const_monomial m, int m_comp, const_monomial n, int n_comp) const
Definition schorder.cpp:337
void remove()
Definition schorder.cpp:18
int rank() const
Definition schorder.hpp:89
SchreyerOrder * direct_sum(const SchreyerOrder *G) const
Definition schorder.cpp:190
SchreyerOrder * tensor(const SchreyerOrder *G) const
Definition schorder.cpp:198
gc_vector< int > _order
Definition schorder.hpp:73
int compare_num(int i) const
Definition schorder.hpp:90
const_monomial base_monom(int i) const
Definition schorder.hpp:91
SchreyerOrder * copy() const
Definition schorder.cpp:146
Per-component tie-breaker data for a Schreyer monomial order on a FreeModule.
Definition schorder.hpp:68
static bool increment(size_t n, Subset &s)
Definition comb.cpp:124
std::vector< size_t > Subset
Definition comb.hpp:58
Subsets — combinatorial-number-system encoding of p-subsets of {0,...,n-1}.
static CanonicalForm base
Definition factory.cpp:289
#define Matrix
Definition factory.cpp:14
void intern_SchreyerOrder(SchreyerOrder *G)
Definition finalize.cpp:171
intern_* helpers that register long-lived engine objects with bdwgc finalisers.
#define monomial
Definition gb-toric.cpp:11
int p
const int * const_monomial
Definition imonorder.hpp:45
void freemem(void *s)
Definition m2-mem.cpp:103
const int ERROR
Definition m2-mem.cpp:55
VALGRIND_MAKE_MEM_DEFINED & result(result)
Matrix — the engine's immutable homomorphism F -> G between free modules.
#define newarray_atomic(T, len)
Definition newdelete.hpp:91
volatile int x
PolynomialRing — abstract polynomial-ring base, the engine's most-reused class.
tbb::flow::graph G
TermIterator< Nterm > end(Nterm *)
Definition ringelem.cpp:5
SchreyerOrder — per-basis-element data backing the Schreyer order on a free module.
const FreeModule * get_free_module() const
Definition Eschreyer.hpp:61
gc_vector< gbvector * > elems
Definition Eschreyer.hpp:56
gbvector-side matrix: a target FreeModule plus a list of gbvector* columns living in it.
Definition Eschreyer.hpp:54
const SchreyerOrder * S
Definition schorder.cpp:265
SchreyerOrder * value()
Definition schorder.cpp:303
SchreyerOrder_symm(const SchreyerOrder *S0, int n0)
Definition schorder.cpp:293
const Monoid * M
Definition schorder.cpp:267
void symm1(int lastn, int pow)
Definition schorder.cpp:273
SchreyerOrder * symm1_result
Definition schorder.cpp:269
Helper functor that builds the n-th symmetric power of a SchreyerOrder by walking multi-indices.
Definition schorder.cpp:264
int monom[1]
Definition gbring.hpp:83
int comp
Definition gbring.hpp:82
const int EQ
Definition style.hpp:40
const int GT
Definition style.hpp:41
const int LT
Definition style.hpp:39
#define INTSIZE(a)
Definition style.hpp:37