Macaulay2 Engine
Loading...
Searching...
No Matches
monomial-ordering.cpp
Go to the documentation of this file.
1// TODO: there are many duplicate methods in C and C++ style in this file
2
4
5// TODO: remove this when to_string methods are moved together
6#include <stdio.h>
7
8#include <vector>
9#include <string>
10#include <sstream>
11
12#include "interface/m2-mem.h" // for getmemvectortype, getmematomicvectortype
13#include "error.h"
14#include "monordering.hpp" // TODO: where can this go? it only defines one class
15
17 int nvars,
18 const int *wts)
19{
20 mon_part result;
21 result = getmemstructtype(mon_part);
22 result->type = type;
23 result->nvars = nvars;
24 if (wts != nullptr)
25 {
26 int i;
28 for (i = 0; i < nvars; i++) result->wts[i] = wts[i];
29 }
30 else
31 result->wts = nullptr;
32 return result;
33}
34
36{
37 static unsigned int next_hash = 23023421;
39 z->len = n;
40 z->_hash = next_hash++;
41 int i;
42 for (i = 0; i < n; i++) z->array[i] = nullptr;
43 return z;
44}
45
46static MonomialOrdering *M2_mo_offset(const MonomialOrdering *mo, int offset)
47{
48 int i, j;
50 for (i = 0; i < mo->len; i++)
51 {
52 mon_part p = mo->array[i];
53 if (p->type != MO_WEIGHTS)
54 result->array[i] = mo_make(p->type, p->nvars, p->wts);
55 else
56 {
57 mon_part q = mo_make(MO_WEIGHTS, offset + p->nvars, nullptr);
58 q->wts = getmemvectortype(int, q->nvars);
59 for (j = 0; j < offset; j++) q->wts[j] = 0;
60 for (; j < q->nvars; j++) q->wts[j] = p->wts[j - offset];
61 }
62 }
63 return result;
64}
65
66static bool is_good(mon_part p)
67{
68 switch (p->type)
69 {
70 case MO_LEX:
71 case MO_LEX2:
72 case MO_LEX4:
73 case MO_GREVLEX:
74 case MO_GREVLEX2:
75 case MO_GREVLEX4:
76 case MO_GREVLEX_WTS:
77 case MO_GREVLEX2_WTS:
78 case MO_GREVLEX4_WTS:
79 case MO_LAURENT:
80 case MO_NC_LEX:
82 case MO_REVLEX:
83 case MO_WEIGHTS:
84 return (p->nvars > 0);
85 case MO_POSITION_UP:
87 return true;
88 }
89 return false;
90}
91
105{
106 std::vector<int> w;
107 for (int i = 0; i < nvars; i++) w.push_back(1);
108 return GRevLex(w);
109}
111{
112 std::vector<int> w;
113 for (int i = 0; i < nvars; i++) w.push_back(1);
114 return GRevLex2(w);
115}
117{
118 std::vector<int> w;
119 for (int i = 0; i < nvars; i++) w.push_back(1);
120 return GRevLex4(w);
121}
123{
124 return GRevLex(wts, 1);
125}
127{
128 return GRevLex(wts, 2);
129}
131{
132 return GRevLex(wts, 4);
133}
139{
140 mon_part p = mo_make(MO_WEIGHTS, wts.size(), wts.data());
142 result->array[0] = p;
143 return result;
144}
161
162MonomialOrdering *MonomialOrderings::GRevLex(const std::vector<int> &degs,
163 int packing)
164{
166 mon_part p;
167 enum MonomialOrdering_type typ;
168 const int *wts;
169 bool all_one = true;
170 for (int i = 0; i < degs.size(); i++)
171 if (degs[i] <= 0)
172 {
173 ERROR("grevlex: expected all degrees to be positive");
174 return nullptr;
175 }
176 else if (degs[i] > 1)
177 all_one = false;
178
179 if (all_one)
180 {
181 if (packing == 2)
182 typ = MO_GREVLEX2;
183 else if (packing == 4)
184 typ = MO_GREVLEX4;
185 else
186 typ = MO_GREVLEX;
187 wts = nullptr;
188 }
189 else
190 {
191 if (packing == 2)
192 typ = MO_GREVLEX2_WTS;
193 else if (packing == 4)
194 typ = MO_GREVLEX4_WTS;
195 else
196 typ = MO_GREVLEX_WTS;
197 wts = degs.data();
198 }
199
200 p = mo_make(typ, degs.size(), wts);
202 result->array[0] = p;
203 return result;
204}
205
207 const std::vector<MonomialOrdering *> &M)
208{
210 const MonomialOrdering *mo;
211 int i, j, sum, next;
212 int nvars_so_far = 0;
213
214 sum = 0;
215 for (i = 0; i < M.size(); i++)
216 {
217 mo = M[i];
218 for (j = 0; j < mo->len; j++)
219 if (is_good(mo->array[j])) sum++;
220 }
221
222 result = make_mon_order(sum);
223 next = 0;
224 for (i = 0; i < M.size(); i++)
225 {
226 mo = M[i];
227 for (j = 0; j < mo->len; j++)
228 {
229 mon_part p = mo->array[j];
230 if (!is_good(p)) continue;
231 if (p->type != MO_WEIGHTS)
232 nvars_so_far += p->nvars;
233 else
234 {
235 /* Shift the weights over by nvars_so_far */
236 mon_part q = mo_make(MO_WEIGHTS, nvars_so_far + p->nvars, nullptr);
237 q->wts = getmemvectortype(int, q->nvars);
238 for (j = 0; j < nvars_so_far; j++) q->wts[j] = 0;
239 for (; j < q->nvars; j++) q->wts[j] = p->wts[j - nvars_so_far];
240 p = q;
241 }
242 result->array[next++] = p;
243 }
244 }
245 return result;
246}
247
249 const std::vector<MonomialOrdering *> &M)
250{
252 int i, j, sum, next, offset;
253 sum = 0;
254 for (i = 0; i < M.size(); i++) sum += M[i]->len;
255
256 result = make_mon_order(sum);
257 next = 0;
258 offset = 0;
259 for (i = 0; i < M.size(); i++)
260 {
261 int nvars = rawNumberOfVariables(M[i]);
262 MonomialOrdering *mo = M2_mo_offset(M[i], offset);
263 for (j = 0; j < mo->len; j++) result->array[next++] = mo->array[j];
264 offset += nvars;
265 }
266 return result;
267}
268
269std::ostringstream &toString(std::ostringstream &o, int len, int *p)
270{
271 o << "{";
272 for (int i = 0; i < len; i++)
273 {
274 if (i > 0) o << ",";
275 o << p[i];
276 }
277 o << "}";
278 return o;
279}
280
281std::ostringstream &ones(std::ostringstream &o, int len)
282{
283 o << "{";
284 for (int i = 0; i < len; i++)
285 {
286 if (i > 0) o << ",";
287 o << 1;
288 }
289 o << "}";
290 return o;
291}
292
294{
295 std::ostringstream o;
296 o << "MonomialOrder => {";
297 for (int i = 0; i < mo->len; i++)
298 {
299 mon_part p = mo->array[i];
300 bool p_ones = false;
301 if (i == 0)
302 o << "\n ";
303 else
304 o << ",\n ";
305 switch (p->type)
306 {
307 case MO_LEX:
308 o << "Lex => " << p->nvars;
309 break;
310 case MO_LEX2:
311 o << "LexSmall => " << p->nvars;
312 break;
313 case MO_LEX4:
314 o << "LexTiny => " << p->nvars;
315 break;
316 case MO_GREVLEX:
317 o << "GRevLex => ";
318 p_ones = true;
319 break;
320 case MO_GREVLEX2:
321 o << "GRevLexSmall => ";
322 p_ones = true;
323 break;
324 case MO_GREVLEX4:
325 o << "GRevLexTiny => ";
326 p_ones = true;
327 break;
328 case MO_GREVLEX_WTS:
329 o << "GRevLex => ";
330 break;
331 case MO_GREVLEX2_WTS:
332 o << "GRevLexSmall => ";
333 break;
334 case MO_GREVLEX4_WTS:
335 o << "GRevLexTiny => ";
336 break;
337 case MO_REVLEX:
338 o << "RevLex => " << p->nvars;
339 break;
340 case MO_WEIGHTS:
341 o << "Weights => ";
342 break;
343 case MO_LAURENT:
344 o << "GroupLex => " << p->nvars;
345 break;
347 o << "GroupRevLex => " << p->nvars;
348 break;
349 case MO_NC_LEX:
350 o << "NCLex => " << p->nvars;
351 break;
352 case MO_POSITION_UP:
353 o << "Position => Up";
354 break;
355 case MO_POSITION_DOWN:
356 o << "Position => Down";
357 break;
358 default:
359 o << "UNKNOWN";
360 break;
361 }
362 if (p->wts != nullptr) { ::toString(o, p->nvars, p->wts); }
363 else if (p_ones)
364 {
365 ::ones(o, p->nvars);
366 }
367 }
368 o << "\n }";
369 return o.str();
370}
371
373
375{
376 // The monomial order is lex if what?
377 // one lex block, no grevlex blocks, no weightvector blocks.
378 // only: lex block and position blocks are allowed.
379 int nlex = 0;
380 int i;
381 for (i = 0; i < mo->len; i++)
382 {
383 enum MonomialOrdering_type typ = mo->array[i]->type;
384 switch (typ)
385 {
386 case MO_LEX:
387 case MO_LEX2:
388 case MO_LEX4:
389 nlex++;
390 break;
391 case MO_POSITION_UP:
392 case MO_POSITION_DOWN:
393 break;
394 default:
395 return 0;
396 }
397 }
398 return (nlex == 1);
399}
400
402{
403 // The monomial order is lex if what?
404 // one lex block, no grevlex blocks, no weightvector blocks.
405 // only: lex block and position blocks are allowed.
406 int ngrevlex = 0;
407 int i;
408 for (i = 0; i < mo->len; i++)
409 {
410 enum MonomialOrdering_type typ = mo->array[i]->type;
411 switch (typ)
412 {
413 case MO_GREVLEX:
414 case MO_GREVLEX2:
415 case MO_GREVLEX4:
416 case MO_GREVLEX_WTS:
417 case MO_GREVLEX2_WTS:
418 case MO_GREVLEX4_WTS:
419 ngrevlex++;
420 break;
421 case MO_POSITION_UP:
422 case MO_POSITION_DOWN:
423 break;
424 default:
425 return 0;
426 }
427 }
428 return (ngrevlex == 1);
429}
430
432{
433 int i, sum = 0;
434 for (i = 0; i < mo->len; i++)
435 if (mo->array[i]->type != MO_WEIGHTS) sum += mo->array[i]->nvars;
436 return sum;
437}
438
440{
441 int nvars = rawNumberOfVariables(mo);
442 // grab the first weight vector
443 if (mo->len == 0) return nullptr;
444 if (mo->array[0]->type == MO_WEIGHTS)
445 {
446 int i;
448 int *wts = mo->array[0]->wts;
449 for (i = 0; i < mo->array[0]->nvars; i++) result->array[i] = wts[i];
450 for (; i < nvars; i++) result->array[i] = 0;
451 return result;
452 }
453 return nullptr;
454}
455
457{
458 int i, sum = 0;
459 for (i = 0; i < mo->len; i++)
460 if (mo->array[i]->type == MO_LAURENT ||
461 mo->array[i]->type == MO_LAURENT_REVLEX)
462 sum += mo->array[i]->nvars;
463 return sum;
464}
465
467// returns a list of the indices of those variables which are less than 1 in
468// the given monomial order.
469{
470 int i, j, sum, nextvar;
471 int nvars = rawNumberOfVariables(mo);
472 int *gt = getmematomicvectortype(int, nvars);
473 for (i = 0; i < nvars; i++)
474 gt[i] =
475 0; // 0 means undecided, -1 means non term order, 1 means term order
476 // Now we loop through the parts of the monomial order
477 nextvar = 0;
478 for (i = 0; i < mo->len; i++)
479 {
480 mon_part p = mo->array[i];
481 switch (p->type)
482 {
483 case MO_LEX:
484 case MO_LEX2:
485 case MO_LEX4:
486 case MO_GREVLEX:
487 case MO_GREVLEX2:
488 case MO_GREVLEX4:
489 case MO_GREVLEX_WTS:
490 case MO_GREVLEX2_WTS:
491 case MO_GREVLEX4_WTS:
492 case MO_LAURENT:
493 case MO_NC_LEX:
494 for (j = 0; j < p->nvars; j++, nextvar++)
495 if (gt[nextvar] == 0) gt[nextvar] = 1;
496 break;
498 case MO_REVLEX:
499 for (j = 0; j < p->nvars; j++, nextvar++)
500 if (gt[nextvar] == 0) gt[nextvar] = -1;
501 break;
502 case MO_WEIGHTS:
503 for (j = nextvar; j < p->nvars; j++)
504 if (gt[j] == 0)
505 {
506 if (p->wts[j] > 0)
507 gt[j] = 1;
508 else if (p->wts[j] < 0)
509 gt[j] = -1;
510 }
511 break;
512 case MO_POSITION_UP:
513 case MO_POSITION_DOWN:
514 break;
515 }
516 }
517 // At this point every variables' gt should be 1 or -1.
518 sum = 0;
519 for (i = 0; i < nvars; i++)
520 {
521 if (gt[i] == 0) INTERNAL_ERROR("gt[i] should not be 0");
522 if (gt[i] < 0) sum++;
523 }
524
525 // Make an array of this length.
527 nextvar = 0;
528 for (i = 0; i < nvars; i++)
529 if (gt[i] < 0) result->array[nextvar++] = i;
530 return result;
531}
532
534{
536 mon_part p;
537 enum MonomialOrdering_type typ;
538
539 if (packing == 2)
540 typ = MO_LEX2;
541 else if (packing == 4)
542 typ = MO_LEX4;
543 else
544 typ = MO_LEX;
545
546 p = mo_make(typ, nvars, nullptr);
548 result->array[0] = p;
549 return result;
550}
551
553 int packing)
554{
556 mon_part p;
557 enum MonomialOrdering_type typ;
558 int *wts;
559 int all_one = 1;
560 unsigned int i;
561 for (i = 0; i < degs->len; i++)
562 if (degs->array[i] <= 0)
563 {
564 ERROR("grevlex: expected all degrees to be positive");
565 return nullptr;
566 }
567 else if (degs->array[i] > 1)
568 all_one = 0;
569
570 if (all_one)
571 {
572 if (packing == 2)
573 typ = MO_GREVLEX2;
574 else if (packing == 4)
575 typ = MO_GREVLEX4;
576 else
577 typ = MO_GREVLEX;
578 wts = nullptr;
579 }
580 else
581 {
582 if (packing == 2)
583 typ = MO_GREVLEX2_WTS;
584 else if (packing == 4)
585 typ = MO_GREVLEX4_WTS;
586 else
587 typ = MO_GREVLEX_WTS;
588 wts = degs->array;
589 }
590
591 p = mo_make(typ, degs->len, wts);
593 result->array[0] = p;
594 return result;
595}
596
598{
599 mon_part p = mo_make(MO_REVLEX, nvars, nullptr);
601 result->array[0] = p;
602 return result;
603}
604
606{
607 mon_part p = mo_make(MO_WEIGHTS, wts->len, wts->array);
609 result->array[0] = p;
610 return result;
611}
613{
614 mon_part p = mo_make(MO_LAURENT, nvars, nullptr);
616 result->array[0] = p;
617 return result;
618}
620{
621 mon_part p = mo_make(MO_LAURENT_REVLEX, nvars, nullptr);
623 result->array[0] = p;
624 return result;
625}
627{
628 mon_part p = mo_make(MO_NC_LEX, nvars, nullptr);
630 result->array[0] = p;
631 return result;
632}
634{
635 mon_part p =
636 mo_make((up_or_down ? MO_POSITION_UP : MO_POSITION_DOWN), 0, nullptr);
638 result->array[0] = p;
639 return result;
640}
641
642MonomialOrdering *rawJoinMonomialOrdering(engine_RawMonomialOrderingArray M)
643{
645 const MonomialOrdering *mo;
646 int i, j, sum, next;
647 int nvars_so_far = 0;
648
649 // sum = 0;
650 // for (i=0; i<M->len; i++)
651 // sum += M->array[i]->len;
652
653 sum = 0;
654 for (i = 0; i < M->len; i++)
655 {
656 mo = M->array[i];
657 for (j = 0; j < mo->len; j++)
658 if (is_good(mo->array[j])) sum++;
659 }
660
661 result = make_mon_order(sum);
662 next = 0;
663 for (i = 0; i < M->len; i++)
664 {
665 mo = M->array[i];
666 for (j = 0; j < mo->len; j++)
667 {
668 mon_part p = mo->array[j];
669 if (!is_good(p)) continue;
670 if (p->type != MO_WEIGHTS)
671 nvars_so_far += p->nvars;
672 else
673 {
674 /* Shift the weights over by nvars_so_far */
675 mon_part q = mo_make(MO_WEIGHTS, nvars_so_far + p->nvars, nullptr);
676 q->wts = getmemvectortype(int, q->nvars);
677 for (j = 0; j < nvars_so_far; j++) q->wts[j] = 0;
678 for (; j < q->nvars; j++) q->wts[j] = p->wts[j - nvars_so_far];
679 p = q;
680 }
681 result->array[next++] = p;
682 }
683 }
684 return result;
685}
686
687MonomialOrdering *rawProductMonomialOrdering(engine_RawMonomialOrderingArray M)
688{
690 int i, j, sum, next, offset;
691 sum = 0;
692 for (i = 0; i < M->len; i++) sum += M->array[i]->len;
693
694 result = make_mon_order(sum);
695 next = 0;
696 offset = 0;
697 for (i = 0; i < M->len; i++)
698 {
699 int nvars = rawNumberOfVariables(M->array[i]);
700 MonomialOrdering *mo = M2_mo_offset(M->array[i], offset);
701 for (j = 0; j < mo->len; j++) result->array[next++] = mo->array[j];
702 offset += nvars;
703 }
704 return result;
705}
706
707M2_string intarray_to_string(int len, int *p)
708{
709 int i;
710 const int N = 200;
711 char s[N];
712 M2_string result = M2_tostring("{");
713 for (i = 0; i < len; i++)
714 {
715 if (i > 0) result = M2_join(result, M2_tostring(","));
716 snprintf(s, N, "%d", p[i]);
718 }
720 return result;
721}
722
723M2_string ones_to_string(int len)
724{
725 int i;
726 const int N = 200;
727 char s[N];
728 M2_string one;
729 M2_string result = M2_tostring("{");
730 snprintf(s, N, "1");
731 one = M2_tostring(s);
732 for (i = 0; i < len; i++)
733 {
734 if (i > 0) result = M2_join(result, M2_tostring(","));
735 result = M2_join(result, one);
736 }
738 return result;
739}
740
742{
743 return mo->_hash;
744}
745
747{
748 int i;
749 const int N = 200;
750 char s[N];
751 int p_ones = 0;
752 M2_string result = M2_tostring("MonomialOrder => {");
753 for (i = 0; i < mo->len; i++)
754 {
755 mon_part p = mo->array[i];
756 p_ones = 0;
757 if (i == 0)
758 result = M2_join(result, M2_tostring("\n "));
759 else
760 result = M2_join(result, M2_tostring(",\n "));
761 switch (p->type)
762 {
763 case MO_LEX:
764 snprintf(s, N, "Lex => %d", p->nvars);
765 break;
766 case MO_LEX2:
767 snprintf(s, N, "LexSmall => %d", p->nvars);
768 break;
769 case MO_LEX4:
770 snprintf(s, N, "LexTiny => %d", p->nvars);
771 break;
772 case MO_GREVLEX:
773 snprintf(s, N, "GRevLex => ");
774 p_ones = 1;
775 break;
776 case MO_GREVLEX2:
777 snprintf(s, N, "GRevLexSmall => ");
778 p_ones = 1;
779 break;
780 case MO_GREVLEX4:
781 snprintf(s, N, "GRevLexTiny => ");
782 p_ones = 1;
783 break;
784 case MO_GREVLEX_WTS:
785 snprintf(s, N, "GRevLex => ");
786 break;
787 case MO_GREVLEX2_WTS:
788 snprintf(s, N, "GRevLexSmall => ");
789 break;
790 case MO_GREVLEX4_WTS:
791 snprintf(s, N, "GRevLexTiny => ");
792 break;
793 case MO_REVLEX:
794 snprintf(s, N, "RevLex => %d", p->nvars);
795 break;
796 case MO_WEIGHTS:
797 snprintf(s, N, "Weights => ");
798 break;
799 case MO_LAURENT:
800 snprintf(s, N, "GroupLex => %d", p->nvars);
801 break;
803 snprintf(s, N, "GroupRevLex => %d", p->nvars);
804 break;
805 case MO_NC_LEX:
806 snprintf(s, N, "NCLex => %d", p->nvars);
807 break;
808 case MO_POSITION_UP:
809 snprintf(s, N, "Position => Up");
810 break;
811 case MO_POSITION_DOWN:
812 snprintf(s, N, "Position => Down");
813 break;
814 default:
815 snprintf(s, N, "UNKNOWN");
816 break;
817 }
819 if (p->wts != nullptr)
820 result = M2_join(result, intarray_to_string(p->nvars, p->wts));
821 else if (p_ones)
823 }
824 result = M2_join(result, M2_tostring("\n }"));
825 return result;
826}
827
828// Many monomial ordering routines are in monordering.c
829// Here are some that use c++ features, so cannot be there.
830// @todo Make monordering.{h,c} into a c++ class.
831
832static void write_row(std::vector<int> &grading,
833 int nvars,
834 int which,
835 int value)
836{
837 for (int i = 0; i < nvars; i++)
838 if (i == which)
839 grading.push_back(value);
840 else
841 grading.push_back(0);
842}
843static void write_weights(std::vector<int> &grading,
844 int nvars,
845 int firstvar,
846 int *wts,
847 int nwts)
848// place nvars ints into grading: 0 ... 0 wts[0] wts[1] ... wts[nwts-1] 0 ....
849// 0
850// where wts[0] is in the 'firstvar' location. If wts is NULL, treat it as the
851// vector with nwts '1's.
852{
853 for (int i = 0; i < firstvar; i++) grading.push_back(0);
854 if (wts == nullptr)
855 for (int i = 0; i < nwts; i++) grading.push_back(1);
856 else
857 for (int i = 0; i < nwts; i++) grading.push_back(wts[i]);
858 for (int i = firstvar + nwts; i < nvars; i++) grading.push_back(0);
859}
860
862 const struct MonomialOrdering &mo,
863 std::vector<int> &mat,
864 bool &base_is_revlex,
865 int &component_direction, // -1 is Down, +1 is Up, 0 is not present
866 int &component_is_before_row) // -1 means at the end, 0 means before the
867 // order, and r means considered before row
868 // 'r' of the matrix.
869{
870 // a false return value means an error has occurred.
871 int nvars = rawNumberOfVariables(&mo);
872 base_is_revlex = true;
873 enum LastBlock { LEX, REVLEX, WEIGHTS, NONE };
874 LastBlock last = NONE;
875 int nwts = 0; // local var used in MO_WEIGHTS section
876 int nrows = 0;
877 int firstvar = 0;
878 component_direction = 0;
879 component_is_before_row =
880 -2; // what should the default value be? Probably: -1.
881 size_t last_element = 0; // The vector 'mat' will be resized back to this
882 // value if the last part of the order is lex or
883 // revlex.
884 for (int i = 0; i < mo.len; i++)
885 {
886 mon_part p = mo.array[i];
887 switch (p->type)
888 {
889 case MO_LEX:
890 case MO_LEX2:
891 case MO_LEX4:
892 // printf("lex %d\n", p->nvars);
893 last_element = mat.size();
894 for (int j = 0; j < p->nvars; j++)
895 {
896 write_row(mat, nvars, firstvar + j, 1);
897 }
898 last = LEX;
899 firstvar += p->nvars;
900 nrows += p->nvars;
901 break;
902 case MO_GREVLEX:
903 case MO_GREVLEX2:
904 case MO_GREVLEX4:
905 // printf("grevlex %d %ld\n", p->nvars, p->wts);
906 write_weights(mat, nvars, firstvar, p->wts, p->nvars);
907 last_element = mat.size();
908 for (int j = p->nvars - 1; j >= 1; --j)
909 {
910 write_row(mat, nvars, firstvar + j, -1);
911 }
912 last = REVLEX;
913 firstvar += p->nvars;
914 nrows += p->nvars;
915 break;
916 case MO_GREVLEX_WTS:
917 case MO_GREVLEX2_WTS:
918 case MO_GREVLEX4_WTS:
919 // printf("grevlex_wts %d %ld\n", p->nvars, p->wts);
920 write_weights(mat, nvars, firstvar, p->wts, p->nvars);
921 last_element = mat.size();
922 for (int j = p->nvars - 1; j >= 1; --j)
923 {
924 write_row(mat, nvars, firstvar + j, -1);
925 }
926 last = REVLEX;
927 firstvar += p->nvars;
928 nrows += p->nvars;
929 break;
930 case MO_REVLEX:
931 // printf("revlex %d\n", p->nvars);
932 last_element = mat.size();
933 for (int j = p->nvars - 1; j >= 0; --j)
934 {
935 write_row(mat, nvars, firstvar + j, -1);
936 }
937 last = REVLEX;
938 firstvar += p->nvars;
939 nrows += p->nvars;
940 break;
941 case MO_WEIGHTS:
942 // printf("matsize= %d weights %d p->wts=%lu\n", mat.size(),
943 // p->nvars, p->wts);
944 nwts = (p->nvars > nvars ? nvars : p->nvars);
945 write_weights(mat, nvars, 0, p->wts, nwts);
946 nrows++;
947 last_element = mat.size();
948 last = WEIGHTS;
949 break;
950 case MO_LAURENT:
952 case MO_NC_LEX:
953 return false;
954 break;
955 case MO_POSITION_UP:
956 component_direction = 1;
957 component_is_before_row = nrows;
958 break;
959 case MO_POSITION_DOWN:
960 component_direction = -1;
961 component_is_before_row = nrows;
962 break;
963 default:
964 // DO nothing
965 break;
966 }
967 }
968 if (last == LEX)
969 {
970 // last block was lex, so use lex tie-breaker
971 mat.resize(last_element);
972 if (nrows == component_is_before_row) component_is_before_row = -1;
973 base_is_revlex = false;
974 }
975 else if (last == REVLEX)
976 {
977 // last block was revlex, so use revlex tie-breaker
978 if (nrows == component_is_before_row) component_is_before_row = -1;
979 mat.resize(last_element);
980 }
981 else
982 {
983 // last block is a weight vector, so use revlex as the tie-breaker.
984 // nothing to change here.
985 }
986 return true;
987}
988
990{
991 bool base;
992 std::vector<int> mat;
993 M2_arrayint result = nullptr;
994 int component_is_before_row = 0;
995 int component_direction = 0;
997 *mo, mat, base, component_direction, component_is_before_row))
998 {
999 int top = static_cast<int>(mat.size());
1000 result = M2_makearrayint(top + 3);
1001 for (int i = 0; i < top; i++) result->array[i] = mat[i];
1002 result->array[top] = (base ? 1 : 0);
1003 result->array[top + 1] = component_direction;
1004 result->array[top + 2] = component_is_before_row;
1005 }
1006 return result;
1007}
static MonomialOrdering * GRevLex2(int nvars)
static MonomialOrdering * Weights(const std::vector< int > &wts)
static MonomialOrdering * Lex4(int nvars)
static MonomialOrdering * Lex2(int nvars)
static MonomialOrdering * PositionDown()
static MonomialOrdering * PositionUp()
static MonomialOrdering * GRevLex(int nvars)
static MonomialOrdering * GRevLex4(int nvars)
static MonomialOrdering * GroupLex(int nvars)
static MonomialOrdering * product(const std::vector< MonomialOrdering * > &M)
static MonomialOrdering * Lex(int nvars)
static MonomialOrdering * GroupRevLex(int nvars)
static MonomialOrdering * RevLex(int nvars)
static std::string toString(const MonomialOrdering *mo)
static MonomialOrdering * join(const std::vector< MonomialOrdering * > &M)
void INTERNAL_ERROR(const char *s,...)
Definition error.c:36
Engine error-reporting primitives: ERROR, INTERNAL_ERROR, error, error_message.
static CanonicalForm base
Definition factory.cpp:289
int p
void size_t s
Definition m2-mem.cpp:271
const int ERROR
Definition m2-mem.cpp:55
VALGRIND_MAKE_MEM_DEFINED & result(result)
#define getmematomicvectortype(S, len)
Definition m2-mem.h:147
#define getmemarraytype(S, len)
Definition m2-mem.h:142
#define getmemvectortype(S, len)
Definition m2-mem.h:146
#define getmemstructtype(S)
Definition m2-mem.h:143
Engine-wide GC allocator surface (getmem / getmem_atomic) and debug-allocation trap.
M2_string M2_tostring(const char *s)
Definition m2-types.cpp:31
M2_arrayint M2_makearrayint(int n)
Definition m2-types.cpp:6
M2_string M2_join(M2_string x, M2_string y)
Definition m2-types.cpp:21
char M2_bool
Definition m2-types.h:82
int moIsLex(const MonomialOrdering *mo)
MonomialOrdering * rawRevLexMonomialOrdering(int nvars)
MonomialOrdering * rawNClexMonomialOrdering(int nvars)
static struct mon_part_rec_ * mo_make(enum MonomialOrdering_type type, int nvars, const int *wts)
int rawNumberOfInvertibleVariables(const MonomialOrdering *mo)
std::ostringstream & toString(std::ostringstream &o, int len, int *p)
unsigned int rawMonomialOrderingHash(const MonomialOrdering *mo)
static void write_weights(std::vector< int > &grading, int nvars, int firstvar, int *wts, int nwts)
MonomialOrdering * rawProductMonomialOrdering(engine_RawMonomialOrderingArray M)
static void write_row(std::vector< int > &grading, int nvars, int which, int value)
int moIsGRevLex(const MonomialOrdering *mo)
M2_arrayint rawNonTermOrderVariables(const MonomialOrdering *mo)
static MonomialOrdering * M2_mo_offset(const MonomialOrdering *mo, int offset)
MonomialOrdering * rawGroupLexMonomialOrdering(int nvars)
static bool is_good(mon_part p)
static MonomialOrdering * make_mon_order(int n)
MonomialOrdering * rawLexMonomialOrdering(int nvars, int packing)
M2_arrayint rawMonomialOrderingToMatrix(const struct MonomialOrdering *mo)
MonomialOrdering * rawGroupRevLexMonomialOrdering(int nvars)
M2_string IM2_MonomialOrdering_to_string(const MonomialOrdering *mo)
MonomialOrdering * rawWeightsMonomialOrdering(M2_arrayint wts)
MonomialOrdering * rawGRevLexMonomialOrdering(M2_arrayint degs, int packing)
bool monomialOrderingToMatrix(const struct MonomialOrdering &mo, std::vector< int > &mat, bool &base_is_revlex, int &component_direction, int &component_is_before_row)
M2_string ones_to_string(int len)
M2_string intarray_to_string(int len, int *p)
MonomialOrdering * rawJoinMonomialOrdering(engine_RawMonomialOrderingArray M)
MonomialOrdering * rawPositionMonomialOrdering(M2_bool up_or_down)
std::ostringstream & ones(std::ostringstream &o, int len)
int rawNumberOfVariables(const MonomialOrdering *mo)
M2_arrayint moGetWeightValues(const MonomialOrdering *mo)
MonomialOrdering_type
@ MO_GREVLEX4_WTS
@ MO_LAURENT_REVLEX
@ MO_NC_LEX
@ MO_LEX4
@ MO_REVLEX
@ MO_POSITION_UP
@ MO_LEX
@ MO_GREVLEX
@ MO_LEX2
@ MO_GREVLEX4
@ MO_LAURENT
@ MO_GREVLEX2_WTS
@ MO_WEIGHTS
@ MO_POSITION_DOWN
@ MO_GREVLEX2
@ MO_GREVLEX_WTS
Engine-boundary C API for assembling block-level MonomialOrderings from declarative pieces.
MonomialOrderings — C++ factories for the declarative MonomialOrdering blocks.
Front-end-side description of a monomial ordering as a list of mon_part blocks.
enum MonomialOrdering_type type