Macaulay2 Engine
Loading...
Searching...
No Matches
schur2.cpp
Go to the documentation of this file.
1// Copyright 1996-2017 Michael E. Stillman
2
3#include "schur2.hpp"
4#include <stdio.h>
5#include <iostream>
6#include "text-io.hpp"
7#include "ZZ.hpp"
8#include "relem.hpp"
9#include "monomial.hpp"
10#include "ringmap.hpp"
11#include "monoid.hpp"
12
13const int SCHUR_MAX_WT = 100;
14const int LARGE_NUMBER = 32000;
15
16void tableau2::initialize(int nvars, int maxwt0)
17{
18 (void) nvars;
19 (void) maxwt0;
21 wt = 0;
22 lambda = nullptr;
23 p = nullptr;
26}
27
28void tableau2::resize(int max_wt)
29{
30 if (max_wt <= SCHUR_MAX_WT) return;
33 maxwt = max_wt;
34 wt = max_wt;
35 xloc = newarray_atomic(int, maxwt + 1);
36 yloc = newarray_atomic(int, maxwt + 1);
37}
38
39int tableau2::elem(int x, int y) const
40{
41 // slow: only used for debugging
42 for (int i = 1; i <= wt; i++)
43 if (xloc[i] == x && yloc[i] == y) return i;
44
45 // otherwise perhaps throw an error
46 fprintf(stderr, "tableau2: location (%d,%d) out of range\n", x, y);
47 return 0;
48}
49
50void tableau2::fill(int *lamb, int *pp) // FLAG: should be const, schur_word..
51// Fill the skew tableau2 p\lambda with 1..nboxes
52// starting at top right, moving left and then down
53// row by row.
54{
55 int i, j;
56 p = pp; // FLAG: why is this here?
57 lambda = lamb; // FLAG: why is this here?
58
59 int next = 1;
60 for (i = 1; i < p[0]; i++)
61 {
62 int a = lambda[i];
63 for (j = p[i]; j > a; j--)
64 {
65 xloc[next] = i;
66 yloc[next++] = j;
67 }
68 }
69 // display();
70}
71
73{
74 int i, j;
75
76 for (i = 1; i < p[0]; i++)
77 {
78 for (j = 1; j <= lambda[i]; j++) fprintf(stdout, "-- ");
79 for (; j <= p[i]; j++) fprintf(stdout, "%2d ", elem(i, j));
80 fprintf(stdout, "\n");
81 }
82}
83
85
86template<typename T>
87static inline void hash_combine(size_t& seed, const T& val)
88{
89// the typical implementation
90 seed ^= std::hash<T>()(val) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
91}
92
93unsigned int SchurRing2::computeHashValue(const ring_elem a) const
94{
95// assuming a normal form: distinct monomials in the linear order introduced by compare_partitions()
96
97 const auto& coeffs = a.get_schur_poly()->coeffs;
98 const auto& monoms = a.get_schur_poly()->monoms;
99
100 size_t seed = 95864398; // using previous M2's constant hash value
101
102 for(auto it=coeffs.begin(); it!=coeffs.end(); ++it)
103 hash_combine(seed, coefficientRing->computeHashValue(*it));
104 for(auto it=monoms.begin(); it!=monoms.end(); ++it)
105 hash_combine(seed, *it);
106
107 return static_cast<unsigned>(seed);
108}
109
111{
112 return a.ic == b.ic;
113}
115{
116 return a.ic != b.ic;
117}
118
120{
121 coeffs.push_back(coeff);
122 for (int i = 0; i < monom[0]; i++) monoms.push_back(monom[i]);
123}
125{
126 for (; first != last; ++first)
127 appendTerm(first.getCoefficient(), first.getMonomial());
128}
129
131{
132 SchurRing2 *R = new SchurRing2(A, n);
134 return R;
135}
136
138{
139 SchurRing2 *R = new SchurRing2(A);
141 return R;
142}
143
146{
147 initialize_ring(coefficientRing->characteristic());
148
149 zeroV = from_long(0);
150 oneV = from_long(1);
151 minus_oneV = from_long(-1);
152
154 return true;
155}
156
157bool SchurRing2::is_valid_partition(M2_arrayint part, bool set_error) const
158{
159 if (nvars >= 0 && part->len > nvars)
160 {
161 if (set_error) ERROR("expected a partition of size at most %d\n", nvars);
162 return false;
163 }
164 for (int i = 1; i < part->len; i++)
165 if (part->array[i - 1] < part->array[i])
166 {
167 if (set_error) ERROR("expected a non-increasing sequence of integers");
168 return false;
169 }
170 if (part->len > 0 && part->array[part->len - 1] < 0)
171 {
172 if (set_error) ERROR("expected nonnegative integers only");
173 return false;
174 }
175 return true;
176}
177
178static int last_nonzero(M2_arrayint part)
179{
180 for (int i = part->len - 1; i >= 0; i--)
181 if (part->array[i] != 0) return i;
182 return -1;
183}
185{
186 schur_poly *f = new schur_poly;
187 f->coeffs.push_back(coefficientRing->one());
188 int len = last_nonzero(part) + 1;
189 f->monoms.push_back(len + 1);
190 for (int i = 0; i < len; i++) f->monoms.push_back(part->array[i]);
191 return ring_elem(f);
192}
193
195{
196 o << "SchurRing2(";
197 if (nvars >= 0) o << nvars << ",";
198 coefficientRing->text_out(o);
199 o << ")";
200}
201
203 const ring_elem f,
204 bool p_one,
205 bool p_plus,
206 bool p_parens) const
207{
208 const schur_poly *g = f.get_schur_poly();
209 size_t n = g->size();
210
211 bool needs_parens = p_parens && (n > 1);
212 if (needs_parens)
213 {
214 if (p_plus) o << '+';
215 o << '(';
216 p_plus = false;
217 }
218
219 p_one = false;
220 for (schur_poly::iterator i = g->begin(); i != g->end(); ++i)
221 {
222 const_schur_partition part = i.getMonomial();
223 int len = *part++;
224 int isone = (len == 1); // the empty partition
225 p_parens = !isone;
226 coefficientRing->elem_text_out(
227 o, i.getCoefficient(), p_one, p_plus, p_parens);
228 o << "{";
229 for (int j = 0; j < len - 1; j++)
230 {
231 if (j > 0) o << ",";
232 o << part[j];
233 }
234 o << "}";
235 p_plus = true;
236 }
237 if (needs_parens) o << ')';
238}
239
241{
242 const schur_poly *g = f.get_schur_poly();
243 if (g->size() != 1) return false;
244 return (g->monoms.size() == 1) && (coefficientRing->is_unit(g->coeffs[0]));
245}
246
248{
249 const schur_poly *g = f.get_schur_poly();
250 return g->size() == 0;
251}
252
253bool SchurRing2::is_equal(const ring_elem f, const ring_elem g) const
254{
255 const schur_poly *f1 = f.get_schur_poly();
256 const schur_poly *g1 = g.get_schur_poly();
257 if (f1->size() != g1->size()) return false;
258 if (f1->monoms.size() != g1->monoms.size()) return false;
259
260 VECTOR(schur_word)::const_iterator m_f = f1->monoms.begin();
261 VECTOR(schur_word)::const_iterator m_g = g1->monoms.begin();
262 for (; m_f != f1->monoms.end(); ++m_f, ++m_g)
263 if (*m_f != *m_g) return false;
264
265 VECTOR(ring_elem)::const_iterator c_f = f1->coeffs.begin();
266 VECTOR(ring_elem)::const_iterator c_g = g1->coeffs.begin();
267 for (; c_f != f1->coeffs.end(); ++c_f, ++c_g)
268 if (!coefficientRing->is_equal(*c_f, *c_g)) return false;
269
270 return true;
271}
272
274{
275 if (g->size() != 1) return false;
276 if (g->monoms.size() != 1) return false;
277 result = g->coeffs[0];
278 return true;
279}
280
282{
283 schur_poly *f = new schur_poly;
284 if (!coefficientRing->is_zero(a))
285 {
286 f->coeffs.push_back(a);
287 f->monoms.push_back(1);
288 }
289 return ring_elem(f);
290}
292{
293 ring_elem a = coefficientRing->from_long(n);
294 return from_coeff(a);
295}
297{
298 ring_elem a = coefficientRing->from_int(n);
299 return from_coeff(a);
300}
302{
303 ring_elem a;
304 bool ok = coefficientRing->from_rational(q, a);
305 if (not ok) return false;
306 result = from_coeff(a);
307 return true;
308}
309
311{
312 const schur_poly *f1 = f.get_schur_poly();
313
314 schur_poly *g = new schur_poly;
315 g->coeffs.insert(g->coeffs.end(), f1->coeffs.begin(), f1->coeffs.end());
316 g->monoms.insert(g->monoms.end(), f1->monoms.begin(), f1->monoms.end());
317
318 return ring_elem(g);
319}
320
322{
323 (void) f;
324 // This function is not relevant for this ring
325 return zero();
326}
327
329{
330 (void) f;
331 (void) g;
332 // This function is not relevant for this ring
333 return zero();
334}
335
337 const ring_elem b,
338 ring_elem &x,
339 ring_elem &y) const
340{
341 (void) a;
342 (void) b;
343 // This function is not relevant for this ring
344 x = zero();
345 y = zero();
346}
347
349 const_schur_partition b) const
350{
351 int len = a[0];
352 if (b[0] < len) len = b[0];
353 for (int i = 1; i < len; i++)
354 {
355 int cmp = a[i] - b[i];
356 if (cmp < 0) return LT;
357 if (cmp > 0) return GT;
358 }
359 int cmp = a[0] - b[0];
360 if (cmp < 0) return LT;
361 if (cmp > 0) return GT;
362 return EQ;
363}
364
366{
367// assuming the monomials are sorted in the linear order on the partitions
368// see SchurRing2::compare_partitions
369
370 auto f_it = f.get_schur_poly()->begin(),
371 f_end = f.get_schur_poly()->end();
372 auto g_it = g.get_schur_poly()->begin(),
373 g_end = g.get_schur_poly()->end();
374
375 for(; f_it!=f_end && g_it!=g_end; ++f_it, ++g_it) {
376 auto cmp = compare_partitions(f_it.getMonomial(), g_it.getMonomial());
377 if(cmp) return cmp;
378 }
379
380 return (f_it!=f_end)-(g_it!=g_end); // LT, EQ or GT
381}
382
384 const ring_elem f,
385 ring_elem &resultRE) const
386{
387 // Assumption in use: Rf (ring of f) is a Schur ring, with coeff ring coeffRf
388 const schur_poly *f1 = f.get_schur_poly();
390
391 for (schur_poly::iterator i = f1->begin(); i != f1->end(); ++i)
392 {
393 if (i.getMonomial()[0] - 1 > nvars) continue;
394 ring_elem a;
395 if (!coefficientRing->promote(
396 Rf->getCoefficientRing(), i.getCoefficient(), a))
397 {
398 delete result;
399 resultRE = from_long(0);
400 return false;
401 }
402 result->appendTerm(a, i.getMonomial());
403 }
404 resultRE = ring_elem(result);
405 return true;
406}
408 const ring_elem f,
409 ring_elem &resultRE) const
410{
411 const schur_poly *f1 = f.get_schur_poly();
413
414 for (schur_poly::iterator i = f1->begin(); i != f1->end(); ++i)
415 {
416 if (i.getMonomial()[0] - 1 > Sg->n_vars()) continue;
417 ring_elem a;
418 if (!coefficientRing->lift(
419 Sg->getCoefficientRing(), i.getCoefficient(), a))
420 {
421 delete result;
422 resultRE = from_long(0);
423 return false;
424 }
425 result->appendTerm(a, i.getMonomial());
426 }
427 resultRE = ring_elem(result);
428 return true;
429}
430
432 const ring_elem f,
433 ring_elem &result) const
434{
435 // Cases:
436 // 1. Rf is ZZ
437 // 2. Rf is coefficientRing
438 // 3. Rf is another SchurRing2
439
440 if (Rf == globalZZ)
441 {
443 return true;
444 }
445 else if (Rf == coefficientRing)
446 {
447 result = from_coeff(f);
448 return true;
449 }
450 else
451 {
452 const SchurRing2 *Sf = Rf->cast_to_SchurRing2();
453 if (Sf != nullptr)
454 {
456 {
457 result = truncate(f);
458 return true;
459 }
460
461 return promote_coeffs(Sf, f, result);
462 }
463 }
464 return false;
465}
466bool SchurRing2::lift(const Ring *Rg,
467 const ring_elem f,
468 ring_elem &result) const
469{
470 const schur_poly *f1 = f.get_schur_poly();
471 if (Rg == coefficientRing || Rg == globalZZ)
472 {
473 if (get_scalar(f1, result))
474 {
475 if (Rg == globalZZ)
476 return coefficientRing->lift(globalZZ, result, result);
477 return true;
478 }
479 }
480 else
481 {
482 const SchurRing2 *Sg = Rg->cast_to_SchurRing2();
483 if (Sg != nullptr)
484 {
486 {
487 result = Sg->truncate(f);
488 return true;
489 }
490
491 return lift_coeffs(Sg, f, result);
492 }
493 }
494 return false;
495}
497{
498 if (is_zero(f)) return f;
499 const schur_poly *f1 = f.get_schur_poly();
501
502 for (VECTOR(ring_elem)::const_iterator i = f1->coeffs.begin();
503 i != f1->coeffs.end();
504 ++i)
505 result->coeffs.push_back(coefficientRing->negate(*i));
506
507 result->monoms.insert(
508 result->monoms.end(), f1->monoms.begin(), f1->monoms.end());
509 return ring_elem(result);
510}
511
513// assumption: f is a Schur poly over another Schur ring, with the SAME coeff
514// ring
515// each term is copied over, if the number of elements in the partition is <=
516// n_vars()
517{
518 if (is_zero(f)) return f;
519 const schur_poly *f1 = f.get_schur_poly();
521
522 for (schur_poly::iterator i = f1->begin(); i != f1->end(); ++i)
523 {
524 if (i.getMonomial()[0] - 1 > nvars) continue;
525 result->appendTerm(i.getCoefficient(), i.getMonomial());
526 }
527 return ring_elem(result);
528}
529
531{
532 if (is_zero(f)) return g;
533 if (is_zero(g)) return f;
534 const schur_poly *f1 = f.get_schur_poly();
535 const schur_poly *g1 = g.get_schur_poly();
536
538
539 schur_poly::iterator i = f1->begin();
540 schur_poly::iterator j = g1->begin();
541 schur_poly::iterator iend = f1->end();
542 schur_poly::iterator jend = g1->end();
543
544 bool done = false;
545 while (!done)
546 {
547 int cmp = compare_partitions(i.getMonomial(), j.getMonomial());
548 switch (cmp)
549 {
550 case LT:
551 result->appendTerm(j.getCoefficient(), j.getMonomial());
552 ++j;
553 if (j == jend)
554 {
555 result->append(i, iend);
556 done = true;
557 }
558 break;
559 case GT:
560 result->appendTerm(i.getCoefficient(), i.getMonomial());
561 ++i;
562 if (i == iend)
563 {
564 result->append(j, jend);
565 done = true;
566 }
567 break;
568 case EQ:
569 ring_elem c =
571 if (!coefficientRing->is_zero(c))
572 result->appendTerm(c, i.getMonomial());
573 ++j;
574 ++i;
575 if (j == jend)
576 {
577 result->append(i, iend);
578 done = true;
579 }
580 else
581 {
582 if (i == iend)
583 {
584 result->append(j, jend);
585 done = true;
586 }
587 }
588 break;
589 }
590 }
591 return ring_elem(result);
592}
593
595{
596 ring_elem h = negate(g);
597 return add(f, h);
598}
599
601 const schur_poly *f) const
602{
604
605 VECTOR(ring_elem)::iterator c_result;
606 for (VECTOR(ring_elem)::const_iterator c_f = f->coeffs.begin();
607 c_f != f->coeffs.end();
608 ++c_f)
609 result->coeffs.push_back(coefficientRing->mult(a, *c_f));
610
611 result->monoms.insert(
612 result->monoms.end(), f->monoms.begin(), f->monoms.end());
613
614 return result;
615}
617{
618 ring_elem resultRE;
619 const schur_poly *f1 = f.get_schur_poly();
620 const schur_poly *g1 = g.get_schur_poly();
621 ring_elem a;
622 if (get_scalar(f1, a))
623 {
624 return ring_elem(mult_by_coefficient(a, g1));
625 // In this case, do a simple multiplication
626 }
627 else if (get_scalar(g1, a))
628 {
629 return ring_elem(mult_by_coefficient(a, f1));
630 }
631 else
632 {
633 // use the poly heap
634 schur_poly_heap H(this);
635 for (schur_poly::iterator i = f1->begin(); i != f1->end(); ++i)
636 for (schur_poly::iterator j = g1->begin(); j != g1->end(); ++j)
637 {
638 ring_elem c =
639 coefficientRing->mult(i.getCoefficient(), j.getCoefficient());
640 ring_elem r = const_cast<SchurRing2 *>(this)->mult_terms(
641 i.getMonomial(), j.getMonomial());
643 }
644 return H.value();
645 }
646}
647
649{
650 int len = a[0];
651 result.resize(2 * len);
652 int *result_vp = result.data();
653 int *orig_result_vp = result_vp;
654 result_vp++;
655
656 if (len > 1)
657 {
658 int v = a[1];
659 int e = 1;
660
661 for (int i = 2; i < len; i++)
662 {
663 if (v == a[i])
664 e++;
665 else
666 {
667 *result_vp++ = v;
668 *result_vp++ = e;
669 v = a[i];
670 e = 1;
671 }
672 }
673 *result_vp++ = v;
674 *result_vp++ = e;
675 }
676
677 int newlen = static_cast<int>(result_vp - orig_result_vp);
678 *orig_result_vp = newlen;
679 result.resize(newlen);
680}
681
683 const ring_elem f) const
684{
685 if (coeffR != coefficientRing)
686 {
687 ERROR("expected coefficient ring of Schur ring");
688 return nullptr;
689 }
690 const schur_poly *f1 = f.get_schur_poly();
691 int n = static_cast<int>(f1->size()); // this is here because the lengths of
692 // arrays for M3 front end use int as
693 // length field.
694 engine_RawMonomialArray monoms =
695 GETMEM(engine_RawMonomialArray, sizeofarray(monoms, n));
696 engine_RawRingElementArray coeffs =
697 GETMEM(engine_RawRingElementArray, sizeofarray(coeffs, n));
698 monoms->len = n;
699 coeffs->len = n;
700 engine_RawArrayPair result = newitem(struct engine_RawArrayPair_struct);
701 result->monoms = monoms;
702 result->coeffs = coeffs;
703
704 // Loop through the terms
706 schur_poly::iterator i = f1->begin();
707 for (int next = 0; next < n; ++i, ++next)
708 {
709 coeffs->array[next] =
711 to_varpower(i.getMonomial(), vp);
712 monoms->array[next] = EngineMonomial::make(vp.data());
713 vp.resize(0);
714 }
715 return result;
716}
717
719 const ring_elem f,
720 int first_var) const
721{
722 (void) f;
723 (void) first_var;
724 // Should we allow ring maps to other Schur rings? No others are that well
725 // defined...
726 // Use promote and lift for those instead?
727 return map->get_ring()->zero();
728}
729
731// FLAG: put in a reference to the paper/algorithm being used here.
733 int maxwt) // FLAG: only called with maxwt==0
734{
735 SMmaxrows = n;
736 SMmaxweight = maxwt; // need this?
737
738 SMtab.initialize(SMmaxrows, SMmaxweight);
739 SMfilled.initialize(SMmaxrows, SMmaxweight);
740 SMcurrent = 0;
741 SMfinalwt = 0;
742 SMtab.p = new int[nvars + 1]; // FLAG: is this correct? use schur_word?, what
743 // about nvars==-1
744 for (int i = 0; i <= nvars; i++) SMtab.p[i] = 0;
745 SMheap = new schur_poly_heap(this);
746}
747
748void SchurRing2::SMbounds(int &lo, int &hi)
749{
750 int i, k;
751 int x = SMfilled.xloc[SMcurrent];
752 int y = SMfilled.yloc[SMcurrent];
753
754 // First set the high bound, using info from the "one to the right"
755 // in the reverse lex filled skew tableau.
756
757 if (y == SMfilled.p[x]) // There is not one to the right
758 {
759 hi = SMmaxrows;
760 for (k = 1; k <= SMmaxrows; k++)
761 if (SMtab.p[k] == 0)
762 {
763 hi = k;
764 break;
765 }
766 }
767 else // note that the case SMcurrent==1 will be handled
768 { // in the previous statement.
769 hi = SMtab.xloc[SMcurrent - 1];
770 }
771
772 // Now we set the lo bound, using info from the "one above"
773
774 if (x == 1 || y <= SMfilled.lambda[x - 1])
775 lo = 1; // There is not one above
776 else
777 {
778 int above = SMcurrent - SMfilled.p[x] + SMfilled.lambda[x - 1];
779 int xabove = SMtab.xloc[above];
780 int yabove = SMtab.yloc[above];
781 for (i = xabove + 1; i <= hi; i++)
782 if (SMtab.p[i] < yabove) break;
783 lo = i;
784 }
785}
786
788{
789 int i;
790 for (i = 1; i <= SMmaxrows; i++)
791 if (p[i] == 0) break;
792 p[0] = i;
793}
794
796{
797 int lo, hi;
798
799 if (SMcurrent == SMfinalwt)
800 {
801 // partition is to be output
804 return;
805 }
806
807 SMcurrent++;
808 SMbounds(lo, hi);
809 int this_one = LARGE_NUMBER; // larger than any entry of SMtab: SMfinalwt+1
810 // should work...
811 int last_one;
812 for (int i = lo; i <= hi; i++)
813 {
814 last_one = this_one;
815 this_one = SMtab.p[i];
816 if (last_one > this_one)
817 {
818 SMtab.p[i]++;
819 SMtab.xloc[SMcurrent] = i;
820 SMtab.yloc[SMcurrent] = SMtab.p[i];
821 SM();
822 SMtab.p[i]--;
823 }
824 }
825 SMcurrent--;
826}
827
829{
830 // make a poly, and insert it into the heap
831 schur_poly * val = new schur_poly;
832 val->appendTerm(coefficientRing->one(), f);
833 SMheap->add(ring_elem(val));
834}
835
838{
839 SMcurrent = 0;
840
841 SMfinalwt = 0;
842 for (int i = 1; i < p[0]; i++) SMfinalwt += p[i];
843 for (int i = 1; i < lambda[0]; i++) SMfinalwt -= lambda[i];
844 SMmaxrows = p[0] - 1; // this is the number of elements in the partition p
845 if (nvars != -1 && SMmaxrows > nvars) SMmaxrows = nvars;
846
847 delete[] SMtab
848 .p; // FLAG: should use gc for this? or not use it, but not both!
849 SMtab.p = new int[SMmaxrows + 1]; // FLAG: should use gc for this? or not
850 // use it, but not both!
851 for (int i = 0; i <= SMmaxrows; i++) SMtab.p[i] = 0;
852
853 SMtab.wt = SMfinalwt;
854 SMtab.resize(SMfinalwt);
855 SMfilled.resize(SMfinalwt);
856
857 // lambda and p should not be modified in the following call
858 SMfilled.fill(const_cast<schur_partition>(lambda),
859 const_cast<schur_partition>(
860 p)); // FLAG:fill should take const arguments...
861 lambda++; // FLAG: why is this here?
862 p++; // FLAG: why is this here?
863 SM();
864 return SMheap->value(); // resets itself back to new
865}
866
869{
870 int maxsize = (a[0] - 1 + b[0] - 1) + 1; // this is the max number of
871 // elements in the output partition,
872 // plus one
873
874 schur_partition lambda = ALLOCATE_EXPONENTS(sizeof(schur_word) * maxsize);
875 schur_partition p = ALLOCATE_EXPONENTS(sizeof(schur_word) * maxsize);
876
877 // Second: make the skew partition (note: r,s>=1)
878 // this is: if a = r+1 a1 a2 ... ar
879 // b = s+1 b1 b2 ... bs
880 // p is:
881 // (r+s+1) b1+a1 b1+a2 ... b1+ar b1 b2 ... bs
882 // lambda is:
883 // (r+1) b1 b1 ... b1 0 0 ... 0
884
885 int r = a[0] - 1;
886 int s = b[0] - 1;
887 int c = b[1];
888
889 assert(r + s + 1 == maxsize);
890
891 for (int i = 1; i <= r; i++)
892 {
893 assert(i < maxsize);
894 p[i] = c + a[i];
895 lambda[i] = c;
896 }
897 for (int i = r + 1; i < r + s + 1; i++)
898 {
899 assert(i < maxsize);
900 p[i] = b[i - r];
901 lambda[i] = 0;
902 }
903 p[0] = r + s + 1;
904 lambda[0] = r + 1;
905 return skew_schur(lambda, p);
906}
907
909
910// Local Variables:
911// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
912// indent-tabs-mode: nil
913// End:
Legacy RingZZ — a Ring-derived integer ring backed by GMP mpz_t.
static EngineMonomial * make(int v, int e)
Definition monomial.cpp:26
virtual bool promote(const Ring *R, const ring_elem f, ring_elem &result) const =0
virtual const SchurRing2 * cast_to_SchurRing2() const
Definition ring.hpp:277
ring_elem minus_oneV
Definition ring.hpp:131
ring_elem zero() const
Definition ring.hpp:359
void initialize_ring(long charac, const PolynomialRing *DR=nullptr, const std::vector< int > &heft_vec={})
Definition ring.cpp:30
ring_elem oneV
Definition ring.hpp:130
ring_elem zeroV
Definition ring.hpp:129
Ring()
Definition ring.hpp:136
static RingElement * make_raw(const Ring *R, ring_elem f)
Definition relem.cpp:20
const Ring * get_ring() const
Definition ringmap.hpp:111
Engine-side ring homomorphism: stores, for each source-ring variable, the target-ring element it maps...
Definition ringmap.hpp:60
virtual bool is_equal(const ring_elem f, const ring_elem g) const
Definition schur2.cpp:253
ring_elem skew_schur(const_schur_partition lambda, const_schur_partition p)
Definition schur2.cpp:836
bool get_scalar(const schur_poly *f, ring_elem &result) const
Definition schur2.cpp:273
virtual ring_elem subtract(const ring_elem f, const ring_elem g) const
Definition schur2.cpp:594
ring_elem from_coeff(ring_elem a) const
Definition schur2.cpp:281
virtual ring_elem copy(const ring_elem f) const
Definition schur2.cpp:310
virtual unsigned int computeHashValue(const ring_elem a) const
Definition schur2.cpp:93
void SMinitialize(int max_rows, int max_weight)
Definition schur2.cpp:732
virtual ring_elem invert(const ring_elem f) const
Definition schur2.cpp:321
virtual bool is_unit(const ring_elem f) const
Definition schur2.cpp:240
virtual void text_out(buffer &o) const
Definition schur2.cpp:194
ring_elem mult_terms(const_schur_partition a, const_schur_partition b)
Definition schur2.cpp:867
schur_poly_heap * SMheap
Definition schur2.hpp:255
int SMfinalwt
Definition schur2.hpp:254
int n_vars() const
Definition schur2.hpp:174
virtual bool lift(const Ring *R, const ring_elem f, ring_elem &result) const
Definition schur2.cpp:466
ring_elem truncate(const ring_elem f) const
Definition schur2.cpp:512
virtual ring_elem negate(const ring_elem f) const
Definition schur2.cpp:496
virtual ring_elem from_int(mpz_srcptr n) const
Definition schur2.cpp:296
void SMsetPartitionLength(schur_word *p, int SMmaxrows)
Definition schur2.cpp:787
tableau2 SMfilled
Definition schur2.hpp:252
virtual bool promote(const Ring *R, const ring_elem f, ring_elem &result) const
Definition schur2.cpp:431
bool lift_coeffs(const SchurRing2 *Sg, const ring_elem f, ring_elem &resultRE) const
Definition schur2.cpp:407
bool initialize_SchurRing2()
Definition schur2.cpp:145
virtual bool is_zero(const ring_elem f) const
Definition schur2.cpp:247
virtual ring_elem divide(const ring_elem f, const ring_elem g) const
Definition schur2.cpp:328
static SchurRing2 * createInfinite(const Ring *A)
Definition schur2.cpp:137
virtual bool from_rational(mpq_srcptr q, ring_elem &result) const
Definition schur2.cpp:301
int SMmaxrows
Definition schur2.hpp:250
bool is_valid_partition(M2_arrayint part, bool set_error=true) const
Definition schur2.cpp:157
void SM()
Definition schur2.cpp:795
virtual ring_elem eval(const RingMap *map, const ring_elem f, int first_var) const
Definition schur2.cpp:718
static SchurRing2 * create(const Ring *A, int n=-1)
Definition schur2.cpp:130
virtual ring_elem from_long(long n) const
Definition schur2.cpp:291
void SMbounds(int &lo, int &hi)
Definition schur2.cpp:748
virtual ring_elem add(const ring_elem f, const ring_elem g) const
Definition schur2.cpp:530
virtual void syzygy(const ring_elem a, const ring_elem b, ring_elem &x, ring_elem &y) const
Definition schur2.cpp:336
int SMcurrent
Definition schur2.hpp:253
engine_RawArrayPairOrNull list_form(const Ring *coeffR, const ring_elem f) const
Definition schur2.cpp:682
virtual ring_elem mult(const ring_elem f, const ring_elem g) const
Definition schur2.cpp:616
void SMappendTerm(const_schur_partition f)
Definition schur2.cpp:828
schur_poly * mult_by_coefficient(ring_elem a, const schur_poly *f) const
Definition schur2.cpp:600
int SMmaxweight
Definition schur2.hpp:249
bool promote_coeffs(const SchurRing2 *Sf, const ring_elem f, ring_elem &resultRE) const
Definition schur2.cpp:383
ring_elem from_partition(M2_arrayint part) const
Definition schur2.cpp:184
virtual int compare_elems(const ring_elem f, const ring_elem g) const
Definition schur2.cpp:365
virtual void elem_text_out(buffer &o, const ring_elem f, bool p_one=true, bool p_plus=false, bool p_parens=false) const
Definition schur2.cpp:202
int compare_partitions(const_schur_partition a, const_schur_partition b) const
Definition schur2.cpp:348
const Ring * getCoefficientRing() const
Definition schur2.hpp:175
tableau2 SMtab
Definition schur2.hpp:251
const Ring * coefficientRing
Definition schur2.hpp:154
void add(ring_elem p)
const_schur_partition getMonomial()
Definition schur2.hpp:118
ring_elem getCoefficient()
Definition schur2.hpp:117
schur_poly_iterator iterator
Definition schur2.hpp:90
void appendTerm(ring_elem coeff, const_schur_partition monom)
Definition schur2.cpp:119
iterator begin() const
Definition schur2.hpp:128
iterator end() const
Definition schur2.hpp:132
void append(iterator &first, iterator &last)
Definition schur2.cpp:124
size_t size() const
Definition schur2.hpp:94
int * lambda
Definition schur2.hpp:60
int * xloc
Definition schur2.hpp:62
void initialize(int nvars)
int elem(int x, int y) const
Definition schur2.cpp:39
void fill(int *lamb, int *pp)
Definition schur2.cpp:50
void resize(int max_wt)
Definition schur2.cpp:28
int * yloc
Definition schur2.hpp:64
int wt
Definition schur2.hpp:59
void display() const
Definition schur2.cpp:72
int * p
Definition schur2.hpp:61
int maxwt
Definition schur2.hpp:58
RingZZ * globalZZ
Definition relem.cpp:13
int p
void freemem(void *s)
Definition m2-mem.cpp:103
void size_t s
Definition m2-mem.cpp:271
const int ERROR
Definition m2-mem.cpp:55
VALGRIND_MAKE_MEM_DEFINED & result(result)
#define sizeofarray(s, len)
Definition m2-mem.h:129
struct engine_RawArrayPair_struct * engine_RawArrayPair
Definition m2-types.h:183
engine_RawArrayPair engine_RawArrayPairOrNull
Definition m2-types.h:184
#define ALLOCATE_EXPONENTS(byte_len)
Definition monoid.hpp:62
Monoid — variable count, naming, grading, and monomial order of a polynomial ring.
EngineMonomial — opaque single-monomial value type used at the engine boundary.
typename std::vector< T, gc_allocator< T > > gc_vector
a version of the STL vector, which allocates its backing memory with gc.
Definition newdelete.hpp:76
#define newitem(T)
Definition newdelete.hpp:86
#define VECTOR(T)
Definition newdelete.hpp:78
#define GETMEM(T, size)
#define newarray_atomic(T, len)
Definition newdelete.hpp:91
volatile int x
RingElement — tagged (Ring*, ring_elem) pair, the engine's universal element type.
RingMap — engine representation of a ring homomorphism.
static int last_nonzero(M2_arrayint part)
Definition schur2.cpp:178
void to_varpower(const_schur_partition a, gc_vector< int > &result)
Definition schur2.cpp:648
bool operator==(const schur_poly::iterator &a, const schur_poly::iterator &b)
Definition schur2.cpp:110
bool operator!=(const schur_poly::iterator &a, const schur_poly::iterator &b)
Definition schur2.cpp:114
static void hash_combine(size_t &seed, const T &val)
Definition schur2.cpp:87
int schur_word
Definition schur2.hpp:43
schur_word * schur_partition
Definition schur2.hpp:51
const schur_word * const_schur_partition
Definition schur2.hpp:52
SchurRing2 — refactored Schur ring with length-prefixed partitions and an explicit Ring base.
const int SCHUR_MAX_WT
Definition schur.hpp:40
const int LARGE_NUMBER
Definition schur.hpp:41
const int EQ
Definition style.hpp:40
const int GT
Definition style.hpp:41
const int LT
Definition style.hpp:39
#define T
Definition table.c:13
Text-formatting helpers layered on buffer: bignum print, line wrapping, M2_gbTrace-gated emit.
const schur_poly * get_schur_poly() const
Definition ringelem.hpp:137