Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/combinat/k_tableau.py
8817 views
1
r"""
2
Strong and weak tableaux
3
4
There are two types of `k`-tableaux: strong `k`-tableaux and weak `k`-tableaux.
5
Standard weak `k`-tableaux correspond to saturated chains in the weak order,
6
whereas standard strong `k`-tableaux correspond to saturated chains in the strong Bruhat order.
7
For semistandard tableaux, the notion of weak and strong horizontal strip is necessary.
8
More information can be found in [LLMS2006]_ .
9
10
.. SEEALSO:: :meth:`sage.combinat.k_tableau.StrongTableau`, :meth:`sage.combinat.k_tableau.WeakTableau`
11
12
REFERENCES:
13
14
.. [LLMS2006] T. Lam, L. Lapointe, J. Morse, M. Shimozono,
15
Affine insertion and Pieri rules for the affine Grassmannian,
16
Memoirs of the AMS, 208 (2010), no. 977, :arxiv:`math.CO/0609110`
17
18
.. [LLMSSZ2013] T. Lam, L. Lapointe, J. Morse, A. Schilling, M. Shimozono, M. Zabrocki,
19
`k`-Schur functions and affine Schubert calculus,
20
preprint :arXiv:`1301.3569`
21
22
Authors:
23
24
- Anne Schilling and Mike Zabrocki (2013): initial version
25
- Avi Dalal and Nate Gallup (2013): implementation of `k`-charge
26
"""
27
#*****************************************************************************
28
# Copyright (C) 2013 Anne Schilling <anne at math.ucdavis.edu>
29
# Mike Zabrocki <zabrocki at mathstat.yorku.ca>
30
#
31
# Distributed under the terms of the GNU General Public License (GPL)
32
#
33
# This code is distributed in the hope that it will be useful,
34
# but WITHOUT ANY WARRANTY; without even the implied warranty of
35
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
36
# General Public License for more details.
37
#
38
# The full text of the GPL is available at:
39
#
40
# http://www.gnu.org/licenses/
41
#****************************************************************************
42
from sage.structure.unique_representation import UniqueRepresentation
43
from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets
44
from sage.structure.parent import Parent
45
from sage.structure.list_clone import ClonableList
46
from sage.misc.classcall_metaclass import ClasscallMetaclass
47
from sage.combinat.skew_tableau import SkewTableau, SemistandardSkewTableaux
48
from sage.combinat.partition import Partition, Partitions
49
from sage.combinat.root_system.weyl_group import WeylGroup
50
from sage.combinat.core import Core
51
from sage.rings.all import ZZ
52
from sage.misc.misc import uniq
53
from sage.functions.generalized import sgn
54
from sage.misc.flatten import flatten
55
from sage.combinat.skew_partition import SkewPartition
56
from sage.combinat.tableau import TableauOptions
57
from sage.combinat.composition import Composition
58
import cartesian_product
59
import copy
60
61
def WeakTableau(t, k, inner_shape = [], representation = "core"):
62
r"""
63
This is the dispatcher method for the element class of weak `k`-tableaux.
64
65
Standard weak `k`-tableaux correspond to saturated chains in the weak order.
66
There are three formulations of weak tableaux, one in terms of cores, one in terms
67
of `k`-bounded partitions, and one in terms of factorizations of affine Grassmannian
68
elements. For semistandard weak `k`-tableaux, all letters of the same value have to
69
satisfy the conditions of a horizontal strip. In the affine Grassmannian formulation this
70
means that all factors are cyclically decreasing elements. For more information, see
71
for example [LLMSSZ2013]_.
72
73
INPUT:
74
75
- ``t`` -- a weak `k`-tableau in the specified representation:
76
77
- for the 'core' representation ``t`` is a list of lists where each subtableaux
78
should have a `k+1`-core shape; ``None`` is allowed as an entry for skew weak
79
`k`-tableaux
80
- for the 'bounded' representation ``t`` is a list of lists where each subtableaux
81
should have a `k`-bounded shape; ``None`` is allowed as an entry for skew weak
82
`k`-tableaux
83
- for the 'factorized_permutation' representation ``t`` is either a list of
84
cyclically decreasing Weyl group elements or a list of reduced words of cyclically
85
decreasing Weyl group elements; to indicate a skew tableau in this representation,
86
``inner_shape`` should be the inner shape as a `(k+1)`-core
87
88
- ``k`` -- positive integer
89
90
- ``inner_shape`` -- this entry is only relevant for the 'factorized_permutation'
91
representation and specifies the inner shape in case the tableau is skew
92
(default: ``[]``)
93
94
- ``representation`` -- 'core', 'bounded', or 'factorized_permutation'
95
(default: 'core')
96
97
EXAMPLES:
98
99
Here is an example of a weak 3-tableau in core representation::
100
101
sage: t = WeakTableau([[1, 1, 2, 2, 3], [2, 3], [3]], 3)
102
sage: t.shape()
103
[5, 2, 1]
104
sage: t.weight()
105
(2, 2, 2)
106
sage: type(t)
107
<class 'sage.combinat.k_tableau.WeakTableaux_core_with_category.element_class'>
108
109
And now we give a skew weak 3-tableau in core representation::
110
111
sage: ts = WeakTableau([[None, 1, 1, 2, 2], [None, 2], [1]], 3)
112
sage: ts.shape()
113
([5, 2, 1], [1, 1])
114
sage: ts.weight()
115
(2, 2)
116
sage: type(ts)
117
<class 'sage.combinat.k_tableau.WeakTableaux_core_with_category.element_class'>
118
119
Next we create the analogue of the first example in bounded representation::
120
121
sage: tb = WeakTableau([[1,1,2],[2,3],[3]], 3, representation="bounded")
122
sage: tb.shape()
123
[3, 2, 1]
124
sage: tb.weight()
125
(2, 2, 2)
126
sage: type(tb)
127
<class 'sage.combinat.k_tableau.WeakTableaux_bounded_with_category.element_class'>
128
sage: tb.to_core_tableau()
129
[[1, 1, 2, 2, 3], [2, 3], [3]]
130
sage: t == tb.to_core_tableau()
131
True
132
133
And the analogue of the skew example in bounded representation::
134
135
sage: tbs = WeakTableau([[None, 1, 2], [None, 2], [1]], 3, representation = "bounded")
136
sage: tbs.shape()
137
([3, 2, 1], [1, 1])
138
sage: tbs.weight()
139
(2, 2)
140
sage: tbs.to_core_tableau()
141
[[None, 1, 1, 2, 2], [None, 2], [1]]
142
sage: ts.to_bounded_tableau() == tbs
143
True
144
145
Finally we do the same examples for the factorized permutation representation::
146
147
sage: tf = WeakTableau([[2,0],[3,2],[1,0]], 3, representation = "factorized_permutation")
148
sage: tf.shape()
149
[5, 2, 1]
150
sage: tf.weight()
151
(2, 2, 2)
152
sage: type(tf)
153
<class 'sage.combinat.k_tableau.WeakTableaux_factorized_permutation_with_category.element_class'>
154
sage: tf.to_core_tableau() == t
155
True
156
157
sage: tfs = WeakTableau([[0,3],[2,1]], 3, inner_shape = [1,1], representation = 'factorized_permutation')
158
sage: tfs.shape()
159
([5, 2, 1], [1, 1])
160
sage: tfs.weight()
161
(2, 2)
162
sage: type(tfs)
163
<class 'sage.combinat.k_tableau.WeakTableaux_factorized_permutation_with_category.element_class'>
164
sage: tfs.to_core_tableau()
165
[[None, 1, 1, 2, 2], [None, 2], [1]]
166
167
Another way to pass from one representation to another is as follows::
168
169
sage: ts
170
[[None, 1, 1, 2, 2], [None, 2], [1]]
171
sage: ts.parent()._representation
172
'core'
173
sage: ts.representation('bounded')
174
[[None, 1, 2], [None, 2], [1]]
175
176
To test whether a given semistandard tableau is a weak `k`-tableau in the bounded representation,
177
one can ask::
178
179
sage: t = Tableau([[1,1,2],[2,3],[3]])
180
sage: t.is_k_tableau(3)
181
True
182
sage: t = SkewTableau([[None, 1, 2], [None, 2], [1]])
183
sage: t.is_k_tableau(3)
184
True
185
sage: t = SkewTableau([[None, 1, 1], [None, 2], [2]])
186
sage: t.is_k_tableau(3)
187
False
188
189
TESTS::
190
191
sage: t = WeakTableau([[2,0],[3,2],[1,0]], 3, representation = "bla")
192
Traceback (most recent call last):
193
...
194
NotImplementedError: The representation option needs to be 'core', 'bounded', or 'factorized_permuation'
195
"""
196
if representation == "core":
197
return WeakTableau_core(t, k)
198
elif representation == "bounded":
199
return WeakTableau_bounded(t, k)
200
elif representation == "factorized_permutation":
201
return WeakTableau_factorized_permutation(t, k, inner_shape = inner_shape)
202
else:
203
raise NotImplementedError, "The representation option needs to be 'core', 'bounded', or 'factorized_permuation'"
204
205
def WeakTableaux(k, shape , weight, representation = "core"):
206
r"""
207
This is the dispatcher method for the parent class of weak `k`-tableaux.
208
209
INPUT:
210
211
- ``k`` -- positive integer
212
- ``shape`` -- shape of the weak `k`-tableaux; for the 'core' and
213
'factorized_permutation' representation, the shape is inputted as a `(k+1)`-core;
214
for the 'bounded' representation, the shape is inputted as a `k`-bounded partition;
215
for skew tableaux, the shape is inputted as a tuple of the outer and inner shape
216
- ``weight`` -- the weight of the weak `k`-tableaux as a list or tuple
217
- ``representation`` -- 'core', 'bounded', or 'factorized_permutation' (default: 'core')
218
219
EXAMPLES::
220
221
sage: T = WeakTableaux(3, [5,2,1], [1,1,1,1,1,1])
222
sage: T.list()
223
[[[1, 3, 4, 5, 6], [2, 6], [4]],
224
[[1, 2, 4, 5, 6], [3, 6], [4]],
225
[[1, 2, 3, 4, 6], [4, 6], [5]],
226
[[1, 2, 3, 4, 5], [4, 5], [6]]]
227
sage: T.cardinality()
228
4
229
230
sage: T = WeakTableaux(3, [[5,2,1], [2]], [1,1,1,1])
231
sage: T.list()
232
[[[None, None, 2, 3, 4], [1, 4], [2]],
233
[[None, None, 1, 2, 4], [2, 4], [3]],
234
[[None, None, 1, 2, 3], [2, 3], [4]]]
235
236
sage: T = WeakTableaux(3, [3,2,1], [1,1,1,1,1,1], representation = 'bounded')
237
sage: T.list()
238
[[[1, 3, 5], [2, 6], [4]],
239
[[1, 2, 5], [3, 6], [4]],
240
[[1, 2, 3], [4, 6], [5]],
241
[[1, 2, 3], [4, 5], [6]]]
242
243
sage: T = WeakTableaux(3, [[3,2,1], [2]], [1,1,1,1], representation = 'bounded')
244
sage: T.list()
245
[[[None, None, 3], [1, 4], [2]],
246
[[None, None, 1], [2, 4], [3]],
247
[[None, None, 1], [2, 3], [4]]]
248
249
sage: T = WeakTableaux(3, [5,2,1], [1,1,1,1,1,1], representation = 'factorized_permutation')
250
sage: T.list()
251
[[s0, s3, s2, s1, s3, s0],
252
[s0, s3, s2, s3, s1, s0],
253
[s0, s2, s3, s2, s1, s0],
254
[s2, s0, s3, s2, s1, s0]]
255
256
sage: T = WeakTableaux(3, [[5,2,1], [2]], [1,1,1,1], representation = 'factorized_permutation')
257
sage: T.list()
258
[[s0, s3, s2, s3], [s0, s2, s3, s2], [s2, s0, s3, s2]]
259
"""
260
if representation == "core":
261
return WeakTableaux_core(k, shape, weight)
262
elif representation == "bounded":
263
return WeakTableaux_bounded(k, shape, weight)
264
elif representation == "factorized_permutation":
265
return WeakTableaux_factorized_permutation(k, shape, weight)
266
else:
267
raise NotImplementedError, "The representation option needs to be 'core', 'bounded', or 'factorized_permuation'"
268
269
#Abstract class for the elements of weak tableau
270
class WeakTableau_abstract(ClonableList):
271
r"""
272
Abstract class for the various element classes of WeakTableau.
273
"""
274
__metaclass__ = ClasscallMetaclass
275
276
def shape(self):
277
r"""
278
Return the shape of ``self``.
279
280
When the tableau is straight, the outer shape is returned.
281
When the tableau is skew, the tuple of the outer and inner shape is returned.
282
283
EXAMPLES::
284
285
sage: t = WeakTableau([[1, 1, 2, 2, 3], [2, 3], [3]], 3)
286
sage: t.shape()
287
[5, 2, 1]
288
sage: t = WeakTableau([[None, None, 2, 3, 4], [1, 4], [2]], 3)
289
sage: t.shape()
290
([5, 2, 1], [2])
291
292
sage: t = WeakTableau([[1,1,1],[2,2],[3]], 3, representation = 'bounded')
293
sage: t.shape()
294
[3, 2, 1]
295
sage: t = WeakTableau([[None, None, 1], [2, 4], [3]], 3, representation = 'bounded')
296
sage: t.shape()
297
([3, 2, 1], [2])
298
299
sage: t = WeakTableau([[2],[0,3],[2,1,0]], 3, representation = 'factorized_permutation')
300
sage: t.shape()
301
[5, 2, 1]
302
sage: t = WeakTableau([[2,0],[3,2]], 3, inner_shape = [2], representation = 'factorized_permutation')
303
sage: t.shape()
304
([5, 2, 1], [2])
305
"""
306
return self.parent().shape()
307
308
def weight(self):
309
r"""
310
Return the weight of ``self``.
311
312
The weight is a tuple whose `i`-th entry is the number of labels `i` in the
313
bounded representation of ``self``.
314
315
EXAMPLES::
316
317
sage: t = WeakTableau([[1, 1, 2, 2, 3], [2, 3], [3]], 3)
318
sage: t.weight()
319
(2, 2, 2)
320
sage: t = WeakTableau([[None, None, 2, 3, 4], [1, 4], [2]], 3)
321
sage: t.weight()
322
(1, 1, 1, 1)
323
sage: t = WeakTableau([[None,2,3],[3]],2)
324
sage: t.weight()
325
(0, 1, 1)
326
327
sage: t = WeakTableau([[1,1,1],[2,2],[3]], 3, representation = 'bounded')
328
sage: t.weight()
329
(3, 2, 1)
330
sage: t = WeakTableau([[1,1,2],[2,3],[3]], 3, representation = 'bounded')
331
sage: t.weight()
332
(2, 2, 2)
333
sage: t = WeakTableau([[None, None, 1], [2, 4], [3]], 3, representation = 'bounded')
334
sage: t.weight()
335
(1, 1, 1, 1)
336
337
sage: t = WeakTableau([[2],[0,3],[2,1,0]], 3, representation = 'factorized_permutation')
338
sage: t.weight()
339
(3, 2, 1)
340
sage: t = WeakTableau([[2,0],[3,2],[1,0]], 3, representation = 'factorized_permutation')
341
sage: t.weight()
342
(2, 2, 2)
343
sage: t = WeakTableau([[2,0],[3,2]], 3, inner_shape = [2], representation = 'factorized_permutation')
344
sage: t.weight()
345
(2, 2)
346
"""
347
return self.parent()._weight
348
349
def size(self):
350
r"""
351
Return the size of the shape of ``self``.
352
353
In the bounded representation, the size of the shape is the number of boxes in the
354
outer shape minus the number of boxes in the inner shape. For the core and
355
factorized permutation representation, the size is the length of the outer shape
356
minus the length of the inner shape.
357
358
.. SEEALSO:: :meth:`sage.combinat.core.Core.length`
359
360
EXAMPLES::
361
362
sage: t = WeakTableau([[None, 1, 1, 2, 2], [None, 2], [1]], 3)
363
sage: t.shape()
364
([5, 2, 1], [1, 1])
365
sage: t.size()
366
4
367
sage: t = WeakTableau([[1,1,2],[2,3],[3]], 3, representation="bounded")
368
sage: t.shape()
369
[3, 2, 1]
370
sage: t.size()
371
6
372
"""
373
return self.parent().size()
374
375
def intermediate_shapes(self):
376
r"""
377
Return the intermediate shapes of ``self``.
378
379
A (skew) tableau with letters `1,2,\ldots,\ell` can be viewed as a sequence of shapes,
380
where the `i`-th shape is given by the shape of the subtableau on letters `1,2,\ldots,i`.
381
The output is the list of these shapes.
382
383
EXAMPLES::
384
385
sage: t = WeakTableau([[1, 1, 2, 2, 3], [2, 3], [3]],3)
386
sage: t.intermediate_shapes()
387
[[], [2], [4, 1], [5, 2, 1]]
388
389
sage: t = WeakTableau([[None, None, 2, 3, 4], [1, 4], [2]], 3)
390
sage: t.intermediate_shapes()
391
[[2], [2, 1], [3, 1, 1], [4, 1, 1], [5, 2, 1]]
392
393
sage: t = WeakTableau([[1,1,1],[2,2],[3]], 3, representation = 'bounded')
394
sage: t.intermediate_shapes()
395
[[], [3], [3, 2], [3, 2, 1]]
396
397
sage: t = WeakTableau([[None, None, 1], [2, 4], [3]], 3, representation = 'bounded')
398
sage: t.intermediate_shapes()
399
[[2], [3], [3, 1], [3, 1, 1], [3, 2, 1]]
400
401
sage: t = WeakTableau([[0],[3],[2],[3]], 3, inner_shape = [2], representation = 'factorized_permutation')
402
sage: t.intermediate_shapes()
403
[[2], [2, 1], [3, 1, 1], [4, 1, 1], [5, 2, 1]]
404
"""
405
if self.parent()._representation in ['core', 'bounded']:
406
return intermediate_shapes(self)
407
else:
408
return intermediate_shapes(self.to_core_tableau())
409
410
def pp(self):
411
r"""
412
Return a pretty print string of the tableau.
413
414
EXAMPLES::
415
416
sage: t = WeakTableau([[None, 1, 1, 2, 2], [None, 2], [1]], 3)
417
sage: t.pp()
418
. 1 1 2 2
419
. 2
420
1
421
sage: t = WeakTableau([[2,0],[3,2]], 3, inner_shape = [2], representation = 'factorized_permutation')
422
sage: t.pp()
423
[s2*s0, s3*s2]
424
"""
425
if self.parent()._representation in ['core', 'bounded']:
426
print self._repr_diagram()
427
else:
428
print self
429
430
def _latex_(self):
431
r"""
432
Return a latex method for the tableau.
433
434
EXAMPLES::
435
436
sage: t = WeakTableau([[None, 1, 1, 2, 2], [None, 2], [1]], 3)
437
sage: latex(t)
438
{\def\lr#1{\multicolumn{1}{|@{\hspace{.6ex}}c@{\hspace{.6ex}}|}{\raisebox{-.3ex}{$#1$}}}
439
\raisebox{-.6ex}{$\begin{array}[b]{*{5}c}\cline{1-5}
440
\lr{}&\lr{1}&\lr{1}&\lr{2}&\lr{2}\\\cline{1-5}
441
\lr{}&\lr{2}\\\cline{1-2}
442
\lr{1}\\\cline{1-1}
443
\end{array}$}
444
}
445
446
sage: t = WeakTableau([[0,3],[2,1]], 3, inner_shape = [1,1], representation = 'factorized_permutation')
447
sage: latex(t)
448
[s_{0}s_{3},s_{2}s_{1}]
449
"""
450
def chi(x):
451
if x is None:
452
return ""
453
if x in ZZ:
454
return x
455
return "%s"%x
456
if self.parent()._representation in ['core', 'bounded']:
457
t = [[chi(x) for x in row] for row in self._list]
458
from output import tex_from_array
459
return tex_from_array(t)
460
else:
461
return "["+"".join(self[i]._latex_()+',' for i in range(len(self)-1))+self[len(self)-1]._latex_()+"]"
462
463
def representation(self, representation = 'core'):
464
r"""
465
Return the analogue of ``self`` in the specified representation.
466
467
INPUT:
468
469
- ``representation`` -- 'core', 'bounded', or 'factorized_permutation' (default: 'core')
470
471
EXAMPLES::
472
473
sage: t = WeakTableau([[1, 1, 2, 3, 4, 4, 5, 5, 6], [2, 3, 5, 5, 6], [3, 4, 7], [5, 6], [6], [7]], 4)
474
sage: t.parent()._representation
475
'core'
476
sage: t.representation('bounded')
477
[[1, 1, 2, 4], [2, 3, 5], [3, 4], [5, 6], [6], [7]]
478
sage: t.representation('factorized_permutation')
479
[s0, s3*s1, s2*s1, s0*s4, s3*s0, s4*s2, s1*s0]
480
481
sage: tb = WeakTableau([[1, 1, 2, 4], [2, 3, 5], [3, 4], [5, 6], [6], [7]], 4, representation = 'bounded')
482
sage: tb.parent()._representation
483
'bounded'
484
sage: tb.representation('core') == t
485
True
486
sage: tb.representation('factorized_permutation')
487
[s0, s3*s1, s2*s1, s0*s4, s3*s0, s4*s2, s1*s0]
488
489
sage: tp = WeakTableau([[0],[3,1],[2,1],[0,4],[3,0],[4,2],[1,0]], 4, representation = 'factorized_permutation')
490
sage: tp.parent()._representation
491
'factorized_permutation'
492
sage: tp.representation('core') == t
493
True
494
sage: tp.representation('bounded') == tb
495
True
496
"""
497
t = self
498
if self.parent()._representation in ['bounded', 'factorized_permutation']:
499
t = t.to_core_tableau()
500
if representation == 'core':
501
return t
502
elif representation == 'bounded':
503
return t.to_bounded_tableau()
504
elif representation == 'factorized_permutation':
505
return t.to_factorized_permutation_tableau()
506
else:
507
raise ValueError("The representation must be one of 'core', 'bounded', or 'factorized_permutation'")
508
509
#Abstract class for the parents of weak tableaux
510
class WeakTableaux_abstract(UniqueRepresentation, Parent):
511
r"""
512
Abstract class for the various parent classes of WeakTableaux.
513
"""
514
def shape(self):
515
r"""
516
Return the shape of the tableaux of ``self``.
517
518
When ``self`` is the class of straight tableaux, the outer shape is returned.
519
When ``self`` is the class of skew tableaux, the tuple of the outer and inner
520
shape is returned.
521
522
Note that in the 'core' and 'factorized_permutation' representation, the shapes
523
are `(k+1)`-cores. In the 'bounded' representation, the shapes are `k`-bounded
524
partitions.
525
526
If the user wants to access the skew shape (even if the inner shape is empty),
527
please use ``self._shape``.
528
529
EXAMPLES::
530
531
sage: T = WeakTableaux(3, [5,2,2], [2,2,2,1])
532
sage: T.shape()
533
[5, 2, 2]
534
sage: T._shape
535
([5, 2, 2], [])
536
sage: T = WeakTableaux(3, [[5,2,2], [1]], [2,1,2,1])
537
sage: T.shape()
538
([5, 2, 2], [1])
539
540
sage: T = WeakTableaux(3, [3,2,2], [2,2,2,1], representation = 'bounded')
541
sage: T.shape()
542
[3, 2, 2]
543
sage: T._shape
544
([3, 2, 2], [])
545
sage: T = WeakTableaux(3, [[3,2,2], [1]], [2,1,2,1], representation = 'bounded')
546
sage: T.shape()
547
([3, 2, 2], [1])
548
549
sage: T = WeakTableaux(3, [4,1], [2,2], representation = 'factorized_permutation')
550
sage: T.shape()
551
[4, 1]
552
sage: T._shape
553
([4, 1], [])
554
sage: T = WeakTableaux(4, [[6,2,1], [2]], [2,1,1,1], representation = 'factorized_permutation')
555
sage: T.shape()
556
([6, 2, 1], [2])
557
"""
558
if self._skew:
559
return (self._outer_shape, self._inner_shape)
560
return self._outer_shape
561
562
def size(self):
563
r"""
564
Return the size of the shape.
565
566
In the bounded representation, the size of the shape is the number of boxes in the
567
outer shape minus the number of boxes in the inner shape. For the core and
568
factorized permutation representation, the size is the length of the outer shape
569
minus the length of the inner shape.
570
571
EXAMPLES::
572
573
sage: T = WeakTableaux(3, [5,2,1], [1,1,1,1,1,1])
574
sage: T.size()
575
6
576
sage: T = WeakTableaux(3, [3,2,1], [1,1,1,1,1,1], representation = 'bounded')
577
sage: T.size()
578
6
579
sage: T = WeakTableaux(4, [[6,2,1], [2]], [2,1,1,1], 'factorized_permutation')
580
sage: T.size()
581
5
582
"""
583
if self._representation == 'bounded':
584
return self._outer_shape.size() - self._inner_shape.size()
585
else:
586
return self._outer_shape.length() - self._inner_shape.length()
587
588
def representation(self, representation = 'core'):
589
r"""
590
Return the analogue of ``self`` in the specified representation.
591
592
INPUT:
593
594
- ``representation`` -- 'core', 'bounded', or 'factorized_permutation' (default: 'core')
595
596
EXAMPLES::
597
598
sage: T = WeakTableaux(3, [5,2,1], [1,1,1,1,1,1])
599
sage: T._representation
600
'core'
601
sage: T.representation('bounded')
602
Bounded weak 3-Tableaux of (skew) 3-bounded shape [3, 2, 1] and weight (1, 1, 1, 1, 1, 1)
603
sage: T.representation('factorized_permutation')
604
Factorized permutation (skew) weak 3-Tableaux of shape [5, 2, 1] and weight (1, 1, 1, 1, 1, 1)
605
606
sage: T = WeakTableaux(3, [3,2,1], [1,1,1,1,1,1], representation = 'bounded')
607
sage: T._representation
608
'bounded'
609
sage: T.representation('core')
610
Core weak 3-Tableaux of (skew) core shape [5, 2, 1] and weight (1, 1, 1, 1, 1, 1)
611
sage: T.representation('bounded')
612
Bounded weak 3-Tableaux of (skew) 3-bounded shape [3, 2, 1] and weight (1, 1, 1, 1, 1, 1)
613
sage: T.representation('bounded') == T
614
True
615
sage: T.representation('factorized_permutation')
616
Factorized permutation (skew) weak 3-Tableaux of shape [5, 2, 1] and weight (1, 1, 1, 1, 1, 1)
617
sage: T.representation('factorized_permutation') == T
618
False
619
620
sage: T = WeakTableaux(3, [5,2,1], [1,1,1,1,1,1], representation = 'factorized_permutation')
621
sage: T._representation
622
'factorized_permutation'
623
sage: T.representation('core')
624
Core weak 3-Tableaux of (skew) core shape [5, 2, 1] and weight (1, 1, 1, 1, 1, 1)
625
sage: T.representation('bounded')
626
Bounded weak 3-Tableaux of (skew) 3-bounded shape [3, 2, 1] and weight (1, 1, 1, 1, 1, 1)
627
sage: T.representation('factorized_permutation')
628
Factorized permutation (skew) weak 3-Tableaux of shape [5, 2, 1] and weight (1, 1, 1, 1, 1, 1)
629
"""
630
outer_shape = self._outer_shape
631
inner_shape = self._inner_shape
632
weight = self._weight
633
if (self._representation in ['core', 'factorized_permutation']) and representation == 'bounded':
634
outer_shape = outer_shape.to_bounded_partition()
635
inner_shape = inner_shape.to_bounded_partition()
636
if self._representation == 'bounded' and (representation in ['core', 'factorized_permutation']):
637
outer_shape = outer_shape.to_core(self.k)
638
inner_shape = inner_shape.to_core(self.k)
639
return WeakTableaux(self.k, [outer_shape, inner_shape], weight, representation = representation)
640
641
642
#Weak Tableaux in terms of cores
643
class WeakTableau_core(WeakTableau_abstract):
644
r"""
645
A (skew) weak `k`-tableau represented in terms of `(k+1)`-cores.
646
"""
647
@staticmethod
648
def __classcall_private__(cls, t, k):
649
r"""
650
Implements the shortcut ``WeakTableau_core(t, k)`` to ``WeakTableaux_core(k, shape , weight)(t)``
651
where ``shape`` is the shape of the tableau and ``weight`` is its weight.
652
653
TESTS::
654
655
sage: from sage.combinat.k_tableau import WeakTableau_core
656
sage: t = WeakTableau_core([[1, 1, 2, 2, 3], [2, 3], [3]], 3)
657
sage: t.check()
658
sage: type(t)
659
<class 'sage.combinat.k_tableau.WeakTableaux_core_with_category.element_class'>
660
sage: TestSuite(t).run()
661
sage: t.parent()._skew
662
False
663
664
sage: t = WeakTableau_core([[None, None, 1, 1, 2], [1, 2], [2]],3)
665
sage: t.check()
666
sage: type(t)
667
<class 'sage.combinat.k_tableau.WeakTableaux_core_with_category.element_class'>
668
sage: TestSuite(t).run()
669
sage: t.parent()._skew
670
True
671
"""
672
if isinstance(t, cls):
673
return t
674
tab = SkewTableau(list(t))
675
outer = Core(tab.outer_shape(),k+1)
676
inner = Core(tab.inner_shape(),k+1)
677
weight = WeakTableau_bounded.from_core_tableau(t,k).weight()
678
return WeakTableaux_core(k, [outer, inner], weight)(t)
679
680
def __init__(self, parent, t):
681
r"""
682
Initialization of weak `k`-tableau ``t`` in core representation.
683
684
INPUT:
685
686
- ``t`` -- weak tableau in core representation; the input is supposed to be a list
687
of lists specifying the rows of the tableau;
688
``None`` is allowed as an entry for skew weak `k`-tableaux
689
690
TESTS::
691
692
sage: from sage.combinat.k_tableau import WeakTableau_core, WeakTableaux_core
693
sage: T = WeakTableaux_core(3,[5,2,1],[2,2,2])
694
sage: t = T([[1, 1, 2, 2, 3], [2, 3], [3]]); t
695
[[1, 1, 2, 2, 3], [2, 3], [3]]
696
sage: c = WeakTableau_core([[1, 1, 2, 2, 3], [2, 3], [3]],3)
697
sage: T = WeakTableaux_core(3,[5,2,1],[2,2,2])
698
sage: t = T([[1, 1, 2, 2, 3], [2, 3], [3]]); t
699
[[1, 1, 2, 2, 3], [2, 3], [3]]
700
sage: c == t
701
True
702
sage: type(t)
703
<class 'sage.combinat.k_tableau.WeakTableaux_core_with_category.element_class'>
704
sage: t.parent()
705
Core weak 3-Tableaux of (skew) core shape [5, 2, 1] and weight (2, 2, 2)
706
sage: TestSuite(t).run()
707
708
sage: t = WeakTableau_core([[None, None, 1, 1, 2], [1, 2], [2]],3); t
709
[[None, None, 1, 1, 2], [1, 2], [2]]
710
sage: t.weight()
711
(2, 2)
712
sage: t.shape()
713
([5, 2, 1], [2])
714
sage: TestSuite(t).run()
715
"""
716
self.k = parent.k
717
self._list = [r for r in t]
718
ClonableList.__init__(self, parent, t)
719
720
def _repr_diagram(self):
721
r"""
722
Return a string representation of ``self`` as a diagram.
723
724
EXAMPLES::
725
726
sage: t = WeakTableau([[None, None, 2, 3, 4], [1, 4], [2]], 3)
727
sage: print t._repr_diagram()
728
. . 2 3 4
729
1 4
730
2
731
"""
732
t = SkewTableau(list(self))
733
return t._repr_diagram()
734
735
def shape_core(self):
736
r"""
737
Return the shape of ``self`` as a `(k+1)`-core.
738
739
When the tableau is straight, the outer shape is returned as a core. When the
740
tableau is skew, the tuple of the outer and inner shape is returned as cores.
741
742
EXAMPLES::
743
744
sage: t = WeakTableau([[1, 1, 2, 2, 3], [2, 3], [3]],3)
745
sage: t.shape_core()
746
[5, 2, 1]
747
748
sage: t = WeakTableau([[None, None, 2, 3, 4], [1, 4], [2]], 3)
749
sage: t.shape_core()
750
([5, 2, 1], [2])
751
"""
752
return self.shape()
753
754
def shape_bounded(self):
755
r"""
756
Return the shape of ``self`` as a `k`-bounded partition.
757
758
When the tableau is straight, the outer shape is returned as a `k`-bounded
759
partition. When the tableau is skew, the tuple of the outer and inner shape is
760
returned as `k`-bounded partitions.
761
762
EXAMPLES::
763
764
sage: t = WeakTableau([[1, 1, 2, 2, 3], [2, 3], [3]],3)
765
sage: t.shape_bounded()
766
[3, 2, 1]
767
768
sage: t = WeakTableau([[None, None, 2, 3, 4], [1, 4], [2]], 3)
769
sage: t.shape_bounded()
770
([3, 2, 1], [2])
771
"""
772
if self.parent()._skew:
773
return tuple([r.to_bounded_partition() for r in self.shape_core()])
774
return self.shape_core().to_bounded_partition()
775
776
def check(self):
777
r"""
778
Check that ``self`` is a valid weak `k`-tableau.
779
780
EXAMPLES::
781
782
sage: t = WeakTableau([[1, 1, 2], [2]], 2)
783
sage: t.check()
784
sage: t = WeakTableau([[None, None, 2, 3, 4], [1, 4], [2]], 3)
785
sage: t.check()
786
787
TESTS::
788
789
sage: T = WeakTableaux(2, [3,1], [1,1,1,1])
790
sage: t = T([[1,2,3],[3]])
791
Traceback (most recent call last):
792
...
793
ValueError: The weight of the parent does not agree with the weight of the tableau!
794
795
sage: t = WeakTableau([[1, 2, 2], [1]], 2)
796
Traceback (most recent call last):
797
...
798
ValueError: The tableau is not semistandard!
799
"""
800
if not self.parent()._weight == WeakTableau_bounded.from_core_tableau(self._list,self.k).weight():
801
raise ValueError("The weight of the parent does not agree with the weight of the tableau!")
802
t = SkewTableau(list(self))
803
if not t in SemistandardSkewTableaux():
804
raise ValueError("The tableau is not semistandard!")
805
outer = Core(t.outer_shape(),self.k+1)
806
inner = Core(t.inner_shape(),self.k+1)
807
if self.parent()._outer_shape != outer:
808
raise ValueError("The outer shape of the parent does not agree with the outer shape of the tableau!")
809
if self.parent()._inner_shape != inner:
810
raise ValueError("The inner shape of the parent does not agree with the inner shape of the tableau!")
811
self.to_bounded_tableau().check()
812
813
def to_bounded_tableau(self):
814
r"""
815
Return the bounded representation of the weak `k`-tableau ``self``.
816
817
Each restricted sutableaux of the output is a `k`-bounded partition.
818
819
EXAMPLES::
820
821
sage: t = WeakTableau([[1, 1, 2, 2, 3], [2, 3], [3]], 3)
822
sage: c = t.to_bounded_tableau(); c
823
[[1, 1, 2], [2, 3], [3]]
824
sage: type(c)
825
<class 'sage.combinat.k_tableau.WeakTableaux_bounded_with_category.element_class'>
826
827
sage: t = WeakTableau([[None, None, 2, 3, 4], [1, 4], [2]], 3)
828
sage: t.to_bounded_tableau()
829
[[None, None, 3], [1, 4], [2]]
830
sage: t.to_bounded_tableau().to_core_tableau() == t
831
True
832
"""
833
shapes = [ Core(p,self.k+1).to_bounded_partition() for p in self.intermediate_shapes() ]
834
if self.parent()._skew:
835
l = [[None]*i for i in shapes[0]]
836
else:
837
l = []
838
for i in range(1,len(shapes)):
839
p = shapes[i]
840
if len(l) < len(p):
841
l += [[]]
842
l_new = []
843
for j in range(len(l)):
844
l_new += [l[j] + [i]*(p[j]-len(l[j]))]
845
l = l_new
846
return WeakTableau_bounded(l, self.k)
847
848
def to_factorized_permutation_tableau(self):
849
r"""
850
Return the factorized permutation representation of the weak `k`-tableau ``self``.
851
852
EXAMPLES::
853
854
sage: t = WeakTableau([[1, 1, 2, 2, 3], [2, 3], [3]], 3)
855
sage: c = t.to_factorized_permutation_tableau(); c
856
[s2*s0, s3*s2, s1*s0]
857
sage: type(c)
858
<class 'sage.combinat.k_tableau.WeakTableaux_factorized_permutation_with_category.element_class'>
859
sage: c.to_core_tableau() == t
860
True
861
862
sage: t = WeakTableau([[None, None, 2, 3, 4], [1, 4], [2]], 3)
863
sage: c = t.to_factorized_permutation_tableau(); c
864
[s0, s3, s2, s3]
865
sage: c._inner_shape
866
[2]
867
sage: c.to_core_tableau() == t
868
True
869
870
TESTS::
871
872
sage: t = WeakTableau([], 4)
873
sage: c = t.to_factorized_permutation_tableau(); c
874
[1]
875
sage: c._inner_shape
876
[]
877
sage: c.to_core_tableau() == t
878
True
879
"""
880
shapes = [ Core(p,self.k+1).to_grassmannian() for p in self.intermediate_shapes() ]
881
perms = [ shapes[i]*(shapes[i-1].inverse()) for i in range(len(shapes)-1,0,-1)]
882
return WeakTableau_factorized_permutation(perms, self.k, inner_shape = self.parent()._inner_shape)
883
884
def residues_of_entries(self, v):
885
r"""
886
Return a list of residues of cells of weak `k`-tableau ``self`` labeled by ``v``.
887
888
INPUT:
889
890
- ``v`` -- a label of a cell in ``self``
891
892
OUTPUT:
893
894
- a list of residues
895
896
EXAMPLES::
897
898
sage: t = WeakTableau([[1, 1, 2, 2, 3], [2, 3], [3]],3)
899
sage: t.residues_of_entries(1)
900
[0, 1]
901
902
sage: t = WeakTableau([[None, None, 1, 1, 4], [1, 4], [3]], 3)
903
sage: t.residues_of_entries(1)
904
[2, 3]
905
"""
906
return uniq([(j - i)%(self.k+1) for i in range(len(self)) for j in range(len(self[i])) if self[i][j] == v])
907
908
def dictionary_of_coordinates_at_residues(self, v):
909
r"""
910
Return a dictionary assigning to all residues of ``self`` with label ``v`` a list
911
of cells with the given residue.
912
913
INPUT:
914
915
- ``v`` -- a label of a cell in ``self``
916
917
OUTPUT:
918
919
- dictionary assigning coordinates in ``self`` to residues
920
921
EXAMPLES::
922
923
sage: t = WeakTableau([[1, 1, 2, 2, 3], [2, 3], [3]],3)
924
sage: t.dictionary_of_coordinates_at_residues(3)
925
{0: [(0, 4), (1, 1)], 2: [(2, 0)]}
926
927
sage: t = WeakTableau([[None, None, 1, 1, 4], [1, 4], [3]], 3)
928
sage: t.dictionary_of_coordinates_at_residues(1)
929
{2: [(0, 2)], 3: [(0, 3), (1, 0)]}
930
931
sage: t = WeakTableau([], 3)
932
sage: t.dictionary_of_coordinates_at_residues(1)
933
{}
934
"""
935
d = {}
936
for r in self.residues_of_entries(v):
937
d[r] = []
938
for i in range(len(self)):
939
for j in range(len(self[i])):
940
if self[i][j]==v and (j - i)%(self.k+1) == r:
941
d[r]+=[(i,j)]
942
return d
943
944
def list_of_standard_cells(self):
945
r"""
946
Return a list of lists of the coordinates of the standard cells of ``self``.
947
948
INPUT:
949
950
- ``self`` -- a weak `k`-tableau in core representation with partition weight
951
952
OUTPUT:
953
954
- a list of lists of coordinates
955
956
.. WARNING::
957
958
This method currently only works for straight weak tableaux with partition
959
weight.
960
961
EXAMPLES::
962
963
sage: t = WeakTableau([[1, 1, 2, 2, 3], [2, 3], [3]], 3)
964
sage: t.list_of_standard_cells()
965
[[(0, 1), (1, 0), (2, 0)], [(0, 0), (0, 2), (1, 1)]]
966
sage: t = WeakTableau([[1, 1, 1, 2], [2, 2, 3]], 5)
967
sage: t.list_of_standard_cells()
968
[[(0, 2), (1, 1), (1, 2)], [(0, 1), (1, 0)], [(0, 0), (0, 3)]]
969
sage: t = WeakTableau([[1, 1, 2, 3, 4, 4, 5, 5, 6], [2, 3, 5, 5, 6], [3, 4, 7], [5, 6], [6], [7]], 4)
970
sage: t.list_of_standard_cells()
971
[[(0, 1), (1, 0), (2, 0), (0, 5), (3, 0), (4, 0), (5, 0)], [(0, 0), (0, 2), (1, 1), (2, 1), (1, 2), (3, 1)]]
972
973
TESTS::
974
975
sage: t = WeakTableau([],3)
976
sage: t.list_of_standard_cells()
977
[]
978
979
sage: t = WeakTableau([[None, None, 2, 3, 4], [1, 4], [2]], 3)
980
sage: t.list_of_standard_cells()
981
Traceback (most recent call last):
982
...
983
ValueError: This method only works for straight tableaux!
984
985
sage: t = WeakTableau([[1,2],[2]], 3)
986
sage: t.list_of_standard_cells()
987
Traceback (most recent call last):
988
...
989
ValueError: This method only works for weak tableaux with partition weight!
990
"""
991
if self.parent()._skew:
992
raise ValueError("This method only works for straight tableaux!")
993
if self.weight() not in Partitions(sum(self.weight())):
994
raise ValueError("This method only works for weak tableaux with partition weight!")
995
if self._list == []:
996
return []
997
mu = Partition(self.weight()).conjugate()
998
already_used = []
999
out = []
1000
for i in range(self[0].count(1)):
1001
standard_cells = [(0,self[0].count(1) - i - 1)]
1002
r = self[0].count(1) - i - 1
1003
for v in range(1,mu[i]):
1004
D = self.dictionary_of_coordinates_at_residues(v+1)
1005
new_D = {a:b for (a,b) in D.iteritems() if all(x not in already_used for x in b)}
1006
r = (r - min([self.k+1 - (x-r)%(self.k+1) for x in new_D.keys()]))%(self.k+1)
1007
standard_cells.append(new_D[r][-1])
1008
already_used += new_D[r]
1009
out.append(standard_cells)
1010
return out
1011
1012
def k_charge(self, algorithm = "I"):
1013
r"""
1014
Return the `k`-charge of ``self``.
1015
1016
INPUT:
1017
1018
- ``algorithm`` -- (default: "I") if "I", computes `k`-charge using the `I`
1019
algorithm, otherwise uses the `J`-algorithm
1020
1021
OUTPUT:
1022
1023
- a nonnegative integer
1024
1025
For the definition of `k`-charge and the various algorithms to compute it see
1026
Section 3.3 of [LLMSSZ2013]_.
1027
1028
.. SEEALSO:: :meth:`k_charge_I` and :meth:`k_charge_J`
1029
1030
EXAMPLES::
1031
1032
sage: t = WeakTableau([[1, 1, 2, 2, 3], [2, 3], [3]], 3)
1033
sage: t.k_charge()
1034
2
1035
sage: t = WeakTableau([[1, 3, 4, 5, 6], [2, 6], [4]], 3)
1036
sage: t.k_charge()
1037
8
1038
sage: t = WeakTableau([[1, 1, 2, 3, 4, 4, 5, 5, 6], [2, 3, 5, 5, 6], [3, 4, 7], [5, 6], [6], [7]], 4)
1039
sage: t.k_charge()
1040
12
1041
1042
TESTS::
1043
1044
sage: T = WeakTableaux(4, [13,9,5,3,2,1,1], [4,3,3,2,2,1,1,1])
1045
sage: T.cardinality()
1046
6
1047
sage: all(t.k_charge_I() == t.k_charge_J() for t in T)
1048
True
1049
"""
1050
if algorithm == "I":
1051
return self.k_charge_I()
1052
return self.k_charge_J()
1053
1054
def k_charge_I(self):
1055
r"""
1056
Return the `k`-charge of ``self`` using the `I`-algorithm.
1057
1058
For the definition of `k`-charge and the `I`-algorithm see Section 3.3 of [LLMSSZ2013]_.
1059
1060
OUTPUT:
1061
1062
- a nonnegative integer
1063
1064
.. SEEALSO:: :meth:`k_charge` and :meth:`k_charge_J`
1065
1066
EXAMPLES::
1067
1068
sage: t = WeakTableau([[1, 1, 2, 2, 3], [2, 3], [3]], 3)
1069
sage: t.k_charge_I()
1070
2
1071
sage: t = WeakTableau([[1, 3, 4, 5, 6], [2, 6], [4]], 3)
1072
sage: t.k_charge_I()
1073
8
1074
sage: t = WeakTableau([[1, 1, 2, 3, 4, 4, 5, 5, 6], [2, 3, 5, 5, 6], [3, 4, 7], [5, 6], [6], [7]], 4)
1075
sage: t.k_charge_I()
1076
12
1077
1078
TESTS::
1079
1080
sage: t = WeakTableau([[None, None, 1, 1, 4], [1, 4], [3]], 3)
1081
sage: t.k_charge_I()
1082
Traceback (most recent call last):
1083
...
1084
ValueError: k-charge is not defined for skew weak tableaux
1085
"""
1086
if self.parent()._skew:
1087
raise ValueError("k-charge is not defined for skew weak tableaux")
1088
stt = self.list_of_standard_cells()
1089
kch = 0
1090
for sw in stt:
1091
Ii = 0
1092
for r in range(len(sw)-1):
1093
if sw[r][1] < sw[r+1][1]:
1094
Ii += 1 + abs(self.parent().diag(sw[r+1],sw[r]))
1095
else:
1096
Ii += - abs(self.parent().diag(sw[r],sw[r+1]))
1097
kch += Ii
1098
return kch
1099
1100
def k_charge_J(self):
1101
r"""
1102
Return the `k`-charge of ``self`` using the `J`-algorithm.
1103
1104
For the definition of `k`-charge and the `J`-algorithm see Section 3.3 of [LLMSSZ2013]_.
1105
1106
OUTPUT:
1107
1108
- a nonnegative integer
1109
1110
.. SEEALSO:: :meth:`k_charge` and :meth:`k_charge_I`
1111
1112
EXAMPLES::
1113
1114
sage: t = WeakTableau([[1, 1, 2, 2, 3], [2, 3], [3]], 3)
1115
sage: t.k_charge_J()
1116
2
1117
sage: t = WeakTableau([[1, 3, 4, 5, 6], [2, 6], [4]], 3)
1118
sage: t.k_charge_J()
1119
8
1120
sage: t = WeakTableau([[1, 1, 2, 3, 4, 4, 5, 5, 6], [2, 3, 5, 5, 6], [3, 4, 7], [5, 6], [6], [7]], 4)
1121
sage: t.k_charge_J()
1122
12
1123
1124
TESTS::
1125
1126
sage: t = WeakTableau([[None, None, 1, 1, 4], [1, 4], [3]], 3)
1127
sage: t.k_charge_I()
1128
Traceback (most recent call last):
1129
...
1130
ValueError: k-charge is not defined for skew weak tableaux
1131
1132
sage: t = WeakTableau([[1, 1, 2, 3], [2, 4, 4], [3, 6], [5]], 4, representation='bounded')
1133
sage: t.k_charge() == t.k_charge(algorithm = 'J')
1134
True
1135
"""
1136
if self.parent()._skew:
1137
raise ValueError("k-charge is not defined for skew weak tableaux")
1138
stt = self.list_of_standard_cells()
1139
kch = 0
1140
for sw in stt:
1141
Ji = 0
1142
for i in range(len(sw)-1):
1143
c = (self._height_of_restricted_subword(sw,i+2)+1,0)
1144
cdi = self.parent().circular_distance((-c[0])%(self.k+1),(sw[i][1]-sw[i][0])%(self.k+1))
1145
cdi1 = self.parent().circular_distance((-c[0])%(self.k+1),(sw[i+1][1]-sw[i+1][0])%(self.k+1))
1146
if (cdi > cdi1):
1147
Ji += 1
1148
kch += Ji + self.parent().diag(sw[i+1],c)
1149
return kch
1150
1151
def _height_of_restricted_subword(self, sw, r):
1152
r"""
1153
Return the row of the highest addable cell of the subtableau of ``self`` with letters `\le r`
1154
(excluding letters `r` in standard subwords before ``sw``).
1155
1156
Restrict the weak `k`-tableau ``self`` to letters `\le r` and remove all letters
1157
`r` that appeared in a previous standard subword selected by
1158
:meth:`list_of_standard_cells`.
1159
1160
INPUT:
1161
1162
- ``sw`` -- one of the subwords of standard cells of ``self``
1163
- ``r`` -- nonnegative integer
1164
1165
OUTPUT:
1166
1167
- a nonnegative integer
1168
1169
EXAMPLES::
1170
1171
sage: t = WeakTableau([[1, 1, 2, 2, 3], [2, 3], [3]], 3)
1172
sage: s = t.list_of_standard_cells()[0]; s
1173
[(0, 1), (1, 0), (2, 0)]
1174
sage: t._height_of_restricted_subword(s,2)
1175
1
1176
1177
sage: t = WeakTableau([[1, 3, 4, 5, 6], [2, 6], [4]], 3)
1178
sage: s = t.list_of_standard_cells()[0]; s
1179
[(0, 0), (1, 0), (0, 1), (2, 0), (0, 3), (1, 1)]
1180
sage: t._height_of_restricted_subword(s,4)
1181
2
1182
1183
sage: t = WeakTableau([[1, 1, 2, 3, 4, 4, 5, 5, 6], [2, 3, 5, 5, 6], [3, 4, 7], [5, 6], [6], [7]], 4)
1184
sage: s = t.list_of_standard_cells()[0]; s
1185
[(0, 1), (1, 0), (2, 0), (0, 5), (3, 0), (4, 0), (5, 0)]
1186
sage: t._height_of_restricted_subword(s,6)
1187
4
1188
"""
1189
R = filter(lambda v : self[v[0]][v[1]] < r, self.shape().to_partition().cells())
1190
L = filter(lambda v: self[v[0]][v[1]] <= r, sw)
1191
return max([v[0] for v in L+R])
1192
1193
class WeakTableaux_core(WeakTableaux_abstract):
1194
r"""
1195
The class of (skew) weak `k`-tableaux in the core representation of shape ``shape``
1196
(as `k+1`-core) and weight ``weight``.
1197
1198
INPUT:
1199
1200
- ``k`` -- positive integer
1201
- ``shape`` -- the shape of the `k`-tableaux represented as a `(k+1)`-core; if the
1202
tableaux are skew, the shape is a tuple of the outer and inner shape (both as
1203
`(k+1)`-cores)
1204
- ``weight`` -- the weight of the `k`-tableaux
1205
1206
EXAMPLES::
1207
1208
sage: T = WeakTableaux(3, [4,1], [2,2])
1209
sage: T.list()
1210
[[[1, 1, 2, 2], [2]]]
1211
1212
sage: T = WeakTableaux(3, [[5,2,1], [2]], [1,1,1,1])
1213
sage: T.list()
1214
[[[None, None, 2, 3, 4], [1, 4], [2]],
1215
[[None, None, 1, 2, 4], [2, 4], [3]],
1216
[[None, None, 1, 2, 3], [2, 3], [4]]]
1217
"""
1218
1219
@staticmethod
1220
def __classcall_private__(cls, k, shape, weight):
1221
r"""
1222
Straighten arguments before unique representation.
1223
1224
TESTS::
1225
1226
sage: from sage.combinat.k_tableau import WeakTableaux_core
1227
sage: T = WeakTableaux_core(3, [2,1], [1,1,1])
1228
sage: TestSuite(T).run()
1229
sage: T = WeakTableaux_core(3, [[5,2,1], [2]], [1,1,1,1])
1230
sage: TestSuite(T).run()
1231
"""
1232
if shape == [] or shape[0] in ZZ:
1233
shape = (Core(shape, k+1), Core([],k+1))
1234
else:
1235
shape = tuple([Core(r,k+1) for r in shape])
1236
return super(WeakTableaux_core, cls).__classcall__(cls, k, shape, tuple(weight))
1237
1238
def __init__(self, k, shape, weight):
1239
r"""
1240
Initializes the parent class of (skew) weak `k`-tableaux in core representation.
1241
1242
INPUT:
1243
1244
- ``k`` -- positive integer
1245
- ``outer_shape`` -- the outer shape of the `k`-tableaux represented as a
1246
`(k+1)`-core
1247
- ``weight`` -- the weight of the `k`-tableaux
1248
- ``inner_shape`` -- the inner shape of the skew `k`-tableaux represented as a
1249
`(k+1)`-core; for straight tableaux the inner shape does not need to be
1250
specified (default: [])
1251
1252
TESTS::
1253
1254
sage: from sage.combinat.k_tableau import WeakTableaux_core
1255
sage: T = WeakTableaux_core(3, [4,1], [2,2])
1256
sage: TestSuite(T).run()
1257
sage: T = WeakTableaux_core(3, [[5,2,1], [2]], [1,1,1,1])
1258
sage: TestSuite(T).run()
1259
"""
1260
self.k = k
1261
self._skew = shape[1]!=[]
1262
self._outer_shape = shape[0]
1263
self._inner_shape = shape[1]
1264
self._shape = (self._outer_shape, self._inner_shape)
1265
self._weight = weight
1266
self._representation = 'core'
1267
Parent.__init__(self, category = FiniteEnumeratedSets())
1268
1269
def _repr_(self):
1270
"""
1271
TESTS::
1272
1273
sage: from sage.combinat.k_tableau import WeakTableaux_core
1274
sage: repr(WeakTableaux_core(3, [2,1], [1,1,1]))
1275
'Core weak 3-Tableaux of (skew) core shape [2, 1] and weight (1, 1, 1)'
1276
sage: repr(WeakTableaux_core(3, [[5,2,1], [2]], [1,1,1,1]))
1277
'Core weak 3-Tableaux of (skew) core shape ([5, 2, 1], [2]) and weight (1, 1, 1, 1)'
1278
"""
1279
return "Core weak %s-Tableaux of (skew) core shape %s and weight %s"%(self.k, self.shape(), self._weight)
1280
1281
def __iter__(self):
1282
r"""
1283
TESTS::
1284
1285
sage: T = WeakTableaux(3, [4,1], [2,2])
1286
sage: T.list()
1287
[[[1, 1, 2, 2], [2]]]
1288
sage: T = WeakTableaux(3, [5,2,2], [2,2,2,1])
1289
sage: T.list()
1290
[[[1, 1, 3, 3, 4], [2, 2], [3, 3]], [[1, 1, 2, 2, 3], [2, 3], [3, 4]]]
1291
sage: T = WeakTableaux(3, [[5,2,2], [1]], [2,1,2,1])
1292
sage: T.list()
1293
[[[None, 1, 3, 3, 4], [1, 2], [3, 3]],
1294
[[None, 1, 2, 3, 3], [1, 3], [2, 4]],
1295
[[None, 1, 1, 2, 3], [2, 3], [3, 4]]]
1296
"""
1297
for t in WeakTableaux_bounded(self.k, [self._outer_shape.to_bounded_partition(), self._inner_shape.to_bounded_partition()], self._weight):
1298
yield t.to_core_tableau()
1299
1300
def diag(self, c, ha):
1301
r"""
1302
Return the number of diagonals strictly between cells ``c`` and ``ha`` of the same residue as ``c``.
1303
1304
INPUT:
1305
1306
- ``c`` -- a cell in the lattice
1307
- ``ha`` -- another cell in the lattice with bigger row and smaller column than `c`
1308
1309
OUTPUT:
1310
1311
- a nonnegative integer
1312
1313
EXAMPLES::
1314
1315
sage: T = WeakTableaux(4, [5,2,2], [2,2,2,1])
1316
sage: T.diag((1,2),(4,0))
1317
0
1318
"""
1319
return divmod((c[1]-c[0])-(ha[1]-ha[0])-1, self.k+1)[0]
1320
1321
def circular_distance(self, cr, r):
1322
r"""
1323
Return the shortest counterclockwise distance between ``cr`` and ``r`` modulo `k+1`.
1324
1325
INPUT:
1326
1327
- ``cr``, ``r`` -- nonnegative integers between `0` and `k`
1328
1329
OUTPUT:
1330
1331
- a positive integer
1332
1333
EXAMPLES::
1334
1335
sage: T = WeakTableaux(10, [], [])
1336
sage: T.circular_distance(8, 6)
1337
2
1338
sage: T.circular_distance(8, 8)
1339
0
1340
sage: T.circular_distance(8, 9)
1341
10
1342
"""
1343
return self.k - ((r+self.k-cr)%(self.k+1))
1344
1345
Element = WeakTableau_core
1346
1347
1348
#Weak tableaux in terms of `k`-bounded partitions
1349
class WeakTableau_bounded(WeakTableau_abstract):
1350
r"""
1351
A (skew) weak `k`-tableau represented in terms of `k`-bounded partitions.
1352
"""
1353
@staticmethod
1354
def __classcall_private__(cls, t, k):
1355
r"""
1356
Implements the shortcut ``WeakTableau_bounded(t, k)`` to ``WeakTableaux_bounded(k, shape, weight)(t)``
1357
where ``shape`` is the shape of the tableau and ``weight`` is its weight.
1358
1359
TESTS::
1360
1361
sage: from sage.combinat.k_tableau import WeakTableau_bounded
1362
sage: t = WeakTableau_bounded([[1,1,2],[2,3],[3]],3)
1363
sage: t.check()
1364
sage: type(t)
1365
<class 'sage.combinat.k_tableau.WeakTableaux_bounded_with_category.element_class'>
1366
sage: TestSuite(t).run()
1367
sage: t.parent()._skew
1368
False
1369
1370
sage: t = WeakTableau_bounded([[None, None, 1], [1, 2], [2]], 3)
1371
sage: t.check()
1372
sage: type(t)
1373
<class 'sage.combinat.k_tableau.WeakTableaux_bounded_with_category.element_class'>
1374
sage: TestSuite(t).run()
1375
sage: t.parent()._skew
1376
True
1377
"""
1378
if isinstance(t, cls):
1379
return t
1380
tab = SkewTableau(list(t))
1381
outer = tab.outer_shape()
1382
inner = tab.inner_shape()
1383
weight = tuple(tab.weight())
1384
if outer.conjugate().length() > k:
1385
raise ValueError, "The shape of %s is not %s-bounded"%(t, k)
1386
return WeakTableaux_bounded(k, [outer, inner], weight)(t)
1387
1388
def __init__(self, parent, t):
1389
r"""
1390
Initialization of (skew) weak `k`-tableau ``t`` in `k`-bounded representation.
1391
1392
INPUT:
1393
1394
- ``t`` -- weak tableau in `k`-bounded representation; the input is supposed to be
1395
a list of lists specifying the rows of the tableau; ``None`` is allowed as an
1396
entry for skew weak `k`-tableaux
1397
1398
TESTS::
1399
1400
sage: from sage.combinat.k_tableau import WeakTableau_bounded, WeakTableaux_bounded
1401
sage: c = WeakTableau_bounded([[1,1,2],[2,3],[3]],3)
1402
sage: T = WeakTableaux_bounded(3,[3,2,1],[2,2,2])
1403
sage: t = T([[1,1,2],[2,3],[3]]); t
1404
[[1, 1, 2], [2, 3], [3]]
1405
sage: c == t
1406
True
1407
sage: type(t)
1408
<class 'sage.combinat.k_tableau.WeakTableaux_bounded_with_category.element_class'>
1409
sage: t.parent()
1410
Bounded weak 3-Tableaux of (skew) 3-bounded shape [3, 2, 1] and weight (2, 2, 2)
1411
sage: TestSuite(t).run()
1412
1413
sage: t = WeakTableau_bounded([[None, None, 1], [2, 4], [3]], 3)
1414
sage: t.shape()
1415
([3, 2, 1], [2])
1416
sage: t.weight()
1417
(1, 1, 1, 1)
1418
sage: TestSuite(t).run()
1419
1420
sage: t = T([[1,1,3],[2,2],[3]])
1421
Traceback (most recent call last):
1422
...
1423
ValueError: This is not a proper weak 3-tableau
1424
"""
1425
k = parent.k
1426
self.k = k
1427
self._list = [r for r in t]
1428
if parent._outer_shape.conjugate().length() > k:
1429
raise ValueError, "%s is not a %s-bounded tableau"%(t, k)
1430
ClonableList.__init__(self, parent, t)
1431
1432
def _repr_diagram(self):
1433
r"""
1434
Return a string representation of ``self`` as a diagram.
1435
1436
EXAMPLES::
1437
1438
sage: t = WeakTableau([[None, None, 1], [2, 4], [3]], 3, representation = 'bounded')
1439
sage: print t._repr_diagram()
1440
. . 1
1441
2 4
1442
3
1443
sage: t = WeakTableau([[1,1,1],[2,2],[3]], 3, representation = 'bounded')
1444
sage: print t._repr_diagram()
1445
1 1 1
1446
2 2
1447
3
1448
"""
1449
t = SkewTableau(list(self))
1450
return t._repr_diagram()
1451
1452
def shape_core(self):
1453
r"""
1454
Return the shape of ``self`` as `(k+1)`-core.
1455
1456
When the tableau is straight, the outer shape is returned as a `(k+1)`-core.
1457
When the tableau is skew, the tuple of the outer and inner shape is returned as
1458
`(k+1)`-cores.
1459
1460
EXAMPLES::
1461
1462
sage: t = WeakTableau([[1,1,1],[2,2],[3]], 3, representation = 'bounded')
1463
sage: t.shape_core()
1464
[5, 2, 1]
1465
1466
sage: t = WeakTableau([[None, None, 1], [2, 4], [3]], 3, representation = 'bounded')
1467
sage: t.shape_core()
1468
([5, 2, 1], [2])
1469
"""
1470
if self.parent()._skew:
1471
return tuple([r.to_core(self.k) for r in self.shape_bounded()])
1472
return self.shape_bounded().to_core(self.k)
1473
1474
def shape_bounded(self):
1475
r"""
1476
Return the shape of ``self`` as `k`-bounded partition.
1477
1478
When the tableau is straight, the outer shape is returned as a `k`-bounded
1479
partition. When the tableau is skew, the tuple of the outer and inner shape is
1480
returned as `k`-bounded partitions.
1481
1482
EXAMPLES::
1483
1484
sage: t = WeakTableau([[1,1,1],[2,2],[3]], 3, representation = 'bounded')
1485
sage: t.shape_bounded()
1486
[3, 2, 1]
1487
1488
sage: t = WeakTableau([[None, None, 1], [2, 4], [3]], 3, representation = 'bounded')
1489
sage: t.shape_bounded()
1490
([3, 2, 1], [2])
1491
"""
1492
return self.shape()
1493
1494
def check(self):
1495
r"""
1496
Check that ``self`` is a valid weak `k`-tableau.
1497
1498
EXAMPLES::
1499
1500
sage: t = WeakTableau([[1,1],[2]], 2, representation = 'bounded')
1501
sage: t.check()
1502
1503
sage: t = WeakTableau([[None, None, 1], [2, 4], [3]], 3, representation = 'bounded')
1504
sage: t.check()
1505
1506
TESTS::
1507
1508
sage: t = WeakTableau([[1,1,3],[2,2],[3]], 3, representation = 'bounded')
1509
Traceback (most recent call last):
1510
...
1511
ValueError: This is not a proper weak 3-tableau
1512
1513
sage: T = WeakTableaux(3, [3,1], [2,1], representation = 'bounded')
1514
sage: t = T([[None, 1,1], [2]])
1515
Traceback (most recent call last):
1516
...
1517
ValueError: The inner shape of the parent does not agree with the inner shape of the tableau!
1518
1519
sage: t = WeakTableau([[1,1],[1]], 3, representation = 'bounded')
1520
Traceback (most recent call last):
1521
...
1522
ValueError: The tableaux is not semistandard!
1523
"""
1524
t = SkewTableau(list(self))
1525
if not t in SemistandardSkewTableaux():
1526
raise ValueError("The tableaux is not semistandard!")
1527
if not self.parent()._weight == tuple(t.weight()):
1528
raise ValueError("The weight of the parent does not agree with the weight of the tableau!")
1529
outer = t.outer_shape()
1530
inner = t.inner_shape()
1531
if self.parent()._outer_shape != outer:
1532
raise ValueError("The outer shape of the parent does not agree with the outer shape of the tableau!")
1533
if self.parent()._inner_shape != inner:
1534
raise ValueError("The inner shape of the parent does not agree with the inner shape of the tableau!")
1535
if not t.is_k_tableau(self.k):
1536
raise ValueError("This is not a proper weak %s-tableau"%(self.k))
1537
1538
def _is_k_tableau(self):
1539
r"""
1540
Checks whether ``self`` is a valid weak `k`-tableau.
1541
1542
EXAMPLES::
1543
1544
sage: t = WeakTableau([[1,1,1],[2,2],[3]], 3, representation = 'bounded')
1545
sage: t._is_k_tableau()
1546
True
1547
1548
sage: t = WeakTableau([[None, None, 1], [2, 4], [3]], 3, representation = 'bounded')
1549
sage: t._is_k_tableau()
1550
True
1551
"""
1552
shapes = self.intermediate_shapes()
1553
kshapes = [ la.k_conjugate(self.k) for la in shapes ]
1554
return all( kshapes[i+1].contains(kshapes[i]) for i in range(len(shapes)-1) )
1555
1556
def to_core_tableau(self):
1557
r"""
1558
Return the weak `k`-tableau ``self`` where the shape of each restricted tableau is a `(k+1)`-core.
1559
1560
EXAMPLES::
1561
1562
sage: t = WeakTableau([[1,1,2,4],[2,3,5],[3,4],[5,6],[6],[7]], 4, representation = 'bounded')
1563
sage: c = t.to_core_tableau(); c
1564
[[1, 1, 2, 3, 4, 4, 5, 5, 6], [2, 3, 5, 5, 6], [3, 4, 7], [5, 6], [6], [7]]
1565
sage: type(c)
1566
<class 'sage.combinat.k_tableau.WeakTableaux_core_with_category.element_class'>
1567
sage: t = WeakTableau([], 4, representation = 'bounded')
1568
sage: t.to_core_tableau()
1569
[]
1570
1571
sage: from sage.combinat.k_tableau import WeakTableau_bounded
1572
sage: t = WeakTableau([[1,1,2],[2,3],[3]], 3, representation = 'bounded')
1573
sage: WeakTableau_bounded.from_core_tableau(t.to_core_tableau(),3)
1574
[[1, 1, 2], [2, 3], [3]]
1575
sage: t == WeakTableau_bounded.from_core_tableau(t.to_core_tableau(),3)
1576
True
1577
1578
sage: t = WeakTableau([[None, None, 1], [2, 4], [3]], 3, representation = 'bounded')
1579
sage: t.to_core_tableau()
1580
[[None, None, 1, 2, 4], [2, 4], [3]]
1581
sage: t == WeakTableau_bounded.from_core_tableau(t.to_core_tableau(),3)
1582
True
1583
"""
1584
shapes = [ p.to_core(self.k) for p in self.intermediate_shapes() ]
1585
if self.parent()._skew:
1586
l = [[None]*i for i in shapes[0]]
1587
else:
1588
l = []
1589
for i in range(1,len(shapes)):
1590
p = shapes[i]
1591
if len(l) < len(p):
1592
l += [[]]
1593
l_new = []
1594
for j in range(len(l)):
1595
l_new += [l[j] + [i]*(p[j]-len(l[j]))]
1596
l = l_new
1597
return WeakTableau_core(l, self.k)
1598
1599
@classmethod
1600
def from_core_tableau(cls, t, k):
1601
r"""
1602
Construct weak `k`-bounded tableau from in `k`-core tableau.
1603
1604
EXAMPLES::
1605
1606
sage: from sage.combinat.k_tableau import WeakTableau_bounded
1607
sage: WeakTableau_bounded.from_core_tableau([[1, 1, 2, 2, 3], [2, 3], [3]], 3)
1608
[[1, 1, 2], [2, 3], [3]]
1609
1610
sage: WeakTableau_bounded.from_core_tableau([[None, None, 2, 3, 4], [1, 4], [2]], 3)
1611
[[None, None, 3], [1, 4], [2]]
1612
1613
sage: WeakTableau_bounded.from_core_tableau([[None,2,3],[3]], 2)
1614
[[None, 2], [3]]
1615
"""
1616
t = SkewTableau(list(t))
1617
shapes = [ Core(p, k+1).to_bounded_partition() for p in intermediate_shapes(t) ]#.to_chain() ]
1618
if t.inner_shape() == Partition([]):
1619
l = []
1620
else:
1621
l = [[None]*i for i in shapes[0]]
1622
for i in range(1,len(shapes)):
1623
p = shapes[i]
1624
if len(l) < len(p):
1625
l += [[]]
1626
l_new = []
1627
for j in range(len(l)):
1628
l_new += [l[j] + [i]*(p[j]-len(l[j]))]
1629
l = l_new
1630
return cls(l, k)
1631
1632
def k_charge(self, algorithm = 'I'):
1633
r"""
1634
Return the `k`-charge of ``self``.
1635
1636
INPUT:
1637
1638
- ``algorithm`` -- (default: "I") if "I", computes `k`-charge using the `I`
1639
algorithm, otherwise uses the `J`-algorithm
1640
1641
OUTPUT:
1642
1643
- a nonnegative integer
1644
1645
For the definition of `k`-charge and the various algorithms to compute it see Section 3.3 of [LLMSSZ2013]_.
1646
1647
EXAMPLES::
1648
1649
sage: t = WeakTableau([[1, 1, 2], [2, 3], [3]], 3, representation = 'bounded')
1650
sage: t.k_charge()
1651
2
1652
sage: t = WeakTableau([[1, 3, 5], [2, 6], [4]], 3, representation = 'bounded')
1653
sage: t.k_charge()
1654
8
1655
sage: t = WeakTableau([[1, 1, 2, 4], [2, 3, 5], [3, 4], [5, 6], [6], [7]], 4, representation = 'bounded')
1656
sage: t.k_charge()
1657
12
1658
"""
1659
return self.to_core_tableau().k_charge(algorithm = algorithm)
1660
1661
1662
class WeakTableaux_bounded(WeakTableaux_abstract):
1663
r"""
1664
The class of (skew) weak `k`-tableaux in the bounded representation of shape ``shape``
1665
(as `k`-bounded partition or tuple of `k`-bounded partitions in the skew case) and
1666
weight ``weight``.
1667
1668
INPUT:
1669
1670
- ``k`` -- positive integer
1671
- ``shape`` -- the shape of the `k`-tableaux represented as a `k`-bounded partition;
1672
if the tableaux are skew, the shape is a tuple of the outer and inner shape each
1673
represented as a `k`-bounded partition
1674
- ``weight`` -- the weight of the `k`-tableaux
1675
1676
EXAMPLES::
1677
1678
sage: T = WeakTableaux(3, [3,1], [2,2], representation = 'bounded')
1679
sage: T.list()
1680
[[[1, 1, 2], [2]]]
1681
1682
sage: T = WeakTableaux(3, [[3,2,1], [2]], [1,1,1,1], representation = 'bounded')
1683
sage: T.list()
1684
[[[None, None, 3], [1, 4], [2]],
1685
[[None, None, 1], [2, 4], [3]],
1686
[[None, None, 1], [2, 3], [4]]]
1687
"""
1688
@staticmethod
1689
def __classcall_private__(cls, k, shape, weight):
1690
r"""
1691
Straighten arguments before unique representation.
1692
1693
TESTS::
1694
1695
sage: from sage.combinat.k_tableau import WeakTableaux_bounded
1696
sage: T = WeakTableaux_bounded(3, [2,1], [1,1,1])
1697
sage: TestSuite(T).run()
1698
sage: T = WeakTableaux_bounded(3, [[3,2,1], [2]], [1,1,1,1])
1699
sage: TestSuite(T).run()
1700
"""
1701
if shape == [] or shape[0] in ZZ:
1702
shape = (Partition(shape), Partition([]))
1703
else:
1704
shape = tuple([Partition(r) for r in shape])
1705
return super(WeakTableaux_bounded, cls).__classcall__(cls, k, shape, tuple(weight))
1706
1707
def __init__(self, k, shape, weight):
1708
r"""
1709
Initializes the parent class of (skew) weak `k`-tableaux in bounded representation.
1710
1711
INPUT:
1712
1713
- ``k`` -- positive integer
1714
- ``shape`` -- the shape of the `k`-tableaux represented as a `k`-bounded
1715
partition; if the tableaux are skew, the shape is a tuple of the outer and inner
1716
shape each represented as a `k`-bounded partition
1717
- ``weight`` -- the weight of the `k`-tableaux
1718
1719
TESTS::
1720
1721
sage: from sage.combinat.k_tableau import WeakTableaux_bounded
1722
sage: T = WeakTableaux_bounded(3, [3,1], [2,2])
1723
sage: TestSuite(T).run()
1724
sage: T = WeakTableaux_bounded(3, [[3,2,1], [2]], [1,1,1,1])
1725
sage: TestSuite(T).run()
1726
"""
1727
self.k = k
1728
self._skew = shape[1]!=[]
1729
self._outer_shape = Partition(shape[0])
1730
self._inner_shape = Partition(shape[1])
1731
self._shape = (self._outer_shape, self._inner_shape)
1732
self._weight = tuple(weight)
1733
self._representation = 'bounded'
1734
Parent.__init__(self, category = FiniteEnumeratedSets())
1735
1736
def _repr_(self):
1737
"""
1738
TESTS::
1739
1740
sage: from sage.combinat.k_tableau import WeakTableaux_bounded
1741
sage: repr(WeakTableaux_bounded(3, [2,1], [1,1,1]))
1742
'Bounded weak 3-Tableaux of (skew) 3-bounded shape [2, 1] and weight (1, 1, 1)'
1743
sage: repr(WeakTableaux_bounded(3, [[3,2,1], [2]], [1,1,1,1]))
1744
'Bounded weak 3-Tableaux of (skew) 3-bounded shape ([3, 2, 1], [2]) and weight (1, 1, 1, 1)'
1745
"""
1746
return "Bounded weak %s-Tableaux of (skew) %s-bounded shape %s and weight %s"%(self.k, self.k, self.shape(), self._weight)
1747
1748
def __iter__(self):
1749
r"""
1750
TESTS::
1751
1752
sage: T = WeakTableaux(3, [3,1], [2,2], representation = 'bounded')
1753
sage: T.list()
1754
[[[1, 1, 2], [2]]]
1755
sage: T = WeakTableaux(3, [3,2,2], [2,2,2,1], representation = 'bounded')
1756
sage: T.list()
1757
[[[1, 1, 4], [2, 2], [3, 3]], [[1, 1, 2], [2, 3], [3, 4]]]
1758
sage: T = WeakTableaux(3, [[3,2,2], [1]], [2,1,2,1], representation = 'bounded')
1759
sage: T.list()
1760
[[[None, 1, 4], [1, 2], [3, 3]],
1761
[[None, 1, 3], [1, 3], [2, 4]],
1762
[[None, 1, 1], [2, 3], [3, 4]]]
1763
"""
1764
for t in SemistandardSkewTableaux([self._outer_shape, self._inner_shape], self._weight):
1765
if t.is_k_tableau(self.k):
1766
yield self(t)
1767
1768
Element = WeakTableau_bounded
1769
1770
#Weak tableaux in terms of factorized permutations
1771
class WeakTableau_factorized_permutation(WeakTableau_abstract):
1772
r"""
1773
A weak (skew) `k`-tableau represented in terms of factorizations of affine
1774
permutations into cyclically decreasing elements.
1775
"""
1776
@staticmethod
1777
def straighten_input(t, k):
1778
r"""
1779
Straightens input.
1780
1781
INPUT:
1782
1783
- ``t`` -- a list of reduced words or a list of elements in the Weyl group of type
1784
`A_k^{(1)}`
1785
- ``k`` -- a positive integer
1786
1787
EXAMPLES::
1788
1789
sage: from sage.combinat.k_tableau import WeakTableau_factorized_permutation
1790
sage: WeakTableau_factorized_permutation.straighten_input([[2,0],[3,2],[1,0]], 3)
1791
(s2*s0, s3*s2, s1*s0)
1792
sage: W = WeylGroup(['A',4,1])
1793
sage: WeakTableau_factorized_permutation.straighten_input([W.an_element(),W.an_element()], 4)
1794
(s0*s1*s2*s3*s4, s0*s1*s2*s3*s4)
1795
1796
TESTS::
1797
1798
sage: WeakTableau_factorized_permutation.straighten_input([W.an_element(),W.an_element()], 3)
1799
Traceback (most recent call last):
1800
...
1801
ValueError: a matrix from Full MatrixSpace of 5 by 5 dense matrices over Rational Field cannot be converted to a matrix in Full MatrixSpace of 4 by 4 dense matrices over Rational Field!
1802
"""
1803
W = WeylGroup(['A', k, 1], prefix='s')
1804
if len(t) > 0:
1805
if isinstance(t[0], list) or isinstance(t[0], tuple):
1806
w_tuple = tuple(W.from_reduced_word(p) for p in t)
1807
elif t[0] not in W:
1808
raise ValueError, "The input must be a list of reduced words or Weyl group elements"
1809
else:
1810
w_tuple = tuple(W(r) for r in t)
1811
else:
1812
w_tuple = tuple([W.one()])
1813
return w_tuple
1814
1815
@staticmethod
1816
def __classcall_private__(cls, t, k, inner_shape = []):
1817
r"""
1818
Implements the shortcut ``WeakTableau_factorized_permutation(t, k)`` to
1819
``WeakTableaux_factorized_permutation(k, shape, weight)(t)``
1820
where ``shape`` is the shape of the tableau as a `(k+1)`-core (or a tuple of
1821
`(k+1)`-cores if the tableau is skew) and ``weight`` is its weight.
1822
1823
TESTS::
1824
1825
sage: from sage.combinat.k_tableau import WeakTableau_factorized_permutation
1826
sage: t = WeakTableau_factorized_permutation([[2,0],[3,2],[1,0]], 3)
1827
sage: t.check()
1828
sage: type(t)
1829
<class 'sage.combinat.k_tableau.WeakTableaux_factorized_permutation_with_category.element_class'>
1830
sage: TestSuite(t).run()
1831
1832
sage: t = WeakTableau_factorized_permutation([[0,3],[2,1]], 3, inner_shape = [1,1])
1833
sage: t.check()
1834
sage: TestSuite(t).run()
1835
1836
sage: t = WeakTableau_factorized_permutation([], 3); t
1837
[1]
1838
sage: t.check()
1839
sage: TestSuite(t).run()
1840
"""
1841
if isinstance(t, cls):
1842
return t
1843
W = WeylGroup(['A', k, 1], prefix='s')
1844
w = cls.straighten_input(t, k)
1845
weight = tuple(w[i].length() for i in range(len(w)-1,-1,-1))
1846
inner_shape = Core(inner_shape, k+1)
1847
outer_shape = (W.prod(w)*W(inner_shape.to_grassmannian())).affine_grassmannian_to_core()
1848
return WeakTableaux_factorized_permutation(k, [outer_shape, inner_shape], weight)(w)
1849
1850
def __init__(self, parent, t):
1851
r"""
1852
Initialization of (skew) weak `k`-tableau ``t`` in factorized permutation representation.
1853
1854
INPUT:
1855
1856
- ``t`` -- (skew) weak tableau in factorized permutation representation; the input
1857
can either be a list of reduced words of cyclically decreasing elements, or a
1858
list of cyclically decreasing elements; when the tableau is skew, the inner
1859
shape needs to be specified as a `(k+1)`-core
1860
1861
TESTS::
1862
1863
sage: from sage.combinat.k_tableau import WeakTableau_factorized_permutation, WeakTableaux_factorized_permutation
1864
sage: c = WeakTableau_factorized_permutation([[2,0],[3,2],[1,0]], 3)
1865
sage: T = WeakTableaux_factorized_permutation(3, [5,2,1],[2,2,2])
1866
sage: t = T([[2,0],[3,2],[1,0]]); t
1867
[s2*s0, s3*s2, s1*s0]
1868
sage: c == t
1869
True
1870
sage: type(t)
1871
<class 'sage.combinat.k_tableau.WeakTableaux_factorized_permutation_with_category.element_class'>
1872
sage: t.parent()
1873
Factorized permutation (skew) weak 3-Tableaux of shape [5, 2, 1] and weight (2, 2, 2)
1874
sage: TestSuite(t).run()
1875
1876
sage: t = WeakTableau_factorized_permutation([[2,0],[3,2]], 3, inner_shape = [2]); t
1877
[s2*s0, s3*s2]
1878
sage: t._inner_shape
1879
[2]
1880
sage: t.weight()
1881
(2, 2)
1882
sage: t.shape()
1883
([5, 2, 1], [2])
1884
sage: TestSuite(t).run()
1885
1886
sage: t = T([[3,0],[0,3],[1,0]])
1887
Traceback (most recent call last):
1888
...
1889
ValueError: The outer shape of the parent does not agree with the outer shape of the tableau!
1890
1891
sage: t = WeakTableau_factorized_permutation([], 3); t
1892
[1]
1893
sage: t.parent()._outer_shape
1894
[]
1895
sage: t.parent()._weight
1896
(0,)
1897
"""
1898
self.k = parent.k
1899
self._inner_shape = parent._inner_shape
1900
ClonableList.__init__(self, parent, self.straighten_input(t, parent.k))
1901
1902
def shape_core(self):
1903
r"""
1904
Return the shape of ``self`` as a `(k+1)`-core.
1905
1906
When the tableau is straight, the outer shape is returned as a core.
1907
When the tableau is skew, the tuple of the outer and inner shape is returned as
1908
cores.
1909
1910
EXAMPLES::
1911
1912
sage: t = WeakTableau([[2],[0,3],[2,1,0]], 3, representation = 'factorized_permutation')
1913
sage: t.shape_core()
1914
[5, 2, 1]
1915
1916
sage: t = WeakTableau([[2,0],[3,2]], 3, inner_shape = [2], representation = 'factorized_permutation')
1917
sage: t.shape()
1918
([5, 2, 1], [2])
1919
"""
1920
return self.shape()
1921
1922
def shape_bounded(self):
1923
r"""
1924
Return the shape of ``self`` as a `k`-bounded partition.
1925
1926
When the tableau is straight, the outer shape is returned as a `k`-bounded
1927
partition. When the tableau is skew, the tuple of the outer and inner shape is
1928
returned as `k`-bounded partitions.
1929
1930
EXAMPLES::
1931
1932
sage: t = WeakTableau([[2],[0,3],[2,1,0]], 3, representation = 'factorized_permutation')
1933
sage: t.shape_bounded()
1934
[3, 2, 1]
1935
1936
sage: t = WeakTableau([[2,0],[3,2]], 3, inner_shape = [2], representation = 'factorized_permutation')
1937
sage: t.shape_bounded()
1938
([3, 2, 1], [2])
1939
"""
1940
if self.parent()._skew:
1941
return tuple([r.to_bounded_partition() for r in self.shape_core()])
1942
return self.shape_core().to_bounded_partition()
1943
1944
def check(self):
1945
r"""
1946
Check that ``self`` is a valid weak `k`-tableau.
1947
1948
EXAMPLES::
1949
1950
sage: t = WeakTableau([[2],[0,3],[2,1,0]], 3, representation = 'factorized_permutation')
1951
sage: t.check()
1952
1953
TESTS::
1954
1955
sage: t = WeakTableau([[2,0],[3,2]], 3, representation = 'factorized_permutation')
1956
Traceback (most recent call last):
1957
...
1958
ValueError: Error! this only works on type 'A' affine Grassmannian elements
1959
1960
sage: T = WeakTableaux(3, [4,1], [2,1], representation = 'factorized_permutation')
1961
sage: t = T([[2],[1],[0]])
1962
Traceback (most recent call last):
1963
...
1964
ValueError: The weight of the parent does not agree with the weight of the tableau!
1965
"""
1966
weight = tuple(self[i].length() for i in range(len(self)-1,-1,-1))
1967
if not self.parent()._weight == weight:
1968
raise ValueError("The weight of the parent does not agree with the weight of the tableau!")
1969
W = self[0].parent()
1970
outer = (W.prod(self)*W((self._inner_shape).to_grassmannian())).affine_grassmannian_to_core()
1971
if self.parent()._outer_shape != outer:
1972
raise ValueError("The outer shape of the parent does not agree with the outer shape of the tableau!")
1973
if not self._is_k_tableau():
1974
raise ValueError("This is not a proper weak %s-tableau"%(self.k))
1975
1976
def _is_k_tableau(self):
1977
r"""
1978
Checks whether ``self`` is a valid weak `k`-tableau.
1979
1980
EXAMPLES::
1981
1982
sage: t = WeakTableau([[2],[0,3],[2,1,0]], 3, representation = 'factorized_permutation')
1983
sage: t._is_k_tableau()
1984
True
1985
1986
sage: t = WeakTableau([[2,0],[3,2]], 3, inner_shape = [2], representation = 'factorized_permutation')
1987
sage: t._is_k_tableau()
1988
True
1989
"""
1990
W = self[0].parent()
1991
if (W.prod(self)*W(self.parent()._inner_shape.to_grassmannian())).is_affine_grassmannian():
1992
return all( r.is_pieri_factor() for r in self )
1993
return False
1994
1995
def to_core_tableau(self):
1996
r"""
1997
Return the weak `k`-tableau ``self`` where the shape of each restricted tableau is a `(k+1)`-core.
1998
1999
EXAMPLES::
2000
2001
sage: t = WeakTableau([[0], [3,1], [2,1], [0,4], [3,0], [4,2], [1,0]], 4, representation = 'factorized_permutation'); t
2002
[s0, s3*s1, s2*s1, s0*s4, s3*s0, s4*s2, s1*s0]
2003
sage: c = t.to_core_tableau(); c
2004
[[1, 1, 2, 3, 4, 4, 5, 5, 6], [2, 3, 5, 5, 6], [3, 4, 7], [5, 6], [6], [7]]
2005
sage: type(c)
2006
<class 'sage.combinat.k_tableau.WeakTableaux_core_with_category.element_class'>
2007
sage: t = WeakTableau([[]], 4, representation = 'factorized_permutation'); t
2008
[1]
2009
sage: t.to_core_tableau()
2010
[]
2011
2012
sage: from sage.combinat.k_tableau import WeakTableau_factorized_permutation
2013
sage: t = WeakTableau([[2,0],[3,2],[1,0]], 3, representation = 'factorized_permutation')
2014
sage: WeakTableau_factorized_permutation.from_core_tableau(t.to_core_tableau(), 3)
2015
[s2*s0, s3*s2, s1*s0]
2016
sage: t == WeakTableau_factorized_permutation.from_core_tableau(t.to_core_tableau(), 3)
2017
True
2018
2019
sage: t = WeakTableau([[2,0],[3,2]], 3, inner_shape = [2], representation = 'factorized_permutation')
2020
sage: t.to_core_tableau()
2021
[[None, None, 1, 1, 2], [1, 2], [2]]
2022
sage: t == WeakTableau_factorized_permutation.from_core_tableau(t.to_core_tableau(), 3)
2023
True
2024
"""
2025
W = self[0].parent()
2026
factor = W(self._inner_shape.to_grassmannian())
2027
shapes = [factor]
2028
for i in range(len(self)-1,-1,-1):
2029
factor = self[i]*factor
2030
shapes += [factor.affine_grassmannian_to_core()]
2031
if self.parent()._skew:
2032
l = [[None]*i for i in self._inner_shape]
2033
else:
2034
l = []
2035
for i in range(1,len(shapes)):
2036
p = shapes[i]
2037
if len(l) < len(p):
2038
l += [[]]
2039
l_new = []
2040
for j in range(len(l)):
2041
l_new += [l[j] + [i]*(p[j]-len(l[j]))]
2042
l = l_new
2043
return WeakTableau_core(l, self.k)
2044
2045
@classmethod
2046
def from_core_tableau(cls, t, k):
2047
r"""
2048
Construct weak factorized affine permutation tableau from a `k`-core tableau.
2049
2050
EXAMPLES::
2051
2052
sage: from sage.combinat.k_tableau import WeakTableau_factorized_permutation
2053
sage: WeakTableau_factorized_permutation.from_core_tableau([[1, 1, 2, 2, 3], [2, 3], [3]],3)
2054
[s2*s0, s3*s2, s1*s0]
2055
sage: WeakTableau_factorized_permutation.from_core_tableau([[1, 1, 2, 3, 4, 4, 5, 5, 6], [2, 3, 5, 5, 6], [3, 4, 7], [5, 6], [6], [7]], 4)
2056
[s0, s3*s1, s2*s1, s0*s4, s3*s0, s4*s2, s1*s0]
2057
sage: WeakTableau_factorized_permutation.from_core_tableau([[None, 1, 1, 2, 2], [None, 2], [1]], 3)
2058
[s0*s3, s2*s1]
2059
"""
2060
t = SkewTableau(list(t))
2061
shapes = [ Core(p, k+1).to_grassmannian() for p in intermediate_shapes(t) ] #t.to_chain() ]
2062
perms = [ shapes[i]*(shapes[i-1].inverse()) for i in range(len(shapes)-1,0,-1)]
2063
return cls(perms, k, inner_shape = t.inner_shape())
2064
2065
def k_charge(self, algorithm = 'I'):
2066
r"""
2067
Return the `k`-charge of ``self``.
2068
2069
OUTPUT:
2070
2071
- a nonnegative integer
2072
2073
EXAMPLES::
2074
2075
sage: t = WeakTableau([[2,0],[3,2],[1,0]], 3, representation = 'factorized_permutation')
2076
sage: t.k_charge()
2077
2
2078
sage: t = WeakTableau([[0],[3],[2],[1],[3],[0]], 3, representation = 'factorized_permutation')
2079
sage: t.k_charge()
2080
8
2081
sage: t = WeakTableau([[0],[3,1],[2,1],[0,4],[3,0],[4,2],[1,0]], 4, representation = 'factorized_permutation')
2082
sage: t.k_charge()
2083
12
2084
"""
2085
return self.to_core_tableau().k_charge(algorithm = algorithm)
2086
2087
2088
class WeakTableaux_factorized_permutation(WeakTableaux_abstract):
2089
r"""
2090
The class of (skew) weak `k`-tableaux in the factorized permutation representation of shape ``shape`` (as `k+1`-core
2091
or tuple of `(k+1)`-cores in the skew case) and weight ``weight``.
2092
2093
INPUT:
2094
2095
- ``k`` -- positive integer
2096
- ``shape`` -- the shape of the `k`-tableaux represented as a `(k+1)`-core;
2097
in the skew case the shape is a tuple of the outer and inner shape both as `(k+1)`-cores
2098
- ``weight`` -- the weight of the `k`-tableaux
2099
2100
EXAMPLES::
2101
2102
sage: T = WeakTableaux(3, [4,1], [2,2], representation = 'factorized_permutation')
2103
sage: T.list()
2104
[[s3*s2, s1*s0]]
2105
2106
sage: T = WeakTableaux(4, [[6,2,1], [2]], [2,1,1,1], representation = 'factorized_permutation')
2107
sage: T.list()
2108
[[s0, s4, s3, s4*s2], [s0, s3, s4, s3*s2], [s3, s0, s4, s3*s2]]
2109
"""
2110
@staticmethod
2111
def __classcall_private__(cls, k, shape, weight):
2112
r"""
2113
Straighten arguments before unique representation.
2114
2115
TESTS::
2116
2117
sage: from sage.combinat.k_tableau import WeakTableaux_factorized_permutation
2118
sage: T = WeakTableaux_factorized_permutation(3, [2,1], [1,1,1])
2119
sage: TestSuite(T).run()
2120
sage: T = WeakTableaux_factorized_permutation(4, [[6,2,1], [2]], [2,1,1,1])
2121
sage: TestSuite(T).run()
2122
"""
2123
if shape == [] or shape[0] in ZZ:
2124
shape = (Core(shape, k+1), Core([],k+1))
2125
else:
2126
shape = tuple([Core(r,k+1) for r in shape])
2127
return super(WeakTableaux_factorized_permutation, cls).__classcall__(cls, k, shape, tuple(weight))
2128
2129
def __init__(self, k, shape, weight):
2130
r"""
2131
Initializes the parent class of weak `k`-tableaux in factorized permutation representation.
2132
2133
INPUT:
2134
2135
- ``k`` -- positive integer
2136
- ``shape`` -- the shape of the `k`-tableaux represented as a `(k+1)`-core;
2137
in the skew case the shape is a tuple of the outer and inner shape both as
2138
`(k+1)`-cores
2139
- ``weight`` -- the weight of the `k`-tableaux
2140
2141
TESTS::
2142
2143
sage: from sage.combinat.k_tableau import WeakTableaux_factorized_permutation
2144
sage: T = WeakTableaux_factorized_permutation(3, [4,1], [2,2])
2145
sage: TestSuite(T).run()
2146
sage: T = WeakTableaux_factorized_permutation(4, [[6,2,1], [2]], [2,1,1,1])
2147
sage: TestSuite(T).run()
2148
"""
2149
self.k = k
2150
self._skew = shape[1]!=[]
2151
self._outer_shape = Core(shape[0], k+1)
2152
self._inner_shape = Core(shape[1], k+1)
2153
self._shape = (self._outer_shape, self._inner_shape)
2154
self._weight = weight
2155
self._representation = 'factorized_permutation'
2156
Parent.__init__(self, category = FiniteEnumeratedSets())
2157
2158
def _repr_(self):
2159
"""
2160
TESTS::
2161
2162
sage: from sage.combinat.k_tableau import WeakTableaux_factorized_permutation
2163
sage: repr(WeakTableaux_factorized_permutation(3, [2,1], [1,1,1]))
2164
'Factorized permutation (skew) weak 3-Tableaux of shape [2, 1] and weight (1, 1, 1)'
2165
sage: repr(WeakTableaux_factorized_permutation(4, [[6,2,1], [2]], [2,1,1,1]))
2166
'Factorized permutation (skew) weak 4-Tableaux of shape ([6, 2, 1], [2]) and weight (2, 1, 1, 1)'
2167
"""
2168
return "Factorized permutation (skew) weak %s-Tableaux of shape %s and weight %s"%(self.k, self.shape(), self._weight)
2169
2170
def __iter__(self):
2171
r"""
2172
TESTS::
2173
2174
sage: T = WeakTableaux(3, [4,1], [2,2], representation = 'factorized_permutation')
2175
sage: T.list()
2176
[[s3*s2, s1*s0]]
2177
sage: T = WeakTableaux(3, [5,2,2], [2,2,2,1], representation = 'factorized_permutation')
2178
sage: T.list()
2179
[[s0, s3*s2, s0*s3, s1*s0], [s3, s2*s0, s3*s2, s1*s0]]
2180
sage: T = WeakTableaux(4, [[6,2,1], [2]], [2,1,1,1], representation = 'factorized_permutation')
2181
sage: T.list()
2182
[[s0, s4, s3, s4*s2], [s0, s3, s4, s3*s2], [s3, s0, s4, s3*s2]]
2183
"""
2184
for t in WeakTableaux_core(self.k, self.shape(), self._weight):
2185
yield WeakTableau_factorized_permutation.from_core_tableau(t, self.k)
2186
2187
Element = WeakTableau_factorized_permutation
2188
2189
2190
######## END weak tableaux BEGIN strong tableaux
2191
2192
class StrongTableau(ClonableList):
2193
r"""
2194
A (standard) strong `k`-tableau is a (saturated) chain in Bruhat order.
2195
2196
Combinatorially, it is a sequence of embedded `k+1`-cores (subject to some conditions)
2197
together with a set of markings.
2198
2199
A strong cover in terms of cores corresponds to certain translated ribbons. A marking
2200
corresponds to the choice of one of the translated ribbons, which is indicated by
2201
marking the head (southeast most cell in French notation) of the chosen ribbon. For
2202
more information, see [LLMS2006]_ and [LLMSSZ2013]_.
2203
2204
In Sage, a strong `k`-tableau is created by specifying `k`, a standard strong
2205
tableau together with its markings, and a weight `\mu`. Here the standard tableau is
2206
represented by a sequence of `k+1`-cores
2207
2208
.. MATH::
2209
2210
\lambda^{(0)} \subseteq \lambda^{(1)} \subseteq \cdots \subseteq \lambda^{(m)}
2211
2212
where each of the `\lambda^{(i)}` is a `k+1`-core. The standard tableau is a filling
2213
of the diagram for the core `\lambda^{(m)}/\lambda^{(0)}` where a strong cover
2214
is represented by letters `\pm i` in the skew shape `\lambda^{(i)}/\lambda^{(i-1)}`.
2215
Each skew `(k+1)`-core `\lambda^{(i)}/\lambda^{(i-1)}` is a ribbon or multiple
2216
copies of the same ribbon which are separated by `k+1` diagonals. Precisely one of
2217
the copies of the ribbons will be marked in the largest diagonal of the connected
2218
component (the 'head' of the ribbon). The marked cells are indicated by negative
2219
signs.
2220
2221
The strong tableau is stored as a standard strong marked tableau (referred to as the
2222
standard part of the strong tableau) and a vector representing the weight.
2223
2224
EXAMPLES::
2225
2226
sage: StrongTableau( [[-1, -2, -3], [3]], 2, [3] )
2227
[[-1, -1, -1], [1]]
2228
sage: StrongTableau([[-1,-2,-4,-7],[-3,6,-6,8],[4,7],[-5,-8]], 3, [2,2,3,1])
2229
[[-1, -1, -2, -3], [-2, 3, -3, 4], [2, 3], [-3, -4]]
2230
2231
Alternatively, the strong `k`-tableau can also be entered directly in semistandard
2232
format and then the standard tableau and the weight are computed and stored::
2233
2234
sage: T = StrongTableau([[-1,-1,-1],[1]], 2); T
2235
[[-1, -1, -1], [1]]
2236
sage: T.to_standard_list()
2237
[[-1, -2, -3], [3]]
2238
sage: T.weight()
2239
(3,)
2240
sage: T = StrongTableau([[-1, -1, -2, -3], [-2, 3, -3, 4], [2, 3], [-3, -4]], 3); T
2241
[[-1, -1, -2, -3], [-2, 3, -3, 4], [2, 3], [-3, -4]]
2242
sage: T.to_standard_list()
2243
[[-1, -2, -4, -7], [-3, 6, -6, 8], [4, 7], [-5, -8]]
2244
sage: T.weight()
2245
(2, 2, 3, 1)
2246
"""
2247
2248
def __init__(self, parent, T):
2249
"""
2250
INPUT:
2251
2252
- ``parent`` - an instance of ``StrongTableaux``
2253
- ``T`` -- standard marked strong (possibly skew) `k`-tableau or a semistandard
2254
marked strong (possibly skew) `k`-tableau with inner cells represented by
2255
``None``
2256
2257
EXAMPLES::
2258
2259
sage: T = StrongTableau( [[-1, -2, -3]], 3 ); T
2260
[[-1, -2, -3]]
2261
sage: T
2262
[[-1, -2, -3]]
2263
sage: T.weight()
2264
(1, 1, 1)
2265
sage: T.size()
2266
3
2267
sage: T.parent()
2268
Set of strong 3-tableaux of shape [3] and of weight (1, 1, 1)
2269
sage: StrongTableau( [[-1, -2, -3], [3]], 2 )
2270
[[-1, -2, -3], [3]]
2271
sage: StrongTableau( [[-1, -1, 2], [-2]], 2 )
2272
[[-1, -1, 2], [-2]]
2273
sage: T = StrongTableau( [[-1, -2, 3], [-3]], 2, weight=[2,1] ); T
2274
[[-1, -1, 2], [-2]]
2275
sage: T = StrongTableau( [[-1, -2, 3], [-3]], 2, weight=[0,2,1] ); T
2276
[[-2, -2, 3], [-3]]
2277
sage: T.weight()
2278
(0, 2, 1)
2279
sage: T.size()
2280
3
2281
sage: T.parent()
2282
Set of strong 2-tableaux of shape [3, 1] and of weight (0, 2, 1)
2283
sage: StrongTableau( [[-1, -2, 3], [-3]], 2, weight=[1,2] )
2284
Traceback (most recent call last):
2285
...
2286
ValueError: The weight=(1, 2) and the markings on the standard tableau=[[-1, -2, 3], [-3]] do not agree.
2287
sage: StrongTableau( [[None, None, -2, -4], [None, None], [-1, -3], [2, 4], [-5], [5], [5], [5]], 4 )
2288
[[None, None, -2, -4], [None, None], [-1, -3], [2, 4], [-5], [5], [5], [5]]
2289
sage: StrongTableau( [[None, None, -2, -4], [None, None], [-1, -3], [2, 4], [-5], [5], [5], [5]], 4, weight=[2,2,1] )
2290
[[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]]
2291
sage: StrongTableau( [[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]], 4)
2292
[[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]]
2293
2294
TESTS::
2295
2296
sage: T = StrongTableau([], 3); T
2297
[]
2298
sage: T.weight()
2299
()
2300
sage: T.parent()
2301
Set of strong 3-tableaux of shape [] and of weight ()
2302
sage: T = StrongTableau( [[None, None], [None, None]], 4, weight=() ); T
2303
[[None, None], [None, None]]
2304
sage: T.size()
2305
0
2306
"""
2307
self.k = parent.k
2308
self._tableau = T
2309
ClonableList.__init__(self, parent, T)
2310
2311
__metaclass__ = ClasscallMetaclass
2312
2313
@staticmethod
2314
def __classcall_private__(cls, T, k, weight=None):
2315
r"""
2316
Straighten input and implement the shortcut ``StrongTableau(T, k, weight=None)``
2317
to ``StrongTableaux(k, shape, weight)(T)``.
2318
2319
TESTS::
2320
2321
sage: t = StrongTableau( [[-1, -2, -3]], 3 )
2322
sage: t.parent()
2323
Set of strong 3-tableaux of shape [3] and of weight (1, 1, 1)
2324
sage: TestSuite(t).run()
2325
sage: t = StrongTableau( [[-1, -2, 3], [-3]], 2, weight=[2,1] )
2326
sage: TestSuite(t).run()
2327
sage: StrongTableau([[-1,-1,-1]], 3)
2328
[[-1, -1, -1]]
2329
sage: StrongTableau([[None, None, None], [None]], 2)
2330
[[None, None, None], [None]]
2331
2332
sage: StrongTableau([[-1, -2, -2], [1]], 2)
2333
Traceback (most recent call last):
2334
...
2335
ValueError: Unable to parse strong marked tableau : [[-1, -2, -2], [1]]
2336
2337
sage: StrongTableau([[-1,-1,-1,-1]], 3)
2338
Traceback (most recent call last):
2339
...
2340
ValueError: [4] is not a 4-core
2341
2342
sage: StrongTableau([[-1, -2], [2]], 3)
2343
Traceback (most recent call last):
2344
...
2345
ValueError: The marks in [[-1, -2], [2]] are not correctly placed.
2346
2347
sage: StrongTableau([[None, None, None], [None]], 3)
2348
Traceback (most recent call last):
2349
...
2350
ValueError: [3, 1] is not a 4-core
2351
2352
sage: StrongTableau([[None, -1, 2], [-2]], 2, [2])
2353
Traceback (most recent call last):
2354
...
2355
ValueError: The weight=(2,) and the markings on the standard tableau=[[None, -1, 2], [-2]] do not agree.
2356
"""
2357
if isinstance(T, cls):
2358
return T
2359
outer_shape = Core(map(len, T),k+1)
2360
inner_shape = Core(filter(lambda x: x>0, [row.count(None) for row in T]), k+1)
2361
Te = [v for row in T for v in row if v is not None]+[0]
2362
count_marks = tuple([Te.count(-(i+1)) for i in range(-min(Te))])
2363
if not all( v==1 for v in count_marks ):
2364
# if T is not standard -> turn into standard
2365
if weight is not None and tuple(weight)!=count_marks:
2366
raise ValueError("Weight = %s and tableau = %s do not agree"%(weight, T))
2367
tijseq = StrongTableaux.marked_CST_to_transposition_sequence(T, k)
2368
if len(tijseq)<sum(list(count_marks)):
2369
raise ValueError("Unable to parse strong marked tableau : %s"%T)
2370
T = StrongTableaux.transpositions_to_standard_strong( tijseq, k, [[None]*r for r in inner_shape] ) # build from scratch
2371
T = T.set_weight( count_marks )
2372
return T
2373
else:
2374
if weight is not None:
2375
count_marks = tuple(weight) # in the case that it is standard + weight
2376
return StrongTableaux.__classcall__(StrongTableaux, k, (outer_shape, inner_shape), count_marks)(T)
2377
2378
def check(self):
2379
r"""
2380
Check that ``self`` is a valid strong `k`-tableau.
2381
2382
This function verifies that the outer and inner shape of the parent class is equal to
2383
the outer and inner shape of the tableau, that the tableau portion of ``self`` is
2384
a valid standard tableau, that the marks are placed correctly and that the size
2385
and weight agree.
2386
2387
EXAMPLES::
2388
2389
sage: T = StrongTableau([[-1, -1, -2], [2]], 2)
2390
sage: T.check()
2391
sage: T = StrongTableau([[None, None, 2, -4, -4], [-1, 4], [-2]], 3)
2392
sage: T.check()
2393
2394
TESTS::
2395
2396
sage: ST = StrongTableaux(2, [3,1], [1,1,1,1])
2397
sage: ST([[-1,-2,3],[-3]])
2398
Traceback (most recent call last):
2399
...
2400
ValueError: The size of the tableau [[-1, -2, 3], [-3]] and weight (1, 1, 1, 1) do not match
2401
sage: ST([[-1,-3],[-2],[3]])
2402
Traceback (most recent call last):
2403
...
2404
ValueError: The outer shape of the parent does not agree with the outer shape of the tableau!
2405
2406
sage: StrongTableau([[-1, -2, 2], [1]], 2)
2407
Traceback (most recent call last):
2408
...
2409
ValueError: The marks in [[-1, -2, 2], [1]] are not correctly placed.
2410
2411
sage: StrongTableau([[-1, -2, 3], [3]], 2)
2412
Traceback (most recent call last):
2413
...
2414
ValueError: The marks in [[-1, -2, 3], [3]] are not correctly placed.
2415
2416
sage: StrongTableau([[-1,-2,-4,7],[-3,6,-6,8],[4,-7],[-5,-8]], 3, [2,2,3,1])
2417
Traceback (most recent call last):
2418
...
2419
ValueError: The weight=(2, 2, 3, 1) and the markings on the standard tableau=[[-1, -2, -4, 7], [-3, 6, -6, 8], [4, -7], [-5, -8]] do not agree.
2420
"""
2421
T = SkewTableau(self.to_standard_list())
2422
outer = Core(T.outer_shape(),self.k+1)
2423
inner = Core(T.inner_shape(),self.k+1)
2424
if self.parent()._outer_shape != outer:
2425
raise ValueError("The outer shape of the parent does not agree with the outer shape of the tableau!")
2426
if self.parent()._inner_shape != inner:
2427
raise ValueError("The inner shape of the parent does not agree with the inner shape of the tableau!")
2428
if not self._is_valid_marked():
2429
raise ValueError("The marks in %s are not correctly placed."%(self.to_standard_list()))
2430
if not self._is_valid_standard():
2431
raise ValueError("At least one shape in %s is not a valid %s-core."%(self.to_standard_list(), self.k+1))
2432
if not self.outer_shape().length()-self.inner_shape().length()==self.size():
2433
raise ValueError("The size of the tableau %s and weight %s do not match"%(self.to_standard_list(),self.weight()))
2434
if not self.is_column_strict_with_weight( self.weight() ):
2435
raise ValueError("The weight=%s and the markings on the standard tableau=%s do not agree."%(self.weight(),self.to_standard_list()))
2436
2437
def _is_valid_marked( self ):
2438
r"""
2439
Check the validity of marks of a potential tableau ``self``.
2440
2441
This method is called by method :meth:`check` and is not meant to be
2442
accessed by the user.
2443
2444
This method first checks that there is one marked cell for the size of the
2445
tableau. Then, for each marked cell, it verifies that the cell below and to the
2446
right is not a positive value.
2447
2448
In other words this checks that the marked cells are at the head of the connected
2449
components. This function verifies that the markings of ``self`` are
2450
consistent with a strong marked standard tableau.
2451
2452
INPUT:
2453
2454
- ``self`` -- a list of lists representing a potential *standard* marked tableau
2455
2456
OUTPUT:
2457
2458
- a boolean, ``True`` if the marks are properly placed in the tableau
2459
2460
EXAMPLES::
2461
2462
sage: all( T._is_valid_marked() for T in StrongTableaux.standard_marked_iterator(3, 6))
2463
True
2464
sage: StrongTableau([[-1,-2,-4,-7],[-3,6,-6,8],[4,7],[-5,-8]], 3)._is_valid_marked()
2465
True
2466
sage: StrongTableau([[-1, -2, 3], [3]], 2)
2467
Traceback (most recent call last):
2468
...
2469
ValueError: The marks in [[-1, -2, 3], [3]] are not correctly placed.
2470
2471
Marking in the wrong place::
2472
2473
sage: StrongTableau([[None, None, -4, 5, -5], [None, None], [-1, -3], [2], [-2], [2], [3]], 4)
2474
Traceback (most recent call last):
2475
...
2476
ValueError: The marks in [[None, None, -4, 5, -5], [None, None], [-1, -3], [2], [-2], [2], [3]] are not correctly placed.
2477
2478
No marking on a 2::
2479
2480
sage: StrongTableau([[None, None, -4, 5, -5], [None, None], [-1, -3], [2], [2], [2], [3]], 4)
2481
Traceback (most recent call last):
2482
...
2483
ValueError: Unable to parse strong marked tableau : [[None, None, -4, 5, -5], [None, None], [-1, -3], [2], [2], [2], [3]]
2484
2485
TESTS::
2486
2487
sage: StrongTableau([[None, None, None], [None]], 2)._is_valid_marked()
2488
True
2489
sage: StrongTableau([], 4)._is_valid_marked()
2490
True
2491
"""
2492
T = self.to_standard_list()
2493
size = Core(map(len,T), self.k+1).length()
2494
inner_size = Core(map(len,filter(lambda y: len(y)>0, map(lambda row: filter(lambda x: x==None, row ), T))),self.k+1).length()
2495
if len(uniq([v for v in flatten(list(T)) if v in ZZ and v<0]))!=size-inner_size:
2496
return False # TT does not have exactly self.size() marked cells
2497
for i in range(len(T)):
2498
for j in range(len(T[i])):
2499
v = T[i][j]
2500
if v!=None and v<0 and ((i!=0 and T[i-1][j]==abs(v)) or (j<len(T[i])-1 and T[i][j+1]==abs(v))):
2501
return False
2502
return True
2503
2504
def _is_valid_standard( self ):
2505
r"""
2506
Test if ``self`` has a valid strong (un)marked standard part of the tableau.
2507
2508
This method is called by method :meth:`check` and is not meant to be
2509
accessed by the user.
2510
2511
This methods returns ``True`` if every intermediate shape (restricted to values
2512
less than or equal to `i` for each `i`) is a `k+1`-core and that the length
2513
of the `i+1`-restricted core is the length of the `i`-restricted core plus 1.
2514
2515
OUTPUT:
2516
2517
- a boolean, ``True`` means the standard strong marked tableau is valid
2518
2519
EXAMPLES::
2520
2521
sage: all( T._is_valid_standard() for T in StrongTableaux.standard_marked_iterator(4, 6))
2522
True
2523
2524
Inner shape is not a a 3-core::
2525
2526
sage: StrongTableau([[None, None, None], [-1]], 2)
2527
Traceback (most recent call last):
2528
...
2529
ValueError: [3] is not a 3-core
2530
2531
Restrict to 1 and 2 is not a 5-core::
2532
2533
sage: StrongTableau([[None, None, -4, 5, -5], [None, None], [-1, -3], [-2], [2], [3], [3]], 4)
2534
Traceback (most recent call last):
2535
...
2536
ValueError: At least one shape in [[None, None, -4, 5, -5], [None, None], [-1, -3], [-2], [2], [3], [3]] is not a valid 5-core.
2537
2538
TESTS::
2539
2540
sage: StrongTableau([[None, None, None], [None]], 2)._is_valid_standard()
2541
True
2542
sage: StrongTableau([], 4)._is_valid_standard()
2543
True
2544
"""
2545
Tshapes = intermediate_shapes(self.to_unmarked_standard_list())
2546
if not all( Partition(la).is_core(self.k+1) for la in Tshapes):
2547
return False
2548
Tsizes =[Core(lam, self.k+1).length() for lam in Tshapes]
2549
return all(Tsizes[i]==Tsizes[i+1]-1 for i in range(len(Tsizes)-1))
2550
2551
def is_column_strict_with_weight( self, mu ):
2552
"""
2553
Test if ``self`` is a column strict tableau with respect to the weight ``mu``.
2554
2555
INPUT:
2556
2557
- ``mu`` -- a vector of weights
2558
2559
OUTPUT:
2560
2561
- a boolean, ``True`` means the underlying column strict strong marked tableau is valid
2562
2563
EXAMPLES::
2564
2565
sage: StrongTableau([[-1, -2, -3], [3]], 2).is_column_strict_with_weight([3])
2566
True
2567
sage: StrongTableau([[-1, -2, 3], [-3]], 2).is_column_strict_with_weight([3])
2568
False
2569
2570
TESTS::
2571
2572
sage: StrongTableau([[None, None, None], [None]], 2).is_column_strict_with_weight([])
2573
True
2574
sage: StrongTableau([], 4).is_column_strict_with_weight([])
2575
True
2576
"""
2577
ss = 0
2578
for i in range(len(mu)):
2579
for j in range(mu[i]-1):
2580
# the markings should move from left to right
2581
if self.content_of_marked_head( ss+j+1 ) >= self.content_of_marked_head( ss+j+2 ):
2582
return False
2583
ss += mu[i]
2584
return True
2585
2586
def _repr_diagram(self):
2587
r"""
2588
Return a string representing the pretty print of the tableau.
2589
2590
EXAMPLES::
2591
2592
sage: StrongTableau([[-1,-2,-4,-7],[-3,6,-6,8],[4,7],[-5,-8]], 3, [2,2,3,1])._repr_diagram()
2593
' -1 -1 -2 -3\n -2 3 -3 4\n 2 3\n -3 -4'
2594
sage: StrongTableau([[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]], 4)._repr_diagram()
2595
' . . -1 -2\n . .\n -1 -2\n 1 2\n -3\n 3\n 3\n 3'
2596
sage: StrongTableau([], 4)._repr_diagram()
2597
''
2598
"""
2599
return SkewTableau(self.to_list())._repr_diagram()
2600
2601
def _repr_list(self):
2602
r"""
2603
Return a string representing the list of lists of the tableau.
2604
2605
EXAMPLES::
2606
2607
sage: StrongTableau([[-1,-2,-4,-7],[-3,6,-6,8],[4,7],[-5,-8]], 3, [2,2,3,1])._repr_list()
2608
'[[-1, -1, -2, -3], [-2, 3, -3, 4], [2, 3], [-3, -4]]'
2609
sage: StrongTableau([[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]], 4)._repr_list()
2610
'[[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]]'
2611
sage: StrongTableau([], 4)._repr_list()
2612
'[]'
2613
"""
2614
return repr(self.to_list())
2615
2616
def _repr_compact(self):
2617
"""
2618
Return a compact string representation of ``self``.
2619
2620
EXAMPLES::
2621
2622
sage: StrongTableau([[-1,-2,-4,-7],[-3,6,-6,8],[4,7],[-5,-8]], 3, [2,2,3,1])._repr_compact()
2623
'-1,-1,-2,-3/-2,3,-3,4/2,3/-3,-4'
2624
sage: StrongTableau([[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]], 4)._repr_compact()
2625
'.,.,-1,-2/.,./-1,-2/1,2/-3/3/3/3'
2626
sage: StrongTableau([],4)._repr_compact()
2627
'-'
2628
"""
2629
return SkewTableau(self.to_list())._repr_compact()
2630
2631
def _repr_(self):
2632
r"""
2633
Return a representation of ``self``.
2634
2635
To display a strong marked tableau we display the semistandard version.
2636
2637
EXAMPLES::
2638
2639
sage: StrongTableau( [[-1, -2, -3]], 3 )
2640
[[-1, -2, -3]]
2641
sage: StrongTableau( [[-1, -2, -3]], 3 , weight=[3])
2642
[[-1, -1, -1]]
2643
sage: StrongTableau( [], 3 )
2644
[]
2645
sage: T = StrongTableau([[-1,-2,3],[-3]],2)
2646
sage: T
2647
[[-1, -2, 3], [-3]]
2648
sage: Tableaux.global_options(display="diagram")
2649
sage: T
2650
-1 -2 3
2651
-3
2652
sage: Tableaux.global_options(convention="French")
2653
sage: T
2654
-3
2655
-1 -2 3
2656
sage: Tableaux.global_options(display="compact")
2657
sage: T
2658
-1,-2,3/-3
2659
sage: Tableaux.global_options(display="list",convention="English")
2660
"""
2661
return self.parent().global_options.dispatch(self, '_repr_', 'display')
2662
2663
def cell_of_marked_head(self, v):
2664
r"""
2665
Return location of marked head labeled by ``v`` in the standard part of ``self``.
2666
2667
Return the coordinates of the ``v``-th marked cell in the strong standard tableau
2668
``self``. If there is no mark, then the value returned is `(0, r)` where `r` is
2669
the length of the first row.
2670
2671
INPUT:
2672
2673
- ``v`` -- an integer representing the label in the standard tableau
2674
2675
OUTPUT:
2676
2677
- a pair of the coordinates of the marked cell with entry ``v``
2678
2679
EXAMPLES::
2680
2681
sage: T = StrongTableau([[-1, -3, 4, -5], [-2], [-4]], 3)
2682
sage: [ T.cell_of_marked_head(i) for i in range(1,7)]
2683
[(0, 0), (1, 0), (0, 1), (2, 0), (0, 3), (0, 4)]
2684
sage: T = StrongTableau([[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]], 4)
2685
sage: [ T.cell_of_marked_head(i) for i in range(1,7)]
2686
[(2, 0), (0, 2), (2, 1), (0, 3), (4, 0), (0, 4)]
2687
2688
TESTS::
2689
2690
sage: StrongTableau([],4).cell_of_marked_head(4)
2691
(0, 0)
2692
"""
2693
T = self.to_standard_list()
2694
if T==[]:
2695
return (0,0)
2696
for i in range(len(T)):
2697
for j in range(len(T[i])):
2698
if T[i][j]==-v:
2699
return (i,j)
2700
return (0,len(T[0]))
2701
2702
def content_of_marked_head(self, v):
2703
r"""
2704
Return the diagonal of the marked label ``v`` in the standard part of ``self``.
2705
2706
Return the content (the `j-i` coordinate of the cell) of the ``v``-th marked cell
2707
in the strong standard tableau ``self``. If there is no mark, then the value
2708
returned is the size of first row.
2709
2710
INPUT:
2711
2712
- ``v`` -- an integer representing the label in the standard tableau
2713
2714
OUTPUT:
2715
2716
- an integer representing the residue of the location of the mark
2717
2718
EXAMPLES::
2719
2720
sage: [ StrongTableau([[-1, -3, 4, -5], [-2], [-4]], 3).content_of_marked_head(i) for i in range(1,7)]
2721
[0, -1, 1, -2, 3, 4]
2722
sage: T = StrongTableau([[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]], 4)
2723
sage: [ T.content_of_marked_head(i) for i in range(1,7)]
2724
[-2, 2, -1, 3, -4, 4]
2725
2726
TESTS::
2727
2728
sage: StrongTableau([],4).content_of_marked_head(4)
2729
0
2730
"""
2731
c = self.cell_of_marked_head(v)
2732
return c[1]-c[0]
2733
2734
def cells_of_marked_ribbon(self, v):
2735
r"""
2736
Return a list of all cells the marked ribbon labeled by ``v`` in the standard part of ``self``.
2737
2738
Return the list of coordinates of the cells which are in the marked
2739
ribbon with label ``v`` in the standard part of the tableau. Note that
2740
the result is independent of the weight of the tableau.
2741
2742
The cells are listed from largest content (where the mark is located)
2743
to the smallest. Hence, the first entry in this list will be the marked cell.
2744
2745
INPUT:
2746
2747
- ``v`` -- the entry of the standard tableau
2748
2749
OUTPUT:
2750
2751
- a list of pairs representing the coordinates of the cells of
2752
the marked ribbon
2753
2754
EXAMPLES::
2755
2756
sage: T = StrongTableau([[-1, -1, -2, -2, 3], [2, -3], [-3]],3)
2757
sage: T.to_standard_list()
2758
[[-1, -2, -3, -4, 6], [4, -6], [-5]]
2759
sage: T.cells_of_marked_ribbon(1)
2760
[(0, 0)]
2761
sage: T.cells_of_marked_ribbon(4)
2762
[(0, 3)]
2763
sage: T = StrongTableau([[-1,-2,-4,-7],[-3,6,-6,8],[4,7],[-5,-8]], 3)
2764
sage: T.cells_of_marked_ribbon(6)
2765
[(1, 2), (1, 1)]
2766
sage: T.cells_of_marked_ribbon(9)
2767
[]
2768
sage: T = StrongTableau([[None, None, -1, -1, 3], [1, -3], [-3]],3)
2769
sage: T.to_standard_list()
2770
[[None, None, -1, -2, 4], [2, -4], [-3]]
2771
sage: T.cells_of_marked_ribbon(1)
2772
[(0, 2)]
2773
2774
TESTS::
2775
2776
sage: StrongTableau([],3).cells_of_marked_ribbon(1)
2777
[]
2778
"""
2779
d = self.content_of_marked_head(v)
2780
T = SkewTableau(self.to_unmarked_standard_list())
2781
cells = []
2782
while d is not None:
2783
adt=[c for c in T.cells_by_content(d) if T[c[0]][c[1]]==v]
2784
if adt==[]:
2785
d = None
2786
else:
2787
d -= 1
2788
cells += adt
2789
return cells
2790
2791
def cell_of_highest_head( self, v ):
2792
"""
2793
Return the cell of the highest head of label ``v`` in the standard part of ``self``.
2794
2795
Return the cell where the head of the ribbon in the highest row is located
2796
in the underlying standard tableau. If there is no cell with entry ``v`` then
2797
the cell returned is `(0, r)` where `r` is the length of the first row.
2798
2799
This cell is calculated by iterating through the diagonals of the tableau.
2800
2801
INPUT:
2802
2803
- ``v`` -- an integer indicating the label in the standard tableau
2804
2805
OUTPUT:
2806
2807
- a pair of integers indicating the coordinates of the head of the highest
2808
ribbon with label ``v``
2809
2810
EXAMPLES::
2811
2812
sage: T = StrongTableau([[-1,2,-3],[-2,3],[3]], 1)
2813
sage: [T.cell_of_highest_head(v) for v in range(1,5)]
2814
[(0, 0), (1, 0), (2, 0), (0, 3)]
2815
sage: T = StrongTableau([[None,None,-3,4],[3,-4]],2)
2816
sage: [T.cell_of_highest_head(v) for v in range(1,5)]
2817
[(1, 0), (1, 1), (0, 4), (0, 4)]
2818
2819
TESTS::
2820
2821
sage: StrongTableau([],2).cell_of_highest_head(1)
2822
(0, 0)
2823
"""
2824
Tlist = SkewTableau(self.to_standard_list())
2825
if Tlist==[]:
2826
return (0, 0)
2827
r = len(Tlist[0])
2828
dout = (0, r)
2829
for d in range(-len(Tlist),r+1):
2830
for c in Tlist.cells_by_content(d):
2831
if nabs(Tlist[c[0]][c[1]])==v:
2832
dout = c
2833
if dout!=(0, r) and dout[1]-dout[0]!=d:
2834
return dout
2835
return dout
2836
2837
def content_of_highest_head( self, v ):
2838
r"""
2839
Return the diagonal of the highest head of the cells labeled ``v`` in the standard part of ``self``.
2840
2841
Return the content of the cell of the head in the highest row of all ribbons labeled by ``v`` of
2842
the underlying standard tableau. If there is no cell with entry ``v`` then
2843
the value returned is the length of the first row.
2844
2845
INPUT:
2846
2847
- ``v`` -- an integer representing the label in the standard tableau
2848
2849
OUTPUT:
2850
2851
- an integer representing the content of the head of the highest
2852
ribbon with label ``v``
2853
2854
EXAMPLES::
2855
2856
sage: [StrongTableau([[-1,2,-3],[-2,3],[3]], 1).content_of_highest_head(v) for v in range(1,5)]
2857
[0, -1, -2, 3]
2858
2859
TESTS::
2860
2861
sage: StrongTableau([], 4).content_of_highest_head(1)
2862
0
2863
sage: StrongTableau([[-1,-1]], 4).content_of_highest_head(3)
2864
2
2865
"""
2866
c = self.cell_of_highest_head(v)
2867
return c[1]-c[0]
2868
2869
def cells_head_dictionary(self):
2870
r"""
2871
Return a dictionary with the locations of the heads of all markings.
2872
2873
Return a dictionary of values and lists of cells where the heads with the values
2874
are located.
2875
2876
OUPUT:
2877
2878
- a dictionary with keys the entries in the tableau and values are the coordinates
2879
of the heads with those entries
2880
2881
EXAMPLES::
2882
2883
sage: T = StrongTableau([[-1,-2,-4,7],[-3,6,-6,8],[4,-7],[-5,-8]], 3)
2884
sage: T.cells_head_dictionary()
2885
{1: [(0, 0)],
2886
2: [(0, 1)],
2887
3: [(1, 0)],
2888
4: [(2, 0), (0, 2)],
2889
5: [(3, 0)],
2890
6: [(1, 2)],
2891
7: [(2, 1), (0, 3)],
2892
8: [(3, 1), (1, 3)]}
2893
sage: T = StrongTableau([[None, 4, -4, -6, -7, 8, 8, -8], [None, -5, 8, 8, 8], [-3, 6]],3)
2894
sage: T.cells_head_dictionary()
2895
{1: [(2, 0)],
2896
2: [(0, 2)],
2897
3: [(1, 1)],
2898
4: [(2, 1), (0, 3)],
2899
5: [(0, 4)],
2900
6: [(1, 4), (0, 7)]}
2901
sage: StrongTableau([[None, None], [None, -1]], 4).cells_head_dictionary()
2902
{1: [(1, 1)]}
2903
2904
TESTS::
2905
2906
sage: StrongTableau([[None, None], [None]], 4).cells_head_dictionary()
2907
{}
2908
sage: StrongTableau([],4).cells_head_dictionary()
2909
{}
2910
"""
2911
return StrongTableaux.cells_head_dictionary(self.to_unmarked_standard_list())
2912
2913
def cells_of_heads(self, v):
2914
r"""
2915
Return a list of cells of the heads with label ``v`` in the standard part of ``self``.
2916
2917
A list of cells which are heads of the ribbons with label ``v`` in the
2918
standard part of the tableau ``self``. If there is no cell labelled by ``v`` then return the empty
2919
list.
2920
2921
INPUT:
2922
2923
- ``v`` -- an integer label
2924
2925
OUPUT:
2926
2927
- a list of pairs of integers of the coordinates of the heads of the ribbons
2928
with label ``v``
2929
2930
EXAMPLES::
2931
2932
sage: T = StrongTableau([[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]], 4)
2933
sage: T.cells_of_heads(1)
2934
[(2, 0)]
2935
sage: T.cells_of_heads(2)
2936
[(3, 0), (0, 2)]
2937
sage: T.cells_of_heads(3)
2938
[(2, 1)]
2939
sage: T.cells_of_heads(4)
2940
[(3, 1), (0, 3)]
2941
sage: T.cells_of_heads(5)
2942
[(4, 0)]
2943
sage: T.cells_of_heads(6)
2944
[]
2945
2946
TESTS::
2947
2948
sage: StrongTableau([[None, None], [None]], 4).cells_of_heads(1)
2949
[]
2950
sage: StrongTableau([],4).cells_of_heads(1)
2951
[]
2952
"""
2953
dout = self.cells_head_dictionary()
2954
if v in dout.keys():
2955
return dout[v]
2956
else:
2957
return []
2958
2959
def contents_of_heads(self, v):
2960
r"""
2961
A list of contents of the cells which are heads of the ribbons with label ``v``.
2962
2963
If there is no cell labelled by ``v`` then return the empty list.
2964
2965
INPUT:
2966
2967
- ``v`` -- an integer label
2968
2969
OUPUT:
2970
2971
- a list of integers of the content of the heads of the ribbons with label ``v``
2972
2973
EXAMPLES::
2974
2975
sage: T = StrongTableau([[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]], 4)
2976
sage: T.contents_of_heads(1)
2977
[-2]
2978
sage: T.contents_of_heads(2)
2979
[-3, 2]
2980
sage: T.contents_of_heads(3)
2981
[-1]
2982
sage: T.contents_of_heads(4)
2983
[-2, 3]
2984
sage: T.contents_of_heads(5)
2985
[-4]
2986
sage: T.contents_of_heads(6)
2987
[]
2988
2989
TESTS::
2990
2991
sage: StrongTableau([[None, None], [None]], 4).contents_of_heads(1)
2992
[]
2993
sage: StrongTableau([],4).contents_of_heads(1)
2994
[]
2995
"""
2996
return [c[1]-c[0] for c in self.cells_of_heads(v)]
2997
2998
def entries_by_content(self, diag):
2999
r"""
3000
Return the entries on the diagonal of ``self``.
3001
3002
Return the entries in the tableau that are in the cells `(i,j)` with
3003
`j-i` equal to ``diag`` (that is, with content equal to ``diag``).
3004
3005
INPUT:
3006
3007
- ``diag`` -- an integer indicating the diagonal
3008
3009
OUTPUT:
3010
3011
- a list (perhaps empty) of labels on the diagonal ``diag``
3012
3013
EXAMPLES::
3014
3015
sage: T = StrongTableau([[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]], 4)
3016
sage: T.entries_by_content(0)
3017
[]
3018
sage: T.entries_by_content(1)
3019
[]
3020
sage: T.entries_by_content(2)
3021
[-1]
3022
sage: T.entries_by_content(-2)
3023
[-1, 2]
3024
3025
TESTS::
3026
3027
sage: StrongTableau([[None, None], [None]], 4).entries_by_content(1)
3028
[]
3029
sage: StrongTableau([],4).entries_by_content(1)
3030
[]
3031
"""
3032
return SkewTableau(self.to_list()).entries_by_content(diag)
3033
3034
def entries_by_content_standard(self, diag):
3035
r"""
3036
Return the entries on the diagonal of the standard part of ``self``.
3037
3038
Return the entries in the tableau that are in the cells `(i,j)` with
3039
`j-i` equal to ``diag`` (that is, with content equal to ``diag``) in the
3040
standard tableau.
3041
3042
INPUT:
3043
3044
- ``diag`` -- an integer indicating the diagonal
3045
3046
OUTPUT:
3047
3048
- a list (perhaps empty) of labels on the diagonal ``diag``
3049
3050
EXAMPLES::
3051
3052
sage: T = StrongTableau([[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]], 4)
3053
sage: T.entries_by_content_standard(0)
3054
[]
3055
sage: T.entries_by_content_standard(1)
3056
[]
3057
sage: T.entries_by_content_standard(2)
3058
[-2]
3059
sage: T.entries_by_content_standard(-2)
3060
[-1, 4]
3061
3062
TESTS::
3063
3064
sage: StrongTableau([[None, None], [None]], 4).entries_by_content_standard(1)
3065
[]
3066
sage: StrongTableau([],4).entries_by_content_standard(1)
3067
[]
3068
"""
3069
return SkewTableau(self.to_standard_list()).entries_by_content(diag)
3070
3071
def ribbons_above_marked(self, v):
3072
r"""
3073
Number of ribbons of label ``v`` higher than the marked ribbon in the standard part.
3074
3075
Return the number of copies of the ribbon with label ``v`` in the standard part
3076
of ``self`` which are in a higher row than the marked ribbon. Note that the result
3077
is independent of the weight of the tableau.
3078
3079
INPUT:
3080
3081
- ``v`` -- the entry of the standard tableau
3082
3083
OUTPUT:
3084
3085
- an integer representing the number of copies of the ribbon above the marked
3086
ribbon
3087
3088
EXAMPLES::
3089
3090
sage: T = StrongTableau([[-1,-2,-4,-7],[-3,6,-6,8],[4,7],[-5,-8]], 3)
3091
sage: T.ribbons_above_marked(4)
3092
1
3093
sage: T.ribbons_above_marked(6)
3094
0
3095
sage: T.ribbons_above_marked(9)
3096
0
3097
sage: StrongTableau([[-1,-2,-3,-4],[2,3,4],[3,4],[4]], 1).ribbons_above_marked(4)
3098
3
3099
3100
TESTS::
3101
3102
sage: StrongTableau([[None, None], [None]], 4).ribbons_above_marked(1)
3103
0
3104
sage: StrongTableau([],4).ribbons_above_marked(1)
3105
0
3106
"""
3107
d = self.content_of_marked_head(v)
3108
count = 0
3109
for i in range(self.k+1, len(self.to_standard_list())+d, self.k+1):
3110
count += int(v in self.entries_by_content_standard(d-i))
3111
return count
3112
3113
def height_of_ribbon(self, v):
3114
r"""
3115
The number of rows occupied by one of the ribbons with label ``v``.
3116
3117
The number of rows occupied by the marked ribbon with label ``v``
3118
(and by consequence the number of rows occupied by any ribbon with the same label)
3119
in the standard part of ``self``.
3120
3121
INPUT:
3122
3123
- ``v`` -- the label of the standard marked tableau
3124
3125
OUTPUT:
3126
3127
- a non-negative integer representing the number of rows
3128
occupied by the ribbon which is marked
3129
3130
EXAMPLES::
3131
3132
sage: T = StrongTableau([[-1, -1, -2, -2, 3], [2, -3], [-3]],3)
3133
sage: T.to_standard_list()
3134
[[-1, -2, -3, -4, 6], [4, -6], [-5]]
3135
sage: T.height_of_ribbon(1)
3136
1
3137
sage: T.height_of_ribbon(4)
3138
1
3139
sage: T = StrongTableau([[None,None,1,-2],[None,-3,4,-5],[-1,3],[-4,5]], 3)
3140
sage: T.height_of_ribbon(3)
3141
2
3142
sage: T.height_of_ribbon(6)
3143
0
3144
3145
TESTS::
3146
3147
sage: StrongTableau([[None, None], [None]], 4).height_of_ribbon(1)
3148
0
3149
sage: StrongTableau([],4).height_of_ribbon(1)
3150
0
3151
"""
3152
return len(uniq([c[0] for c in self.cells_of_marked_ribbon(v)]))
3153
3154
def number_of_connected_components(self, v):
3155
r"""
3156
Number of connected components of ribbons with label ``v`` in the standard part.
3157
3158
The number of connected components is calculated by finding the number of cells
3159
with label ``v`` in the standard part of the tableau and dividing by the number
3160
of cells in the ribbon.
3161
3162
INPUT:
3163
3164
- ``v`` -- the label of the standard marked tableau
3165
3166
OUTPUT:
3167
3168
- a non-negative integer representing the number of connected
3169
components
3170
3171
EXAMPLES::
3172
3173
sage: T = StrongTableau([[-1, -1, -2, -2, 3], [2, -3], [-3]],3)
3174
sage: T.to_standard_list()
3175
[[-1, -2, -3, -4, 6], [4, -6], [-5]]
3176
sage: T.number_of_connected_components(1)
3177
1
3178
sage: T.number_of_connected_components(4)
3179
2
3180
sage: T = StrongTableau([[-1,-2,-4,-7],[-3,6,-6,8],[4,7],[-5,-8]], 3)
3181
sage: T.number_of_connected_components(6)
3182
1
3183
sage: T.number_of_connected_components(9)
3184
0
3185
3186
TESTS::
3187
3188
sage: StrongTableau([[None, None], [None]], 4).number_of_connected_components(1)
3189
0
3190
sage: StrongTableau([],4).number_of_connected_components(1)
3191
0
3192
"""
3193
sz = len(self.cells_of_marked_ribbon(v))
3194
if sz==0:
3195
return 0
3196
T = self.to_standard_list()
3197
nocells = len([i for i in range(len(T)) for j in range(len(T[i])) if T[i][j]==v])+1
3198
return ZZ(nocells/sz)
3199
3200
def intermediate_shapes(self):
3201
r"""
3202
Return the intermediate shapes of ``self``.
3203
3204
A (skew) tableau with letters `1, 2, \ldots, \ell` can be viewed as a sequence of
3205
shapes, where the `i`-th shape is given by the shape of the subtableau on letters
3206
`1, 2, \ldots, i`.
3207
3208
The output is the list of these shapes. The marked cells are ignored so to
3209
recover the strong tableau one would need the intermediate shapes and the
3210
:meth:`content_of_marked_head` for each pair of adjacent shapes in the list.
3211
3212
OUTPUT:
3213
3214
- a list of lists of integers representing `k+1`-cores
3215
3216
EXAMPLES::
3217
3218
sage: T = StrongTableau([[-1,-2,-4,-7],[-3,6,-6,8],[4,7],[-5,-8]], 3, [2,2,3,1])
3219
sage: T.intermediate_shapes()
3220
[[], [2], [3, 1, 1], [4, 3, 2, 1], [4, 4, 2, 2]]
3221
sage: T = StrongTableau([[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]], 4)
3222
sage: T.intermediate_shapes()
3223
[[2, 2], [3, 2, 1, 1], [4, 2, 2, 2], [4, 2, 2, 2, 1, 1, 1, 1]]
3224
3225
TESTS::
3226
3227
sage: StrongTableau([[None, None], [None]], 4).intermediate_shapes()
3228
[[2, 1]]
3229
sage: StrongTableau([],4).intermediate_shapes()
3230
[[]]
3231
"""
3232
return intermediate_shapes(self.to_unmarked_list())
3233
3234
def pp( self ):
3235
r"""
3236
Print the strong tableau ``self`` in pretty print format.
3237
3238
EXAMPLES::
3239
3240
sage: T = StrongTableau([[-1,-2,-4,-7],[-3,6,-6,8],[4,7],[-5,-8]], 3, [2,2,3,1])
3241
sage: T.pp()
3242
-1 -1 -2 -3
3243
-2 3 -3 4
3244
2 3
3245
-3 -4
3246
sage: T = StrongTableau([[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]], 4)
3247
sage: T.pp()
3248
. . -1 -2
3249
. .
3250
-1 -2
3251
1 2
3252
-3
3253
3
3254
3
3255
3
3256
sage: Tableaux.global_options(convention="French")
3257
sage: T.pp()
3258
3
3259
3
3260
3
3261
-3
3262
1 2
3263
-1 -2
3264
. .
3265
. . -1 -2
3266
sage: Tableaux.global_options(convention="English")
3267
"""
3268
print self._repr_diagram()
3269
3270
def outer_shape( self ):
3271
r"""
3272
Return the outer shape of ``self``.
3273
3274
This method returns the outer shape of ``self`` as viewed as a ``Core``.
3275
The outer shape of a strong tableau is always a `(k+1)`-core.
3276
3277
OUTPUT:
3278
3279
- a `(k+1)`-core
3280
3281
EXAMPLES::
3282
3283
sage: StrongTableau([[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]], 4).outer_shape()
3284
[4, 2, 2, 2, 1, 1, 1, 1]
3285
sage: StrongTableau([[-1,-2,-4,-7],[-3,6,-6,8],[4,7],[-5,-8]], 3, [2,2,3,1]).outer_shape()
3286
[4, 4, 2, 2]
3287
3288
TESTS::
3289
3290
sage: StrongTableau([[None, None], [None]], 4).outer_shape()
3291
[2, 1]
3292
sage: StrongTableau([],4).outer_shape()
3293
[]
3294
"""
3295
return self.parent().outer_shape()
3296
3297
def inner_shape( self ):
3298
r"""
3299
Return the inner shape of ``self``.
3300
3301
If ``self`` is a strong skew tableau, then this method returns the inner shape
3302
(the shape of the cells labelled with ``None``).
3303
If ``self`` is not skew, then the inner shape is empty.
3304
3305
OUTPUT:
3306
3307
- a `(k+1)`-core
3308
3309
EXAMPLES::
3310
3311
sage: StrongTableau([[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]], 4).inner_shape()
3312
[2, 2]
3313
sage: StrongTableau([[-1,-2,-4,-7],[-3,6,-6,8],[4,7],[-5,-8]], 3, [2,2,3,1]).inner_shape()
3314
[]
3315
3316
TESTS::
3317
3318
sage: StrongTableau([[None, None], [None]], 4).inner_shape()
3319
[2, 1]
3320
sage: StrongTableau([],4).inner_shape()
3321
[]
3322
"""
3323
return self.parent().inner_shape()
3324
3325
def shape( self ):
3326
r"""
3327
Return the shape of ``self``.
3328
3329
If ``self`` is a skew tableau then return a pair of `k+1`-cores consisting of the
3330
outer and the inner shape. If ``self`` is strong tableau with no inner shape then
3331
return a `k+1`-core.
3332
3333
INPUT:
3334
3335
- ``form`` - optional argument to indicate 'inner', 'outer' or 'skew' (default : 'outer')
3336
3337
OUTPUT:
3338
3339
- a `k+1`-core or a pair of `k+1`-cores if form is not 'inner' or 'outer'
3340
3341
EXAMPLES::
3342
3343
sage: T = StrongTableau([[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]], 4)
3344
sage: T.shape()
3345
([4, 2, 2, 2, 1, 1, 1, 1], [2, 2])
3346
sage: StrongTableau([[-1, -2, 3], [-3]], 2).shape()
3347
[3, 1]
3348
sage: type(StrongTableau([[-1, -2, 3], [-3]], 2).shape())
3349
<class 'sage.combinat.core.Cores_length_with_category.element_class'>
3350
3351
TESTS::
3352
3353
sage: StrongTableau([[None, None, None], [None]], 2).shape()
3354
([3, 1], [3, 1])
3355
sage: StrongTableau([],4).shape()
3356
[]
3357
"""
3358
return self.parent().shape()
3359
3360
def weight( self ):
3361
r"""
3362
Return the weight of the tableau.
3363
3364
The weight is a list of non-negative integers indicating the number of 1s,
3365
number of 2s, number of 3s, etc.
3366
3367
OUTPUT:
3368
3369
- a list of non-negative integers
3370
3371
EXAMPLES::
3372
3373
sage: T = StrongTableau([[-1, -2, -3, 4], [-4], [-5]], 3); T.weight()
3374
(1, 1, 1, 1, 1)
3375
sage: T.set_weight([3,1,1]).weight()
3376
(3, 1, 1)
3377
sage: StrongTableau([[-1,-1,-2,-3],[-2,3,-3,4],[2,3],[-3,-4]], 3).weight()
3378
(2, 2, 3, 1)
3379
3380
TESTS::
3381
3382
sage: StrongTableau([[None, None], [None]], 4).weight()
3383
()
3384
sage: StrongTableau([],4).weight()
3385
()
3386
"""
3387
return self.parent()._weight
3388
3389
def size( self ):
3390
"""
3391
Return the size of the strong tableau.
3392
3393
The size of the strong tableau is the sum of the entries in the
3394
:meth:`weight`. It will also be equal to the length of the
3395
outer shape (as a `k+1`-core) minus the length of the inner shape.
3396
3397
.. SEEALSO:: :meth:`sage.combinat.core.Core.length`
3398
3399
OUTPUT:
3400
3401
- a non-negative integer
3402
3403
EXAMPLES::
3404
3405
sage: StrongTableau([[-1, -2, -3, 4], [-4], [-5]], 3).size()
3406
5
3407
sage: StrongTableau([[None, None, -1, 2], [-2], [-3]], 3).size()
3408
3
3409
3410
TESTS::
3411
3412
sage: StrongTableau([[None, None], [None]], 4).size()
3413
0
3414
sage: StrongTableau([],4).size()
3415
0
3416
"""
3417
return sum(self.weight())
3418
3419
def to_list( self ):
3420
"""
3421
Return the marked column strict (possibly skew) tableau as a list of lists.
3422
3423
OUTPUT:
3424
3425
- a list of lists of integers or ``None``
3426
3427
EXAMPLES::
3428
3429
sage: StrongTableau([[-1, -2, -3, 4], [-4], [-5]], 3).set_weight([2,1,1,1]).to_list()
3430
[[-1, -1, -2, 3], [-3], [-4]]
3431
sage: StrongTableau([[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]], 4).to_list()
3432
[[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]]
3433
sage: StrongTableau([[-1, -2, -3, 4], [-4], [-5]], 3, [3,1,1]).to_list()
3434
[[-1, -1, -1, 2], [-2], [-3]]
3435
3436
TESTS::
3437
3438
sage: StrongTableau([[None, None], [None]], 4).to_list()
3439
[[None, None], [None]]
3440
sage: StrongTableau([],4).to_list()
3441
[]
3442
"""
3443
def f(v):
3444
# f is a function which maps v or -v to the weight value corresponding to the partition mu
3445
if v is None:
3446
return None
3447
else:
3448
return sgn(v)*min([i for i in range(len(self.weight())+1) if sum(self.weight()[:i])>=abs(v)])
3449
return [[f(v) for v in row] for row in self.to_standard_list()]
3450
3451
def to_unmarked_list( self ):
3452
"""
3453
Return the tableau as a list of lists with markings removed.
3454
3455
Return the list of lists of the rows of the tableau where the markings have been
3456
removed.
3457
3458
OUTPUT:
3459
3460
- a list of lists of integers or ``None``
3461
3462
EXAMPLES::
3463
3464
sage: T = StrongTableau( [[-1, -2, -3, 4], [-4], [-5]], 3, [3,1,1])
3465
sage: T.to_unmarked_list()
3466
[[1, 1, 1, 2], [2], [3]]
3467
sage: TT = T.set_weight([2,1,1,1])
3468
sage: TT.to_unmarked_list()
3469
[[1, 1, 2, 3], [3], [4]]
3470
sage: StrongTableau( [[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]], 4).to_unmarked_list()
3471
[[None, None, 1, 2], [None, None], [1, 2], [1, 2], [3], [3], [3], [3]]
3472
3473
TESTS::
3474
3475
sage: StrongTableau([[None, None], [None]], 4).to_unmarked_list()
3476
[[None, None], [None]]
3477
sage: StrongTableau([],4).to_unmarked_list()
3478
[]
3479
"""
3480
return [[nabs(v) for v in row] for row in self.to_list()]
3481
3482
def to_standard_list(self):
3483
"""
3484
Return the underlying standard strong tableau as a list of lists.
3485
3486
Internally, for a strong tableau the standard strong tableau and its weight
3487
is stored separately. This method returns the underlying standard part.
3488
3489
OUTPUT:
3490
3491
- a list of lists of integers or ``None``
3492
3493
EXAMPLES::
3494
3495
sage: StrongTableau([[-1, -2, -3, 4], [-4], [-5]], 3, [3,1,1]).to_standard_list()
3496
[[-1, -2, -3, 4], [-4], [-5]]
3497
sage: StrongTableau([[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]], 4).to_standard_list()
3498
[[None, None, -2, -4], [None, None], [-1, -3], [2, 4], [-5], [5], [5], [5]]
3499
3500
TESTS::
3501
3502
sage: StrongTableau([[None, None], [None]], 4).to_standard_list()
3503
[[None, None], [None]]
3504
sage: StrongTableau([],4).to_standard_list()
3505
[]
3506
"""
3507
return self._tableau
3508
3509
def to_standard_tableau(self):
3510
"""
3511
Return the underlying standard strong tableau as a ``StrongTableau`` object.
3512
3513
Internally, for a strong tableau the standard strong tableau and its weight
3514
is stored separately. This method returns the underlying standard part as a
3515
``StrongTableau``.
3516
3517
OUTPUT:
3518
3519
- a strong tableau with standard weight
3520
3521
EXAMPLES::
3522
3523
sage: T = StrongTableau([[-1, -2, -3, 4], [-4], [-5]], 3, [3,1,1])
3524
sage: T.to_standard_tableau()
3525
[[-1, -2, -3, 4], [-4], [-5]]
3526
sage: T.to_standard_tableau() == T.to_standard_list()
3527
False
3528
sage: StrongTableau([[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]], 4).to_standard_tableau()
3529
[[None, None, -2, -4], [None, None], [-1, -3], [2, 4], [-5], [5], [5], [5]]
3530
3531
TESTS::
3532
3533
sage: StrongTableau([[None, None], [None]], 4).to_standard_tableau()
3534
[[None, None], [None]]
3535
sage: StrongTableau([],4).to_standard_tableau()
3536
[]
3537
"""
3538
return StrongTableau(self._tableau, self.k)
3539
3540
def to_unmarked_standard_list( self ):
3541
"""
3542
Return the standard part of the tableau as a list of lists with markings removed.
3543
3544
Return the list of lists of the rows of the tableau where the markings have been
3545
removed.
3546
3547
OUTPUT:
3548
3549
- a list of lists of integers or ``None``
3550
3551
EXAMPLES::
3552
3553
sage: StrongTableau( [[-1, -2, -3, 4], [-4], [-5]], 3, [3,1,1]).to_unmarked_standard_list()
3554
[[1, 2, 3, 4], [4], [5]]
3555
sage: StrongTableau( [[None, None, -1, -2], [None, None], [-1, -2], [1, 2], [-3], [3], [3], [3]], 4).to_unmarked_standard_list()
3556
[[None, None, 2, 4], [None, None], [1, 3], [2, 4], [5], [5], [5], [5]]
3557
3558
TESTS::
3559
3560
sage: StrongTableau([[None, None], [None]], 4).to_unmarked_standard_list()
3561
[[None, None], [None]]
3562
sage: StrongTableau([],4).to_unmarked_standard_list()
3563
[]
3564
"""
3565
return map(lambda x: map(nabs,x), self.to_standard_list())
3566
3567
def _latex_(self):
3568
r"""
3569
Return a latex method for the tableau.
3570
3571
EXAMPLES::
3572
3573
sage: T = StrongTableau( [[None, -1, -2, 3], [2, -3]], 2, weight=[2,1] )
3574
sage: Tableaux.global_options(convention = "English")
3575
sage: latex(T)
3576
{\def\lr#1{\multicolumn{1}{|@{\hspace{.6ex}}c@{\hspace{.6ex}}|}{\raisebox{-.3ex}{$#1$}}}
3577
\raisebox{-.6ex}{$\begin{array}[b]{*{4}c}\cline{1-4}
3578
\lr{}&\lr{1^\ast}&\lr{1^\ast}&\lr{2}\\\cline{1-4}
3579
\lr{1}&\lr{2^\ast}\\\cline{1-2}
3580
\end{array}$}
3581
}
3582
sage: Tableaux.global_options(convention = "French")
3583
sage: latex(T)
3584
{\def\lr#1{\multicolumn{1}{|@{\hspace{.6ex}}c@{\hspace{.6ex}}|}{\raisebox{-.3ex}{$#1$}}}
3585
\raisebox{-.6ex}{$\begin{array}[t]{*{4}c}\cline{1-2}
3586
\lr{1}&\lr{2^\ast}\\\cline{1-4}
3587
\lr{}&\lr{1^\ast}&\lr{1^\ast}&\lr{2}\\\cline{1-4}
3588
\end{array}$}
3589
}
3590
"""
3591
def chi(x):
3592
if x==None:
3593
return ""
3594
if x in ZZ:
3595
s = "%s"%abs(x)
3596
if x<0:
3597
s += "^\\ast"
3598
return s
3599
return "%s"%x
3600
T = [[chi(x) for x in row] for row in self.to_list()]
3601
from output import tex_from_array
3602
return tex_from_array(T)
3603
3604
def restrict( self, r ):
3605
r"""
3606
Restrict the standard part of the tableau to the labels `1, 2, \ldots, r`.
3607
3608
Return the tableau consisting of the labels of the standard part of ``self``
3609
restricted to the labels of `1` through ``r``. The result is another
3610
``StrongTableau`` object.
3611
3612
INPUT:
3613
3614
- ``r`` -- an integer
3615
3616
OUTPUT:
3617
3618
- A strong tableau
3619
3620
EXAMPLES::
3621
3622
sage: T = StrongTableau([[None, None, -4, 5, -5], [None, None], [-1, -3], [-2], [2], [2], [3]], 4, weight=[1,1,1,1,1])
3623
sage: T.restrict(3)
3624
[[None, None], [None, None], [-1, -3], [-2], [2], [2], [3]]
3625
sage: TT = T.restrict(0)
3626
sage: TT
3627
[[None, None], [None, None]]
3628
sage: TT == StrongTableau( [[None, None], [None, None]], 4 )
3629
True
3630
sage: T.restrict(5) == T
3631
True
3632
3633
TESTS::
3634
3635
sage: StrongTableau([[None, None], [None]], 4).restrict(1)
3636
[[None, None], [None]]
3637
sage: StrongTableau([],4).restrict(1)
3638
[]
3639
"""
3640
rr = sum(self.weight()[:r])
3641
rest_tab = filter(lambda y: len(y)>0, map(lambda row: filter(lambda x: x==None or abs(x)<=rr, row ), self.to_standard_list()))
3642
new_parent = StrongTableaux( self.k, (Core(map(len, rest_tab), self.k+1), self.inner_shape()), self.weight()[:r] )
3643
return new_parent(rest_tab)
3644
3645
def set_weight( self, mu ):
3646
"""
3647
Sets a new weight ``mu`` for ``self``.
3648
3649
This method first tests if the underlying standard tableau is column-strict with
3650
respect to the weight ``mu``. If it is, then it changes the weight and returns
3651
the tableau; otherwise it raises an error.
3652
3653
INPUT:
3654
3655
- ``mu`` -- a list of non-negative integers representing the new weight
3656
3657
EXAMPLES::
3658
3659
sage: StrongTableau( [[-1, -2, -3], [3]], 2 ).set_weight( [3] )
3660
[[-1, -1, -1], [1]]
3661
sage: StrongTableau( [[-1, -2, -3], [3]], 2 ).set_weight( [0,3] )
3662
[[-2, -2, -2], [2]]
3663
sage: StrongTableau( [[-1, -2, 3], [-3]], 2 ).set_weight( [2, 0, 1] )
3664
[[-1, -1, 3], [-3]]
3665
sage: StrongTableau( [[-1, -2, 3], [-3]], 2 ).set_weight( [3] )
3666
Traceback (most recent call last):
3667
...
3668
ValueError: [[-1, -2, 3], [-3]] is not a semistandard strong tableau with respect to the partition [3]
3669
3670
TESTS::
3671
3672
sage: StrongTableau([[None, None], [None]], 4).set_weight([])
3673
[[None, None], [None]]
3674
sage: StrongTableau([],4).set_weight([])
3675
[]
3676
"""
3677
if sum(mu)!=self.size() or self.is_column_strict_with_weight( mu ):
3678
return StrongTableaux.__classcall__(StrongTableaux, self.k, (self.outer_shape(), self.inner_shape()), tuple(mu))(self.to_standard_list())
3679
else:
3680
raise ValueError("%s is not a semistandard strong tableau with respect to the partition %s"%(self,mu))
3681
3682
def left_action( self, tij ):
3683
r"""
3684
Action of transposition ``tij`` on ``self`` by adding marked ribbons.
3685
3686
Computes the left action of the transposition ``tij`` on the tableau.
3687
If ``tij`` acting on the element of the affine grassmannian raises the length by 1,
3688
then this function will add a cell to the standard tableau.
3689
3690
INPUT:
3691
3692
- ``tij`` -- a transposition represented as a pair `(i, j)`.
3693
3694
OUPUT:
3695
3696
- ``self`` after it has been modified by the action of the transposition ``tij``
3697
3698
EXAMPLES::
3699
3700
sage: StrongTableau( [[None, -1, -2, -3], [3], [-4]], 3, weight=[1,1,1,1] ).left_action([0,1])
3701
[[None, -1, -2, -3, 5], [3, -5], [-4]]
3702
sage: StrongTableau( [[None, -1, -2, -3], [3], [-4]], 3, weight=[1,1,1,1] ).left_action([4,5])
3703
[[None, -1, -2, -3, -5], [3, 5], [-4]]
3704
sage: T = StrongTableau( [[None, -1, -2, -3], [3], [-4]], 3, weight=[1,1,1,1] )
3705
sage: T.left_action([-3,-2])
3706
[[None, -1, -2, -3], [3], [-4], [-5]]
3707
sage: T = StrongTableau( [[None, -1, -2, -3], [3], [-4]], 3, weight=[3,1] )
3708
sage: T.left_action([-3,-2])
3709
[[None, -1, -1, -1], [1], [-2], [-3]]
3710
sage: T
3711
[[None, -1, -1, -1], [1], [-2]]
3712
sage: T.check()
3713
sage: T.weight()
3714
(3, 1)
3715
3716
TESTS::
3717
3718
sage: StrongTableau([[None, None], [None]], 4).left_action([-2,-1])
3719
[[None, None], [None], [-1]]
3720
sage: StrongTableau([],4).left_action([0,1])
3721
[[-1]]
3722
"""
3723
T = StrongTableaux._left_action_list(copy.deepcopy( self.to_standard_list() ), tij, self.size()+1, self.k)
3724
return StrongTableau( T, self.k, self.weight()+(1,) )
3725
3726
def follows_tableau( self ):
3727
r"""
3728
Return a list of strong marked tableaux with length one longer than ``self``.
3729
3730
Return list of all strong tableaux obtained from ``self`` by extending to a core
3731
which follows the shape of ``self`` in the strong order.
3732
3733
OUTPUT:
3734
3735
- a list of strong tableaux which follow ``self`` in strong order
3736
3737
EXAMPLES::
3738
3739
sage: T = StrongTableau([[-1,-2,-4,-7],[-3,6,-6,8],[4,7],[-5,-8]], 3, [2,2,3,1])
3740
sage: T.follows_tableau()
3741
[[[-1, -1, -2, -3, 5, 5, -5], [-2, 3, -3, 4], [2, 3], [-3, -4]],
3742
[[-1, -1, -2, -3, 5], [-2, 3, -3, 4], [2, 3, 5], [-3, -4], [-5]],
3743
[[-1, -1, -2, -3, 5], [-2, 3, -3, 4], [2, 3, -5], [-3, -4], [5]],
3744
[[-1, -1, -2, -3, -5], [-2, 3, -3, 4], [2, 3, 5], [-3, -4], [5]],
3745
[[-1, -1, -2, -3], [-2, 3, -3, 4], [2, 3], [-3, -4], [-5], [5], [5]]]
3746
sage: StrongTableau([[-1,-2],[-3,-4]],3).follows_tableau()
3747
[[[-1, -2, 5, 5, -5], [-3, -4]], [[-1, -2, 5], [-3, -4], [-5]],
3748
[[-1, -2, -5], [-3, -4], [5]], [[-1, -2], [-3, -4], [-5], [5], [5]]]
3749
3750
TESTS::
3751
3752
sage: StrongTableau([[None, None], [None]], 4).follows_tableau()
3753
[[[None, None, -1], [None]], [[None, None], [None, -1]], [[None, None], [None], [-1]]]
3754
sage: StrongTableau([],4).follows_tableau()
3755
[[[-1]]]
3756
"""
3757
v = self.size()+1
3758
out = []
3759
for T in StrongTableaux.follows_tableau_unsigned_standard( self.to_standard_list(), self.k ):
3760
for m in StrongTableaux.cells_head_dictionary(T)[v]:
3761
TT = copy.deepcopy(T)
3762
TT[m[0]][m[1]] = -v
3763
out.append(StrongTableau(TT, self.k, self.weight()+(1,)))
3764
return out
3765
3766
def spin_of_ribbon( self, v ):
3767
r"""
3768
Return the spin of the ribbon with label ``v`` in the standard part of ``self``.
3769
3770
The spin of a ribbon is an integer statistic. It is the sum of `(h-1) r` plus
3771
the number of connected components above the marked one where `h` is the height
3772
of the marked ribbon and `r` is the number of connected components.
3773
3774
.. SEEALSO:: :meth:`height_of_ribbon`, :meth:`number_of_connected_components`,
3775
:meth:`ribbons_above_marked`
3776
3777
INPUT:
3778
3779
- ``v`` -- a label of the standard part of the tableau
3780
3781
OUTPUT:
3782
3783
- an integer value representing the spin of the ribbon with label ``v``.
3784
3785
EXAMPLES::
3786
3787
sage: T = StrongTableau([[-1,-2,5,6],[-3,-4,-7,8],[-5,-6],[7,-8]], 3)
3788
sage: [T.spin_of_ribbon(v) for v in range(1,9)]
3789
[0, 0, 0, 0, 0, 0, 1, 0]
3790
sage: T = StrongTableau([[None,None,-1,-3],[-2,3,-3,4],[2,3],[-3,-4]], 3)
3791
sage: [T.spin_of_ribbon(v) for v in range(1,7)]
3792
[0, 1, 0, 0, 1, 0]
3793
3794
TESTS::
3795
3796
sage: StrongTableau([[None, None], [None]], 4).spin_of_ribbon(1)
3797
0
3798
sage: StrongTableau([],4).spin_of_ribbon(1)
3799
0
3800
"""
3801
return (self.height_of_ribbon(v)-1)*self.number_of_connected_components(v)+self.ribbons_above_marked(v)
3802
3803
def spin( self ):
3804
r"""
3805
Return the spin statistic of the tableau ``self``.
3806
3807
The spin is an integer statistic on a strong marked tableau. It is
3808
the sum of `(h-1) r` plus the number of connected components above the
3809
marked one where `h` is the height of the marked ribbon and `r` is
3810
the number of connected components.
3811
3812
.. SEEALSO:: :meth:`height_of_ribbon`, :meth:`number_of_connected_components`,
3813
:meth:`ribbons_above_marked`
3814
3815
The `k`-Schur functions with a parameter `t` can be defined as
3816
3817
.. MATH::
3818
3819
s^{(k)}_\lambda[X; t] = \sum_T t^{spin(T)} m_{weight(T)}[X]
3820
3821
where the sum is over all column strict marked strong `k`-tableaux
3822
of shape `\lambda` and partition content.
3823
3824
OUTPUT:
3825
3826
- an integer value representing the spin.
3827
3828
EXAMPLES::
3829
3830
sage: StrongTableau([[-1,-2,5,6],[-3,-4,-7,8],[-5,-6],[7,-8]], 3, [2,2,3,1]).spin()
3831
1
3832
sage: StrongTableau([[-1,-2,-4,-7],[-3,6,-6,8],[4,7],[-5,-8]], 3, [2,2,3,1]).spin()
3833
2
3834
sage: StrongTableau([[None,None,-1,-3],[-2,3,-3,4],[2,3],[-3,-4]], 3).spin()
3835
2
3836
sage: ks3 = SymmetricFunctions(QQ['t'].fraction_field()).kschur(3)
3837
sage: t = ks3.realization_of().t
3838
sage: m = ks3.ambient().realization_of().m()
3839
sage: myks221 = sum(sum(t**T.spin() for T in StrongTableaux(3,[3,2,1],weight=mu))*m(mu) for mu in Partitions(5, max_part=3))
3840
sage: myks221 == m(ks3[2,2,1])
3841
True
3842
sage: h = ks3.ambient().realization_of().h()
3843
sage: Core([4,4,2,2],4).to_bounded_partition()
3844
[2, 2, 2, 2]
3845
sage: ks3[2,2,2,2].lift().scalar(h[3,3,2]) == sum( t**T.spin() for T in StrongTableaux(3, [4,4,2,2], weight=[3,3,2]) )
3846
True
3847
3848
TESTS::
3849
3850
sage: StrongTableau([[None, None], [None]], 4).spin()
3851
0
3852
sage: StrongTableau([],4).spin()
3853
0
3854
"""
3855
return sum(self.spin_of_ribbon(v) for v in range(1,self.size()+1))
3856
3857
def to_transposition_sequence( self ):
3858
"""
3859
Return a list of transpositions corresponding to ``self``.
3860
3861
Given a strong column strict tableau ``self`` returns the the list of transpositions
3862
which when applied to the left of an empty tableau gives the corresponding strong
3863
standard tableau.
3864
3865
OUTPUT:
3866
3867
- a list of pairs of values ``[i,j]`` representing the transpositions `t_{ij}`
3868
3869
EXAMPLES::
3870
3871
sage: T = StrongTableau([[-1, -1, -1], [1]],2)
3872
sage: T.to_transposition_sequence()
3873
[[2, 3], [1, 2], [0, 1]]
3874
sage: T = StrongTableau([[-1, -1, 2], [-2]],2)
3875
sage: T.to_transposition_sequence()
3876
[[-1, 0], [1, 2], [0, 1]]
3877
sage: T = StrongTableau([[None, -1, 2, -3], [-2, 3]],2)
3878
sage: T.to_transposition_sequence()
3879
[[3, 4], [-1, 0], [1, 2]]
3880
3881
TESTS::
3882
3883
sage: StrongTableau([[None, None], [None]], 4).to_transposition_sequence()
3884
[]
3885
sage: StrongTableau([],4).to_transposition_sequence()
3886
[]
3887
"""
3888
return StrongTableaux.marked_CST_to_transposition_sequence( self.to_list(), self.k )
3889
3890
class StrongTableaux(UniqueRepresentation, Parent):
3891
3892
def __init__( self, k, shape, weight ):
3893
r"""
3894
TESTS::
3895
3896
sage: strongT = StrongTableaux(2, [3,1], weight=[2,1])
3897
sage: TestSuite(strongT).run()
3898
3899
sage: strongT = StrongTableaux(0, [2,2], weight=[2,2])
3900
Traceback (most recent call last):
3901
...
3902
ValueError: The input k has to be a positive integer
3903
"""
3904
self._outer_shape = shape[0]
3905
self._inner_shape = shape[1]
3906
self.k = k
3907
if weight is None:
3908
self._weight = (1,)*(self._outer_shape.length()-self._inner_shape.length())
3909
else:
3910
self._weight = weight
3911
Parent.__init__(self, category = FiniteEnumeratedSets())
3912
3913
@staticmethod
3914
def __classcall_private__(cls, k, shape, weight=None):
3915
r"""
3916
Straighten arguments before unique representation.
3917
3918
TESTS::
3919
3920
sage: ST3 = StrongTableaux(3, [2,2], weight=[1,1,1,1])
3921
sage: TestSuite(ST3).run()
3922
"""
3923
if k<=0:
3924
raise ValueError("The input k has to be a positive integer")
3925
if shape==[] or shape[0] in ZZ:
3926
outer_shape = Core(shape,k+1)
3927
inner_shape = Core([],k+1)
3928
else:
3929
outer_shape = Core(shape[0],k+1)
3930
inner_shape = Core(shape[1],k+1)
3931
if weight is not None:
3932
weight = tuple(weight)
3933
return super(StrongTableaux, cls).__classcall__(cls, k, (outer_shape, inner_shape), weight)
3934
3935
def _repr_( self ):
3936
r"""
3937
Return the representation of ``self``.
3938
3939
EXAMPLES::
3940
3941
sage: StrongTableaux(3, [2,2], weight=[1,1,1,1])
3942
Set of strong 3-tableaux of shape [2, 2] and of weight (1, 1, 1, 1)
3943
sage: StrongTableaux(3, [2,2])
3944
Set of strong 3-tableaux of shape [2, 2] and of weight (1, 1, 1, 1)
3945
sage: StrongTableaux(3, [[2,2],[1]], weight=[0,0,2,1])
3946
Set of strong 3-tableaux of shape [[2, 2], [1]] and of weight (0, 0, 2, 1)
3947
sage: StrongTableaux(3, [[],[]], weight=[])
3948
Set of strong 3-tableaux of shape [] and of weight ()
3949
"""
3950
if self._inner_shape==[]:
3951
s = "Set of strong %s-tableaux"%self.k
3952
s +=" of shape %s"%self._outer_shape
3953
else:
3954
s = "Set of strong %s-tableaux"%self.k
3955
s +=" of shape [%s, %s]"%(self._outer_shape, self._inner_shape)
3956
s +="%sand of weight %s"%(" ",self._weight)
3957
return s
3958
3959
global_options = TableauOptions
3960
3961
def an_element(self):
3962
r"""
3963
Return the first generated element of the class of ``StrongTableaux``.
3964
3965
EXAMPLES::
3966
3967
sage: ST = StrongTableaux(3, [3], weight=[3])
3968
sage: ST.an_element()
3969
[[-1, -1, -1]]
3970
"""
3971
return self.__iter__().next()
3972
3973
def outer_shape(self):
3974
r"""
3975
Return the outer shape of the class of strong tableaux.
3976
3977
OUTPUT:
3978
3979
- a `k+1`-core
3980
3981
EXAMPLES::
3982
3983
sage: StrongTableaux( 2, [3,1] ).outer_shape()
3984
[3, 1]
3985
sage: type(StrongTableaux( 2, [3,1] ).outer_shape())
3986
<class 'sage.combinat.core.Cores_length_with_category.element_class'>
3987
sage: StrongTableaux( 4, [[2,1], [1]] ).outer_shape()
3988
[2, 1]
3989
"""
3990
return self._outer_shape
3991
3992
def inner_shape(self):
3993
r"""
3994
Return the inner shape of the class of strong tableaux.
3995
3996
OUTPUT:
3997
3998
- a `k+1`-core
3999
4000
EXAMPLES::
4001
4002
sage: StrongTableaux( 2, [3,1] ).inner_shape()
4003
[]
4004
sage: type(StrongTableaux( 2, [3,1] ).inner_shape())
4005
<class 'sage.combinat.core.Cores_length_with_category.element_class'>
4006
sage: StrongTableaux( 4, [[2,1], [1]] ).inner_shape()
4007
[1]
4008
"""
4009
return self._inner_shape
4010
4011
def shape(self):
4012
r"""
4013
Return the shape of ``self``.
4014
4015
If the ``self`` has an inner shape return a pair consisting of an inner and
4016
an outer shape. If the inner shape is empty then return only the outer shape.
4017
4018
OUTPUT:
4019
4020
- a `k+1`-core or a pair of `k+1`-cores
4021
4022
EXAMPLES::
4023
4024
sage: StrongTableaux( 2, [3,1] ).shape()
4025
[3, 1]
4026
sage: type(StrongTableaux( 2, [3,1] ).shape())
4027
<class 'sage.combinat.core.Cores_length_with_category.element_class'>
4028
sage: StrongTableaux( 4, [[2,1], [1]] ).shape()
4029
([2, 1], [1])
4030
"""
4031
if self._inner_shape != []:
4032
return (self._outer_shape, self._inner_shape)
4033
return self._outer_shape
4034
4035
def __iter__(self):
4036
r"""
4037
TESTS::
4038
4039
sage: ST = StrongTableaux(3, [4,1], weight=[2,2])
4040
sage: ST.list()
4041
[[[-1, -1, -2, -2], [2]], [[-1, -1, 2, -2], [-2]]]
4042
sage: ST = StrongTableaux(3, [5,2,2], weight=[2,2,2,1])
4043
sage: ST.cardinality()
4044
14
4045
sage: StrongTableaux(3, [5,2,2], weight=[3,3,1]).list()
4046
[[[-1, -1, -1, -2, -2], [-2, 2], [2, -3]], [[-1, -1, -1, 2, -2], [-2, -2], [2, -3]], [[-1, -1, -1, -2, -3], [-2, -2], [2, 2]]]
4047
sage: StrongTableaux(3, [4,1,1]).cardinality()
4048
10
4049
sage: StrongTableaux(3, [5,2,2], weight=[6,1]).list() # there are no strong column strict tableaux of shape [5,2,2] and weight (6,1)
4050
[]
4051
sage: StrongTableaux(3, [[5,2,2], [3,1,1]], weight=[2,1]).list()
4052
[[[None, None, None, -1, -1], [None, 1], [None, -2]],
4053
[[None, None, None, 1, -1], [None, -1], [None, -2]],
4054
[[None, None, None, -1, -2], [None, -1], [None, 1]]]
4055
sage: StrongTableaux(2, [[4,3,3,2,2,1,1], [2,1,1]], weight=[1,1,1,1]).cardinality()
4056
150
4057
sage: StrongTableaux(2, [[7,5,3,1], [2,1,1]], weight=[2,2]).cardinality()
4058
18
4059
sage: StrongTableaux(2, [[3,1],[3,1]]).list()
4060
[[[None, None, None], [None]]]
4061
sage: StrongTableaux(4, []).list()
4062
[[]]
4063
"""
4064
size = sum(self._weight)
4065
if size==0:
4066
yield self([[None]*(row) for row in self._inner_shape])
4067
else:
4068
for unT in StrongTableaux.standard_unmarked_iterator( self.k, size, self._outer_shape, self._inner_shape ):
4069
for T in StrongTableaux.marked_given_unmarked_and_weight_iterator( unT, self.k, self._weight ):
4070
yield T
4071
4072
@classmethod
4073
def standard_unmarked_iterator( cls, k, size, outer_shape=None, inner_shape=[] ):
4074
r"""
4075
An iterator for standard unmarked strong tableaux.
4076
4077
An iterator which generates all unmarked tableaux of a given ``size`` which are
4078
contained in ``outer_shape`` and which contain the ``inner_shape``.
4079
4080
These are built recursively by building all standard marked strong tableaux of
4081
size ``size`` `-1` and adding all possible covers.
4082
4083
If ``outer_shape`` is ``None`` then there is no restriction on the shape of the
4084
tableaux which are created.
4085
4086
INPUT:
4087
4088
- ``k``, ``size`` - a positive integers
4089
- ``outer_shape`` - a list representing a `k+1`-core (default: ``None``)
4090
- ``inner_shape`` - a list representing a `k+1`-core (default: [])
4091
4092
OUTPUT:
4093
4094
- an iterator which lists all standard strong unmarked tableaux with ``size``
4095
cells and which are contained in ``outer_shape`` and contain ``inner_shape``
4096
4097
EXAMPLES::
4098
4099
sage: list(StrongTableaux.standard_unmarked_iterator(2, 3))
4100
[[[1, 2, 3], [3]], [[1, 2], [3], [3]], [[1, 3, 3], [2]], [[1, 3], [2], [3]]]
4101
sage: list(StrongTableaux.standard_unmarked_iterator(2, 1, inner_shape=[1,1]))
4102
[[[None, 1, 1], [None]], [[None, 1], [None], [1]]]
4103
sage: len(list(StrongTableaux.standard_unmarked_iterator(4,4)))
4104
10
4105
sage: len(list(StrongTableaux.standard_unmarked_iterator(4,6)))
4106
98
4107
sage: len(list(StrongTableaux.standard_unmarked_iterator(4,4, inner_shape=[2,2])))
4108
92
4109
sage: len(list(StrongTableaux.standard_unmarked_iterator(4,4, outer_shape=[5,2,2,1], inner_shape=[2,2])))
4110
10
4111
4112
TESTS::
4113
4114
sage: list(StrongTableaux.standard_unmarked_iterator(2,0, outer_shape=[3,1], inner_shape=[3,1]))
4115
[[[None, None, None], [None]]]
4116
sage: list(StrongTableaux.standard_unmarked_iterator(4,0, outer_shape=[]))
4117
[[]]
4118
"""
4119
if size==0:
4120
if outer_shape is None or Core(outer_shape,k+1).contains(inner_shape):
4121
yield [[None]*(inner_shape[i]) for i in range(len(inner_shape))]
4122
else:
4123
for T in cls.standard_unmarked_iterator(k, size-1, outer_shape, inner_shape):
4124
for TT in cls.follows_tableau_unsigned_standard(T, k):
4125
if outer_shape is None or Core(outer_shape, k+1).contains(map(len,TT)):
4126
yield TT
4127
4128
@classmethod
4129
def marked_given_unmarked_and_weight_iterator( cls, unmarkedT, k, weight ):
4130
r"""
4131
An iterator generating strong marked tableaux from an unmarked strong tableau.
4132
4133
Iterator which lists all marked tableaux of weight ``weight`` such that the
4134
standard unmarked part of the tableau is equal to ``unmarkedT``.
4135
4136
INPUT:
4137
4138
- ``unmarkedT`` - a list of lists representing a strong unmarked tableau
4139
- ``k`` - a positive integer
4140
- ``weight`` - a list of non-negative integers indicating the weight
4141
4142
OUTPUT:
4143
4144
- an iterator that returns ``StrongTableau`` objects
4145
4146
EXAMPLES::
4147
4148
sage: ST = StrongTableaux.marked_given_unmarked_and_weight_iterator([[1,2,3],[3]], 2, [3])
4149
sage: list(ST)
4150
[[[-1, -1, -1], [1]]]
4151
sage: ST = StrongTableaux.marked_given_unmarked_and_weight_iterator([[1,2,3],[3]], 2, [0,3])
4152
sage: list(ST)
4153
[[[-2, -2, -2], [2]]]
4154
sage: ST = StrongTableaux.marked_given_unmarked_and_weight_iterator([[1,2,3],[3]], 2, [1,2])
4155
sage: list(ST)
4156
[[[-1, -2, -2], [2]]]
4157
sage: ST = StrongTableaux.marked_given_unmarked_and_weight_iterator([[1,2,3],[3]], 2, [2,1])
4158
sage: list(ST)
4159
[[[-1, -1, 2], [-2]], [[-1, -1, -2], [2]]]
4160
sage: ST = StrongTableaux.marked_given_unmarked_and_weight_iterator([[None, None, 1, 2, 4], [2, 4], [3]], 3, [3,1])
4161
sage: list(ST)
4162
[]
4163
sage: ST = StrongTableaux.marked_given_unmarked_and_weight_iterator([[None, None, 1, 2, 4], [2, 4], [3]], 3, [2,2])
4164
sage: list(ST)
4165
[[[None, None, -1, -1, 2], [1, -2], [-2]],
4166
[[None, None, -1, -1, -2], [1, 2], [-2]]]
4167
4168
TESTS::
4169
4170
sage: list(StrongTableaux.marked_given_unmarked_and_weight_iterator([[None, None, None],[None]], 2, []))
4171
[[[None, None, None], [None]]]
4172
sage: list(StrongTableaux.marked_given_unmarked_and_weight_iterator([], 4, weight=[]))
4173
[[]]
4174
"""
4175
td = StrongTableaux.cells_head_dictionary( unmarkedT )
4176
if td == {}: # the tableau is empty
4177
yield StrongTableau( unmarkedT, k, [] )
4178
else:
4179
allmarkings = cartesian_product.CartesianProduct(*[td[v] for v in td.keys()])
4180
dsc = Composition(weight).descents()
4181
for m in allmarkings:
4182
if all(((m[i][1]-m[i][0]<m[i+1][1]-m[i+1][0]) or (i in dsc)) for i in range(len(m)-1)):
4183
yield StrongTableaux.add_marking( unmarkedT, m, k, weight )
4184
4185
@classmethod
4186
def add_marking( cls, unmarkedT, marking, k, weight ):
4187
r"""
4188
Add markings to a partially marked strong tableau.
4189
4190
Given an partially marked standard tableau and a list of cells where the marks
4191
should be placed along with a ``weight``, return the semi-standard marked strong
4192
tableau. The marking should complete the marking so that the result is a
4193
strong standard marked tableau.
4194
4195
INPUT:
4196
4197
- ``unmarkedT`` - a list of lists which is a partially marked strong `k`-tableau
4198
- ``marking`` - a list of pairs of coordinates where cells are to be marked
4199
- ``k`` - a positive integer
4200
- ``weight`` - a tuple of the weight of the output tableau
4201
4202
OUTPUT:
4203
4204
- a ``StrongTableau`` object
4205
4206
EXAMPLES::
4207
4208
sage: StrongTableaux.add_marking([[None,1,2],[2]], [(0,1), (1,0)], 2, [1,1])
4209
[[None, -1, 2], [-2]]
4210
sage: StrongTableaux.add_marking([[None,1,2],[2]], [(0,1), (1,0)], 2, [2])
4211
Traceback (most recent call last):
4212
...
4213
ValueError: The weight=(2,) and the markings on the standard tableau=[[None, -1, 2], [-2]] do not agree.
4214
sage: StrongTableaux.add_marking([[None,1,2],[2]], [(0,1), (0,2)], 2, [2])
4215
[[None, -1, -1], [1]]
4216
4217
TESTS::
4218
4219
sage: StrongTableaux.add_marking([[None,None,None],[None]], [], 2, [])
4220
[[None, None, None], [None]]
4221
sage: StrongTableaux.add_marking([], [], 2, [])
4222
[]
4223
"""
4224
def msgn(c,v):
4225
if c in marking:
4226
return -v
4227
else:
4228
return v
4229
return StrongTableau([[msgn((i,j),unmarkedT[i][j]) for j in range(len(unmarkedT[i]))] for i in range(len(unmarkedT))], k, weight )
4230
4231
@classmethod
4232
def _left_action_list( cls, Tlist, tij, v, k ):
4233
r"""
4234
Act by the transposition ``tij`` if it increases the size of the tableau by 1.
4235
4236
This method modifies the tableau ``Tlist`` instead of returning a copy.
4237
4238
INPUT:
4239
4240
- ``Tlist`` - a partial standard strong `k`-tableau as a list of lists
4241
- ``tij`` - a pair of integers representing a transposition
4242
- ``v`` - the label to add to the tableau
4243
- ``k`` - a positive integer
4244
4245
OUTPUT:
4246
4247
- a list of lists, in particular, it is ``Tlist``
4248
4249
EXAMPLES::
4250
4251
sage: StrongTableaux._left_action_list( [[None]], [1,2], 10, 2 )
4252
[[None, -10]]
4253
sage: StrongTableaux._left_action_list( [[None]], [1,2], 10, 1 )
4254
[[None, -10], [10]]
4255
sage: StrongTableaux._left_action_list( [[None]], [2,3], 10, 1 )
4256
Traceback (most recent call last):
4257
...
4258
ValueError: [2, 3] is not a single step up in the strong lattice
4259
sage: StrongTableaux._left_action_list( [[None]], [3,4], 10, 1 )
4260
[[None, 10], [10]]
4261
sage: T = StrongTableaux._left_action_list( [[None]], [1,2], 10, 2 )
4262
sage: StrongTableaux._left_action_list( T, [2,3], 4, 2 )
4263
[[None, -10, -4], [4]]
4264
sage: T
4265
[[None, -10, -4], [4]]
4266
"""
4267
innershape = Core(map(len, Tlist), k+1)
4268
outershape = innershape.affine_symmetric_group_action(tij, transposition=True)
4269
if outershape.length()==innershape.length()+1:
4270
for c in SkewPartition([outershape.to_partition(),innershape.to_partition()]).cells():
4271
while c[0]>=len(Tlist):
4272
Tlist.append([])
4273
Tlist[c[0]].append( v )
4274
if len(Tlist[c[0]])-c[0]==tij[1]:
4275
Tlist[c[0]][-1] = -Tlist[c[0]][-1] #mark the cell that is on the j-1 diagonal
4276
return Tlist
4277
else:
4278
raise ValueError("%s is not a single step up in the strong lattice"%tij)
4279
4280
@classmethod
4281
def follows_tableau_unsigned_standard( cls, Tlist, k ):
4282
r"""
4283
Return a list of strong tableaux one longer in length than ``Tlist``.
4284
4285
Return list of all standard strong tableaux obtained from ``Tlist`` by extending to
4286
a core which follows the shape of ``Tlist`` in the strong order. It does not put
4287
the markings on the last entry that it adds but it does keep the markings on all
4288
entries smaller. The objects returned are not ``StrongTableau`` objects (and
4289
cannot be) because the last entry will not properly marked.
4290
4291
INPUT:
4292
4293
- ``Tlist`` -- a filling of a `k+1`-core as a list of lists
4294
- ``k`` - an integer
4295
4296
OUTPUT:
4297
4298
- a list of strong tableaux which follow ``Tlist`` in strong order
4299
4300
EXAMPLES::
4301
4302
sage: StrongTableaux.follows_tableau_unsigned_standard([[-1, -1, -2, -3], [-2, 3, -3, 4], [2, 3], [-3, -4]], 3)
4303
[[[-1, -1, -2, -3, 5, 5, 5], [-2, 3, -3, 4], [2, 3], [-3, -4]],
4304
[[-1, -1, -2, -3, 5], [-2, 3, -3, 4], [2, 3, 5], [-3, -4], [5]],
4305
[[-1, -1, -2, -3], [-2, 3, -3, 4], [2, 3], [-3, -4], [5], [5], [5]]]
4306
sage: StrongTableaux.follows_tableau_unsigned_standard([[None,-1],[-2,-3]],3)
4307
[[[None, -1, 4, 4, 4], [-2, -3]], [[None, -1, 4], [-2, -3], [4]],
4308
[[None, -1], [-2, -3], [4], [4], [4]]]
4309
4310
TESTS::
4311
4312
sage: StrongTableaux.follows_tableau_unsigned_standard([[None, None, None], [None]], 2)
4313
[[[None, None, None, 1], [None, 1]], [[None, None, None], [None], [1]]]
4314
sage: StrongTableaux.follows_tableau_unsigned_standard([], 4)
4315
[[[1]]]
4316
"""
4317
v = max([0]+[abs(v) for rows in Tlist for v in rows if v is not None])+1
4318
out = []
4319
sh = Core(map(len, Tlist), k+1)
4320
for ga in sh.strong_covers():
4321
T = copy.deepcopy(Tlist)
4322
T += [[] for i in range(len(ga)-len(T))]
4323
for c in SkewPartition([ga.to_partition(), sh.to_partition()]).cells():
4324
T[c[0]] += [v]
4325
out.append(T)
4326
return out
4327
4328
@classmethod
4329
def standard_marked_iterator( cls, k, size, outer_shape=None, inner_shape=[] ):
4330
r"""
4331
An iterator for generating standard strong marked tableaux.
4332
4333
An iterator which generates all standard marked `k`-tableaux of a given ``size``
4334
which are contained in ``outer_shape`` and contain the ``inner_shape``.
4335
If ``outer_shape`` is ``None`` then there is no restriction on the shape of the
4336
tableaux which are created.
4337
4338
INPUT:
4339
4340
- ``k`` - a positive integer
4341
- ``size`` - a positive integer
4342
- ``outer_shape`` - a list which is a `k+1`-core (default: ``None``)
4343
- ``inner_shape`` - a list which is a `k+1`-core (default: [])
4344
4345
OUPUT:
4346
4347
- an iterator which returns the standard marked tableaux with ``size`` cells
4348
and that are contained in ``outer_shape`` and contain ``inner_shape``
4349
4350
EXAMPLES::
4351
4352
sage: list(StrongTableaux.standard_marked_iterator(2, 3))
4353
[[[-1, -2, 3], [-3]], [[-1, -2, -3], [3]], [[-1, -2], [-3], [3]], [[-1, 3, -3], [-2]], [[-1, 3], [-2], [-3]], [[-1, -3], [-2], [3]]]
4354
sage: list(StrongTableaux.standard_marked_iterator(2, 1, inner_shape=[1,1]))
4355
[[[None, 1, -1], [None]], [[None, 1], [None], [-1]], [[None, -1], [None], [1]]]
4356
sage: len(list(StrongTableaux.standard_marked_iterator(4,4)))
4357
10
4358
sage: len(list(StrongTableaux.standard_marked_iterator(4,6)))
4359
140
4360
sage: len(list(StrongTableaux.standard_marked_iterator(4,4, inner_shape=[2,2])))
4361
200
4362
sage: len(list(StrongTableaux.standard_marked_iterator(4,4, outer_shape=[5,2,2,1], inner_shape=[2,2])))
4363
24
4364
4365
TESTS::
4366
4367
sage: list(StrongTableaux.standard_marked_iterator(2,0,inner_shape=[3,1]))
4368
[[[None, None, None], [None]]]
4369
sage: list(StrongTableaux.standard_marked_iterator(4,0))
4370
[[]]
4371
"""
4372
for T in cls.standard_unmarked_iterator( k, size, outer_shape, inner_shape ):
4373
for TT in cls.marked_given_unmarked_and_weight_iterator( T, k, [1]*(size) ):
4374
yield TT
4375
4376
@classmethod
4377
def cells_head_dictionary( cls, T ):
4378
r"""
4379
Return a dictionary with the locations of the heads of all markings.
4380
4381
Return a dictionary of values and lists of cells where the heads with the values
4382
are located in a strong standard unmarked tableau ``T``.
4383
4384
INPUT:
4385
4386
- ``T`` -- a strong standard unmarked tableau as a list of lists
4387
4388
OUPUT:
4389
4390
- a dictionary with keys the entries in the tableau and values are the coordinates
4391
of the heads with those entries
4392
4393
EXAMPLES::
4394
4395
sage: StrongTableaux.cells_head_dictionary([[1,2,4,7],[3,6,6,8],[4,7],[5,8]])
4396
{1: [(0, 0)],
4397
2: [(0, 1)],
4398
3: [(1, 0)],
4399
4: [(2, 0), (0, 2)],
4400
5: [(3, 0)],
4401
6: [(1, 2)],
4402
7: [(2, 1), (0, 3)],
4403
8: [(3, 1), (1, 3)]}
4404
sage: StrongTableaux.cells_head_dictionary([[None, 2, 2, 4, 5, 6, 6, 6], [None, 3, 6, 6, 6], [1, 4]])
4405
{1: [(2, 0)],
4406
2: [(0, 2)],
4407
3: [(1, 1)],
4408
4: [(2, 1), (0, 3)],
4409
5: [(0, 4)],
4410
6: [(1, 4), (0, 7)]}
4411
4412
TESTS::
4413
4414
sage: StrongTableaux.cells_head_dictionary([[None, None, None],[None]])
4415
{}
4416
sage: StrongTableaux.cells_head_dictionary([])
4417
{}
4418
"""
4419
if T==[]:
4420
return {}
4421
ST = SkewTableau(T)
4422
dout = {}
4423
for i in range(-len(T),len(T[0])):
4424
nextv = ST.entries_by_content(i+1)
4425
for c in ST.cells_by_content(i):
4426
v = T[c[0]][c[1]]
4427
if not v in nextv:
4428
if v in dout.keys():
4429
dout[v] += [c]
4430
else:
4431
dout[v] = [c]
4432
return dout
4433
4434
@classmethod
4435
def marked_CST_to_transposition_sequence( self, T, k ):
4436
"""
4437
Return a list of transpositions corresponding to ``T``.
4438
4439
Given a strong column strict tableau ``T`` returns the the list of transpositions
4440
which when applied to the left of an empty tableau gives the corresponding strong
4441
standard tableau.
4442
4443
INPUT:
4444
4445
- ``T`` - a non-empty column strict tableau as a list of lists
4446
- ``k`` - a positive integer
4447
4448
OUTPUT:
4449
4450
- a list of pairs of values ``[i,j]`` representing the transpositions `t_{ij}`
4451
4452
EXAMPLES::
4453
4454
sage: StrongTableaux.marked_CST_to_transposition_sequence([[-1, -1, -1], [1]], 2)
4455
[[2, 3], [1, 2], [0, 1]]
4456
sage: StrongTableaux.marked_CST_to_transposition_sequence([], 2)
4457
[]
4458
sage: StrongTableaux.marked_CST_to_transposition_sequence([[-2, -2, -2], [2]], 2)
4459
[[2, 3], [1, 2], [0, 1]]
4460
4461
TESTS::
4462
4463
sage: StrongTableaux.marked_CST_to_transposition_sequence([[None, None, None], [None]], 2)
4464
[]
4465
sage: StrongTableaux.marked_CST_to_transposition_sequence([], 4)
4466
[]
4467
"""
4468
LL = list(T)
4469
marks = [v for row in T for v in row if v!=None and v<0]+[0]
4470
m = -min(marks) # the largest marked cell
4471
transeq = [] # start with the empty list and append on the right
4472
sh = Core(map(len,T), k+1)
4473
for v in range(m,0,-1):
4474
for j in range(len(LL[0]),-len(LL)-1,-1):
4475
if -v in [LL[i][i+j] for i in range(len(LL)) if len(LL[i])>j+i and i+j>=0]:
4476
for l in range(k):
4477
msh = sh.affine_symmetric_group_action([j-l,j+1],transposition=True)
4478
# my worry here is that the affine symmetric group action might apply an invalid
4479
# transposition but get something of the right length anyway. How do I test if it is applying
4480
# a valid or invalid transposition?
4481
if msh.length()==sh.length()-1:
4482
# if applying t_{j-l,j+1} reduces the size of the shape by 1
4483
valcells = [LL[c[0]][c[1]] for c in SkewPartition([sh.to_partition(),msh.to_partition()]).cells()]
4484
if all(x!=None for x in valcells) and all(abs(x)==v for x in valcells) and filter( lambda x: x==-v, valcells )==[-v]:
4485
# if all values are \pm v and exactly one of them is -v
4486
transeq.append([j-l, j+1])
4487
LL = [[LL[a][b] for b in range(len(LL[a])) if (a,b) in msh.to_partition().cells()] for a in range(len(msh.to_partition()))]
4488
sh = msh
4489
if LL==[]:
4490
return transeq
4491
return transeq
4492
4493
@classmethod
4494
def transpositions_to_standard_strong( self, transeq, k, emptyTableau=[] ):
4495
"""
4496
Return a strong tableau correponding to a sequence of transpositions.
4497
4498
This method returns the action by left multiplication on the empty strong tableau
4499
by transpositions specified by ``transeq``.
4500
4501
INPUT:
4502
4503
- ``transeq`` -- a sequence of transpositions `t_{ij}` (a list of pairs).
4504
- ``emptyTableau`` -- (default: ``[]``) an empty list or a skew strong tableau
4505
possibly consisting of ``None`` entries
4506
4507
OUTPUT:
4508
4509
- a ``StrongTableau`` object
4510
4511
EXAMPLES::
4512
4513
sage: StrongTableaux.transpositions_to_standard_strong([[0,1]], 2)
4514
[[-1]]
4515
sage: StrongTableaux.transpositions_to_standard_strong([[-2,-1], [2,3]], 2, [[None, None]])
4516
[[None, None, -1], [1], [-2]]
4517
sage: StrongTableaux.transpositions_to_standard_strong([[2, 3], [1, 2], [0, 1]], 2)
4518
[[-1, -2, -3], [3]]
4519
sage: StrongTableaux.transpositions_to_standard_strong([[-1, 0], [1, 2], [0, 1]], 2)
4520
[[-1, -2, 3], [-3]]
4521
sage: StrongTableaux.transpositions_to_standard_strong([[3, 4], [-1, 0], [1, 2]], 2, [[None]])
4522
[[None, -1, 2, -3], [-2, 3]]
4523
4524
TESTS::
4525
4526
sage: StrongTableaux.transpositions_to_standard_strong([], 2, [[None, None, None], [None]])
4527
[[None, None, None], [None]]
4528
sage: StrongTableaux.transpositions_to_standard_strong([], 4, [])
4529
[]
4530
"""
4531
out = copy.deepcopy(emptyTableau)
4532
for i in range(1,len(transeq)+1):
4533
out = StrongTableaux._left_action_list(out, transeq[-i], i, k)
4534
return StrongTableau(out, k, weight = (1,)*len(transeq))
4535
4536
Element = StrongTableau
4537
4538
#### common or global functions related to weak/strong tableaux
4539
4540
def nabs(v):
4541
r"""
4542
Return the absolute value of ``v`` or ``None``.
4543
4544
INPUT:
4545
4546
- ``v`` -- either an integer or ``None``
4547
4548
OUTPUT:
4549
4550
- either a non-negative integer or ``None``
4551
4552
EXAMPLES::
4553
4554
sage: from sage.combinat.k_tableau import nabs
4555
sage: nabs(None)
4556
sage: nabs(-3)
4557
3
4558
sage: nabs(None)
4559
"""
4560
if v is None:
4561
return v
4562
else:
4563
return abs(v)
4564
4565
def intermediate_shapes(t):
4566
r"""
4567
Return the intermediate shapes of tableau ``t``.
4568
4569
A (skew) tableau with letters `1, 2,\ldots, \ell` can be viewed as a sequence of
4570
shapes, where the `i`-th shape is given by the shape of the subtableau on letters
4571
`1, 2, \ldots, i`. The output is the list of these shapes.
4572
4573
OUTPUT:
4574
4575
- a list of lists representing partitions
4576
4577
EXAMPLES::
4578
4579
sage: from sage.combinat.k_tableau import intermediate_shapes
4580
sage: t = WeakTableau([[1, 1, 2, 2, 3], [2, 3], [3]],3)
4581
sage: intermediate_shapes(t)
4582
[[], [2], [4, 1], [5, 2, 1]]
4583
4584
sage: t = WeakTableau([[None, None, 2, 3, 4], [1, 4], [2]], 3)
4585
sage: intermediate_shapes(t)
4586
[[2], [2, 1], [3, 1, 1], [4, 1, 1], [5, 2, 1]]
4587
"""
4588
shapes = []
4589
t = SkewTableau(list(t))
4590
for i in range(len(t.weight())+1):
4591
shapes += [ t.restrict(i).outer_shape()]
4592
return shapes
4593
4594