Macaulay2 Engine
Loading...
Searching...
No Matches
freemod.cpp
Go to the documentation of this file.
1// Copyright 1996 Michael E. Stillman
2
3#include "util.hpp"
4#include "freemod.hpp"
5#include "comb.hpp"
6#include "polyring.hpp"
7#include "matrix.hpp"
8#include "matrix-con.hpp"
9#include "Eschreyer.hpp"
10#include "gbring.hpp"
11
13// Construction/Destruction routines ////////
15
17{
18 R = RR;
19 schreyer = nullptr;
20}
21
22unsigned int FreeModule::computeHashValue() const
23{
24 unsigned int hashval = 13;
25 if (R->degree_monoid()->n_vars() == 0)
26 hashval += rank();
27 else
28 for (int i = 0; i < rank(); i++) hashval = 14535 * hashval + degree(i)[0];
29 return hashval;
30}
31
32FreeModule::FreeModule(const Ring *RR, int n, bool has_schreyer_order)
33// Create R^n, with all gradings zero.
34{
35 initialize(RR);
36
37 auto D = R->degree_monoid();
38 monomial deg = D->make_one();
39 for (int i = 0; i < n; i++) append(deg);
40 D->remove(deg);
41
42 if (has_schreyer_order)
43 {
44 const PolynomialRing *P = R->cast_to_PolynomialRing();
45 assert(P != 0);
46 assert(n == 0);
48 }
49 else
50 schreyer = nullptr;
51}
52
54{
55 int i;
57 if (R == nullptr)
58 {
59 ERROR("expected a polynomial ring");
60 return nullptr;
61 }
62 FreeModule *F = R->make_FreeModule();
63 int rk = m->n_cols();
64 if (rk == 0) return F;
65
66 for (i = 0; i < rk; i++) F->append(m->cols()->degree(i));
67
69
70 return F;
71}
72
74{
75 const FreeModule *F = m->get_free_module();
77 if (R == nullptr)
78 {
79 ERROR("expected a polynomial ring");
80 return nullptr;
81 }
82 FreeModule *G = R->make_FreeModule();
83 int rk = INTSIZE(m->elems);
84 if (rk == 0) return G;
85
86 auto D = R->degree_monoid();
87 for (int i = 0; i < rk; i++)
88 {
89 monomial deg = D->make_one();
90 gbvector *v = m->elems[i];
91 if (v != nullptr) R->get_gb_ring()->gbvector_multidegree(F, v, deg);
92 G->append(deg);
93 }
94
95 G->schreyer = SchreyerOrder::create(m);
96
97 return G;
98}
99
101{
102 const PolynomialRing *P = R->cast_to_PolynomialRing();
103 if (!schreyer || P == nullptr) return Matrix::zero(R->make_FreeModule(0), this);
104 const SchreyerOrder *S = schreyer;
105 int i;
106 int maxtie = 0;
107 for (i = 0; i < rank(); i++)
108 if (S->compare_num(i) > maxtie) maxtie = S->compare_num(i);
109 const FreeModule *F = R->make_FreeModule(maxtie + 1);
110 MatrixConstructor mat(F, this, nullptr);
111 for (i = 0; i < rank(); i++)
112 {
114 S->base_monom(i));
115 mat.set_entry(S->compare_num(i), i, f);
116 }
117 return mat.to_matrix();
118}
119
121{
122 // schreyer order is finalized, so we don't remove it here
123}
124
125FreeModule *FreeModule::new_free() const { return R->make_FreeModule(); }
127// Manipulations involving components ///////
129
131{
132 assert(schreyer == 0);
133 monomial p = R->degree_monoid()->make_new(d);
134 components.push_back(p);
135}
136
138{
139 assert(schreyer != 0);
140 monomial p = R->degree_monoid()->make_new(d);
141 components.push_back(p);
142 schreyer->append(compare_num, base);
143}
144
146{
147 // WARNING: this modifies the degree, and should only be used during
148 // the construction of a free module (or matrix).
149 assert(i >= 0);
150 assert(i < rank());
151 R->degree_monoid()->copy(deg, components[i]);
152}
153
155{
156 int i;
157 if (this == F) return true;
158 if (R != F->get_ring()) return false;
159 if (rank() != F->rank()) return false;
160
161 auto D = R->degree_monoid();
162 if (D->n_vars() > 0)
163 for (i = 0; i < rank(); i++)
164 if (0 != D->compare(degree(i), F->degree(i))) return false;
165
166 /* free modules with same ranks and degrees should be equal
167 if (schreyer != nullptr) return schreyer->is_equal(F->schreyer);
168 if (F->schreyer != nullptr) return false;
169 */
170
171 return true;
172}
173
175// New free modules from old ////////////////
177
179// Shift degree by d.
180{
181 auto D = R->degree_monoid();
183 monomial deg = D->make_one();
184
185 for (int i = 0; i < rank(); i++)
186 {
187 D->mult(degree(i), d, deg);
188 result->append(deg);
189 }
190
191 if (schreyer != nullptr) result->schreyer = schreyer->copy();
192
193 D->remove(deg);
194 return result;
195}
196
198{
199 if (n < 0 || n > rank())
200 {
201 ERROR("subfreemodule: index out of bounds");
202 return nullptr;
203 }
205 for (int i = 0; i < n; i++) result->append(degree(i));
206
207 if (schreyer != nullptr) result->schreyer = schreyer->sub_space(n);
208 return result;
209}
210
212{
214 for (unsigned int i = 0; i < a->len; i++)
215 if (a->array[i] >= 0 && a->array[i] < rank())
216 result->append(degree(a->array[i]));
217 else
218 {
219 ERROR("subfreemodule: index out of bounds");
221 return nullptr;
222 }
223 if (schreyer != nullptr) result->schreyer = schreyer->sub_space(a);
224 return result;
225}
226
228{
229 auto D = R->degree_monoid();
231 monomial deg = D->make_one();
232
233 for (int i = 0; i < rank(); i++)
234 {
235 D->power(degree(i), -1, deg);
236 result->append(deg);
237 }
238
239 // result has no schreyer order
240 D->remove(deg);
241 return result;
242}
243
245// direct sum
246{
247 int i;
248 if (R != G->get_ring())
249 {
250 ERROR("expected free modules over the same ring");
251 return nullptr;
252 }
254 for (i = 0; i < rank(); i++) result->append(degree(i));
255 for (i = 0; i < G->rank(); i++) result->append(G->degree(i));
256
257 // if (schreyer != NULL && G->schreyer != NULL)
258 // result->schreyer = schreyer->direct_sum(G->schreyer);
259
260 return result;
261}
262
264{
265 for (int i = 0; i < G->rank(); i++) append(G->degree(i));
266
267 // if (schreyer != NULL && G->schreyer != NULL)
268 // schreyer->append_order(G->schreyer);
269}
270
272// tensor product
273{
274 if (R != G->get_ring())
275 {
276 ERROR("expected free modules over the same ring");
277 return nullptr;
278 }
279 auto D = R->degree_monoid();
281 monomial deg = D->make_one();
282
283 for (int i = 0; i < rank(); i++)
284 for (int j = 0; j < G->rank(); j++)
285 {
286 D->mult(degree(i), G->degree(j), deg);
287 result->append(deg);
288 }
289
290 D->remove(deg);
291 if (schreyer != nullptr && G->schreyer != nullptr)
292 result->schreyer = schreyer->tensor(G->schreyer);
293 return result;
294}
295
297// p th exterior power
298{
300 if (pp == 0)
301 return R->make_FreeModule(1);
302 else
303 result = new_free();
304
305 int rk = rank();
306 if (pp > rk || pp < 0) return result;
307
308 size_t p = static_cast<size_t>(pp);
309
310 Subset a(p, 0);
311 for (size_t i = 0; i < p; i++) a[i] = i;
312
313 auto D = R->degree_monoid();
314 monomial deg = D->make_one();
315 do
316 {
317 D->one(deg);
318
319 for (size_t r = 0; r < p; r++)
320 D->mult(deg, degree(static_cast<int>(a[r])), deg);
321
322 result->append(deg);
323 }
324 while (Subsets::increment(rk, a));
325
326 D->remove(deg);
327
328 if (schreyer != nullptr) result->schreyer = schreyer->exterior(pp);
329 return result;
330}
331
346{
347 const FreeModule *F; // original one
348 const Monoid *D; // degree monoid
349 int n;
350
351 FreeModule *symm1_result; // what is being computed
352 monomial symm1_deg; // used in recursion
353
354 void symm1(int lastn, // can use lastn..rank()-1 in product
355 int pow) const // remaining power to take
356 {
357 if (pow == 0)
358 symm1_result->append(symm1_deg);
359 else
360 {
361 for (int i = lastn; i < F->rank(); i++)
362 {
363 // increase symm1_deg, with e_i
364 D->mult(symm1_deg, F->degree(i), symm1_deg);
365
366 symm1(i, pow - 1);
367
368 // decrease symm1_deg back
369 D->divide(symm1_deg, F->degree(i), symm1_deg);
370 }
371 }
372 }
373
374 FreeModule_symm(const FreeModule *F0, int n0)
375 : F(F0), D(F0->get_ring()->degree_monoid()), n(n0), symm1_result(nullptr), symm1_deg(nullptr)
376 {
377 }
378
380 {
381 if (symm1_result == nullptr)
382 {
383 symm1_result = F->get_ring()->make_FreeModule();
384 if (n >= 0)
385 {
386 symm1_deg = D->make_one();
387 symm1(0, n);
388 D->remove(symm1_deg);
389 }
390 }
391 return symm1_result;
392 }
393};
394
396// n th symmetric power
397{
398 FreeModule_symm SF(this, n);
399 FreeModule *result = SF.value();
400 if (schreyer != nullptr) result->schreyer = schreyer->symm(n);
401 return result;
402}
403
404static bool degree_in_box(int len, const_exponents deg, M2_arrayint lo, M2_arrayint hi)
405{
406 if (lo->len != 0)
407 for (int i = 0; i < len; i++)
408 if (deg[i] < lo->array[i]) return false;
409 if (hi->len != 0)
410 for (int i = 0; i < len; i++)
411 if (deg[i] > hi->array[i]) return false;
412 return true;
413}
414
416 M2_arrayintOrNull hi) const
417{
418 auto D = R->degree_monoid();
419 std::vector<size_t> result;
420 int ndegrees = D->n_vars();
421 exponents_t exp = newarray_atomic(int, ndegrees);
422 for (int i = 0; i < rank(); i++)
423 {
424 D->to_expvector(degree(i), exp);
425#if 0
426 for (int i=0; i<ndegrees; i++)
427 printf("%d ", exp[i]);
428 if (degree_in_box(ndegrees, exp, lo, hi))
429 printf("yes\n");
430 else
431 printf("no\n");
432#endif
433 if (degree_in_box(ndegrees, exp, lo, hi)) result.push_back(i);
434 }
436 freemem(exp);
437 return selection;
438}
439
441{
442 int result =
443 R->degree_monoid()->degree_weights(degree(i), R->get_heft_vector());
444 return result;
445}
446
448{
449 if (rank() == 0) return 0;
450 int result = primary_degree(0);
451 for (int i = 1; i < rank(); i++)
452 {
453 int a = primary_degree(i);
454 if (a < result) result = a;
455 }
456 return result;
457}
458
460{
461 if (rank() == 0) return 0;
462 int result = primary_degree(0);
463 for (int i = 1; i < rank(); i++)
464 {
465 int a = primary_degree(i);
466 if (a > result) result = a;
467 }
468 return result;
469}
470
472{
473 int i;
474 int rk = rank();
475 o << "free(rank " << rk << " degrees = {";
476 auto D = R->degree_monoid();
477 for (i = 0; i < rk; i++)
478 {
479 if (i != 0) o << ", ";
480 D->elem_text_out(o, degree(i));
481 }
482 o << "}";
483 if (schreyer != nullptr) schreyer->text_out(o);
484 o << ')';
485}
486
487// Local Variables:
488// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
489// indent-tabs-mode: nil
490// End:
Older Schreyer-style kernel computation, predecessor of schreyer-resolution/.
exponents::ConstExponents const_exponents
exponents::Exponents exponents_t
virtual ~FreeModule()
Definition freemod.cpp:120
FreeModule * transpose() const
Definition freemod.cpp:227
M2_arrayintOrNull select_by_degrees(M2_arrayintOrNull lo, M2_arrayintOrNull hi) const
Definition freemod.cpp:415
virtual FreeModule * new_free() const
Definition freemod.cpp:125
FreeModule * tensor(const FreeModule *G) const
Definition freemod.cpp:271
const Ring * get_ring() const
Definition freemod.hpp:102
SchreyerOrder * schreyer
Definition freemod.hpp:73
const_monomial degree(int i) const
Definition freemod.hpp:104
gc_vector< monomial > components
Definition freemod.hpp:72
void initialize(const Ring *RR)
Definition freemod.cpp:16
void change_degree(int i, const_monomial deg)
Definition freemod.cpp:145
void append(const_monomial d)
Definition freemod.cpp:130
FreeModule * exterior(int p) const
Definition freemod.cpp:296
void direct_sum_to(const FreeModule *G)
Definition freemod.cpp:263
FreeModule * symm(int p) const
Definition freemod.cpp:395
FreeModule(const Ring *R, int n, bool has_schreyer_order)
Definition freemod.cpp:32
bool is_equal(const FreeModule *F) const
Definition freemod.cpp:154
FreeModule * shift(const_monomial d) const
Definition freemod.cpp:178
virtual unsigned int computeHashValue() const
Definition freemod.cpp:22
int primary_degree(int i) const
Definition freemod.cpp:440
const Ring * R
Definition freemod.hpp:75
Matrix * get_induced_order() const
Definition freemod.cpp:100
FreeModule * sub_space(int n) const
Definition freemod.cpp:197
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
friend class Ring
Definition freemod.hpp:67
FreeModule * direct_sum(const FreeModule *G) const
Definition freemod.cpp:244
int highest_primary_degree() const
Definition freemod.cpp:459
int rank() const
Definition freemod.hpp:105
static FreeModule * make_schreyer(const Matrix *m)
Definition freemod.cpp:53
void text_out(buffer &o) const
Definition freemod.cpp:471
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 * cols() const
Definition matrix.hpp:145
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.
Engine-side commutative monomial monoid: variable names, ordering, multidegree machinery,...
Definition monoid.hpp:89
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 const Ring * getCoefficients() const
Definition polyring.hpp:277
Abstract base for the engine's polynomial-ring hierarchy.
Definition polyring.hpp:96
virtual ring_elem from_long(long n) const =0
virtual const PolynomialRing * cast_to_PolynomialRing() const
Definition ring.hpp:243
static SchreyerOrder * create(const Monoid *m)
Definition schorder.cpp:11
int compare_num(int i) const
Definition schorder.hpp:90
const_monomial base_monom(int i) const
Definition schorder.hpp:91
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
static bool degree_in_box(int len, const_exponents deg, M2_arrayint lo, M2_arrayint hi)
Definition freemod.cpp:404
FreeModule — finite-rank free module R^n, the type-level anchor for every Matrix.
#define monomial
Definition gb-toric.cpp:11
GBRing and gbvector — the GB-tuned polynomial-ring view used by classical Buchberger code.
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)
M2_arrayint M2_arrayintOrNull
Definition m2-types.h:99
MatrixConstructor — the mutable builder that produces an immutable Matrix.
Matrix — the engine's immutable homomorphism F -> G between free modules.
#define newarray_atomic(T, len)
Definition newdelete.hpp:91
PolynomialRing — abstract polynomial-ring base, the engine's most-reused class.
tbb::flow::graph G
FreeModule_symm(const FreeModule *F0, int n0)
Definition freemod.cpp:374
FreeModule * value()
Definition freemod.cpp:379
FreeModule * symm1_result
Definition freemod.cpp:351
monomial symm1_deg
Definition freemod.cpp:352
const Monoid * D
Definition freemod.cpp:348
void symm1(int lastn, int pow) const
Definition freemod.cpp:354
const FreeModule * F
Definition freemod.cpp:347
Helper functor that builds the n-th symmetric power of a FreeModule by recursively walking multi-indi...
Definition freemod.cpp:346
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
#define INTSIZE(a)
Definition style.hpp:37
M2_arrayint stdvector_to_M2_arrayint(const std::vector< T > &v)
Definition util.hpp:79
Conversion helpers between M2 boundary types and standard C++ containers.