Macaulay2 Engine
Loading...
Searching...
No Matches
schur.cpp
Go to the documentation of this file.
1// Copyright 1996 Michael E. Stillman
2
3#include "schur.hpp"
4#include <stdio.h>
5#include "text-io.hpp"
6#include "ZZ.hpp"
7#include "monoid.hpp"
8
9void tableau::initialize(int nvars)
10{
11 dim = nvars;
13 wt = 0;
14 lambda = nullptr;
15 p = nullptr;
18}
19
20void tableau::resize(int max_wt)
21{
22 if (max_wt <= SCHUR_MAX_WT) return;
25 maxwt = max_wt;
26 wt = max_wt;
27 xloc = newarray_atomic(int, maxwt + 1);
28 yloc = newarray_atomic(int, maxwt + 1);
29}
30
31int tableau::elem(int x, int y) const
32{
33 // slow: only used for debugging
34 for (int i = 1; i <= wt; i++)
35 if (xloc[i] == x && yloc[i] == y) return i;
36
37 // otherwise perhaps throw an error
38 fprintf(stderr, "tableau: location (%d,%d) out of range\n", x, y);
39 return 0;
40}
41
42void tableau::fill(int *lamb, int *pp)
43// Fill the skew tableau p\lambda with 1..nboxes
44// starting at top right, moving left and then down
45// row by row.
46{
47 int i, j;
48 p = pp;
49 lambda = lamb;
50
51 int next = 1;
52 for (i = 1; p[i] != 0; i++)
53 {
54 int a = lambda[i];
55 for (j = p[i]; j > a; j--)
56 {
57 xloc[next] = i;
58 yloc[next++] = j;
59 }
60 }
61}
62
63void tableau::display() const
64{
65 int i, j;
66
67 for (i = 1; p[i] != 0; i++)
68 {
69 for (j = 1; j <= lambda[i]; j++) fprintf(stdout, "-- ");
70 for (; j <= p[i]; j++) fprintf(stdout, "%2d ", elem(i, j));
71 fprintf(stdout, "\n");
72 }
73}
74
76{
77 _SMtab.initialize(n_vars());
78 _SMfilled.initialize(n_vars());
79 _SMcurrent = 0;
80 _SMfinalwt = 0;
81 _SMresult = nullptr;
82
84 return true;
85}
86
88{
90 result->initialize_poly_ring(R->getCoefficients(), R->getMonoid());
91 if (!result->initialize_schur()) return nullptr;
92 // No GBRing
93 return result;
94}
95
97{
98 (void) A;
99 (void) n;
100 ERROR("not implemented yet");
101 return nullptr;
102}
103
105{
106 (void) A;
107 ERROR("not implemented yet");
108 return nullptr;
109}
110
112{
113 o << "Schur(";
114 K_->text_out(o);
115 o << ", ";
116 M_->text_out(o);
117 o << ")";
118}
119
120void SchurRing::to_partition(const int *m, int *exp) const
121// exp[1]..exp[nvars] are set
122{
123 exponents_t EXP1 = ALLOCATE_EXPONENTS(exp_size); // 0..nvars-1
124 // remark: exp_size is defined in an ancestor class of SchurRing
125 M_->to_expvector(m, EXP1);
126 exp[nvars_] = EXP1[nvars_ - 1];
127 for (int i = nvars_ - 1; i >= 1; i--) exp[i] = exp[i + 1] + EXP1[i - 1];
128}
129void SchurRing::from_partition(const int *exp, int *m) const
130{
131 exponents_t EXP1 = ALLOCATE_EXPONENTS(exp_size); // 0..nvars-1
132 EXP1[nvars_ - 1] = exp[nvars_];
133 for (int i = nvars_ - 1; i > 0; i--) EXP1[i - 1] = exp[i] - exp[i + 1];
134 M_->from_expvector(EXP1, m);
135}
136
137void SchurRing::bounds(int &lo, int &hi)
138{
139 int i, k;
140 int x = _SMfilled.xloc[_SMcurrent];
141 int y = _SMfilled.yloc[_SMcurrent];
142
143 // First set the high bound, using info from the "one to the right"
144 // in the reverse lex filled skew tableau.
145
146 if (y == _SMfilled.p[x]) // There is not one to the right
147 {
148 hi = nvars_;
149 for (k = 1; k <= nvars_; k++)
150 if (_SMtab.p[k] == 0)
151 {
152 hi = k;
153 break;
154 }
155 }
156 else // note that the case _SMcurrent==1 will be handled
157 { // in the previous statement.
158 hi = _SMtab.xloc[_SMcurrent - 1];
159 }
160
161 // Now we set the lo bound, using info from the "one above"
162
163 if (x == 1 || y <= _SMfilled.lambda[x - 1])
164 lo = 1; // There is not one above
165 else
166 {
167 int above = _SMcurrent - _SMfilled.p[x] + _SMfilled.lambda[x - 1];
168 int xabove = _SMtab.xloc[above];
169 int yabove = _SMtab.yloc[above];
170 for (i = xabove + 1; i <= hi; i++)
171 if (_SMtab.p[i] < yabove) break;
172 lo = i;
173 }
174}
175
177{
178 int lo, hi;
179
180 if (_SMcurrent == _SMfinalwt)
181 {
182 // partition is to be output
183 Nterm *f = new_term();
184 f->coeff = K_->from_long(1);
185 // fprintf(stderr, "partition: ");
186 // for (int i=1; i <= nvars_; i++)
187 // fprintf(stderr, " %d", _SMtab.p[i]);
188 // fprintf(stderr, "\n");
190 f->next = _SMresult;
191 _SMresult = f;
192 return;
193 }
194
195 _SMcurrent++;
196 bounds(lo, hi);
197 int this_one = LARGE_NUMBER; // larger than any entry of _SMtab
198 int last_one;
199 for (int i = lo; i <= hi; i++)
200 {
201 last_one = this_one;
202 this_one = _SMtab.p[i];
203 if (last_one > this_one)
204 {
205 _SMtab.p[i]++;
206 _SMtab.xloc[_SMcurrent] = i;
207 _SMtab.yloc[_SMcurrent] = _SMtab.p[i];
208 SM();
209 _SMtab.p[i]--;
210 }
211 }
212 _SMcurrent--;
213}
214
215Nterm *SchurRing::skew_schur(int *lambda, int *p)
216{
217 _SMcurrent = 0;
218
219 _SMfinalwt = 0;
220 for (int i = 1; p[i] != 0; i++) _SMfinalwt += (p[i] - lambda[i]);
221
222 _SMtab.wt = _SMfinalwt;
223 _SMtab.resize(_SMfinalwt);
224 _SMfilled.resize(_SMfinalwt);
225 _SMfilled.fill(lambda, p);
226 _SMresult = nullptr;
227 SM();
229 _SMresult = nullptr;
230 return result;
231}
232
233ring_elem SchurRing::mult_monomials(const int *m, const int *n)
234{
235 int i;
236
237 exponents_t a_part = ALLOCATE_EXPONENTS(sizeof(int) * (nvars_ + 1));
238 exponents_t b_part = ALLOCATE_EXPONENTS(sizeof(int) * (nvars_ + 1));
239 exponents_t lambda = ALLOCATE_EXPONENTS(2 * sizeof(int) * (nvars_ + 1));
240 exponents_t p = ALLOCATE_EXPONENTS(2 * sizeof(int) * (nvars_ + 1));
241
242 // First: obtain the partitions
243 to_partition(m, a_part);
244 to_partition(n, b_part);
245
246 // Second: make the skew partition
247 int a = b_part[1];
248 for (i = 1; i <= nvars_ && a_part[i] != 0; i++)
249 {
250 p[i] = a + a_part[i];
251 lambda[i] = a;
252 }
253 int top = i - 1;
254 for (i = 1; i <= nvars_ && b_part[i] != 0; i++)
255 {
256 p[top + i] = b_part[i];
257 lambda[top + i] = 0;
258 }
259 p[top + i] = 0;
260 lambda[top + i] = 0;
261
262 // Call the SM() algorithm
263 return skew_schur(lambda, p);
264}
265
267 const ring_elem c,
268 const int *m) const
269{
270 // return c*m*f
272 for (Nterm& t : f)
273 {
274 ring_elem a = K_->mult(c, t.coeff);
275 ring_elem g = const_cast<SchurRing *>(this)->mult_monomials(t.monom, m);
276 for (Nterm& s : g)
277 {
278 ring_elem b = K_->mult(a, s.coeff);
279 s.coeff = b;
280 }
281 Nterm *gt = g;
282 sort(gt);
283 g = gt;
284 add_to(result, g);
285 }
286 return result;
287}
288ring_elem SchurRing::power(const ring_elem f, mpz_srcptr n) const
289{
290 if (mpz_sgn(n) < 0) throw exc::engine_error("element not invertible");
291 std::pair<bool, int> n1 = RingZZ::get_si(n);
292 if (n1.first)
293 return power(f, n1.second);
294 else
295 throw exc::engine_error("exponent too large");
296}
297
299{
301 if (n < 0)
302 {
303 throw exc::engine_error("element not invertible");
304 }
305 for (int i = 0; i < n; i++)
306 {
307 ring_elem g = mult(result, f);
308 remove(result);
309 result = g;
310 }
311 return result;
312}
313
314void SchurRing::dimension(const int *exp, mpz_t result) const
315// exp: 0..nvars_
316// Return in 'result' the dimension of the irreducible
317// GL(nvars_) representation having highest weight
318// 'exp'
319{
320 int i, j;
321
322 mpz_set_ui(result, 1);
323 for (i = 1; i < nvars_; i++)
324 for (j = i + 1; j <= nvars_; j++)
325 if (exp[i] != exp[j]) mpz_mul_ui(result, result, exp[i] - exp[j] + j - i);
326
327 for (i = 1; i < nvars_; i++)
328 for (j = i + 1; j <= nvars_; j++)
329 if (exp[i] != exp[j]) mpz_fdiv_q_ui(result, result, j - i);
330}
331
333{
334 exponents_t EXP = ALLOCATE_EXPONENTS(sizeof(int) * (nvars_ + 1));
335 ring_elem result = K_->from_long(0);
336 mpz_t dim;
337 mpz_init(dim);
338 for (Nterm& t : f)
339 {
340 to_partition(t.monom, EXP);
341 dimension(EXP, dim);
342 ring_elem h = K_->from_int(dim);
343 ring_elem h2 = K_->mult(t.coeff, h);
344 K_->add_to(result, h2);
345 K_->remove(h);
346 }
347 mpz_clear(dim);
348 return result;
349}
350
352 const ring_elem f,
353 bool p_one,
354 bool p_plus,
355 bool p_parens) const
356{
357 exponents_t EXP = ALLOCATE_EXPONENTS(sizeof(int) * (nvars_ + 1));
358 int n = n_terms(f);
359
360 bool needs_parens = p_parens && (n > 1);
361 if (needs_parens)
362 {
363 if (p_plus) o << '+';
364 o << '(';
365 p_plus = false;
366 }
367
368 p_one = false;
369 for (Nterm& t : f)
370 {
371 int isone = M_->is_one(t.monom);
372 p_parens = !isone;
373 K_->elem_text_out(o, t.coeff, p_one, p_plus, p_parens);
374 to_partition(t.monom, EXP);
375 o << "{" << EXP[1];
376 for (int i = 2; i <= nvars_ && EXP[i] != 0; i++) o << "," << EXP[i];
377 o << "}";
378 p_plus = true;
379 }
380 if (needs_parens) o << ')';
381}
382
383// Local Variables:
384// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
385// indent-tabs-mode: nil
386// End:
exponents::Exponents exponents_t
Legacy RingZZ — a Ring-derived integer ring backed by GMP mpz_t.
virtual ring_elem from_long(long n) const
Definition poly.cpp:169
virtual ring_elem mult(const ring_elem f, const ring_elem g) const
Definition poly.cpp:821
virtual void remove(ring_elem &f) const
Definition poly.cpp:664
Nterm * new_term() const
Definition poly.cpp:146
void sort(Nterm *&f) const
Definition poly.cpp:2077
int n_terms(const ring_elem f) const
Definition polyring.hpp:360
const Ring * K_
Definition polyring.hpp:123
virtual const Monoid * getMonoid() const
Definition polyring.hpp:282
const Monoid * M_
Definition polyring.hpp:124
virtual const Ring * getCoefficients() const
Definition polyring.hpp:277
int n_vars() const
Definition polyring.hpp:196
void add_to(ring_elem &f, const ring_elem &g) const
Definition ring.cpp:205
xxx xxx xxx
Definition ring.hpp:102
static std::pair< bool, int > get_si(mpz_srcptr n)
Definition ZZ.cpp:46
Nterm * skew_schur(int *lambda, int *p)
Definition schur.cpp:215
int _SMcurrent
Definition schur.hpp:88
ring_elem mult_monomials(const int *m, const int *n)
Definition schur.cpp:233
static SchurRing * create(const PolynomialRing *R)
Definition schur.cpp:87
tableau _SMtab
Definition schur.hpp:86
tableau _SMfilled
Definition schur.hpp:87
void to_partition(const int *m, int *exp) const
Definition schur.cpp:120
void SM()
Definition schur.cpp:176
void bounds(int &lo, int &hi)
Definition schur.cpp:137
virtual void text_out(buffer &o) const
Definition schur.cpp:111
void from_partition(const int *exp, int *m) const
Definition schur.cpp:129
SchurRing()
Definition schur.hpp:103
virtual ring_elem mult_by_term(const ring_elem f, const ring_elem c, const int *m) const
Definition schur.cpp:266
void dimension(const int *exp, mpz_t result) const
Definition schur.cpp:314
static SchurRing * createInfinite(const Ring *A)
Definition schur.cpp:104
ring_elem power(const ring_elem f, mpz_srcptr n) const
Exponentiation. This is the default function, if a class doesn't define this.
Definition schur.cpp:288
bool initialize_schur()
Definition schur.cpp:75
Nterm * _SMresult
Definition schur.hpp:90
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 schur.cpp:351
int _SMfinalwt
Definition schur.hpp:89
int dim
Definition schur.hpp:47
int wt
Definition schur.hpp:49
int * yloc
Definition schur.hpp:54
int maxwt
Definition schur.hpp:48
int * xloc
Definition schur.hpp:52
void resize(int max_wt)
Definition schur.cpp:20
int elem(int x, int y) const
Definition schur.cpp:31
void display() const
Definition schur.cpp:63
void initialize(int nvars)
Definition schur.cpp:9
int * lambda
Definition schur.hpp:50
void fill(int *lamb, int *pp)
Definition schur.cpp:42
int * p
Definition schur.hpp:51
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 ALLOCATE_EXPONENTS(byte_len)
Definition monoid.hpp:62
Monoid — variable count, naming, grading, and monomial order of a polynomial ring.
#define newarray_atomic_clear(T, len)
Definition newdelete.hpp:93
#define newarray_atomic(T, len)
Definition newdelete.hpp:91
volatile int x
#define ZERO_RINGELEM
Definition ring.hpp:677
const int SCHUR_MAX_WT
Definition schur.hpp:40
const int LARGE_NUMBER
Definition schur.hpp:41
SchurRing — symmetric-function ring with Schur-basis multiplication via Littlewood-Richardson.
Nterm * next
Definition ringelem.hpp:157
ring_elem coeff
Definition ringelem.hpp:158
int monom[1]
Definition ringelem.hpp:160
Singly linked-list node carrying one term of a polynomial-ring element.
Definition ringelem.hpp:156
Text-formatting helpers layered on buffer: bignum print, line wrapping, M2_gbTrace-gated emit.