Macaulay2 Engine
Loading...
Searching...
No Matches
moninfo.hpp
Go to the documentation of this file.
1// Copyright 2005-2021 Michael E. Stillman
2
3#ifndef _moninfo_hpp_
4#define _moninfo_hpp_
5
51
52#include "interface/m2-types.h" // for M2_arrayint, M2_arrayint_st...
53#include "f4/ntuple-monomial.hpp" // for ntuple_word, const_ntuple_m...
54#include "f4/varpower-monomial.hpp" // for varpower_word, index_varpow...
55#include "interface/monomial-ordering.h" // for MonomialOrdering
56#include "newdelete.hpp" // for our_new_delete
57#include "skew.hpp" // for SkewMultiplication
58
59#include <iostream>
60
61#if 0
62#include <M2/config.h> // for HAVE_STDINT_H
63#include <cstdio>
64
65#if HAVE_STDINT_H
66#include <stdint.h>
67#elif HAVE_INTTYPES_H
68#include <inttypes.h>
69#else
70#error integer type definitions not available
71#endif
72
73#endif
74
75// typedef int64_t monomial_word; // Used for all types of monomials. Is this
76// OK?
77typedef long monomial_word; // Used for all types of monomials. Is this OK?
80// format: [hash,component,e1,...,envars],
81// where [e1,...,envars] is packed.
82// OR: [hash,component,weight,e1,...,envars]
83// and weight is NOT packed.
84// packing info, hash values, weights are all
85// defined in: PackedMonomials
86
87// with weight vector values:
88// [hashvalue comp w1 w2 ... wr e1 e2 ... en]
89// or is it:
90// [hashvalue comp e1 e2 ... en -wr ... -w1]
91
108{
109 int nvars;
111 monomial_word *hashfcn; // array 0..nvars-1 of hash values for each variable
113
114 // Monomial order and placement info
115 int firstvar; // = 2, if no weight vector, otherwise 2 + mNumWeights
116 int mNumWeights; // number of weight vector values placed. These should all be
117 // positive values?
118
119 std::vector<int> mWeightVectors; // array 0..mNumWeights of array 0..nvars-1 of longs
120 std::vector<int> mHeftDegrees; // heft degree of each variable (dot product of the
121 // heft vector with the (multi)degree of the
122 // corresponding variable.
123 std::vector<int> mModuleHeftDegrees; // heft degree of each generator of free module
124
125 bool mTieBreakerIsRevLex; // true yes, false, tie break is Lex.
126 int mPositionUp; // currently ignored
127 int mComponentLoc; // currently ignored
128
129 // monomial format:
130 // [hashvalue, component, wt1, ..., wts, exp0, ..., exp(r-1)]
131
132 mutable unsigned long ncalls_compare;
133 mutable unsigned long ncalls_mult;
134 mutable unsigned long ncalls_get_component;
135 mutable unsigned long ncalls_from_expvector;
136 mutable unsigned long ncalls_to_expvector;
137 mutable unsigned long ncalls_to_varpower;
138 mutable unsigned long ncalls_from_varpower;
139 mutable unsigned long ncalls_is_equal;
140 mutable unsigned long ncalls_is_equal_true;
141 mutable unsigned long ncalls_divide;
142 mutable unsigned long ncalls_weight;
143 mutable unsigned long ncalls_unneccesary;
144 mutable unsigned long ncalls_quotient_as_vp;
145
146 public:
150
152 const MonomialOrdering *mo,
153 const std::vector<int>& heftDegrees,
154 const std::vector<int>& moduleHeftDegrees);
155
156 virtual ~MonomialInfo();
157
158 int n_vars() const { return nvars; }
159 int max_monomial_size() const { return nslots; }
161 {
162 (void) m;
163 return nslots;
164 }
165
166 void show() const;
167
168 int componentLocation() const { return mComponentLoc; }
169 int positionUp() { return mPositionUp; }
170
171 long hash_value(const_packed_monomial m) const { return *m; }
172 // This hash value is an ADDITIVE hash (trick due to A. Steel)
173
175 {
176 for (int i = 0; i < nslots; i++) *target++ = *src++;
177 }
178
179 long last_exponent(const_packed_monomial m) const { return m[nslots - 1]; }
180 void set_component(long component, packed_monomial m) const
181 {
182 m[1] = component;
183 }
184
186 {
188 return m[1];
189 }
190
192 long comp,
194 {
195 // Pack the vector e[0]..e[nvars-1],comp. Create the hash value at the same
196 // time.
198 result[0] = 0;
199 result[1] = comp;
200
201 for (int i = 0; i < nvars; i++)
202 {
203 result[firstvar + i] = e[i];
204 if (e[i] > 0) result[0] += hashfcn[i] * e[i];
205 }
206
207 const int *wt = mWeightVectors.data();
208 for (int j = 0; j < mNumWeights; j++, wt += nvars)
209 {
210 long val = 0;
211 for (int i = 0; i < nvars; i++)
212 {
213 long a = e[i];
214 if (a > 0) val += a * wt[i];
215 }
216 result[2 + j] = val;
217 }
218 return true;
219 }
220
223 int *skewvars) const
224 {
225 return skew->skew_vars(m + 2 + mNumWeights, skewvars);
226 }
227
230 const_packed_monomial n) const
231 {
232 return skew->mult_sign(m + 2 + mNumWeights, n + 2 + mNumWeights);
233 }
234
235 bool one(long comp, packed_monomial result) const
236 {
237 // Pack the vector (0,...,0,comp) with nvars zeroes.
238 // Hash value = 0. ??? Should the hash-function take component into account
239 // ???
240 result[0] = 0;
241 result[1] = comp;
242 for (int i = 2; i < nslots; i++) result[i] = 0;
243 return true;
244 }
245
248 long &result_comp) const
249 {
250 // Unpack the monomial m.
252 result_comp = m[1];
253 m += 2 + mNumWeights;
254 for (int i = 0; i < nvars; i++) *result++ = *m++;
255 return true;
256 }
257
259 int *result,
260 int &result_comp) const
261 {
262 // Unpack the monomial m into result, which should already be allocated
263 // 0..nvars-1
264 // this is to connect with older 'int *' monomials.
266 result_comp = static_cast<int>(m[1]);
267 m += firstvar;
268 for (int i = 0; i < nvars; i++) *result++ = static_cast<int>(*m++);
269 return true;
270 }
271
274 {
275 // 'result' must have enough space allocated
277 varpower_word *t = result + 1;
279 int len = 0;
280 for (int i = nvars - 1; i >= 0; i--)
281 {
282 if (*--m1 > 0)
283 {
284 *t++ = i;
285 *t++ = *m1;
286 len++;
287 }
288 }
289 *result = len;
290 }
291
293 long comp,
295 {
296 // 'result' must have enough space allocated
298 result[0] = 0;
299 result[1] = comp;
300 for (int i = 2; i < nslots; i++)
301 {
302 result[i] = 0;
303 }
304 for (index_varpower_monomial j = m; j.valid(); ++j)
305 {
306 varpower_word v = j.var();
307 varpower_word e = j.exponent();
308 result[firstvar + v] = e;
309 if (e == 1)
310 result[0] += hashfcn[v];
311 else
312 result[0] += e * hashfcn[v];
313 }
314
315 const int *wt = mWeightVectors.data();
316 for (int j = 0; j < mNumWeights; j++, wt += nvars)
317 {
318 long val = 0;
319 for (index_varpower_monomial i = m; i.valid(); ++i)
320 {
321 varpower_word v = i.var();
322 varpower_word e = i.exponent();
323 long w = wt[v];
324 if (e == 1)
325 val += w;
326 else
327 val += w * e;
328 result[2 + j] = val;
329 }
330 }
331 }
332
334 {
336 for (int j = nslots; j > 0; --j)
337 if (*m++ != *n++) return false;
339 return true;
340 }
341
343 const_packed_monomial n) const
344 {
346 if (*m++ != *n++) return false;
347 m++;
348 n++;
349 for (int j = nslots - 2; j > 0; --j)
350 if (*m++ != *n++) return false;
352 return true;
353 }
354
356 {
357 // Determine if m represents a well-formed monomial.
358 m++;
359 for (int j = nslots - 1; j > 0; --j)
360 if (mask & (*m++)) return false;
361 return true;
362 }
363
367 {
368 ncalls_mult++;
369 for (int j = nslots; j > 0; --j) *result++ = *m++ + *n++;
370 }
371
375 {
377 for (int j = nslots; j > 0; --j) *result++ = *m++ - *n++;
378 }
379
383 {
385 // First, divide monomials
386 // Then, if the division is OK, set the component, hash value and rest of
387 // the monomial
388 if (m[1] != n[1]) // components are not equal
389 return false;
392 packed_monomial result1 = result + nslots;
393 for (int i = nslots - 2; i > 0; i--)
394 {
395 varpower_word cmp = *--m1 - *--n1;
396 if (cmp < 0) return false;
397 *--result1 = cmp;
398 }
399 result[1] = 0; // the component of a division is in the ring (comp 0).
400 result[0] = m[0] - n[0]; // subtract hash codes
401 return true;
402 }
403
411
413
414 void show(const_packed_monomial m) const;
415
416 void showAlpha(const_packed_monomial m) const;
417
418
420 {
424 for (int i = nslots - 2; i > 0; i--)
425 {
426 varpower_word cmp = *--m1 - *--n1;
427 if (cmp < 0) return -1;
428 if (cmp > 0) return 1;
429 }
430 monomial_word cmp = m[1] - n[1];
431 if (cmp < 0) return 1;
432 if (cmp > 0) return -1;
433 return 0;
434 }
435
440 long tie1,
441 long tie2) const
442 {
444#if 0
445 printf("compare_schreyer: ");
446 printf(" m=");
447 showAlpha(m);
448 printf(" n=");
449 showAlpha(n);
450 printf(" m0=");
451 showAlpha(m0);
452 printf(" n0=");
453 showAlpha(n0);
454 printf(" tiebreakers: %ld %ld\n", tie1, tie2);
455#endif
460 for (int i = nslots - 2; i > 0; i--)
461 {
462 varpower_word cmp = *--m1 - *--n1 + *--m2 - *--n2;
463 if (cmp < 0) return -1;
464 if (cmp > 0) return 1;
465 }
466 monomial_word cmp = tie1 - tie2;
467 if (cmp < 0) return 1;
468 if (cmp > 0) return -1;
469 return 0;
470 }
471
473 {
475 const_packed_monomial m1 = m + 2;
476 const_packed_monomial n1 = n + 2;
477 for (int i = nslots - 2; i > 0; i--)
478 {
479 varpower_word cmp = *m1++ - *n1++;
480 if (cmp > 0) return -1;
481 if (cmp < 0) return 1;
482 }
483 monomial_word cmp = m[1] - n[1];
484 if (cmp < 0) return 1;
485 if (cmp > 0) return -1;
486 return 0;
487 }
488
490 const_packed_monomial n) const
491 {
493 const_packed_monomial m1 = m + 2;
494 const_packed_monomial n1 = n + 2;
495 for (int i = 0; i < mNumWeights; i++)
496 {
497 varpower_word cmp = *m1++ - *n1++;
498 if (cmp > 0) return -1;
499 if (cmp < 0) return 1;
500 }
501 m1 = m + nslots;
502 n1 = n + nslots;
503 for (int i = nvars - 1; i > 0; i--)
504 {
505 varpower_word cmp = *--m1 - *--n1;
506 if (cmp < 0) return -1;
507 if (cmp > 0) return 1;
508 }
509 monomial_word cmp = m[1] - n[1];
510 if (cmp < 0) return 1;
511 if (cmp > 0) return -1;
512 return 0;
513 }
514
516 // returns LT, EQ, GT:
517 // LT if m < n in the monomial order
518 // GT if m > n
519 // otherwise EQ
521 const_packed_monomial n) const
522 {
524 const_packed_monomial m1 = m + 2;
525 const_packed_monomial n1 = n + 2;
526 for (int i = 0; i < mNumWeights; i++)
527 {
528 varpower_word cmp = *m1++ - *n1++;
529 if (cmp > 0) return GT;
530 if (cmp < 0) return LT;
531 }
533 {
534 m1 = m + nslots;
535 n1 = n + nslots;
536 for (int i = nvars - 1; i >= 0; i--)
537 {
538 varpower_word cmp = *--m1 - *--n1;
539 if (cmp < 0) return GT;
540 if (cmp > 0) return LT;
541 }
542 } else {
543 m1 = m + firstvar;
544 n1 = n + firstvar;
545 for (int i = 0; i < nvars; ++i)
546 {
547 varpower_word cmp = *m1++ - *n1++;
548 if (cmp > 0) return GT;
549 if (cmp < 0) return LT;
550 }
551 }
552
553 monomial_word cmp = m[1] - n[1];
554 if (cmp < 0) return LT;
555 if (cmp > 0) return GT;
556 return EQ;
557 }
558
560 const_packed_monomial n) const
561 {
562 std::cout << "comparing: ";
563 show(m);
564 std::cout << "and ";
565 show(n);
566 int result = compare(m, n);
567 std::cout << " result: " << result << std::endl;
568 return result;
569 }
570
571 // int (MonomialInfo::*compare)(const_packed_monomial m,
572 // const_packed_monomial n) const;
573
577 const_packed_monomial lcm) const
578 // Returns true if the corresponding pair (p1,p2) could be removed
579 // This is essentially the Buchberger-Moeller criterion
580 // Assumptions: lcm(p1,p2) = lcm.
581 // Here is the criterion:
582 // (a) if component(lcm) != component(m) return false
583 // (b) if m does not divide lcm, return false
584 // (c) need that (A) lcm(p1,m) != lcm and that (B) lcm(p2,m) != lcm
585 // (in these two cases, we will have already removed one of the other
586 // two pairs: (p1,m), (p2,m). Note that in any case,
587 // if (b) holds, then lcm(p1,m) divides lcm, same with lcm(p2,m).
588 // if A and B then return true
589 {
590 // TODO: MES: this maybe should check that lead components of m and p1 and
591 // p2 are the same...
593 bool A = false;
594 bool B = false;
595 m += firstvar;
596 p1 += firstvar;
597 p2 += firstvar;
598 lcm += firstvar;
599 for (int i = 0; i < nvars; i++)
600 {
601 if (m[i] > lcm[i]) return false;
602 if (m[i] == lcm[i]) continue;
603 if (!A && p1[i] < lcm[i])
604 {
605 A = true;
606 continue;
607 }
608 if (!B && p2[i] < lcm[i])
609 {
610 B = true;
611 }
612 }
613 return (A && B);
614 }
615
619 const_packed_monomial lcm) const
620 // Returns true if the corresponding pair (p1,p2) could be removed
621 // This is essentially the Buchberger-Moeller criterion
622 // Assumptions: lcm(p1,p2) = lcm.
623 // Here is the criterion:
624 // (a) if component(lcm) != component(m) return false
625 // (b) if m does not divide lcm, return false
626 // (c) need that (A) lcm(p1,m) != lcm and that (B) lcm(p2,m) != lcm
627 // (in these two cases, we will have already removed one of the other
628 // two pairs: (p1,m), (p2,m). Note that in any case,
629 // if (b) holds, then lcm(p1,m) divides lcm, same with lcm(p2,m).
630 // if A and B then return true
631
632 // Here is the criterion to remove a pair (i.e. return true)
633 // (a) need: component(lcm) == component(m) (else return false)
634 // (b) need: m divides lcm, (else return false)
635 // (c) need: (A) and (B), where
636 // (A) lcm(p1,m) != lcm
637 // (B) lcm(p2,m) != lcm
638 //
639 // (in these two cases, we will have already removed one of the other
640 // two pairs: (p1,m), (p2,m). Note that in any case,
641 // if (b) holds, then lcm(p1,m) divides lcm, same with lcm(p2,m).
642 // if A and B then return true
643
644 {
645 // TODO: MES: this maybe should check that lead components of m and p1 and
646 // p2 are the same...
648 bool A = false;
649 m += firstvar;
650 p1 += firstvar;
651 p2 += firstvar;
652 lcm += firstvar;
653 for (int i = 0; i < nvars; i++)
654 if (m[i] > lcm[i]) return false;
655
656 for (int i = 0; i < nvars; i++)
657 {
658 varpower_word a = lcm[i];
659 if (p1[i] < a && m[i] < a)
660 {
661 A = true;
662 break;
663 }
664 }
665
666 if (!A) return false;
667
668 // Now (b), (A) hold. Check (B).
669 for (int i = 0; i < nvars; i++)
670 {
671 varpower_word a = lcm[i];
672 if (p2[i] < a && m[i] < a) return true;
673 }
674
675 return false;
676 }
677
679 {
680 result[0] = 1;
681 result[1] = v;
682 result[2] = 1;
683 }
684
688 int &deg_result,
689 bool &are_disjoint) const
690 {
692 // sets result, deg, are_disjoint
694 are_disjoint = true;
695 a += firstvar;
696 b += firstvar;
697 int len = 0;
698 varpower_word *r = result + 1;
699 for (int i = nvars - 1; i >= 0; --i)
700 {
701 if (a[i] != 0 && b[i] != 0) are_disjoint = false;
702 long c = a[i] - b[i];
703 if (c > 0)
704 {
705 *r++ = i;
706 *r++ = c;
707 deg += c * mHeftDegrees[i];
708 len++;
709 }
710 }
711 result[0] = len;
712 deg_result = static_cast<int>(deg);
713 }
714};
715#endif
716
717// Local Variables:
718// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
719// indent-tabs-mode: nil
720// End:
bool is_equal(const_packed_monomial m, const_packed_monomial n) const
Definition moninfo.hpp:333
unsigned long ncalls_weight
Definition moninfo.hpp:142
unsigned long ncalls_to_varpower
Definition moninfo.hpp:137
void unchecked_divide(const_packed_monomial m, const_packed_monomial n, packed_monomial result) const
Definition moninfo.hpp:372
unsigned long ncalls_from_expvector
Definition moninfo.hpp:135
int compare(const_packed_monomial m, const_packed_monomial n) const
compare:
Definition moninfo.hpp:520
monomial_word mask
Definition moninfo.hpp:112
void set_component(long component, packed_monomial m) const
Definition moninfo.hpp:180
int skew_vars(const SkewMultiplication *skew, const_packed_monomial m, int *skewvars) const
Definition moninfo.hpp:221
const_packed_monomial const_monomial
Definition moninfo.hpp:148
void quotient_as_vp(const_packed_monomial a, const_packed_monomial b, varpower_monomial result, int &deg_result, bool &are_disjoint) const
Definition moninfo.hpp:685
void to_varpower_monomial(const_packed_monomial m, varpower_monomial result) const
Definition moninfo.hpp:272
long hash_value(const_packed_monomial m) const
Definition moninfo.hpp:171
unsigned long ncalls_is_equal_true
Definition moninfo.hpp:140
unsigned long ncalls_compare
Definition moninfo.hpp:132
void show() const
Definition moninfo.cpp:87
unsigned long ncalls_quotient_as_vp
Definition moninfo.hpp:144
int positionUp()
Definition moninfo.hpp:169
monomial value
Definition moninfo.hpp:149
unsigned long ncalls_unneccesary
Definition moninfo.hpp:143
std::vector< int > mHeftDegrees
Definition moninfo.hpp:120
bool to_expvector(const_packed_monomial m, ntuple_monomial result, long &result_comp) const
Definition moninfo.hpp:246
MonomialInfo(int nvars, const MonomialOrdering *mo, const std::vector< int > &heftDegrees, const std::vector< int > &moduleHeftDegrees)
Definition moninfo.cpp:11
bool check_monomial(const_packed_monomial m) const
Definition moninfo.hpp:355
bool unnecessary(const_packed_monomial m, const_packed_monomial p1, const_packed_monomial p2, const_packed_monomial lcm) const
Definition moninfo.hpp:616
void copy(const_packed_monomial src, packed_monomial target) const
Definition moninfo.hpp:174
int compare_schreyer(const_packed_monomial m, const_packed_monomial n, const_packed_monomial m0, const_packed_monomial n0, long tie1, long tie2) const
Definition moninfo.hpp:436
int compare_weightvector(const_packed_monomial m, const_packed_monomial n) const
Definition moninfo.hpp:489
int componentLocation() const
Definition moninfo.hpp:168
int max_monomial_size() const
Definition moninfo.hpp:159
int skew_mult_sign(const SkewMultiplication *skew, const_packed_monomial m, const_packed_monomial n) const
Definition moninfo.hpp:228
void unchecked_mult(const_packed_monomial m, const_packed_monomial n, packed_monomial result) const
Definition moninfo.hpp:364
std::vector< int > mModuleHeftDegrees
Definition moninfo.hpp:123
long last_exponent(const_packed_monomial m) const
Definition moninfo.hpp:179
int compareVerbose(const_packed_monomial m, const_packed_monomial n) const
Definition moninfo.hpp:559
int compare_grevlex(const_packed_monomial m, const_packed_monomial n) const
Definition moninfo.hpp:419
bool divide(const_packed_monomial m, const_packed_monomial n, packed_monomial result) const
Definition moninfo.hpp:380
long get_component(const_packed_monomial m) const
Definition moninfo.hpp:185
unsigned long ncalls_to_expvector
Definition moninfo.hpp:136
bool mult(const_packed_monomial m, const_packed_monomial n, packed_monomial result) const
Definition moninfo.hpp:404
std::vector< int > mWeightVectors
Definition moninfo.hpp:119
bool mTieBreakerIsRevLex
Definition moninfo.hpp:125
unsigned long ncalls_get_component
Definition moninfo.hpp:134
monomial_word monomial_heft(const_packed_monomial m) const
Definition moninfo.cpp:75
void variable_as_vp(int v, varpower_monomial result) const
Definition moninfo.hpp:678
int compare_lex(const_packed_monomial m, const_packed_monomial n) const
Definition moninfo.hpp:472
bool monomial_part_is_equal(const_packed_monomial m, const_packed_monomial n) const
Definition moninfo.hpp:342
void showAlpha(const_packed_monomial m) const
Definition moninfo.cpp:124
int monomial_size(const_packed_monomial m) const
Definition moninfo.hpp:160
unsigned long ncalls_is_equal
Definition moninfo.hpp:139
unsigned long ncalls_divide
Definition moninfo.hpp:141
unsigned long ncalls_from_varpower
Definition moninfo.hpp:138
bool from_expvector(const_ntuple_monomial e, long comp, packed_monomial result) const
Definition moninfo.hpp:191
unsigned long ncalls_mult
Definition moninfo.hpp:133
int mComponentLoc
Definition moninfo.hpp:127
bool one(long comp, packed_monomial result) const
Definition moninfo.hpp:235
monomial_word * hashfcn
Definition moninfo.hpp:111
int n_vars() const
Definition moninfo.hpp:158
void from_varpower_monomial(const_varpower_monomial m, long comp, packed_monomial result) const
Definition moninfo.hpp:292
packed_monomial monomial
Definition moninfo.hpp:147
virtual ~MonomialInfo()
Definition moninfo.cpp:70
bool to_intstar_vector(const_packed_monomial m, int *result, int &result_comp) const
Definition moninfo.hpp:258
bool unnecessary1(const_packed_monomial m, const_packed_monomial p1, const_packed_monomial p2, const_packed_monomial lcm) const
Definition moninfo.hpp:574
int mult_sign(const int *exp1, const int *exp2) const
Definition skew.cpp:91
int skew_vars(const int *exp, int *result) const
Definition skew.cpp:61
Sign-rule helper used by every ring that has a skew-commutative subset of variables (exterior factor,...
Definition skew.hpp:54
int p1
VALGRIND_MAKE_MEM_DEFINED & result(result)
Engine-to-interpreter type vocabulary across the C++ / .dd boundary.
monomial_word * packed_monomial
Definition moninfo.hpp:78
const monomial_word * const_packed_monomial
Definition moninfo.hpp:79
long monomial_word
Definition moninfo.hpp:77
Engine-boundary C API for assembling block-level MonomialOrderings from declarative pieces.
our_new_delete — per-class opt-in routing of new / delete through bdwgc.
ntuple_word * ntuple_monomial
const ntuple_word * const_ntuple_monomial
F4's dense int64_t exponent-vector specialisation of ExponentVector (legacy).
SkewMultiplication — configuration object naming the skew-commuting variables of a ring.
Front-end-side description of a monomial ordering as a list of mon_part blocks.
const int EQ
Definition style.hpp:40
const int GT
Definition style.hpp:41
const int LT
Definition style.hpp:39
varpower_word * varpower_monomial
const varpower_word * const_varpower_monomial
varpower_monomials::Exponent varpower_word
ExponentListIterator< long, false > index_varpower_monomial
F4's (variable, exponent) sparse-monomial ExponentList specialisation (legacy).