Path: blob/master/src/sage/combinat/crystals/kirillov_reshetikhin.py
8817 views
r"""1Kirillov-Reshetikhin Crystals2"""34#*****************************************************************************5# Copyright (C) 2009 Anne Schilling <anne at math.ucdavis.edu>6#7# Distributed under the terms of the GNU General Public License (GPL)8#9# This code is distributed in the hope that it will be useful,10# but WITHOUT ANY WARRANTY; without even the implied warranty of11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU12# General Public License for more details.13#14# The full text of the GPL is available at:15#16# http://www.gnu.org/licenses/17#****************************************************************************18# Acknowledgment: most of the design and implementation of this19# library is heavily inspired from MuPAD-Combinat.20#****************************************************************************2122from sage.misc.cachefunc import cached_method23from sage.misc.abstract_method import abstract_method24from sage.misc.functional import is_even, is_odd25from sage.functions.other import floor, ceil26from sage.combinat.combinat import CombinatorialObject27from sage.structure.parent import Parent28from sage.categories.regular_crystals import RegularCrystals29from sage.categories.finite_crystals import FiniteCrystals30from sage.rings.integer import Integer31from sage.rings.all import QQ32from sage.combinat.crystals.affine import AffineCrystalFromClassical, \33AffineCrystalFromClassicalElement, AffineCrystalFromClassicalAndPromotion, \34AffineCrystalFromClassicalAndPromotionElement35from sage.combinat.crystals.highest_weight_crystals import HighestWeightCrystal36from sage.combinat.crystals.littelmann_path import CrystalOfProjectedLevelZeroLSPaths37from sage.combinat.crystals.direct_sum import DirectSumOfCrystals38from sage.combinat.root_system.cartan_type import CartanType39from sage.combinat.root_system.root_system import RootSystem40from sage.combinat.crystals.tensor_product import CrystalOfTableaux, TensorProductOfCrystals41from sage.combinat.tableau import Tableau42from sage.combinat.partition import Partition, Partitions43from sage.combinat.integer_vector import IntegerVectors444546def KirillovReshetikhinCrystalFromLSPaths(cartan_type, r, s=1):47r"""48Single column Kirillov-Reshetikhin crystals.4950This yields the single column Kirillov-Reshetikhin crystals51from the projected level zero LS paths, see :class:`sage.combinat.crystals.littelmann_paths.CrystalOfLSPaths`.52This works for all types (even exceptional types).53The weight of the canonical element in this crystal is `\Lambda_r`.54For other implementation see :meth:`KirillovReshetikhinCrystal`.5556EXAMPLES::5758sage: from sage.combinat.crystals.kirillov_reshetikhin import KirillovReshetikhinCrystalFromLSPaths59sage: K = KirillovReshetikhinCrystalFromLSPaths(['A',2,1],2)60sage: KR = KirillovReshetikhinCrystal(['A',2,1],2,1)61sage: G = K.digraph()62sage: GR = KR.digraph()63sage: G.is_isomorphic(GR, edge_labels = True)64True6566sage: K = KirillovReshetikhinCrystalFromLSPaths(['C',3,1],2)67sage: KR = KirillovReshetikhinCrystal(['C',3,1],2,1)68sage: G = K.digraph()69sage: GR = KR.digraph()70sage: G.is_isomorphic(GR, edge_labels = True)71True7273sage: K = KirillovReshetikhinCrystalFromLSPaths(['E',6,1],1)74sage: KR = KirillovReshetikhinCrystal(['E',6,1],1,1)75sage: G = K.digraph()76sage: GR = KR.digraph()77sage: G.is_isomorphic(GR, edge_labels = True)78True79sage: K.cardinality()80278182sage: K = KirillovReshetikhinCrystalFromLSPaths(['G',2,1],1)83sage: K.cardinality()8478586sage: K = KirillovReshetikhinCrystalFromLSPaths(['B',3,1],2)87sage: KR = KirillovReshetikhinCrystal(['B',3,1],2,1)88sage: KR.cardinality()892290sage: K.cardinality()912292sage: G = K.digraph()93sage: GR = KR.digraph()94sage: G.is_isomorphic(GR, edge_labels = True)95True969798TESTS::99100sage: K = KirillovReshetikhinCrystalFromLSPaths(['G',2,1],2)101sage: K.cardinality()10215103104For `s>1` these crystals yield `s`-fold tensor products of Kirillov-Reshetikhin crystals::105106sage: K = KirillovReshetikhinCrystalFromLSPaths(['A',1,1],1,3)107sage: B = KirillovReshetikhinCrystal(['A',1,1],1,1)108sage: T = TensorProductOfCrystals(B,B,B)109sage: G = K.digraph()110sage: GT = T.digraph()111sage: G.is_isomorphic(GT, edge_labels = True)112True113114sage: K = KirillovReshetikhinCrystalFromLSPaths(['B',2,1],1,2)115sage: B = KirillovReshetikhinCrystal(['B',2,1],1,1)116sage: T = TensorProductOfCrystals(B,B)117sage: G = K.digraph()118sage: GT = T.digraph()119sage: G.is_isomorphic(GT, edge_labels = True)120True121122sage: K = KirillovReshetikhinCrystalFromLSPaths(['B',2,1],2,3)123sage: B = KirillovReshetikhinCrystal(['B',2,1],2,1)124sage: T = TensorProductOfCrystals(B,B,B)125sage: GT = T.digraph()126sage: G = K.digraph()127sage: G.is_isomorphic(GT, edge_labels = True)128True129"""130R = RootSystem(cartan_type)131La = R.weight_space().basis()132weight = s*La[r]133return CrystalOfProjectedLevelZeroLSPaths(weight)134135136def KirillovReshetikhinCrystal(cartan_type, r, s):137r"""138Return the Kirillov-Reshetikhin crystal `B^{r,s}` of the given type.139140For more information about general crystals see :mod:`sage.combinat.crystals`.141142Many Kirillov-Reshetikhin crystals are constructed from a143classical crystal together with an automorphism `p` on the level of crystals which144corresponds to a Dynkin diagram automorphism mapping node 0 to some other node `i`.145The action of `f_0` and `e_0` is then constructed using146`f_0 = p^{-1} \circ f_i \circ p`.147148For example, for type `A_n^{(1)}` the Kirillov-Reshetikhin crystal `B^{r,s}`149is obtained from the classical crystal `B(s \omega_r)` using the150promotion operator. For other types, see [Shimozono02]_, [Schilling08]_,151and [JS2010]_.152153Other Kirillov-Reshetikhin crystals are constructed using similarity methods.154See Section 4 of [FOS09]_.155156For an implementation of Kirillov-Reshetikhin crystals for `s = 1` from157crystals of LS paths, see :meth:`KirillovReshetikhinCrystalFromLSPaths`.158159INPUT:160161- ``cartan_type`` -- Affine type and rank162163- ``r`` -- Label of finite Dynkin diagram164165- ``s`` -- Positive integer166167EXAMPLES::168169sage: K = KirillovReshetikhinCrystal(['A',3,1], 2, 1)170sage: K.index_set()171(0, 1, 2, 3)172sage: K.list()173[[[1], [2]], [[1], [3]], [[2], [3]], [[1], [4]], [[2], [4]], [[3], [4]]]174sage: b=K(rows=[[1],[2]])175sage: b.weight()176-Lambda[0] + Lambda[2]177178sage: K = KirillovReshetikhinCrystal(['A',3,1], 2,2)179sage: K.automorphism(K.module_generators[0])180[[2, 2], [3, 3]]181sage: K.module_generators[0].e(0)182[[1, 2], [2, 4]]183sage: K.module_generators[0].f(2)184[[1, 1], [2, 3]]185sage: K.module_generators[0].f(1)186sage: K.module_generators[0].phi(0)1870188sage: K.module_generators[0].phi(1)1890190sage: K.module_generators[0].phi(2)1912192sage: K.module_generators[0].epsilon(0)1932194sage: K.module_generators[0].epsilon(1)1950196sage: K.module_generators[0].epsilon(2)1970198sage: b = K(rows=[[1,2],[2,3]])199sage: b200[[1, 2], [2, 3]]201sage: b.f(2)202[[1, 2], [3, 3]]203204sage: K = KirillovReshetikhinCrystal(['D',4,1], 2, 1)205sage: K.cartan_type()206['D', 4, 1]207sage: type(K.module_generators[0])208<class 'sage.combinat.crystals.kirillov_reshetikhin.KR_type_vertical_with_category.element_class'>209210The following gives some tests with regards to Lemma 3.11 in [LOS12]_.211212TESTS::213214sage: K = KirillovReshetikhinCrystal(['A',4,2],2,1)215sage: Lambda = K.weight_lattice_realization().fundamental_weights()216sage: [b for b in K if b.Epsilon() == Lambda[0]]217[[]]218219sage: K = KirillovReshetikhinCrystal(['D',4,2],1,2)220sage: Lambda = K.weight_lattice_realization().fundamental_weights()221sage: [b for b in K if b.Epsilon() == 2*Lambda[0]]222[[]]223sage: [b for b in K if b.Epsilon() == 2*Lambda[3]]224[[[3, -3]]]225sage: K = KirillovReshetikhinCrystal(['D',4,2],1,1)226sage: [b for b in K if b.Epsilon() == Lambda[3]]227[[[0]]]228229sage: K = KirillovReshetikhinCrystal(['B',3,1],2,1)230sage: Lambda = K.weight_lattice_realization().fundamental_weights()231sage: [b for b in K if b.Epsilon() == Lambda[0]]232[[]]233sage: [b for b in K if b.Epsilon() == Lambda[1]]234[[[2], [-2]]]235sage: K = KirillovReshetikhinCrystal(['B',3,1],2,2)236sage: [b for b in K if b.Epsilon() == 2*Lambda[0]]237[[]]238sage: [b for b in K if b.Epsilon() == 2*Lambda[1]]239[[[1, 2], [-2, -1]]]240sage: K = KirillovReshetikhinCrystal(['B',3,1],2,3)241sage: [b for b in K if b.Epsilon() == 3*Lambda[1]] # long time242[[[1, 2, 2], [-2, -2, -1]]]243244sage: K = KirillovReshetikhinCrystal(['D',4,1],2,2)245sage: Lambda = K.weight_lattice_realization().fundamental_weights()246sage: [b for b in K if b.Epsilon() == 2*Lambda[0]] # long time247[[]]248sage: [b for b in K if b.Epsilon() == 2*Lambda[4]] # long time249[[[3, -4], [4, -3]]]250251sage: K = KirillovReshetikhinCrystal(['B',3,1],3,1)252sage: Lambda = K.weight_lattice_realization().fundamental_weights()253sage: [b for b in K if b.Epsilon() == Lambda[0]]254[[+++, []]]255sage: [b for b in K if b.Epsilon() == Lambda[1]]256[[-++, []]]257sage: K = KirillovReshetikhinCrystal(['B',3,1],3,3)258sage: [b for b in K if b.Epsilon() == 2*Lambda[0]] # long time259[[+++, [[1]]]]260sage: [b for b in K if b.Epsilon() == 2*Lambda[1]] # long time261[[-++, [[-1]]]]262263sage: K = KirillovReshetikhinCrystal(['B',4,1],4,1)264sage: Lambda = K.weight_lattice_realization().fundamental_weights()265sage: [b for b in K if b.Epsilon() == Lambda[0]]266[[++++, []]]267sage: [b for b in K if b.Epsilon() == Lambda[1]]268[[-+++, []]]269270sage: K = KirillovReshetikhinCrystal(['C',3,1],1,1)271sage: Lambda = K.weight_lattice_realization().fundamental_weights()272sage: [b for b in K if b.Epsilon() == Lambda[0]]273[[[1]]]274sage: [b for b in K if b.Epsilon() == Lambda[3]]275[[[-3]]]276sage: K = KirillovReshetikhinCrystal(['C',3,1],1,3)277sage: [b for b in K if b.Epsilon() == 2*Lambda[3]] # long time278[[[3, -3, -3]]]279sage: [b for b in K if b.Epsilon() == 2*Lambda[0]] # long time280[[[1]]]281282REFERENCES:283284.. [Shimozono02] M. Shimozono285*Affine type A crystal structure on tensor products of rectangles,286Demazure characters, and nilpotent varieties*,287J. Algebraic Combin. **15** (2002). no. 2. 151-187.288:arxiv:`math.QA/9804039`.289290.. [Schilling08] A. Schilling. "Combinatorial structure of291Kirillov-Reshetikhin crystals of type `D_n(1)`, `B_n(1)`, `A_{2n-1}(2)`".292J. Algebra. **319** (2008). 2938-2962. :arxiv:`0704.2046`.293294.. [JS2010] B. Jones, A. Schilling.295"Affine structures and a tableau model for `E_6` crystals",296J. Algebra. **324** (2010). 2512-2542.297:doi:`10.1016/j.bbr.2011.03.031`, :arxiv:`0909.2442`.298299.. [FOS09] G. Fourier, M. Okado, A. Schilling.300*Kirillov-Reshetikhin crystals for nonexceptional types*.301Advances in Mathematics. **222** (2009). Issue 3. 1080-1116.302:arxiv:`0810.5067`.303304.. [LOS12] C. Lecouvey, M. Okado, M. Shimozono.305"Affine crystals, one-dimensional sums and parabolic Lusztig306`q`-analogues". Mathematische Zeitschrift. **271** (2012). Issue 3-4.307819-865. :doi:`10.1007/s00209-011-0892-9`, :arxiv:`1002.3715`.308"""309ct = CartanType(cartan_type)310assert ct.is_affine()311if ct.is_untwisted_affine():312if ct.type() == 'A':313return KR_type_A(ct, r, s)314elif ct.type() == 'D':315if r<ct.rank()-2:316return KR_type_vertical(ct, r, s)317elif r in {ct.rank()-2,ct.rank()-1}:318return KR_type_spin(ct, r, s)319else:320raise ValueError("wrong range of parameters")321elif ct.type() == 'B':322if r<ct.rank()-1:323return KR_type_vertical(ct, r, s)324elif r == ct.rank()-1:325return KR_type_Bn(ct, r, s)326else:327raise ValueError("wrong range of parameters")328elif ct.type() == 'C':329if r<ct.rank()-1:330return KR_type_C(ct, r, s)331elif r == ct.rank()-1:332return KR_type_Cn(ct, r, s)333else:334raise ValueError("wrong range of parameters")335elif ct == CartanType(['E',6,1]) and r in [1,6,2]:336return KR_type_E6(ct, r, s)337else:338raise NotImplementedError339else:340if ct.dual().type() == 'B':341return KR_type_vertical(ct, r, s)342elif ct.type() == 'BC':343return KR_type_box(ct, r, s)344elif ct.dual().type() == 'BC':345return KR_type_A2(ct, r, s)346elif ct.dual().type() == 'C':347if r<ct.rank()-1:348return KR_type_box(ct, r, s)349elif r == ct.rank()-1:350return KR_type_Dn_twisted(ct, r, s)351else:352raise ValueError("wrong range of parameters")353else:354raise NotImplementedError355356357class KirillovReshetikhinGenericCrystal(AffineCrystalFromClassical):358r"""359Generic class for Kirillov-Reshetikhin crystal `B^{r,s}` of the given type.360361Input is a Dynkin node ``r``, a positive integer ``s``, and a Cartan type362``cartan_type``.363"""364365def __init__(self, cartan_type, r, s, dual = None):366r"""367Initializes a generic Kirillov-Reshetikhin crystal.368369TESTS::370371sage: K = KirillovReshetikhinCrystal(CartanType(['A',2,1]), 1, 1)372sage: K373Kirillov-Reshetikhin crystal of type ['A', 2, 1] with (r,s)=(1,1)374sage: K.r()3751376sage: K.s()3771378"""379# We need this here for the classical_decomposition() call380Parent.__init__(self, category = (RegularCrystals(), FiniteCrystals()))381if dual is None:382self._cartan_type = cartan_type383else:384self._cartan_type = CartanType(cartan_type).dual()385self._r = r386self._s = s387self._dual = dual388AffineCrystalFromClassical.__init__(self, cartan_type, self.classical_decomposition())389390def _repr_(self):391"""392EXAMPLES::393394sage: KirillovReshetikhinCrystal(CartanType(['A',2,1]), 1, 1) # indirect doctest395Kirillov-Reshetikhin crystal of type ['A', 2, 1] with (r,s)=(1,1)396"""397return "Kirillov-Reshetikhin crystal of type %s with (r,s)=(%d,%d)" % (self.cartan_type(), self.r(), self.s())398399def _element_constructor_(self, *args, **options):400"""401Construct an element of ``self`` from the input.402403EXAMPLES::404405sage: K = KirillovReshetikhinCrystal(['A', 4, 1], 2, 1)406sage: K(columns=[[2,1]]) # indirect doctest407[[1], [2]]408"""409from sage.combinat.rigged_configurations.kr_tableaux import KirillovReshetikhinTableauxElement410if isinstance(args[0], KirillovReshetikhinTableauxElement):411elt = args[0]412# Check to make sure it can be converted413if elt.cartan_type() != self.cartan_type() \414or elt.parent().r() != self._r or elt.parent().s() != self._s:415raise ValueError("The Kirillov-Reshetikhin tableau must have the same Cartan type and shape")416417to_hw = elt.to_classical_highest_weight()418rows = []419letters = elt.parent().letters420for val in to_hw[0].classical_weight():421# val in classical weight is a pair (i, mult)422rows.append([letters(val[0]+1)]*int(val[1]))423hw_elt = self(rows=rows)424f_str = reversed(to_hw[1])425return hw_elt.f_string(f_str)426return AffineCrystalFromClassical._element_constructor_(self, *args, **options)427428@abstract_method429def classical_decomposition(self):430"""431Return the classical decomposition of ``self``.432433EXAMPLES::434435sage: K = KirillovReshetikhinCrystal(['A',3,1], 2,2)436sage: K.classical_decomposition()437The crystal of tableaux of type ['A', 3] and shape(s) [[2, 2]]438"""439440def module_generator(self):441r"""442Returns the unique module generator of classical weight `s \Lambda_r` of a Kirillov-Reshetikhin crystal `B^{r,s}`443444EXAMPLES::445446sage: K = KirillovReshetikhinCrystal(['C',2,1],1,2)447sage: K.module_generator()448[[1, 1]]449sage: K = KirillovReshetikhinCrystal(['E',6,1],1,1)450sage: K.module_generator()451[(1,)]452453sage: K = KirillovReshetikhinCrystal(['D',4,1],2,1)454sage: K.module_generator()455[[1], [2]]456"""457R = self.weight_lattice_realization()458Lambda = R.fundamental_weights()459r = self.r()460s = self.s()461weight = s*Lambda[r] - s*Lambda[0] * Lambda[r].level() / Lambda[0].level()462return [ b for b in self.module_generators if b.weight() == weight][0]463464def r(self):465"""466Returns r of the underlying Kirillov-Reshetikhin crystal `B^{r,s}`467468EXAMPLES::469470sage: K = KirillovReshetikhinCrystal(['D',4,1], 2, 1)471sage: K.r()4722473"""474return self._r475476def s(self):477"""478Returns s of the underlying Kirillov-Reshetikhin crystal `B^{r,s}`479480EXAMPLES::481482sage: K = KirillovReshetikhinCrystal(['D',4,1], 2, 1)483sage: K.s()4841485"""486return self._s487488def is_perfect(self):489r"""490Returns True or False depending on whether ``self`` is a perfect crystal or not, respectively.491492If ``self`` is the Kirillov-Reshetikhin crystal `B^{r,s}`, then it was proven in [FOS2010]_493that it is perfect if and only if `s/c_r` is an integer (where `c_r` is a constant related to the494type of the crystal).495496REFERENCES:497498.. [FOS2010] G. Fourier, M. Okado, A. Schilling.499Perfectness of Kirillov-Reshetikhin crystals for nonexceptional types500Contemp. Math. 506 (2010) 127-143 ( arXiv:0811.1604 [math.RT] )501502EXAMPLES::503504sage: K = KirillovReshetikhinCrystal(['A',2,1], 1, 1)505sage: K.is_perfect()506True507508sage: K = KirillovReshetikhinCrystal(['C',2,1], 1, 1)509sage: K.is_perfect()510False511512sage: K = KirillovReshetikhinCrystal(['C',2,1], 1, 2)513sage: K.is_perfect()514True515"""516x = self.s()/self.cartan_type().c()[self.r()]517return x - ceil(x) == 0518519def level(self):520r"""521Returns the level of ``self`` assuming that it is a perfect crystal.522523If ``self`` is the Kirillov-Reshetikhin crystal `B^{r,s}`, then it was proven in [FOS2010]_524that its level is `s/c_r` which is an integer if ``self`` is perfect525(here `c_r` is a constant related to the type of the crystal).526527EXAMPLES::528529sage: K = KirillovReshetikhinCrystal(['A',2,1], 1, 1)530sage: K.level()5311532sage: K = KirillovReshetikhinCrystal(['C',2,1], 1, 2)533sage: K.level()5341535sage: K = KirillovReshetikhinCrystal(['D',4,1], 1, 3)536sage: K.level()5373538539sage: K = KirillovReshetikhinCrystal(['C',2,1], 1, 1)540sage: K.level()541Traceback (most recent call last):542...543AssertionError: This crystal is not perfect!544"""545assert self.is_perfect(), "This crystal is not perfect!"546return self.s()/self.cartan_type().c()[self.r()]547548@cached_method549def R_matrix(self, K):550r"""551INPUT:552553- ``self`` -- a crystal `L`554- ``K`` -- a Kirillov-Reshetikhin crystal of the same type as `L`.555556Returns the *combinatorial `R`-matrix* from `L \otimes K \to K557\otimes L`, where the combinatorial `R`-matrix is the affine558crystal isomorphism which maps `u_{L} \otimes u_K` to `u_K559\otimes u_{L}`, where `u_K` is the unique element in `K =560B^{r,s}` of weight `s\Lambda_r - s c \Lambda_0` (see561module_generator).562563EXAMPLES::564565sage: K = KirillovReshetikhinCrystal(['A',2,1],1,1)566sage: L = KirillovReshetikhinCrystal(['A',2,1],1,2)567sage: f = K.R_matrix(L)568sage: [[b,f(b)] for b in TensorProductOfCrystals(K,L)]569[[[[[1]], [[1, 1]]], [[[1, 1]], [[1]]]],570[[[[1]], [[1, 2]]], [[[1, 1]], [[2]]]],571[[[[1]], [[2, 2]]], [[[1, 2]], [[2]]]],572[[[[1]], [[1, 3]]], [[[1, 1]], [[3]]]],573[[[[1]], [[2, 3]]], [[[1, 2]], [[3]]]],574[[[[1]], [[3, 3]]], [[[1, 3]], [[3]]]],575[[[[2]], [[1, 1]]], [[[1, 2]], [[1]]]],576[[[[2]], [[1, 2]]], [[[2, 2]], [[1]]]],577[[[[2]], [[2, 2]]], [[[2, 2]], [[2]]]],578[[[[2]], [[1, 3]]], [[[2, 3]], [[1]]]],579[[[[2]], [[2, 3]]], [[[2, 2]], [[3]]]],580[[[[2]], [[3, 3]]], [[[2, 3]], [[3]]]],581[[[[3]], [[1, 1]]], [[[1, 3]], [[1]]]],582[[[[3]], [[1, 2]]], [[[1, 3]], [[2]]]],583[[[[3]], [[2, 2]]], [[[2, 3]], [[2]]]],584[[[[3]], [[1, 3]]], [[[3, 3]], [[1]]]],585[[[[3]], [[2, 3]]], [[[3, 3]], [[2]]]],586[[[[3]], [[3, 3]]], [[[3, 3]], [[3]]]]]587588sage: K = KirillovReshetikhinCrystal(['D',4,1],1,1)589sage: L = KirillovReshetikhinCrystal(['D',4,1],2,1)590sage: f = K.R_matrix(L)591sage: T = TensorProductOfCrystals(K,L)592sage: b = T( K(rows=[[1]]), L(rows=[]) )593sage: f(b)594[[[2], [-2]], [[1]]]595596Alternatively, one can compute the combinatorial `R`-matrix using the isomorphism method597of digraphs::598599sage: K1 = KirillovReshetikhinCrystal(['A',2,1],1,1)600sage: K2 = KirillovReshetikhinCrystal(['A',2,1],2,1)601sage: T1 = TensorProductOfCrystals(K1,K2)602sage: T2 = TensorProductOfCrystals(K2,K1)603sage: T1.digraph().is_isomorphic(T2.digraph(), edge_labels = True, certify = True) #todo: not implemented (see #10904 and #10549)604(True, {[[[1]], [[2], [3]]]: [[[1], [3]], [[2]]], [[[3]], [[2], [3]]]: [[[2], [3]], [[3]]],605[[[3]], [[1], [3]]]: [[[1], [3]], [[3]]], [[[1]], [[1], [3]]]: [[[1], [3]], [[1]]], [[[1]],606[[1], [2]]]: [[[1], [2]], [[1]]], [[[2]], [[1], [2]]]: [[[1], [2]], [[2]]], [[[3]],607[[1], [2]]]: [[[2], [3]], [[1]]], [[[2]], [[1], [3]]]: [[[1], [2]], [[3]]], [[[2]], [[2], [3]]]: [[[2], [3]], [[2]]]})608"""609T1 = TensorProductOfCrystals(self, K)610T2 = TensorProductOfCrystals(K, self)611gen1 = T1( self.module_generator(), K.module_generator() )612gen2 = T2( K.module_generator(), self.module_generator() )613g = { gen1 : gen2 }614return T1.crystal_morphism(g, acyclic = False)615616@cached_method617def kirillov_reshetikhin_tableaux(self):618"""619Return the corresponding set of :class:`KirillovReshetikhinTableaux`.620621EXAMPLES::622623sage: KRC = KirillovReshetikhinCrystal(['D', 4, 1], 2, 2)624sage: KRC.kirillov_reshetikhin_tableaux()625Kirillov-Reshetikhin tableaux of type ['D', 4, 1] and shape (2, 2)626"""627from sage.combinat.rigged_configurations.kr_tableaux import KirillovReshetikhinTableaux628return KirillovReshetikhinTableaux(self.cartan_type(), self._r, self._s)629630class KirillovReshetikhinGenericCrystalElement(AffineCrystalFromClassicalElement):631"""632Abstract class for all Kirillov-Reshetikhin crystal elements.633"""634@cached_method635def to_kirillov_reshetikhin_tableau(self):636r"""637Construct the corresponding638:class:`KirillovReshetikhinTableauxElement` from ``self``.639640We construct the Kirillov-Reshetikhin tableau element as follows:6416421. Let `\lambda` be the shape of ``self``.6432. Determine a path `e_{i_1} e_{i_2} \cdots e_{i_k}` to the highest644weight.6453. Apply `f_{i_k} \cdots f_{i_2} f_{i_1}` to a highest weight KR646tableau from filling the shape `\lambda`.647648EXAMPLES::649650sage: KRC = KirillovReshetikhinCrystal(['A', 4, 1], 2, 1)651sage: KRC(columns=[[2,1]]).to_kirillov_reshetikhin_tableau()652[[1], [2]]653sage: KRC = KirillovReshetikhinCrystal(['D', 4, 1], 2, 1)654sage: KRC(rows=[]).to_kirillov_reshetikhin_tableau()655[[1], [-1]]656"""657return self.parent().kirillov_reshetikhin_tableaux()(self)658659KirillovReshetikhinGenericCrystal.Element = KirillovReshetikhinGenericCrystalElement660661class KirillovReshetikhinCrystalFromPromotion(KirillovReshetikhinGenericCrystal,662AffineCrystalFromClassicalAndPromotion):663r"""664This generic class assumes that the Kirillov-Reshetikhin crystal is constructed665from a classical crystal 'classical_decomposition' and an automorphism 'promotion' and its inverse666which corresponds to a Dynkin diagram automorphism 'dynkin_diagram_automorphism'.667668Each instance using this class needs to implement the methods:669670- classical_decomposition671- promotion672- promotion_inverse673- dynkin_diagram_automorphism674"""675def __init__(self, cartan_type, r, s):676r"""677TESTS::678679sage: K = KirillovReshetikhinCrystal(['B',2,1], 1, 1)680sage: K681Kirillov-Reshetikhin crystal of type ['B', 2, 1] with (r,s)=(1,1)682sage: TestSuite(K).run()683"""684KirillovReshetikhinGenericCrystal.__init__(self, cartan_type, r, s)685AffineCrystalFromClassicalAndPromotion.__init__(self, cartan_type, self.classical_decomposition(),686self.promotion(), self.promotion_inverse(),687self.dynkin_diagram_automorphism(0))688689class KirillovReshetikhinCrystalFromPromotionElement(AffineCrystalFromClassicalAndPromotionElement,690KirillovReshetikhinGenericCrystalElement):691"""692Element for a Kirillov-Reshetikhin crystal from promotion.693"""694pass695696KirillovReshetikhinCrystalFromPromotion.Element = KirillovReshetikhinCrystalFromPromotionElement697698class KR_type_A(KirillovReshetikhinCrystalFromPromotion):699r"""700Class of Kirillov-Reshetikhin crystals of type `A_n^{(1)}`.701702EXAMPLES::703704sage: K = KirillovReshetikhinCrystal(['A',3,1], 2,2)705sage: b = K(rows=[[1,2],[2,4]])706sage: b.f(0)707[[1, 1], [2, 2]]708"""709710def classical_decomposition(self):711"""712Specifies the classical crystal underlying the KR crystal of type A.713714EXAMPLES::715716sage: K = KirillovReshetikhinCrystal(['A',3,1], 2,2)717sage: K.classical_decomposition()718The crystal of tableaux of type ['A', 3] and shape(s) [[2, 2]]719"""720return CrystalOfTableaux(self.cartan_type().classical(), shape = [self.s() for i in range(1,self.r()+1)])721722@cached_method723def promotion(self):724"""725Specifies the promotion operator used to construct the affine type A crystal.726For type A this corresponds to the Dynkin diagram automorphism which maps i to i+1 mod n+1,727where n is the rank.728729EXAMPLES::730731sage: K = KirillovReshetikhinCrystal(['A',3,1], 2,2)732sage: b = K.classical_decomposition()(rows=[[1,2],[3,4]])733sage: K.promotion()(b)734[[1, 3], [2, 4]]735"""736return lambda x : self.classical_crystal(x.to_tableau().promotion(self._cartan_type[1]))737738@cached_method739def promotion_inverse(self):740"""741Specifies the inverse promotion operator used to construct the affine type A crystal.742For type A this corresponds to the Dynkin diagram automorphism which maps i to i-1 mod n+1,743where n is the rank.744745EXAMPLES::746747sage: K = KirillovReshetikhinCrystal(['A',3,1], 2,2)748sage: b = K.classical_decomposition()(rows=[[1,3],[2,4]])749sage: K.promotion_inverse()(b)750[[1, 2], [3, 4]]751sage: b = K.classical_decomposition()(rows=[[1,2],[3,3]])752sage: K.promotion_inverse()(K.promotion()(b))753[[1, 2], [3, 3]]754"""755return lambda x : self.classical_crystal(x.to_tableau().promotion_inverse(self._cartan_type[1]))756757def dynkin_diagram_automorphism(self, i):758"""759Specifies the Dynkin diagram automorphism underlying the promotion action on the crystal760elements. The automorphism needs to map node 0 to some other Dynkin node.761762For type A we use the Dynkin diagram automorphism which maps i to i+1 mod n+1, where n is the rank.763764EXAMPLES::765766sage: K = KirillovReshetikhinCrystal(['A',3,1], 2,2)767sage: K.dynkin_diagram_automorphism(0)7681769sage: K.dynkin_diagram_automorphism(3)7700771"""772aut = range(1,self.cartan_type().rank())+[0]773return aut[i]774775class KR_type_vertical(KirillovReshetikhinCrystalFromPromotion):776r"""777Class of Kirillov-Reshetikhin crystals `B^{r,s}` of type `D_n^{(1)}` for `r\le n-2`,778`B_n^{(1)}` for `r<n`, and `A_{2n-1}^{(2)}` for `r\le n`.779780EXAMPLES::781782sage: K = KirillovReshetikhinCrystal(['D',4,1], 2,2)783sage: b = K(rows=[])784sage: b.f(0)785[[1], [2]]786sage: b.f(0).f(0)787[[1, 1], [2, 2]]788sage: b.e(0)789[[-2], [-1]]790sage: b.e(0).e(0)791[[-2, -2], [-1, -1]]792793sage: K = KirillovReshetikhinCrystal(['D',5,1], 3,1)794sage: b = K(rows=[[1]])795sage: b.e(0)796[[3], [-3], [-2]]797798sage: K = KirillovReshetikhinCrystal(['B',3,1], 1,1)799sage: [[b,b.f(0)] for b in K]800[[[[1]], None], [[[2]], None], [[[3]], None], [[[0]], None], [[[-3]], None], [[[-2]], [[1]]], [[[-1]], [[2]]]]801802sage: K = KirillovReshetikhinCrystal(['A',5,2], 1,1)803sage: [[b,b.f(0)] for b in K]804[[[[1]], None], [[[2]], None], [[[3]], None], [[[-3]], None], [[[-2]], [[1]]], [[[-1]], [[2]]]]805"""806807def classical_decomposition(self):808r"""809Specifies the classical crystal underlying the Kirillov-Reshetikhin crystal of type `D_n^{(1)}`,810`B_n^{(1)}`, and `A_{2n-1}^{(2)}`.811812It is given by `B^{r,s} \cong \bigoplus_\Lambda B(\Lambda)` where `\Lambda` are weights obtained from813a rectangle of width `s` and height `r` by removing verticle dominoes. Here we identify the fundamental814weight `\Lambda_i` with a column of height `i`.815816EXAMPLES::817818sage: K = KirillovReshetikhinCrystal(['D',4,1], 2,2)819sage: K.classical_decomposition()820The crystal of tableaux of type ['D', 4] and shape(s) [[], [1, 1], [2, 2]]821"""822return CrystalOfTableaux(self.cartan_type().classical(),823shapes = vertical_dominoes_removed(self.r(),self.s()))824825@cached_method826def promotion(self):827"""828Specifies the promotion operator used to construct the affine type `D_n^{(1)}` etc. crystal.829This corresponds to the Dynkin diagram automorphism which interchanges nodes 0 and 1,830and leaves all other nodes unchanged. On the level of crystals it is constructed using831`\pm` diagrams.832833EXAMPLES::834835sage: K = KirillovReshetikhinCrystal(['D',4,1], 2,2)836sage: promotion = K.promotion()837sage: b = K.classical_decomposition()(rows=[])838sage: promotion(b)839[[1, 2], [-2, -1]]840sage: b = K.classical_decomposition()(rows=[[1,3],[2,-1]])841sage: promotion(b)842[[1, 3], [2, -1]]843sage: b = K.classical_decomposition()(rows=[[1],[-3]])844sage: promotion(b)845[[2, -3], [-2, -1]]846"""847T = self.classical_decomposition()848ind = list(T.index_set())849ind.remove(1)850return T.crystal_morphism( self.promotion_on_highest_weight_vectors(), index_set = ind)851852def promotion_inverse(self):853"""854Return inverse of promotion.855856In this case promotion is an involution, so promotion inverse equals promotion.857858EXAMPLES::859860sage: K = KirillovReshetikhinCrystal(['D',4,1], 2,2)861sage: promotion = K.promotion()862sage: promotion_inverse = K.promotion_inverse()863sage: all( promotion_inverse(promotion(b.lift())) == b.lift() for b in K )864True865"""866return self.promotion()867868def dynkin_diagram_automorphism(self, i):869"""870Specifies the Dynkin diagram automorphism underlying the promotion action on the crystal871elements. The automorphism needs to map node 0 to some other Dynkin node.872873Here we use the Dynkin diagram automorphism which interchanges nodes 0 and 1 and leaves874all other nodes unchanged.875876EXAMPLES::877878sage: K = KirillovReshetikhinCrystal(['D',4,1],1,1)879sage: K.dynkin_diagram_automorphism(0)8801881sage: K.dynkin_diagram_automorphism(1)8820883sage: K.dynkin_diagram_automorphism(4)8844885"""886aut = [1,0]+range(2,self.cartan_type().rank())887return aut[i]888889@cached_method890def promotion_on_highest_weight_vectors(self):891"""892Calculates promotion on `{2,3,...,n}` highest weight vectors.893894EXAMPLES::895896sage: K = KirillovReshetikhinCrystal(['D',4,1], 2,2)897sage: T = K.classical_decomposition()898sage: hw = [ b for b in T if all(b.epsilon(i)==0 for i in [2,3,4]) ]899sage: [K.promotion_on_highest_weight_vectors()(b) for b in hw]900[[[1, 2], [-2, -1]], [[2, 2], [-2, -1]], [[1, 2], [3, -1]], [[2], [-2]],901[[1, 2], [2, -2]], [[2, 2], [-1, -1]], [[2, 2], [3, -1]], [[2, 2], [3, 3]],902[], [[1], [2]], [[1, 1], [2, 2]], [[2], [-1]], [[1, 2], [2, -1]], [[2], [3]],903[[1, 2], [2, 3]]]904"""905return lambda b: self.from_pm_diagram_to_highest_weight_vector(self.from_highest_weight_vector_to_pm_diagram(b).sigma())906907def from_highest_weight_vector_to_pm_diagram(self, b):908"""909This gives the bijection between an element b in the classical decomposition910of the KR crystal that is `{2,3,..,n}`-highest weight and `\pm` diagrams.911912EXAMPLES::913914sage: K = KirillovReshetikhinCrystal(['D',4,1], 2,2)915sage: T = K.classical_decomposition()916sage: b = T(rows=[[2],[-2]])917sage: pm = K.from_highest_weight_vector_to_pm_diagram(b); pm918[[1, 1], [0, 0], [0]]919sage: pm.__repr__(pretty_printing=True)920+921-922sage: b = T(rows=[])923sage: pm=K.from_highest_weight_vector_to_pm_diagram(b); pm924[[0, 2], [0, 0], [0]]925sage: pm.__repr__(pretty_printing=True)926927sage: hw = [ b for b in T if all(b.epsilon(i)==0 for i in [2,3,4]) ]928sage: all(K.from_pm_diagram_to_highest_weight_vector(K.from_highest_weight_vector_to_pm_diagram(b)) == b for b in hw)929True930"""931n = self.cartan_type().rank()-1932inner = Partition([Integer(b.weight()[i]) for i in range(1,n+1)])933inter = Partition([len([i for i in r if i>0]) for r in b.to_tableau()])934outer = b.to_tableau().shape()935return PMDiagram([self.r(), self.s(), outer, inter, inner], from_shapes=True)936937def from_pm_diagram_to_highest_weight_vector(self, pm):938"""939This gives the bijection between a `\pm` diagram and an element b in the classical940decomposition of the KR crystal that is {2,3,..,n}-highest weight.941942EXAMPLES::943944sage: K = KirillovReshetikhinCrystal(['D',4,1], 2,2)945sage: pm = sage.combinat.crystals.kirillov_reshetikhin.PMDiagram([[1, 1], [0, 0], [0]])946sage: K.from_pm_diagram_to_highest_weight_vector(pm)947[[2], [-2]]948"""949u = [b for b in self.classical_decomposition().module_generators if b.to_tableau().shape() == pm.outer_shape()][0]950ct = self.cartan_type()951rank = ct.rank()-1952ct_type = ct.classical().type()953assert ct_type in ['B', 'C', 'D']954list = []955for h in pm.heights_of_addable_plus():956list += range(1,h+1)957for h in pm.heights_of_minus():958if ct_type == 'D':959list += range(1,rank+1)+[rank-2-k for k in range(rank-1-h)]960elif ct_type == 'B':961list += range(1,rank+1)+[rank-k for k in range(rank+1-h)]962else:963list += range(1,rank+1)+[rank-1-k for k in range(rank-h)]964for i in reversed(list):965u = u.f(i)966return u967968class KR_type_E6(KirillovReshetikhinCrystalFromPromotion):969r"""970Class of Kirillov-Reshetikhin crystals of type `E_6^{(1)}` for `r=1,2,6`.971972EXAMPLES::973974sage: K = KirillovReshetikhinCrystal(['E',6,1],2,1)975sage: K.module_generator().e(0)976[]977sage: K.module_generator().e(0).f(0)978[[(2, -1), (1,)]]979sage: K = KirillovReshetikhinCrystal(['E',6,1], 1,1)980sage: b = K.module_generator()981sage: b982[(1,)]983sage: b.e(0)984[(-2, 1)]985sage: b = [t for t in K if t.epsilon(1) == 1 and t.phi(3) == 1 and t.phi(2) == 0 and t.epsilon(2) == 0][0]986sage: b987[(-1, 3)]988sage: b.e(0)989[(-1, -2, 3)]990991The elements of the Kirillov-Reshetikhin crystals can be constructed from a classical992crystal element using :meth:`retract`.993994EXAMPLES::995996sage: K = KirillovReshetikhinCrystal(['E',6,1],2,1)997sage: La = K.cartan_type().classical().root_system().weight_lattice().fundamental_weights()998sage: H = HighestWeightCrystal(La[2])999sage: t = H.module_generator()1000sage: t1001[[(2, -1), (1,)]]1002sage: type(K.retract(t))1003<class 'sage.combinat.crystals.kirillov_reshetikhin.KR_type_E6_with_category.element_class'>1004sage: K.retract(t).e(0)1005[]10061007TESTS::10081009sage: K = KirillovReshetikhinCrystal(['E',6,1], 2,1)1010sage: La = K.weight_lattice_realization().fundamental_weights()1011sage: all(b.weight() == sum( (K.affine_weight(b.lift())[i] * La[i] for i in K.index_set()), 0*La[0]) for b in K) # long time (26s on sage.math, 2011)1012True1013"""10141015def classical_decomposition(self):1016"""1017Specifies the classical crystal underlying the KR crystal of type `E_6^{(1)}`.10181019EXAMPLES::10201021sage: K = KirillovReshetikhinCrystal(['E',6,1], 2,2)1022sage: K.classical_decomposition()1023Direct sum of the crystals Family (Finite dimensional highest weight crystal of type ['E', 6] and highest weight 0, Finite dimensional highest weight crystal of type ['E', 6] and highest weight Lambda[2], Finite dimensional highest weight crystal of type ['E', 6] and highest weight 2*Lambda[2])1024sage: K = KirillovReshetikhinCrystal(['E',6,1], 1,2)1025sage: K.classical_decomposition()1026Direct sum of the crystals Family (Finite dimensional highest weight crystal of type ['E', 6] and highest weight 2*Lambda[1],)1027"""1028La = self.cartan_type().classical().root_system().weight_lattice().fundamental_weights()1029if self.r() in [1,6]:1030dw = [self.s()*La[self.r()]]1031elif self.r() == 2:1032dw = sum( ([k*La[2]] for k in range(self.s()+1)), [])1033else:1034raise ValueError1035return DirectSumOfCrystals([HighestWeightCrystal(dominant_weight) for dominant_weight in dw], keepkey = False)10361037def dynkin_diagram_automorphism(self, i):1038r"""1039Specifies the Dynkin diagram automorphism underlying the promotion action on the crystal1040elements. The automorphism needs to map node 0 to some other Dynkin node.10411042Here we use the Dynkin diagram automorphism of order 3 which maps node 0 to node 1.10431044EXAMPLES::10451046sage: K = KirillovReshetikhinCrystal(['E',6,1],2,1)1047sage: [K.dynkin_diagram_automorphism(i) for i in K.index_set()]1048[1, 6, 3, 5, 4, 2, 0]1049"""1050aut = [1,6,3,5,4,2,0]1051return aut[i]10521053def affine_weight(self, b):1054r"""1055Returns the affine level zero weight corresponding to the element b of the classical1056crystal underlying self. For the coefficients to calculate the level, see Kac pg. 48.10571058EXAMPLES::10591060sage: K = KirillovReshetikhinCrystal(['E',6,1],2,1)1061sage: [K.affine_weight(x.lift()) for x in K if all(x.epsilon(i) == 0 for i in [2,3,4,5])]1062[(0, 0, 0, 0, 0, 0, 0),1063(-2, 0, 1, 0, 0, 0, 0),1064(-1, -1, 0, 0, 0, 1, 0),1065(0, 0, 0, 0, 0, 0, 0),1066(0, 0, 0, 0, 0, 1, -2),1067(0, -1, 1, 0, 0, 0, -1),1068(-1, 0, 0, 1, 0, 0, -1),1069(-1, -1, 0, 0, 1, 0, -1),1070(0, 0, 0, 0, 0, 0, 0),1071(0, -2, 0, 1, 0, 0, 0)]1072"""1073simple_roots = self.cartan_type().classical().root_system().ambient_space().simple_roots()1074index_set = b.parent().index_set()1075weight = [ Integer(b.weight().scalar( simple_roots[i] )) for i in index_set ]1076E6_coeffs = [ 1, 2, 2, 3, 2, 1 ]1077return tuple( [-sum([ weight[i-1] * E6_coeffs[i-1] for i in index_set ])] + weight )107810791080@cached_method1081def hw_auxiliary(self):1082r"""1083Returns the `{2,3,4,5}` highest weight elements of self.10841085EXAMPLES::10861087sage: K = KirillovReshetikhinCrystal(['E',6,1],2,1)1088sage: K.hw_auxiliary()1089[[], [[(2, -1), (1,)]],1090[[(5, -3), (-1, 3)]],1091[[(6, -2), (-6, 2)]],1092[[(5, -2, -6), (-6, 2)]],1093[[(-1,), (-6, 2)]],1094[[(3, -1, -6), (1,)]],1095[[(4, -3, -6), (-1, 3)]],1096[[(1, -3), (-1, 3)]],1097[[(-1,), (-1, 3)]]]1098"""1099return [x for x in self.classical_decomposition() if all(x.epsilon(i) == 0 for i in [2,3,4,5])]11001101@cached_method1102def highest_weight_dict(self):1103r"""1104Returns a dictionary between `{1,2,3,4,5}` highest weight elements, and a tuple of affine weights and its classical component.11051106EXAMPLES::11071108sage: K = KirillovReshetikhinCrystal(['E',6,1],2,1)1109sage: K.highest_weight_dict()1110{[[(5, -2, -6), (-6, 2)]]: ((0, 0, 0, 0, 0, 1, -2), 1),1111[[(3, -1, -6), (1,)]]: ((-1, 0, 0, 1, 0, 0, -1), 1),1112[[(6, -2), (-6, 2)]]: ((0, 0, 0, 0, 0, 0, 0), 1),1113[[(2, -1), (1,)]]: ((-2, 0, 1, 0, 0, 0, 0), 1),1114[]: ((0, 0, 0, 0, 0, 0, 0), 0)}1115"""1116hw = [x for x in self.hw_auxiliary() if x.epsilon(1) == 0]1117dic = dict( ( x, tuple( [self.affine_weight(x), len(x)] ) ) for x in hw )1118assert len(hw) == len(dic)1119return dic11201121@cached_method1122def highest_weight_dict_inv(self):1123r"""1124Returns a dictionary between a tuple of affine weights and a classical component, and1125`{2,3,4,5,6}` highest weight elements.11261127EXAMPLES::11281129sage: K = KirillovReshetikhinCrystal(['E',6,1],2,1)1130sage: K.highest_weight_dict_inv()1131{((0, 0, 0, 0, 0, 0, 0), 0): [],1132((-1, -1, 0, 0, 0, 1, 0), 1): [[(5, -3), (-1, 3)]],1133((0, 0, 0, 0, 0, 0, 0), 1): [[(1, -3), (-1, 3)]],1134((0, -2, 0, 1, 0, 0, 0), 1): [[(-1,), (-1, 3)]],1135((-2, 0, 1, 0, 0, 0, 0), 1): [[(2, -1), (1,)]]}1136"""1137hw = [x for x in self.hw_auxiliary() if x.epsilon(6) == 0]1138dic = dict( ( tuple( [self.affine_weight(x), len(x)] ), x ) for x in hw )1139assert len(hw) == len(dic)1140return dic11411142def automorphism_on_affine_weight(self, weight):1143r"""1144Acts with the Dynkin diagram automorphism on affine weights as outputted by the affine_weight method.11451146EXAMPLES::11471148sage: K = KirillovReshetikhinCrystal(['E',6,1],2,1)1149sage: [[x[0], K.automorphism_on_affine_weight(x[0])] for x in K.highest_weight_dict().values()]1150[[(0, 0, 0, 0, 0, 1, -2), (-2, 0, 1, 0, 0, 0, 0)],1151[(-1, 0, 0, 1, 0, 0, -1), (-1, -1, 0, 0, 0, 1, 0)],1152[(0, 0, 0, 0, 0, 0, 0), (0, 0, 0, 0, 0, 0, 0)],1153[(-2, 0, 1, 0, 0, 0, 0), (0, -2, 0, 1, 0, 0, 0)],1154[(0, 0, 0, 0, 0, 0, 0), (0, 0, 0, 0, 0, 0, 0)]]1155"""1156f = self.dynkin_diagram_automorphism1157return tuple( [weight[f(f(i))] for i in self.index_set()] )11581159@cached_method1160def promotion_on_highest_weight_vectors(self):1161r"""1162Gives a dictionary of the promotion map on `{1,2,3,4,5}` highest weight elements to1163`{2,3,4,5,6}` elements in self.11641165EXAMPLES::11661167sage: K = KirillovReshetikhinCrystal(['E',6,1],2,1)1168sage: dic = K.promotion_on_highest_weight_vectors()1169sage: dic1170{[[(5, -2, -6), (-6, 2)]]: [[(2, -1), (1,)]],1171[[(3, -1, -6), (1,)]]: [[(5, -3), (-1, 3)]],1172[[(6, -2), (-6, 2)]]: [],1173[[(2, -1), (1,)]]: [[(-1,), (-1, 3)]],1174[]: [[(1, -3), (-1, 3)]]}1175"""1176dic = self.highest_weight_dict()1177dic_inv = self.highest_weight_dict_inv()1178dic_weight = {}1179for (weight, i) in dic.values():1180dic_weight[weight] = dic_weight.get(weight, []) + [i]1181map_index = lambda (i, list) : max(list)+min(list)-i1182map_element = lambda x : tuple([self.automorphism_on_affine_weight(dic[x][0]), map_index((dic[x][1],dic_weight[dic[x][0]]))])1183return dict( (x, dic_inv[map_element(x)]) for x in dic.keys() )11841185@cached_method1186def promotion_on_highest_weight_vectors_function(self):1187"""1188Return a lambda function on ``x`` defined by1189``self.promotion_on_highest_weight_vectors()[x]``.11901191EXAMPLES::11921193sage: K = KirillovReshetikhinCrystal(['E',6,1], 2,1)1194sage: f = K.promotion_on_highest_weight_vectors_function()1195sage: f(K.module_generator().lift())1196[[(-1,), (-1, 3)]]1197"""1198return lambda x : self.promotion_on_highest_weight_vectors()[x]11991200@cached_method1201def promotion(self):1202"""1203Specifies the promotion operator used to construct the affine type `E_6^{(1)}` crystal.12041205EXAMPLES::12061207sage: K = KirillovReshetikhinCrystal(['E',6,1], 2,1)1208sage: promotion = K.promotion()1209sage: all(promotion(promotion(promotion(b))) == b for b in K.classical_decomposition())1210True1211sage: K = KirillovReshetikhinCrystal(['E',6,1],1,1)1212sage: promotion = K.promotion()1213sage: all(promotion(promotion(promotion(b))) == b for b in K.classical_decomposition())1214True1215"""1216T = self.classical_decomposition()1217ind = [1,2,3,4,5]1218return T.crystal_morphism( self.promotion_on_highest_weight_vectors_function(), automorphism = lambda i : self.dynkin_diagram_automorphism(i), index_set = ind)12191220@cached_method1221def promotion_inverse(self):1222r"""1223Returns the inverse promotion. Since promotion is of order 3, the inverse promotion is the same1224as promotion applied twice.12251226EXAMPLES::12271228sage: K = KirillovReshetikhinCrystal(['E',6,1], 2,1)1229sage: p = K.promotion()1230sage: p_inv = K.promotion_inverse()1231sage: all(p_inv(p(b)) == b for b in K.classical_decomposition())1232True1233"""1234p = self.promotion()1235return lambda x : p(p(x))123612371238class KR_type_C(KirillovReshetikhinGenericCrystal):1239r"""1240Class of Kirillov-Reshetikhin crystals `B^{r,s}` of type `C_n^{(1)}` for `r<n`.12411242EXAMPLES::12431244sage: K = KirillovReshetikhinCrystal(['C',2,1], 1,2)1245sage: K1246Kirillov-Reshetikhin crystal of type ['C', 2, 1] with (r,s)=(1,2)1247sage: b = K(rows=[])1248sage: b.f(0)1249[[1, 1]]1250sage: b.e(0)1251[[-1, -1]]1252"""12531254def classical_decomposition(self):1255r"""1256Specifies the classical crystal underlying the Kirillov-Reshetikhin crystal of type `C_n^{(1)}`.12571258It is given by `B^{r,s} \cong \bigoplus_\Lambda B(\Lambda)` where `\Lambda` are weights obtained from1259a rectangle of width `s` and height `r` by removing horizontal dominoes. Here we identify the fundamental1260weight `\Lambda_i` with a column of height `i`.12611262EXAMPLES::12631264sage: K = KirillovReshetikhinCrystal(['C',3,1], 2,2)1265sage: K.classical_decomposition()1266The crystal of tableaux of type ['C', 3] and shape(s) [[], [2], [2, 2]]1267"""1268return CrystalOfTableaux(self.cartan_type().classical(),1269shapes = horizontal_dominoes_removed(self.r(),self.s()))12701271def ambient_crystal(self):1272r"""1273Returns the ambient crystal `B^{r,s}` of type `A_{2n+1}^{(2)}` associated to the Kirillov-Reshetikhin1274crystal of type `C_n^{(1)}`. This ambient crystal is used to construct the zero arrows.12751276EXAMPLES::12771278sage: K = KirillovReshetikhinCrystal(['C',3,1], 2,3)1279sage: K.ambient_crystal()1280Kirillov-Reshetikhin crystal of type ['B', 4, 1]^* with (r,s)=(2,3)1281"""1282return KirillovReshetikhinCrystal(['A',2*self.cartan_type().classical().rank()+1,2], self.r(), self.s())12831284@cached_method1285def ambient_dict_pm_diagrams(self):1286r"""1287Gives a dictionary of all self-dual `\pm` diagrams for the ambient crystal.1288Their key is their inner shape.12891290EXAMPLES::12911292sage: K = KirillovReshetikhinCrystal(['C',2,1], 1,2)1293sage: K.ambient_dict_pm_diagrams()1294{[]: [[1, 1], [0]], [2]: [[0, 0], [2]]}1295sage: K = KirillovReshetikhinCrystal(['C',3,1], 2,2)1296sage: K.ambient_dict_pm_diagrams()1297{[2, 2]: [[0, 0], [0, 0], [2]], []: [[1, 1], [0, 0], [0]], [2]: [[0, 0], [1, 1], [0]]}1298sage: K = KirillovReshetikhinCrystal(['C',3,1], 2,3)1299sage: K.ambient_dict_pm_diagrams()1300{[3, 3]: [[0, 0], [0, 0], [3]], [3, 1]: [[0, 0], [1, 1], [1]], [1, 1]: [[1, 1], [0, 0], [1]]}1301"""1302list = []1303s = self.s()1304r = self.r()1305m = int(s/2)1306for i in range(m+1):1307for la in IntegerVectors(m-i, min_length=r, max_length=r):1308list.append(PMDiagram([[j,j] for j in la]+[[s-2*m+2*i]]))1309return dict( (x.inner_shape(), x) for x in list )13101311@cached_method1312def ambient_highest_weight_dict(self):1313r"""1314Gives a dictionary of all `{2,...,n+1}`-highest weight vectors in the ambient crystal.1315Their key is the inner shape of their corresponding `\pm` diagram, or equivalently, their1316`{2,...,n+1}` weight.13171318EXAMPLES::13191320sage: K = KirillovReshetikhinCrystal(['C',3,1], 2,2)1321sage: K.ambient_highest_weight_dict()1322{[]: [[2], [-2]], [2, 2]: [[2, 2], [3, 3]], [2]: [[1, 2], [2, -1]]}1323"""1324A = self.ambient_dict_pm_diagrams()1325ambient = self.ambient_crystal()1326return dict( (key, ambient.retract(ambient.from_pm_diagram_to_highest_weight_vector(A[key]))) for key in A )13271328@cached_method1329def highest_weight_dict(self):1330r"""1331Gives a dictionary of the classical highest weight vectors of self.1332Their key is their shape.13331334EXAMPLES::13351336sage: K = KirillovReshetikhinCrystal(['C',3,1], 2,2)1337sage: K.highest_weight_dict()1338{[2, 2]: [[1, 1], [2, 2]], []: [], [2]: [[1, 1]]}1339"""1340return dict( (x.lift().to_tableau().shape(),x) for x in self.module_generators )13411342@cached_method1343def to_ambient_crystal(self):1344r"""1345Provides a map from the Kirillov-Reshetikhin crystal of type `C_n^{(1)}` to the1346ambient crystal of type `A_{2n+1}^{(2)}`.13471348EXAMPLES::13491350sage: K = KirillovReshetikhinCrystal(['C',3,1], 2,2)1351sage: b=K(rows=[[1,1]])1352sage: K.to_ambient_crystal()(b)1353[[1, 2], [2, -1]]1354sage: b=K(rows=[])1355sage: K.to_ambient_crystal()(b)1356[[2], [-2]]1357sage: K.to_ambient_crystal()(b).parent()1358Kirillov-Reshetikhin crystal of type ['B', 4, 1]^* with (r,s)=(2,2)1359"""1360keys = self.highest_weight_dict().keys()1361pdict = dict( (self.highest_weight_dict()[key], self.ambient_highest_weight_dict()[key]) for key in keys )1362return self.crystal_morphism( pdict, index_set = self.cartan_type().classical().index_set(),1363automorphism = lambda i : i+1 )13641365@cached_method1366def from_ambient_crystal(self):1367r"""1368Provides a map from the ambient crystal of type `A_{2n+1}^{(2)}` to1369the Kirillov-Reshetikhin crystal of type `C_n^{(1)}`.13701371Note that this map is only well-defined on type `C_n^{(1)}` elements1372that are in the image under :meth:`to_ambient_crystal`.13731374EXAMPLES::13751376sage: K = KirillovReshetikhinCrystal(['C',3,1], 2,2)1377sage: b=K.ambient_crystal()(rows=[[2,2],[3,3]])1378sage: K.from_ambient_crystal()(b)1379[[1, 1], [2, 2]]1380"""1381keys = self.highest_weight_dict().keys()1382pdict_inv = dict( (self.ambient_highest_weight_dict()[key], self.highest_weight_dict()[key]) for key in keys )1383return self.crystal_morphism( pdict_inv, index_set = [j+1 for j in self.cartan_type().classical().index_set()],1384automorphism = lambda i : i-1 )13851386class KR_type_CElement(KirillovReshetikhinGenericCrystalElement):1387r"""1388Class for the elements in the Kirillov-Reshetikhin crystals `B^{r,s}` of type `C_n^{(1)}` for `r<n`.13891390EXAMPLES::13911392sage: K=KirillovReshetikhinCrystal(['C',3,1],1,2)1393sage: type(K.module_generators[0])1394<class 'sage.combinat.crystals.kirillov_reshetikhin.KR_type_C_with_category.element_class'>1395"""13961397def e0(self):1398r"""1399Gives `e_0` on self by mapping self to the ambient crystal, calculating `e_1 e_0` there and1400pulling the element back.14011402EXAMPLES::14031404sage: K=KirillovReshetikhinCrystal(['C',3,1],1,2)1405sage: b = K(rows=[])1406sage: b.e(0) # indirect doctest1407[[-1, -1]]1408"""1409b = self.parent().to_ambient_crystal()(self).e(1)1410if b is None:1411return None1412b = b.e(0)1413return self.parent().from_ambient_crystal()(b)14141415def f0(self):1416r"""1417Gives `f_0` on self by mapping self to the ambient crystal, calculating `f_1 f_0` there and1418pulling the element back.14191420EXAMPLES::14211422sage: K=KirillovReshetikhinCrystal(['C',3,1],1,2)1423sage: b = K(rows=[])1424sage: b.f(0) # indirect doctest1425[[1, 1]]1426"""1427b = self.parent().to_ambient_crystal()(self).f(1)1428if b is None:1429return None1430b = b.f(0)1431return self.parent().from_ambient_crystal()(b)14321433def epsilon0(self):1434r"""1435Calculates `\epsilon_0` of self by mapping the element to the ambient crystal1436and calculating `\epsilon_1` there.14371438EXAMPLES::14391440sage: K = KirillovReshetikhinCrystal(['C',2,1], 1,2)1441sage: b=K(rows=[[1,1]])1442sage: b.epsilon(0) # indirect doctest144321444"""1445b = self.parent().to_ambient_crystal()(self)1446return b.epsilon(1)14471448def phi0(self):1449r"""1450Calculates `\phi_0` of self by mapping the element to the ambient crystal1451and calculating `\phi_1` there.14521453EXAMPLES::14541455sage: K = KirillovReshetikhinCrystal(['C',2,1], 1,2)1456sage: b=K(rows=[[-1,-1]])1457sage: b.phi(0) # indirect doctest145821459"""1460b = self.parent().to_ambient_crystal()(self)1461return b.phi(1)14621463KR_type_C.Element = KR_type_CElement146414651466class KR_type_A2(KirillovReshetikhinGenericCrystal):1467r"""1468Class of Kirillov-Reshetikhin crystals `B^{r,s}` of type `A_{2n}^{(2)}` for `1\le r \le n`1469in the realization with classical subalgebra `B_n`. The cartan type in this case is inputted as1470the dual of `A_{2n}^{(2)}`.14711472This is an alternative implementation to :class:`KR_type_box` which uses1473the classical decomposition into type `C_n` crystals.14741475EXAMPLES::14761477sage: C = CartanType(['A',4,2]).dual()1478sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 1, 1)1479sage: K1480Kirillov-Reshetikhin crystal of type ['BC', 2, 2]^* with (r,s)=(1,1)1481sage: b = K(rows=[[-1]])1482sage: b.f(0)1483[[1]]1484sage: b.e(0)14851486We can now check whether the two KR crystals of type `A_4^{(2)}` (namely the KR crystal and its dual1487construction) are isomorphic up to relabelling of the edges::14881489sage: C = CartanType(['A',4,2])1490sage: K = KirillovReshetikhinCrystal(C,1,1)1491sage: Kdual = KirillovReshetikhinCrystal(C.dual(),1,1)1492sage: G = K.digraph()1493sage: Gdual = Kdual.digraph()1494sage: f = {0:2, 1:1, 2:0}1495sage: Gnew = DiGraph(); Gnew.add_vertices(Gdual.vertices()); Gnew.add_edges([(u,v,f[i]) for (u,v,i) in Gdual.edges()])1496sage: G.is_isomorphic(Gnew, edge_labels = True)1497True1498"""14991500def classical_decomposition(self):1501r"""1502Specifies the classical crystal underlying the Kirillov-Reshetikhin crystal of type `A_{2n}^{(2)}`1503with `B_n` as classical subdiagram.15041505It is given by `B^{r,s} \cong \bigoplus_\Lambda B(\Lambda)` where `B(\Lambda)` is a highest weight crystal of type1506`B_n` of highest weight `\Lambda`. The sum is over all weights `\Lambda` obtained from1507a rectangle of width `s` and height `r` by removing horizontal dominoes. Here we identify the fundamental1508weight `\Lambda_i` with a column of height `i`.15091510EXAMPLES::15111512sage: C = CartanType(['A',4,2]).dual()1513sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 2, 2)1514sage: K.classical_decomposition()1515The crystal of tableaux of type ['B', 2] and shape(s) [[], [2], [2, 2]]1516"""1517return CrystalOfTableaux(['B', self.cartan_type().rank()-1],1518shapes = horizontal_dominoes_removed(self.r(),self.s()))15191520def ambient_crystal(self):1521r"""1522Returns the ambient crystal `B^{r,s}` of type `B_{n+1}^{(1)}` associated to the Kirillov-Reshetikhin1523crystal of type `A_{2n}^{(2)}` dual. This ambient crystal is used to construct the zero arrows.15241525EXAMPLES::15261527sage: C = CartanType(['A',4,2]).dual()1528sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 2, 3)1529sage: K.ambient_crystal()1530Kirillov-Reshetikhin crystal of type ['B', 3, 1] with (r,s)=(2,3)1531"""1532return KR_type_vertical(['B', self.cartan_type().rank(), 1], self.r(), self.s())15331534@cached_method1535def ambient_dict_pm_diagrams(self):1536r"""1537Gives a dictionary of all self-dual `\pm` diagrams for the ambient crystal.1538Their key is their inner shape.15391540EXAMPLES::15411542sage: C = CartanType(['A',4,2]).dual()1543sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 1, 1)1544sage: K.ambient_dict_pm_diagrams()1545{[1]: [[0, 0], [1]]}1546sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 1, 2)1547sage: K.ambient_dict_pm_diagrams()1548{[]: [[1, 1], [0]], [2]: [[0, 0], [2]]}1549sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 2, 2)1550sage: K.ambient_dict_pm_diagrams()1551{[2, 2]: [[0, 0], [0, 0], [2]], []: [[1, 1], [0, 0], [0]], [2]: [[0, 0], [1, 1], [0]]}1552"""1553list = []1554s = self.s()1555r = self.r()1556m = int(s/2)1557for i in range(m+1):1558for la in IntegerVectors(m-i, min_length=r, max_length=r):1559list.append(PMDiagram([[j,j] for j in la]+[[s-2*m+2*i]]))1560return dict( (x.inner_shape(), x) for x in list )15611562@cached_method1563def ambient_highest_weight_dict(self):1564r"""1565Gives a dictionary of all `{2,...,n+1}`-highest weight vectors in the ambient crystal.1566Their key is the inner shape of their corresponding `\pm` diagram, or equivalently, their1567`{2,...,n+1}` weight.15681569EXAMPLES::15701571sage: C = CartanType(['A',4,2]).dual()1572sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 1, 2)1573sage: K.ambient_highest_weight_dict()1574{[]: [[1, -1]], [2]: [[2, 2]]}1575"""1576A = self.ambient_dict_pm_diagrams()1577ambient = self.ambient_crystal()1578return dict( (key, ambient.retract(ambient.from_pm_diagram_to_highest_weight_vector(A[key]))) for key in A )15791580@cached_method1581def highest_weight_dict(self):1582r"""1583Gives a dictionary of the classical highest weight vectors of self.1584Their key is their shape.15851586EXAMPLES::15871588sage: C = CartanType(['A',4,2]).dual()1589sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 1, 2)1590sage: K.highest_weight_dict()1591{[]: [], [2]: [[1, 1]]}1592"""1593return dict( (x.lift().to_tableau().shape(),x) for x in self.module_generators )15941595@cached_method1596def to_ambient_crystal(self):1597r"""1598Provides a map from the Kirillov-Reshetikhin crystal of type `A_{2n}^{(2)}` to the1599ambient crystal of type `B_{n+1}^{(1)}`.16001601EXAMPLES::16021603sage: C = CartanType(['A',4,2]).dual()1604sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 1, 2)1605sage: b=K(rows=[[1,1]])1606sage: K.to_ambient_crystal()(b)1607[[2, 2]]1608sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 2, 2)1609sage: b=K(rows=[[1,1]])1610sage: K.to_ambient_crystal()(b)1611[[1, 2], [2, -1]]1612sage: K.to_ambient_crystal()(b).parent()1613Kirillov-Reshetikhin crystal of type ['B', 3, 1] with (r,s)=(2,2)1614"""1615keys = self.highest_weight_dict().keys()1616pdict = dict( (self.highest_weight_dict()[key], self.ambient_highest_weight_dict()[key]) for key in keys )1617return self.crystal_morphism( pdict, index_set = self.cartan_type().classical().index_set(),1618automorphism = lambda i : i+1 )16191620@cached_method1621def from_ambient_crystal(self):1622r"""1623Provides a map from the ambient crystal of type `B_{n+1}^{(1)}` to1624the Kirillov-Reshetikhin crystal of type `A_{2n}^{(2)}`.16251626Note that this map is only well-defined on type `A_{2n}^{(2)}`1627elements that are in the image under :meth:`to_ambient_crystal`.16281629EXAMPLES::16301631sage: C = CartanType(['A',4,2]).dual()1632sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 1, 2)1633sage: b = K.ambient_crystal()(rows=[[2,2]])1634sage: K.from_ambient_crystal()(b)1635[[1, 1]]1636"""1637keys = self.highest_weight_dict().keys()1638pdict_inv = dict( (self.ambient_highest_weight_dict()[key], self.highest_weight_dict()[key]) for key in keys )1639return self.crystal_morphism( pdict_inv, index_set = [j+1 for j in self.cartan_type().classical().index_set()],1640automorphism = lambda i : i-1 )16411642class KR_type_A2Element(KirillovReshetikhinGenericCrystalElement):1643r"""1644Class for the elements in the Kirillov-Reshetikhin crystals `B^{r,s}` of type `A_{2n}^{(2)}` for `r<n`1645with underlying classcial algebra `B_n`.16461647EXAMPLES::16481649sage: C = CartanType(['A',4,2]).dual()1650sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 1, 2)1651sage: type(K.module_generators[0])1652<class 'sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2_with_category.element_class'>1653"""16541655def e0(self):1656r"""1657Gives `e_0` on self by mapping self to the ambient crystal, calculating `e_1 e_0` there and1658pulling the element back.16591660EXAMPLES::16611662sage: C = CartanType(['A',4,2]).dual()1663sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 1, 1)1664sage: b = K(rows=[[1]])1665sage: b.e(0) # indirect doctest1666[[-1]]1667"""1668b = self.parent().to_ambient_crystal()(self).e(1)1669if b is None:1670return None1671b = b.e(0)1672return self.parent().from_ambient_crystal()(b)16731674def f0(self):1675r"""1676Gives `f_0` on self by mapping self to the ambient crystal, calculating `f_1 f_0` there and1677pulling the element back.16781679EXAMPLES::16801681sage: C = CartanType(['A',4,2]).dual()1682sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 1, 1)1683sage: b = K(rows=[[-1]])1684sage: b.f(0) # indirect doctest1685[[1]]1686"""1687b = self.parent().to_ambient_crystal()(self).f(1)1688if b is None:1689return None1690b = b.f(0)1691return self.parent().from_ambient_crystal()(b)16921693def epsilon0(self):1694r"""1695Calculates `\epsilon_0` of self by mapping the element to the ambient crystal1696and calculating `\epsilon_1` there.16971698EXAMPLES::16991700sage: C = CartanType(['A',4,2]).dual()1701sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 1, 1)1702sage: b=K(rows=[[1]])1703sage: b.epsilon(0) # indirect doctest170411705"""1706b = self.parent().to_ambient_crystal()(self)1707return b.epsilon(1)17081709def phi0(self):1710r"""1711Calculates `\phi_0` of self by mapping the element to the ambient crystal1712and calculating `\phi_1` there.17131714EXAMPLES::17151716sage: C = CartanType(['A',4,2]).dual()1717sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 1, 1)1718sage: b=K(rows=[[-1]])1719sage: b.phi(0) # indirect doctest172011721"""1722b = self.parent().to_ambient_crystal()(self)1723return b.phi(1)17241725KR_type_A2.Element = KR_type_A2Element172617271728class KR_type_box(KirillovReshetikhinGenericCrystal, AffineCrystalFromClassical):1729r"""1730Class of Kirillov-Reshetikhin crystals `B^{r,s}` of type `A_{2n}^{(2)}` for `r\le n`1731and type `D_{n+1}^{(2)}` for `r<n`.17321733EXAMPLES::17341735sage: K = KirillovReshetikhinCrystal(['A',4,2], 1,1)1736sage: K1737Kirillov-Reshetikhin crystal of type ['BC', 2, 2] with (r,s)=(1,1)1738sage: b = K(rows=[])1739sage: b.f(0)1740[[1]]1741sage: b.e(0)1742[[-1]]1743"""1744def __init__(self, cartan_type, r, s):1745r"""1746Initializes a Kirillov-Reshetikhin crystal ``self``.17471748TESTS::17491750sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_box(['A',4,2], 1, 1)1751sage: K1752Kirillov-Reshetikhin crystal of type ['BC', 2, 2] with (r,s)=(1,1)1753sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_box(['D',4,2], 1, 1)1754sage: K1755Kirillov-Reshetikhin crystal of type ['C', 3, 1]^* with (r,s)=(1,1)1756sage: TestSuite(K).run()1757"""1758KirillovReshetikhinGenericCrystal.__init__(self, cartan_type, r ,s)1759AffineCrystalFromClassical.__init__(self, cartan_type, self.classical_decomposition())17601761def classical_decomposition(self):1762r"""1763Specifies the classical crystal underlying the Kirillov-Reshetikhin crystal of type `A_{2n}^{(2)}`1764and `D_{n+1}^{(2)}`.17651766It is given by `B^{r,s} \cong \bigoplus_\Lambda B(\Lambda)` where `\Lambda` are weights obtained from1767a rectangle of width `s` and height `r` by removing boxes. Here we identify the fundamental1768weight `\Lambda_i` with a column of height `i`.17691770EXAMPLES::17711772sage: K = KirillovReshetikhinCrystal(['A',4,2], 2,2)1773sage: K.classical_decomposition()1774The crystal of tableaux of type ['C', 2] and shape(s) [[], [1], [2], [1, 1], [2, 1], [2, 2]]1775sage: K = KirillovReshetikhinCrystal(['D',4,2], 2,3)1776sage: K.classical_decomposition()1777The crystal of tableaux of type ['B', 3] and shape(s) [[], [1], [2], [1, 1], [3], [2, 1], [3, 1], [2, 2], [3, 2], [3, 3]]1778"""1779return CrystalOfTableaux(self.cartan_type().classical(),1780shapes = partitions_in_box(self.r(),self.s()))17811782def ambient_crystal(self):1783r"""1784Returns the ambient crystal `B^{r,2s}` of type `C_n^{(1)}` associated to the Kirillov-Reshetikhin crystal.1785This ambient crystal is used to construct the zero arrows.17861787EXAMPLES::17881789sage: K = KirillovReshetikhinCrystal(['A',4,2], 2,2)1790sage: K.ambient_crystal()1791Kirillov-Reshetikhin crystal of type ['C', 2, 1] with (r,s)=(2,4)1792"""1793# calling KR_type_C instead of KirillovReshetikhin(['C',n,1],r,s) has the advantage that1794# that this also works for r=n for A_{2n}^{(2)}.1795return KR_type_C(['C', self.cartan_type().classical().rank(),1], self.r(), 2*self.s())17961797@cached_method1798def highest_weight_dict(self):1799r"""1800Gives a dictionary of the classical highest weight vectors of self.1801Their key is 2 times their shape.18021803EXAMPLES::18041805sage: K = KirillovReshetikhinCrystal(['A',6,2], 2,2)1806sage: K.highest_weight_dict()1807{[4, 2]: [[1, 1], [2]], [2, 2]: [[1], [2]], []: [], [4]: [[1, 1]], [4, 4]: [[1, 1], [2, 2]], [2]: [[1]]}1808"""1809return dict( (Partition([2*i for i in x.lift().to_tableau().shape()]),x) for x in self.module_generators )18101811@cached_method1812def ambient_highest_weight_dict(self):1813r"""1814Gives a dictionary of the classical highest weight vectors of the ambient crystal of self.1815Their key is their shape.18161817EXAMPLES::18181819sage: K = KirillovReshetikhinCrystal(['A',6,2], 2,2)1820sage: K.ambient_highest_weight_dict()1821{[4, 2]: [[1, 1, 1, 1], [2, 2]], [2, 2]: [[1, 1], [2, 2]], []: [], [4]: [[1, 1, 1, 1]], [4, 4]: [[1, 1, 1, 1], [2, 2, 2, 2]],1822[2]: [[1, 1]]}1823"""1824return dict( (x.lift().to_tableau().shape(),x) for x in self.ambient_crystal().module_generators )18251826def similarity_factor(self):1827r"""1828Sets the similarity factor used to map to the ambient crystal.18291830EXAMPLES::18311832sage: K = KirillovReshetikhinCrystal(['A',6,2], 2,2)1833sage: K.similarity_factor()1834{1: 2, 2: 2, 3: 2}1835sage: K = KirillovReshetikhinCrystal(['D',5,2], 1,1)1836sage: K.similarity_factor()1837{1: 2, 2: 2, 3: 2, 4: 1}1838"""1839C = self.cartan_type().classical()1840p = dict( (i,2) for i in C.index_set() )1841if C.type() == 'B':1842p[C.rank()] = 11843return p18441845@cached_method1846def to_ambient_crystal(self):1847r"""1848Provides a map from self to the ambient crystal of type `C_n^{(1)}`.18491850EXAMPLES::18511852sage: K = KirillovReshetikhinCrystal(['D',4,2], 1,1)1853sage: [K.to_ambient_crystal()(b) for b in K]1854[[], [[1, 1]], [[2, 2]], [[3, 3]], [[3, -3]], [[-3, -3]], [[-2, -2]], [[-1, -1]]]1855sage: K = KirillovReshetikhinCrystal(['A',4,2], 1,1)1856sage: [K.to_ambient_crystal()(b) for b in K]1857[[], [[1, 1]], [[2, 2]], [[-2, -2]], [[-1, -1]]]1858"""1859keys = self.highest_weight_dict().keys()1860pdict = dict( (self.highest_weight_dict()[key], self.ambient_highest_weight_dict()[key]) for key in keys )1861return self.crystal_morphism( pdict, index_set = self.cartan_type().classical().index_set(),1862similarity_factor = self.similarity_factor() )18631864@cached_method1865def from_ambient_crystal(self):1866r"""1867Provides a map from the ambient crystal of type `C_n^{(1)}` to the1868Kirillov-Reshetikhin crystal ``self``.18691870Note that this map is only well-defined on elements that are in the1871image under :meth:`to_ambient_crystal`.18721873EXAMPLES::18741875sage: K = KirillovReshetikhinCrystal(['D',4,2], 1,1)1876sage: b = K.ambient_crystal()(rows=[[3,-3]])1877sage: K.from_ambient_crystal()(b)1878[[0]]1879sage: K = KirillovReshetikhinCrystal(['A',4,2], 1,1)1880sage: b = K.ambient_crystal()(rows=[])1881sage: K.from_ambient_crystal()(b)1882[]1883"""1884keys = self.highest_weight_dict().keys()1885pdict_inv = dict( (self.ambient_highest_weight_dict()[key], self.highest_weight_dict()[key]) for key in keys )1886return self.crystal_morphism( pdict_inv, index_set = self.cartan_type().classical().index_set(),1887similarity_factor_domain = self.similarity_factor() )188818891890class KR_type_boxElement(KirillovReshetikhinGenericCrystalElement):1891r"""1892Class for the elements in the Kirillov-Reshetikhin crystals `B^{r,s}` of type `A_{2n}^{(2)}` for `r\le n`1893and type `D_{n+1}^{(2)}` for `r<n`.18941895EXAMPLES::18961897sage: K=KirillovReshetikhinCrystal(['A',4,2],1,2)1898sage: type(K.module_generators[0])1899<class 'sage.combinat.crystals.kirillov_reshetikhin.KR_type_box_with_category.element_class'>1900"""19011902def e0(self):1903r"""1904Gives `e_0` on self by mapping self to the ambient crystal, calculating `e_0` there and1905pulling the element back.19061907EXAMPLES::19081909sage: K=KirillovReshetikhinCrystal(['A',4,2],1,1)1910sage: b = K(rows=[])1911sage: b.e(0) # indirect doctest1912[[-1]]1913"""1914b = self.parent().to_ambient_crystal()(self).e(0)1915if b is None:1916return None1917return self.parent().from_ambient_crystal()(b)19181919def f0(self):1920r"""1921Gives `f_0` on self by mapping self to the ambient crystal, calculating `f_0` there and1922pulling the element back.19231924EXAMPLES::19251926sage: K=KirillovReshetikhinCrystal(['A',4,2],1,1)1927sage: b = K(rows=[])1928sage: b.f(0) # indirect doctest1929[[1]]1930"""1931b = self.parent().to_ambient_crystal()(self).f(0)1932if b is None:1933return None1934return self.parent().from_ambient_crystal()(b)19351936def epsilon0(self):1937r"""1938Calculates `\epsilon_0` of self by mapping the element to the ambient crystal1939and calculating `\epsilon_0` there.19401941EXAMPLES::19421943sage: K = KirillovReshetikhinCrystal(['A',4,2], 1,1)1944sage: b=K(rows=[[1]])1945sage: b.epsilon(0) # indirect doctest194621947"""1948b = self.parent().to_ambient_crystal()(self)1949return b.epsilon(0)19501951def phi0(self):1952r"""1953Calculates `\phi_0` of self by mapping the element to the ambient crystal1954and calculating `\phi_0` there.19551956EXAMPLES::19571958sage: K = KirillovReshetikhinCrystal(['D',3,2], 1,1)1959sage: b=K(rows=[[-1]])1960sage: b.phi(0) # indirect doctest196121962"""1963b = self.parent().to_ambient_crystal()(self)1964return b.phi(0)19651966KR_type_box.Element = KR_type_boxElement196719681969class KR_type_Bn(KirillovReshetikhinGenericCrystal):1970r"""1971Class of Kirillov-Reshetikhin crystals `B^{n,s}` of type `B_{n}^{(1)}`.19721973EXAMPLES::19741975sage: K = KirillovReshetikhinCrystal(['B',3,1],3,2)1976sage: K1977Kirillov-Reshetikhin crystal of type ['B', 3, 1] with (r,s)=(3,2)1978sage: b = K(rows=[[1],[2],[3]])1979sage: b.f(0)1980sage: b.e(0)1981[[3]]19821983sage: K = KirillovReshetikhinCrystal(['B',3,1],3,2)1984sage: [b.weight() for b in K if b.is_highest_weight([1,2,3])]1985[-Lambda[0] + Lambda[1], -2*Lambda[0] + 2*Lambda[3]]1986sage: [b.weight() for b in K if b.is_highest_weight([0,2,3])]1987[Lambda[0] - Lambda[1], -2*Lambda[1] + 2*Lambda[3]]1988"""1989def _element_constructor_(self, *args, **options):1990"""1991Construct an element of ``self``.19921993TESTS::19941995sage: KRC = KirillovReshetikhinCrystal(['B',3,1], 3, 3)1996sage: KRT = KirillovReshetikhinTableaux(['B',3,1], 3, 3)1997sage: elt = KRC.module_generators[1].f_string([3,2,3,1,3,3]); elt1998[++-, [[2], [0], [-3]]]1999sage: ret = KRT(elt); ret2000[[1, 1, 2], [2, 2, -3], [-3, -3, -1]]2001sage: test = KRC(ret); test2002[++-, [[2], [0], [-3]]]2003sage: test == elt2004True2005"""2006from sage.combinat.rigged_configurations.kr_tableaux import KirillovReshetikhinTableauxElement2007if isinstance(args[0], KirillovReshetikhinTableauxElement):2008elt = args[0]2009# Check to make sure it can be converted2010if elt.cartan_type() != self.cartan_type() \2011or elt.parent().r() != self._r or elt.parent().s() != self._s:2012raise ValueError("The Kirillov-Reshetikhin tableau must have the same Cartan type and shape")20132014to_hw = elt.to_classical_highest_weight()2015wt = to_hw[0].classical_weight() / 22016f_str = reversed(to_hw[1])2017for x in self.module_generators:2018if x.classical_weight() == wt:2019return x.f_string(f_str)2020raise ValueError("No matching highest weight element found")2021return KirillovReshetikhinGenericCrystal._element_constructor_(self, *args, **options)20222023def classical_decomposition(self):2024r"""2025Specifies the classical crystal underlying the Kirillov-Reshetikhin crystal `B^{n,s}` of type `B_n^{(1)}`.20262027It is the same as for `r<n`, given by `B^{n,s} \cong \bigoplus_\Lambda B(\Lambda)` where `\Lambda` are2028weights obtained from a rectangle of width `s/2` and height `n` by removing horizontal dominoes.2029Here we identify the fundamental weight `\Lambda_i` with a column of height `i` for `i<n` and2030a column of width `1/2` for `i=n`.20312032EXAMPLES::20332034sage: K = KirillovReshetikhinCrystal(['B',3,1], 3, 2)2035sage: K.classical_decomposition()2036The crystal of tableaux of type ['B', 3] and shape(s) [[1], [1, 1, 1]]2037sage: K = KirillovReshetikhinCrystal(['B',3,1], 3, 3)2038sage: K.classical_decomposition()2039The crystal of tableaux of type ['B', 3] and shape(s) [[3/2, 1/2, 1/2], [3/2, 3/2, 3/2]]2040"""2041s = self.s()2042r = self.r()2043shapes = vertical_dominoes_removed(r,floor(s/2))2044if is_odd(s):2045shapes = [ [i+QQ(1)/QQ(2) for i in sh]+[QQ(1)/QQ(2)]*(r-len(sh)) for sh in shapes ]2046return CrystalOfTableaux(self.cartan_type().classical(), shapes = shapes)20472048def ambient_crystal(self):2049r"""2050Returns the ambient crystal `B^{n,s}` of type `A_{2n-1}^{(2)}` associated to the Kirillov-Reshetikhin crystal;2051see Lemma 4.2 of reference [4].2052This ambient crystal is used to construct the zero arrows.20532054EXAMPLES::20552056sage: K = KirillovReshetikhinCrystal(['B',3,1],3,2)2057sage: K.ambient_crystal()2058Kirillov-Reshetikhin crystal of type ['B', 3, 1]^* with (r,s)=(3,2)2059"""2060return KirillovReshetikhinCrystal(['A', 2*self.cartan_type().classical().rank()-1,2], self.r(), self.s())20612062@cached_method2063def highest_weight_dict(self):2064r"""2065Gives a dictionary of the classical highest weight vectors of self.2066Their key is 2 times their shape.20672068EXAMPLES::20692070sage: K = KirillovReshetikhinCrystal(['B',3,1],3,2)2071sage: K.highest_weight_dict()2072{(2,): [[1]], (2, 2, 2): [[1], [2], [3]]}2073sage: K = KirillovReshetikhinCrystal(['B',3,1],3,3)2074sage: K.highest_weight_dict()2075{(3, 3, 3): [+++, [[1], [2], [3]]], (3, 1, 1): [+++, [[1]]]}2076"""2077return dict( (tuple([2*i[1] for i in x.classical_weight()]),x) for x in self.module_generators )20782079@cached_method2080def ambient_highest_weight_dict(self):2081r"""2082Gives a dictionary of the classical highest weight vectors of the ambient crystal of self.2083Their key is their shape.20842085EXAMPLES::20862087sage: K = KirillovReshetikhinCrystal(['B',3,1],3,2)2088sage: K.ambient_highest_weight_dict()2089{(2,): [[1, 1]], (2, 1, 1): [[1, 1], [2], [3]], (2, 2, 2): [[1, 1], [2, 2], [3, 3]]}20902091sage: K = KirillovReshetikhinCrystal(['B',3,1],3,3)2092sage: K.ambient_highest_weight_dict()2093{(3, 3, 3): [[1, 1, 1], [2, 2, 2], [3, 3, 3]], (3, 1, 1): [[1, 1, 1], [2], [3]],2094(3, 2, 2): [[1, 1, 1], [2, 2], [3, 3]], (3,): [[1, 1, 1]]}2095"""2096return dict( (tuple([i[1] for i in x.classical_weight()]),x) for x in self.ambient_crystal().module_generators )20972098def similarity_factor(self):2099r"""2100Sets the similarity factor used to map to the ambient crystal.21012102EXAMPLES::21032104sage: K = KirillovReshetikhinCrystal(['B',3,1],3,2)2105sage: K.similarity_factor()2106{1: 2, 2: 2, 3: 1}2107"""2108C = self.cartan_type().classical()2109p = dict( (i,2) for i in C.index_set() )2110p[C.rank()] = 12111return p21122113@cached_method2114def to_ambient_crystal(self):2115r"""2116Provides a map from self to the ambient crystal of type `A_{2n-1}^{(2)}`.21172118EXAMPLES::21192120sage: K = KirillovReshetikhinCrystal(['B',3,1],3,1)2121sage: [K.to_ambient_crystal()(b) for b in K]2122[[[1], [2], [3]], [[1], [2], [-3]], [[1], [3], [-2]], [[2], [3], [-1]], [[1], [-3], [-2]],2123[[2], [-3], [-1]], [[3], [-2], [-1]], [[-3], [-2], [-1]]]2124"""2125keys = self.highest_weight_dict().keys()2126pdict = dict( (self.highest_weight_dict()[key], self.ambient_highest_weight_dict()[key]) for key in keys )2127return self.crystal_morphism( pdict, index_set = self.cartan_type().classical().index_set(),2128similarity_factor = self.similarity_factor() )21292130@cached_method2131def from_ambient_crystal(self):2132r"""2133Provides a map from the ambient crystal of type `A_{2n-1}^{(2)}` to2134the Kirillov-Reshetikhin crystal ``self``.21352136Note that this map is only well-defined on elements that are in the2137image under :meth:`to_ambient_crystal`.21382139EXAMPLES::21402141sage: K = KirillovReshetikhinCrystal(['B',3,1],3,1)2142sage: [b == K.from_ambient_crystal()(K.to_ambient_crystal()(b)) for b in K]2143[True, True, True, True, True, True, True, True]2144sage: b = K.ambient_crystal()(rows=[[1],[2],[-3]])2145sage: K.from_ambient_crystal()(b)2146[++-, []]2147"""2148keys = self.highest_weight_dict().keys()2149pdict_inv = dict( (self.ambient_highest_weight_dict()[key], self.highest_weight_dict()[key]) for key in keys )2150return self.crystal_morphism( pdict_inv, index_set = self.cartan_type().classical().index_set(),2151similarity_factor_domain = self.similarity_factor() )215221532154class KR_type_BnElement(KirillovReshetikhinGenericCrystalElement):2155r"""2156Class for the elements in the Kirillov-Reshetikhin crystals `B^{n,s}` of type `B_n^{(1)}`.21572158EXAMPLES::21592160sage: K=KirillovReshetikhinCrystal(['B',3,1],3,2)2161sage: type(K.module_generators[0])2162<class 'sage.combinat.crystals.kirillov_reshetikhin.KR_type_Bn_with_category.element_class'>2163"""21642165def e0(self):2166r"""2167Gives `e_0` on self by mapping self to the ambient crystal, calculating `e_0` there and2168pulling the element back.21692170EXAMPLES::21712172sage: K=KirillovReshetikhinCrystal(['B',3,1],3,1)2173sage: b = K.module_generators[0]2174sage: b.e(0) # indirect doctest2175[--+, []]2176"""2177b = self.parent().to_ambient_crystal()(self).e_string([0,0])2178if b is None:2179return None2180return self.parent().from_ambient_crystal()(b)21812182def f0(self):2183r"""2184Gives `f_0` on self by mapping self to the ambient crystal, calculating `f_0` there and2185pulling the element back.21862187EXAMPLES::21882189sage: K=KirillovReshetikhinCrystal(['B',3,1],3,1)2190sage: b = K.module_generators[0]2191sage: b.f(0) # indirect doctest21922193"""2194b = self.parent().to_ambient_crystal()(self).f_string([0,0])2195if b is None:2196return None2197return self.parent().from_ambient_crystal()(b)21982199def epsilon0(self):2200r"""2201Calculates `\epsilon_0` of self by mapping the element to the ambient crystal2202and calculating `\epsilon_0` there.22032204EXAMPLES::22052206sage: K=KirillovReshetikhinCrystal(['B',3,1],3,1)2207sage: b = K.module_generators[0]2208sage: b.epsilon(0) # indirect doctest220912210"""2211b = self.parent().to_ambient_crystal()(self)2212return b.epsilon(0)/222132214def phi0(self):2215r"""2216Calculates `\phi_0` of self by mapping the element to the ambient crystal2217and calculating `\phi_0` there.22182219EXAMPLES::22202221sage: K=KirillovReshetikhinCrystal(['B',3,1],3,1)2222sage: b = K.module_generators[0]2223sage: b.phi(0) # indirect doctest222402225"""2226b = self.parent().to_ambient_crystal()(self)2227return b.phi(0)/222282229KR_type_Bn.Element = KR_type_BnElement223022312232class KR_type_Cn(KirillovReshetikhinGenericCrystal):2233r"""2234Class of Kirillov-Reshetikhin crystals `B^{n,s}` of type `C_n^{(1)}`.22352236EXAMPLES::22372238sage: K = KirillovReshetikhinCrystal(['C',3,1],3,1)2239sage: [[b,b.f(0)] for b in K]2240[[[[1], [2], [3]], None], [[[1], [2], [-3]], None], [[[1], [3], [-3]], None],2241[[[2], [3], [-3]], None], [[[1], [3], [-2]], None], [[[2], [3], [-2]], None],2242[[[2], [3], [-1]], [[1], [2], [3]]], [[[1], [-3], [-2]], None], [[[2], [-3], [-2]], None],2243[[[2], [-3], [-1]], [[1], [2], [-3]]], [[[3], [-3], [-2]], None], [[[3], [-3], [-1]],2244[[1], [3], [-3]]], [[[3], [-2], [-1]], [[1], [3], [-2]]], [[[-3], [-2], [-1]], [[1], [-3], [-2]]]]2245"""22462247def classical_decomposition(self):2248r"""2249Specifies the classical crystal underlying the Kirillov-Reshetikhin crystal `B^{n,s}`2250of type `C_n^{(1)}`. It is given by `B^{n,s} \cong B(s \Lambda_n)`.22512252EXAMPLES::22532254sage: K = KirillovReshetikhinCrystal(['C',3,1],3,2)2255sage: K.classical_decomposition()2256The crystal of tableaux of type ['C', 3] and shape(s) [[2, 2, 2]]2257"""2258return CrystalOfTableaux(self.cartan_type().classical(), shape = [self.s()]*self.r() )22592260def from_highest_weight_vector_to_pm_diagram(self, b):2261"""2262This gives the bijection between an element b in the classical decomposition2263of the KR crystal that is `{2,3,..,n}`-highest weight and `\pm` diagrams.22642265EXAMPLES::22662267sage: K = KirillovReshetikhinCrystal(['C',3,1],3,2)2268sage: T = K.classical_decomposition()2269sage: b = T(rows=[[2, 2], [3, 3], [-3, -1]])2270sage: pm = K.from_highest_weight_vector_to_pm_diagram(b); pm2271[[0, 0], [1, 0], [0, 1], [0]]2272sage: pm.__repr__(pretty_printing=True)2273. .2274. +2275- -22762277sage: hw = [ b for b in T if all(b.epsilon(i)==0 for i in [2,3]) ]2278sage: all(K.from_pm_diagram_to_highest_weight_vector(K.from_highest_weight_vector_to_pm_diagram(b)) == b for b in hw)2279True2280"""2281n = self.cartan_type().rank()-12282inner = Partition([Integer(b.weight()[i]) for i in range(1,n+1)])2283inter = Partition([len([i for i in r if i>0]) for r in b.to_tableau()])2284outer = b.to_tableau().shape()2285return PMDiagram([self.r(), self.s(), outer, inter, inner], from_shapes=True)22862287def from_pm_diagram_to_highest_weight_vector(self, pm):2288"""2289This gives the bijection between a `\pm` diagram and an element b in the classical2290decomposition of the KR crystal that is {2,3,..,n}-highest weight.22912292EXAMPLES::22932294sage: K = KirillovReshetikhinCrystal(['C',3,1],3,2)2295sage: pm = sage.combinat.crystals.kirillov_reshetikhin.PMDiagram([[0, 0], [1, 0], [0, 1], [0]])2296sage: K.from_pm_diagram_to_highest_weight_vector(pm)2297[[2, 2], [3, 3], [-3, -1]]2298"""2299u = [b for b in self.classical_decomposition().module_generators if b.to_tableau().shape() == pm.outer_shape()][0]2300ct = self.cartan_type()2301rank = ct.rank()-12302ct_type = ct.classical().type()2303assert ct_type in ['C']2304list = []2305for h in pm.heights_of_addable_plus():2306list += range(1,h+1)2307for h in pm.heights_of_minus():2308list += range(1,rank+1)+[rank-1-k for k in range(rank-h)]2309for i in reversed(list):2310u = u.f(i)2311return u23122313class KR_type_CnElement(KirillovReshetikhinGenericCrystalElement):2314r"""2315Class for the elements in the Kirillov-Reshetikhin crystals `B^{n,s}` of type `C_n^{(1)}`.23162317EXAMPLES::23182319sage: K=KirillovReshetikhinCrystal(['C',3,1],3,2)2320sage: type(K.module_generators[0])2321<class 'sage.combinat.crystals.kirillov_reshetikhin.KR_type_Cn_with_category.element_class'>2322"""23232324def e0(self):2325r"""2326Gives `e_0` on self by going to the `\pm`-diagram corresponding to the `{2,...,n}`-highest weight2327vector in the component of `self`, then applying [Definition 6.1, 4], and pulling back from2328`\pm`-diagrams.23292330EXAMPLES::23312332sage: K=KirillovReshetikhinCrystal(['C',3,1],3,2)2333sage: b = K.module_generators[0]2334sage: b.e(0) # indirect doctest2335[[1, 2], [2, 3], [3, -1]]2336sage: b = K(rows=[[1,2],[2,3],[3,-1]])2337sage: b.e(0)2338[[2, 2], [3, 3], [-1, -1]]2339sage: b=K(rows=[[1, -3], [3, -2], [-3, -1]])2340sage: b.e(0)2341[[3, -3], [-3, -2], [-1, -1]]2342"""2343n = self.parent().cartan_type().n2344[b,l] = self.lift().to_highest_weight(index_set=range(2,n+1))2345pm = self.parent().from_highest_weight_vector_to_pm_diagram(b)2346[l1,l2] = pm.pm_diagram[n-1]2347if l1 == 0:2348return None2349pm.pm_diagram[n-1] = [l1-1,l2+1]2350pm = PMDiagram(pm.pm_diagram)2351b = self.parent().from_pm_diagram_to_highest_weight_vector(pm)2352b = b.f_string(reversed(l))2353return self.parent().retract(b)23542355def f0(self):2356r"""2357Gives `e_0` on self by going to the `\pm`-diagram corresponding to the `{2,...,n}`-highest weight2358vector in the component of `self`, then applying [Definition 6.1, 4], and pulling back from2359`\pm`-diagrams.23602361EXAMPLES::23622363sage: K=KirillovReshetikhinCrystal(['C',3,1],3,1)2364sage: b = K.module_generators[0]2365sage: b.f(0) # indirect doctest2366"""2367n = self.parent().cartan_type().n2368[b,l] = self.lift().to_highest_weight(index_set=range(2,n+1))2369pm = self.parent().from_highest_weight_vector_to_pm_diagram(b)2370[l1,l2] = pm.pm_diagram[n-1]2371if l2 == 0:2372return None2373pm.pm_diagram[n-1] = [l1+1,l2-1]2374pm = PMDiagram(pm.pm_diagram)2375b = self.parent().from_pm_diagram_to_highest_weight_vector(pm)2376b = b.f_string(reversed(l))2377return self.parent().retract(b)23782379def epsilon0(self):2380r"""2381Calculates `\epsilon_0` of self using Lemma 6.1 of [4].23822383EXAMPLES::23842385sage: K=KirillovReshetikhinCrystal(['C',3,1],3,1)2386sage: b = K.module_generators[0]2387sage: b.epsilon(0) # indirect doctest238812389"""2390n = self.parent().cartan_type().n2391b = self.lift().to_highest_weight(index_set=range(2,n+1))[0]2392pm = self.parent().from_highest_weight_vector_to_pm_diagram(b)2393[l1,l2] = pm.pm_diagram[n-1]2394return l123952396def phi0(self):2397r"""2398Calculates `\phi_0` of self.23992400EXAMPLES::24012402sage: K=KirillovReshetikhinCrystal(['C',3,1],3,1)2403sage: b = K.module_generators[0]2404sage: b.phi(0) # indirect doctest240502406"""2407n = self.parent().cartan_type().n2408b = self.lift().to_highest_weight(index_set=range(2,n+1))[0]2409pm = self.parent().from_highest_weight_vector_to_pm_diagram(b)2410[l1,l2] = pm.pm_diagram[n-1]2411return l224122413KR_type_Cn.Element = KR_type_CnElement241424152416class KR_type_Dn_twisted(KirillovReshetikhinGenericCrystal):2417r"""2418Class of Kirillov-Reshetikhin crystals `B^{n,s}` of type `D_{n+1}^{(2)}`.24192420EXAMPLES::24212422sage: K = KirillovReshetikhinCrystal(['D',4,2],3,1)2423sage: [[b,b.f(0)] for b in K]2424[[[+++, []], None], [[++-, []], None], [[+-+, []], None], [[-++, []],2425[+++, []]], [[+--, []], None], [[-+-, []], [++-, []]], [[--+, []], [+-+, []]],2426[[---, []], [+--, []]]]2427"""24282429def classical_decomposition(self):2430r"""2431Specifies the classical crystal underlying the Kirillov-Reshetikhin crystal `B^{n,s}`2432of type `D_{n+1}^{(2)}`. It is given by `B^{n,s} \cong B(s \Lambda_n)`.24332434EXAMPLES::24352436sage: K = KirillovReshetikhinCrystal(['D',4,2],3,1)2437sage: K.classical_decomposition()2438The crystal of tableaux of type ['B', 3] and shape(s) [[1/2, 1/2, 1/2]]2439sage: K = KirillovReshetikhinCrystal(['D',4,2],3,2)2440sage: K.classical_decomposition()2441The crystal of tableaux of type ['B', 3] and shape(s) [[1, 1, 1]]2442"""2443s = self.s()2444if is_even(s):2445s = int(s/2)2446else:2447s = s/22448return CrystalOfTableaux(self.cartan_type().classical(), shape = [s]*self.r() )24492450def from_highest_weight_vector_to_pm_diagram(self, b):2451"""2452This gives the bijection between an element b in the classical decomposition2453of the KR crystal that is `{2,3,..,n}`-highest weight and `\pm` diagrams.24542455EXAMPLES::24562457sage: K = KirillovReshetikhinCrystal(['D',4,2],3,1)2458sage: T = K.classical_decomposition()2459sage: hw = [ b for b in T if all(b.epsilon(i)==0 for i in [2,3]) ]2460sage: [K.from_highest_weight_vector_to_pm_diagram(b) for b in hw]2461[[[0, 0], [0, 0], [1, 0], [0]], [[0, 0], [0, 0], [0, 1], [0]]]24622463sage: K = KirillovReshetikhinCrystal(['D',4,2],3,2)2464sage: T = K.classical_decomposition()2465sage: hw = [ b for b in T if all(b.epsilon(i)==0 for i in [2,3]) ]2466sage: [K.from_highest_weight_vector_to_pm_diagram(b) for b in hw]2467[[[0, 0], [0, 0], [2, 0], [0]], [[0, 0], [0, 0], [0, 0], [2]], [[0, 0], [2, 0], [0, 0], [0]],2468[[0, 0], [0, 0], [0, 2], [0]]]24692470Note that, since the classical decomposition of this crystal is of type `B_n`, there can2471be (at most one) entry `0` in the `{2,3,...,n}`-highest weight elements at height `n`.2472In the following implementation this is realized as an empty column of height `n` since2473this uniquely specifies the existence of the `0`:24742475EXAMPLES::24762477sage: b = hw[1]2478sage: pm = K.from_highest_weight_vector_to_pm_diagram(b)2479sage: pm.__repr__(pretty_printing=True)2480. .2481. .2482. .24832484TESTS::24852486sage: all(K.from_pm_diagram_to_highest_weight_vector(K.from_highest_weight_vector_to_pm_diagram(b)) == b for b in hw)2487True2488sage: K = KirillovReshetikhinCrystal(['D',4,2],3,2)2489sage: T = K.classical_decomposition()2490sage: hw = [ b for b in T if all(b.epsilon(i)==0 for i in [2,3]) ]2491sage: all(K.from_pm_diagram_to_highest_weight_vector(K.from_highest_weight_vector_to_pm_diagram(b)) == b for b in hw)2492True2493sage: K = KirillovReshetikhinCrystal(['D',4,2],3,3)2494sage: T = K.classical_decomposition()2495sage: hw = [ b for b in T if all(b.epsilon(i)==0 for i in [2,3]) ]2496sage: all(K.from_pm_diagram_to_highest_weight_vector(K.from_highest_weight_vector_to_pm_diagram(b)) == b for b in hw)2497True24982499"""2500n = self.cartan_type().rank()-12501s = self.s()2502if is_odd(s):2503t = b[0]2504b = b[1]2505else:2506t = b.parent()(rows=[])2507inner = [Integer(2*b.weight()[i]+2*t.weight()[i]) for i in range(1,n+1)]2508inter1 = Partition([len([i for i in r if i>0]) for r in b.to_tableau()])2509inter = Partition([len([i for i in r if i>=0]) for r in b.to_tableau()])2510if inter != inter1:2511inner[n-1] += 22512inner = Partition(inner)2513inter = [2*i for i in inter]+[0]*(n-len(inter))2514w = t.weight()2515if w[0]==0 and w[n-1]==0:2516v = [0]*n2517else:2518v = [1]*n2519if w[0]<0 and w[n-1]>0:2520v[n-1]=02521elif w[0]>0 and w[n-1]<0:2522v[n-1]=02523v[n-2]=-12524inter = Partition([inter[i] + v[i] for i in range(n)])2525outer = Partition([s]*n)2526return PMDiagram([n, s, outer, inter, inner], from_shapes=True)25272528def from_pm_diagram_to_highest_weight_vector(self, pm):2529"""2530This gives the bijection between a `\pm` diagram and an element b in the classical2531decomposition of the KR crystal that is {2,3,..,n}-highest weight.25322533EXAMPLES::25342535sage: K = KirillovReshetikhinCrystal(['D',4,2],3,2)2536sage: pm = sage.combinat.crystals.kirillov_reshetikhin.PMDiagram([[0, 0], [0, 0], [0, 0], [2]])2537sage: K.from_pm_diagram_to_highest_weight_vector(pm)2538[[2], [3], [0]]2539"""2540u = self.classical_decomposition().module_generators[0]2541ct = self.cartan_type()2542rank = ct.rank()-12543assert ct.classical().type() in ['B']2544list = []2545plus = pm.heights_of_addable_plus()2546minus = pm.heights_of_minus()2547l = len([i for i in plus if i==rank-1])2548a = (len(plus) + l)/22549list += sum(([i]*a for i in range(1,rank+1)),[])2550a = (len(minus)-l)/22551list += (range(1,rank+1)+[rank])*a2552for i in reversed(list):2553u = u.f(i)2554return u25552556class KR_type_Dn_twistedElement(KirillovReshetikhinGenericCrystalElement):2557r"""2558Class for the elements in the Kirillov-Reshetikhin crystals `B^{n,s}` of type `D_{n+1}^{(2)}`.25592560EXAMPLES::25612562sage: K=KirillovReshetikhinCrystal(['D',4,2],3,2)2563sage: type(K.module_generators[0])2564<class 'sage.combinat.crystals.kirillov_reshetikhin.KR_type_Dn_twisted_with_category.element_class'>2565"""25662567def e0(self):2568r"""2569Gives `e_0` on self by going to the `\pm`-diagram corresponding to the `{2,...,n}`-highest weight2570vector in the component of `self`, then applying [Definition 6.2, 4], and pulling back from2571`\pm`-diagrams.25722573EXAMPLES::25742575sage: K=KirillovReshetikhinCrystal(['D',4,2],3,3)2576sage: b = K.module_generators[0]2577sage: b.e(0) # indirect doctest2578[+++, [[2], [3], [0]]]2579"""2580n = self.parent().cartan_type().rank()-12581s = self.parent().s()2582[b,l] = self.lift().to_highest_weight(index_set=range(2,n+1))2583pm = self.parent().from_highest_weight_vector_to_pm_diagram(b)2584[l1,l2] = pm.pm_diagram[n-1]2585l3 = pm.pm_diagram[n-2][0]2586if l1+l2+l3==s and l1==0:2587return None2588if l1+l2+l3<s:2589pm.pm_diagram[n-1][1] = l2+22590pm.pm_diagram[n][0] -= 22591elif l1>1:2592pm.pm_diagram[n-1][0] = l1-22593pm.pm_diagram[n][0] += 22594elif l1 ==1:2595pm.pm_diagram[n-1][0] = 02596pm.pm_diagram[n-1][1] = l2+12597pm = PMDiagram(pm.pm_diagram)2598b = self.parent().from_pm_diagram_to_highest_weight_vector(pm)2599b = b.f_string(reversed(l))2600return self.parent().retract(b)26012602def f0(self):2603r"""2604Gives `e_0` on self by going to the `\pm`-diagram corresponding to the `{2,...,n}`-highest weight2605vector in the component of `self`, then applying [Definition 6.2, 4], and pulling back from2606`\pm`-diagrams.26072608EXAMPLES::26092610sage: K=KirillovReshetikhinCrystal(['D',4,2],3,2)2611sage: b = K.module_generators[0]2612sage: b.f(0) # indirect doctest2613"""2614n = self.parent().cartan_type().rank()-12615s = self.parent().s()2616[b,l] = self.lift().to_highest_weight(index_set=range(2,n+1))2617pm = self.parent().from_highest_weight_vector_to_pm_diagram(b)2618[l1,l2] = pm.pm_diagram[n-1]2619l3 = pm.pm_diagram[n-2][0]2620if l1+l2+l3==s and l2==0:2621return None2622if l1+l2+l3<s:2623pm.pm_diagram[n-1][0] = l1+22624pm.pm_diagram[n][0] -= 22625elif l2>1:2626pm.pm_diagram[n-1][1] = l2-22627pm.pm_diagram[n][0] += 22628elif l2 ==1:2629pm.pm_diagram[n-1][1] = 02630pm.pm_diagram[n-1][0] = l1+12631pm = PMDiagram(pm.pm_diagram)2632b = self.parent().from_pm_diagram_to_highest_weight_vector(pm)2633b = b.f_string(reversed(l))2634return self.parent().retract(b)26352636def epsilon0(self):2637r"""2638Calculates `\epsilon_0` of self using Lemma 6.2 of [4].26392640EXAMPLES::26412642sage: K=KirillovReshetikhinCrystal(['D',4,2],3,1)2643sage: b = K.module_generators[0]2644sage: b.epsilon(0) # indirect doctest264512646"""2647n = self.parent().cartan_type().rank()-12648s = self.parent().s()2649[b,l] = self.lift().to_highest_weight(index_set=range(2,n+1))2650pm = self.parent().from_highest_weight_vector_to_pm_diagram(b)2651l1 = pm.pm_diagram[n-1][0]2652l4 = pm.pm_diagram[n][0]2653return l1+l426542655def phi0(self):2656r"""2657Calculates `\phi_0` of self.26582659EXAMPLES::26602661sage: K=KirillovReshetikhinCrystal(['D',4,2],3,1)2662sage: b = K.module_generators[0]2663sage: b.phi(0) # indirect doctest266402665"""2666n = self.parent().cartan_type().rank()-12667s = self.parent().s()2668[b,l] = self.lift().to_highest_weight(index_set=range(2,n+1))2669pm = self.parent().from_highest_weight_vector_to_pm_diagram(b)2670l2 = pm.pm_diagram[n-1][1]2671l4 = pm.pm_diagram[n][0]2672return l2+l426732674KR_type_Dn_twisted.Element = KR_type_Dn_twistedElement26752676class KR_type_spin(KirillovReshetikhinCrystalFromPromotion):2677r"""2678Class of Kirillov-Reshetikhin crystals `B^{n,s}` of type `D_n^{(1)}`.26792680EXAMPLES::26812682sage: K = KirillovReshetikhinCrystal(['D',4,1],4,1); K2683Kirillov-Reshetikhin crystal of type ['D', 4, 1] with (r,s)=(4,1)2684sage: [[b,b.f(0)] for b in K]2685[[[++++, []], None], [[++--, []], None], [[+-+-, []], None], [[-++-, []], None],2686[[+--+, []], None], [[-+-+, []], None], [[--++, []], [++++, []]], [[----, []], [++--, []]]]26872688sage: K = KirillovReshetikhinCrystal(['D',4,1],4,2); K2689Kirillov-Reshetikhin crystal of type ['D', 4, 1] with (r,s)=(4,2)2690sage: [[b,b.f(0)] for b in K]2691[[[[1], [2], [3], [4]], None], [[[1], [2], [-4], [4]], None], [[[1], [3], [-4], [4]], None],2692[[[2], [3], [-4], [4]], None], [[[1], [4], [-4], [4]], None], [[[2], [4], [-4], [4]], None],2693[[[3], [4], [-4], [4]], [[1], [2], [3], [4]]], [[[-4], [4], [-4], [4]], [[1], [2], [-4], [4]]],2694[[[-4], [4], [-4], [-3]], [[1], [2], [-4], [-3]]], [[[-4], [4], [-4], [-2]], [[1], [3], [-4], [-3]]],2695[[[-4], [4], [-4], [-1]], [[2], [3], [-4], [-3]]], [[[-4], [4], [-3], [-2]], [[1], [4], [-4], [-3]]],2696[[[-4], [4], [-3], [-1]], [[2], [4], [-4], [-3]]], [[[-4], [4], [-2], [-1]], [[-4], [4], [-4], [4]]],2697[[[-4], [-3], [-2], [-1]], [[-4], [4], [-4], [-3]]], [[[1], [2], [-4], [-3]], None], [[[1], [3], [-4], [-3]], None],2698[[[2], [3], [-4], [-3]], None], [[[1], [3], [-4], [-2]], None], [[[2], [3], [-4], [-2]], None],2699[[[2], [3], [-4], [-1]], None], [[[1], [4], [-4], [-3]], None], [[[2], [4], [-4], [-3]], None],2700[[[3], [4], [-4], [-3]], None], [[[3], [4], [-4], [-2]], [[1], [3], [-4], [4]]],2701[[[3], [4], [-4], [-1]], [[2], [3], [-4], [4]]], [[[1], [4], [-4], [-2]], None], [[[2], [4], [-4], [-2]], None],2702[[[2], [4], [-4], [-1]], None], [[[1], [4], [-3], [-2]], None], [[[2], [4], [-3], [-2]], None],2703[[[2], [4], [-3], [-1]], None], [[[3], [4], [-3], [-2]], [[1], [4], [-4], [4]]],2704[[[3], [4], [-3], [-1]], [[2], [4], [-4], [4]]], [[[3], [4], [-2], [-1]], [[3], [4], [-4], [4]]]]27052706TESTS::27072708sage: K = KirillovReshetikhinCrystal(['D',4,1],3,1)2709sage: all(b.e(0).f(0) == b for b in K if b.epsilon(0)>0)2710True27112712sage: K = KirillovReshetikhinCrystal(['D',5,1],5,2)2713sage: all(b.f(0).e(0) == b for b in K if b.phi(0)>0)2714True2715"""2716def _element_constructor_(self, *args, **options):2717"""2718Construct an element of ``self`` from the input.27192720EXAMPLES::27212722sage: KRT = KirillovReshetikhinTableaux(['D',4,1], 4, 3)2723sage: KRC = KirillovReshetikhinCrystal(['D',4,1], 4, 3)2724sage: elt = KRT(-3,-4,2,1,-3,-4,2,1,-2,-4,3,1); elt2725[[1, 1, 1], [2, 2, 3], [-4, -4, -4], [-3, -3, -2]]2726sage: KRC(elt) # indirect doctest2727[++--, [[1], [3], [-4], [-3]]]27282729TESTS:27302731Spinor test::27322733sage: KRC = KirillovReshetikhinCrystal(['D',4,1], 4, 3)2734sage: KRT = KirillovReshetikhinTableaux(['D',4,1], 4, 3)2735sage: elt = KRC.module_generator().f_string([4,2,4,3,4,1]); elt2736[++--, [[2], [4], [-4], [-3]]]2737sage: ret = KRT(elt); ret2738[[1, 1, 2], [2, 2, 4], [-4, -4, -3], [-3, -3, -1]]2739sage: test = KRC(ret); test2740[++--, [[2], [4], [-4], [-3]]]2741sage: test == elt2742True2743"""2744from sage.combinat.rigged_configurations.kr_tableaux import KirillovReshetikhinTableauxElement2745if isinstance(args[0], KirillovReshetikhinTableauxElement):2746elt = args[0]2747# Check to make sure it can be converted2748if elt.cartan_type() != self.cartan_type() \2749or elt.parent().r() != self._r or elt.parent().s() != self._s:2750raise ValueError("The Kirillov-Reshetikhin tableau must have the same Cartan type and shape")27512752to_hw = elt.to_classical_highest_weight()2753f_str = reversed(to_hw[1])2754return self.module_generator().f_string(f_str)2755return KirillovReshetikhinCrystalFromPromotion._element_constructor_(self, *args, **options)27562757def classical_decomposition(self):2758r"""2759Returns the classical crystal underlying the Kirillov-Reshetikhin crystal `B^{r,s}`2760of type `D_n^{(1)}` for `r=n-1,n`. It is given by `B^{n,s} \cong B(s \Lambda_r)`.27612762EXAMPLES::27632764sage: K = KirillovReshetikhinCrystal(['D',4,1],4,1)2765sage: K.classical_decomposition()2766The crystal of tableaux of type ['D', 4] and shape(s) [[1/2, 1/2, 1/2, 1/2]]2767sage: K = KirillovReshetikhinCrystal(['D',4,1],3,1)2768sage: K.classical_decomposition()2769The crystal of tableaux of type ['D', 4] and shape(s) [[1/2, 1/2, 1/2, -1/2]]2770sage: K = KirillovReshetikhinCrystal(['D',4,1],3,2)2771sage: K.classical_decomposition()2772The crystal of tableaux of type ['D', 4] and shape(s) [[1, 1, 1, -1]]2773"""2774C = self.cartan_type().classical()2775s = self.s()2776if self.r() == C.n:2777c = [s/2]*C.n2778else:2779c = [s/2]*(C.n-1)+[-s/2]2780return CrystalOfTableaux(C, shape = c)27812782def dynkin_diagram_automorphism(self, i):2783"""2784Specifies the Dynkin diagram automorphism underlying the promotion action on the crystal2785elements. The automorphism needs to map node 0 to some other Dynkin node.27862787Here we use the Dynkin diagram automorphism which interchanges nodes 0 and 1 and leaves2788all other nodes unchanged.27892790EXAMPLES::27912792sage: K = KirillovReshetikhinCrystal(['D',4,1],4,1)2793sage: K.dynkin_diagram_automorphism(0)279412795sage: K.dynkin_diagram_automorphism(1)279602797sage: K.dynkin_diagram_automorphism(4)279842799"""2800aut = [1,0]+range(2,self.cartan_type().rank())2801return aut[i]28022803@cached_method2804def promotion_on_highest_weight_vectors(self):2805r"""2806Returns the promotion operator on `\{2,3,\ldots,n\}`-highest weight vectors.28072808A `\{2,3,\ldots,n\}`-highest weight vector in `B(s\Lambda_n)` of weight2809`w=(w_1,\ldots,w_n)` is mapped to a `\{2,3,\ldots,n\}`-highest weight vector in `B(s\Lambda_{n-1})`2810of weight `(-w_1,w_2,\ldots,w_n)` and vice versa.28112812See also :meth:`promotion_on_highest_weight_vectors_inverse` and :meth:`promotion`.28132814EXAMPLES::28152816sage: KR = KirillovReshetikhinCrystal(['D',4,1],4,2)2817sage: prom = KR.promotion_on_highest_weight_vectors()2818sage: T = KR.classical_decomposition()2819sage: HW = [t for t in T if t.is_highest_weight([2,3,4])]2820sage: for t in HW:2821... print t, prom[t]2822...2823[4, 3, 2, 1] [-1, 4, 3, 2]2824[4, -4, 3, 2] [-4, 4, 3, 2]2825[-1, -4, 3, 2] [-4, 3, 2, 1]28262827sage: KR = KirillovReshetikhinCrystal(['D',4,1],4,1)2828sage: prom = KR.promotion_on_highest_weight_vectors()2829sage: T = KR.classical_decomposition()2830sage: HW = [t for t in T if t.is_highest_weight([2,3,4])]2831sage: for t in HW:2832... print t, prom[t]2833...2834[++++, []] [-+++, []]2835[-++-, []] [+++-, []]2836"""2837T = self.classical_decomposition()2838ind = list(T.index_set())2839ind.remove(1)2840C = T.cartan_type()2841n = C.n2842sh = [ i for i in T.shapes[0] ]2843sh[n-1] = -sh[n-1]2844T_dual = CrystalOfTableaux(C, shape = sh)2845hw = [ t for t in T if t.is_highest_weight(index_set = ind) ]2846hw_dual = [ t for t in T_dual if t.is_highest_weight(index_set = ind) ]2847dic_weight = {tuple(t.weight().to_vector()) : t for t in hw}2848dic_weight_dual = {tuple(t.weight().to_vector()) : t for t in hw_dual}2849def neg(x):2850y = [i for i in x]2851y[0] = -y[0]2852return tuple(y)2853return dict( (dic_weight[w], dic_weight_dual[neg(w)]) for w in dic_weight.keys() )28542855@cached_method2856def promotion_on_highest_weight_vectors_inverse(self):2857r"""2858Returns the inverse promotion operator on `\{2,3,\ldots,n\}`-highest weight vectors.28592860See also :meth:`promotion_on_highest_weight_vectors` and :meth:`promotion_inverse`.28612862EXAMPLES::28632864sage: KR = KirillovReshetikhinCrystal(['D',4,1],3,2)2865sage: prom = KR.promotion_on_highest_weight_vectors()2866sage: prom_inv = KR.promotion_on_highest_weight_vectors_inverse()2867sage: T = KR.classical_decomposition()2868sage: HW = [t for t in T if t.is_highest_weight([2,3,4])]2869sage: all(prom_inv[prom[t]] == t for t in HW)2870True2871"""2872D = self.promotion_on_highest_weight_vectors()2873return dict( (D[t],t) for t in D.keys())28742875@cached_method2876def promotion(self):2877"""2878Returns the promotion operator on `B^{r,s}` of type `D_n^{(1)}` for `r=n-1,n`.28792880EXAMPLES::28812882sage: K = KirillovReshetikhinCrystal(['D',4,1],3,1)2883sage: T = K.classical_decomposition()2884sage: promotion = K.promotion()2885sage: for t in T:2886... print t, promotion(t)2887...2888[+++-, []] [-++-, []]2889[++-+, []] [-+-+, []]2890[+-++, []] [--++, []]2891[-+++, []] [++++, []]2892[+---, []] [----, []]2893[-+--, []] [++--, []]2894[--+-, []] [+-+-, []]2895[---+, []] [+--+, []]2896"""2897T = self.classical_decomposition()2898ind = list(T.index_set())2899ind.remove(1)2900C = T.cartan_type()2901n = C.n2902def aut(i):2903if i==n:2904return n-12905elif i==n-1:2906return n2907return i2908return T.crystal_morphism( self.promotion_on_highest_weight_vectors(), index_set = ind)29092910@cached_method2911def promotion_inverse(self):2912r"""2913Returns the inverse promotion operator on `B^{r,s}` of type `D_n^{(1)}` for `r=n-1,n`.29142915EXAMPLES::29162917sage: K = KirillovReshetikhinCrystal(['D',4,1],3,1)2918sage: T = K.classical_decomposition()2919sage: promotion = K.promotion()2920sage: promotion_inverse = K.promotion_inverse()2921sage: all(promotion_inverse(promotion(t)) == t for t in T)2922True2923"""2924D = self.promotion_on_highest_weight_vectors_inverse()2925T = D.keys()[0].parent()2926ind = list(T.index_set())2927ind.remove(1)2928C = T.cartan_type()2929n = C.n2930def aut(i):2931if i==n:2932return n-12933elif i==n-1:2934return n2935return i2936return T.crystal_morphism( self.promotion_on_highest_weight_vectors_inverse(), index_set = ind)29372938#####################################################################29392940class PMDiagram(CombinatorialObject):2941"""2942Class of `\pm` diagrams. These diagrams are in one-to-one bijection with `X_{n-1}` highest weight vectors2943in an `X_n` highest weight crystal `X=B,C,D`. See Section 4.1 of A. Schilling, "Combinatorial structure of2944Kirillov-Reshetikhin crystals of type `D_n(1)`, `B_n(1)`, `A_{2n-1}(2)`", J. Algebra 319 (2008) 2938-29622945(arXiv:0704.2046[math.QA]).29462947The input is a list `pm = [[a_0,b_0],[a_1,b_1],...,[a_{n-1},b_{n-1}],[b_n]]` of 2-tuples and a last 1-tuple.2948The tuple `[a_i,b_i]` specifies the number of `a_i` + and `b_i` - in the i-th row of the pm diagram2949if `n-i` is odd and the number of `a_i` +- pairs above row `i` and `b_i` columns of height `i` not containing2950any + or - if `n-i` is even.29512952Setting the option 'from_shapes = True' one can also input a `\pm` diagram in terms of its2953outer, intermediate and inner shape by specifying a tuple [n, s, outer, intermediate, inner]2954where `s` is the width of the `\pm` diagram, and 'outer' , 'intermediate',2955and 'inner' are the outer, intermediate and inner shape, respectively.29562957EXAMPLES::29582959sage: pm=sage.combinat.crystals.kirillov_reshetikhin.PMDiagram([[0,1],[1,2],[1]])2960sage: pm.pm_diagram2961[[0, 1], [1, 2], [1]]2962sage: pm._list2963[1, 1, 2, 0, 1]2964sage: pm.n296522966sage: pm.width296752968sage: pm.__repr__(pretty_printing=True)2969. . . .2970. + - -2971sage: sage.combinat.crystals.kirillov_reshetikhin.PMDiagram([2,5,[4,4],[4,2],[4,1]], from_shapes=True)2972[[0, 1], [1, 2], [1]]29732974TESTS::29752976sage: pm=sage.combinat.crystals.kirillov_reshetikhin.PMDiagram([[1,2],[1,1],[1,1],[1,1],[1]])2977sage: sage.combinat.crystals.kirillov_reshetikhin.PMDiagram([pm.n, pm.width, pm.outer_shape(), pm.intermediate_shape(), pm.inner_shape()], from_shapes=True) == pm2978True2979sage: pm=sage.combinat.crystals.kirillov_reshetikhin.PMDiagram([[1,2],[1,2],[1,1],[1,1],[1,1],[1]])2980sage: sage.combinat.crystals.kirillov_reshetikhin.PMDiagram([pm.n, pm.width, pm.outer_shape(), pm.intermediate_shape(), pm.inner_shape()], from_shapes=True) == pm2981True2982"""29832984def __init__(self, pm_diagram, from_shapes = None):2985r"""2986Initializes `\pm` diagrams.29872988TESTS::29892990sage: sage.combinat.crystals.kirillov_reshetikhin.PMDiagram([[0,1],[1,2],[1]])2991[[0, 1], [1, 2], [1]]2992sage: sage.combinat.crystals.kirillov_reshetikhin.PMDiagram([2,5,[4,4],[4,2],[4,1]], from_shapes=True)2993[[0, 1], [1, 2], [1]]2994"""2995if from_shapes:2996n = pm_diagram[0]2997s = pm_diagram[1]2998outer = [s]+list(pm_diagram[2])+[0 for i in range(n)]2999intermediate = [s]+list(pm_diagram[3])+[0 for i in range(n)]3000inner = [s]+list(pm_diagram[4])+[0 for i in range(n)]3001pm = [[inner[n]]]3002for i in range(int((n+1)/2)):3003pm.append([intermediate[n-2*i]-inner[n-2*i], inner[n-2*i-1]-intermediate[n-2*i]])3004pm.append([outer[n-2*i]-inner[n-2*i-1], inner[n-2*i-2]-outer[n-2*i]])3005if is_odd(n):3006pm.pop(n+1)3007pm_diagram = list(reversed(pm))3008self.pm_diagram = pm_diagram3009self.n = len(pm_diagram)-13010self._list = [i for a in reversed(pm_diagram) for i in a]3011self.width = sum(i for i in self._list)30123013def __repr__(self, pretty_printing = None):3014"""3015Turning on pretty printing allows to display the pm diagram as a3016tableau with the + and - displayed30173018EXAMPLES::30193020sage: pm=sage.combinat.crystals.kirillov_reshetikhin.PMDiagram([[1,0],[0,1],[2,0],[0,0],[0]])3021sage: pm.__repr__(pretty_printing=True)3022. . . +3023. . - -3024+ +3025- -3026sage: pm=sage.combinat.crystals.kirillov_reshetikhin.PMDiagram([[0,2], [0,0], [0]])3027sage: pm.__repr__(pretty_printing=True)30283029"""3030if pretty_printing is None:3031return repr(self.pm_diagram)3032t = []3033ish = self.inner_shape() + [0]*self.n3034msh = self.intermediate_shape() + [0]*self.n3035osh = self.outer_shape() + [0]*self.n3036for i in range(self.n):3037t.append(['.']*ish[i]+['+']*(msh[i]-ish[i])+['-']*(osh[i]-msh[i]))3038t=[i for i in t if i!= []]3039return Tableau(t).pp()30403041def inner_shape(self):3042"""3043Returns the inner shape of the pm diagram30443045EXAMPLES::30463047sage: pm=sage.combinat.crystals.kirillov_reshetikhin.PMDiagram([[0,1],[1,2],[1]])3048sage: pm.inner_shape()3049[4, 1]3050sage: pm=sage.combinat.crystals.kirillov_reshetikhin.PMDiagram([[1,2],[1,1],[1,1],[1,1],[1]])3051sage: pm.inner_shape()3052[7, 5, 3, 1]3053sage: pm=sage.combinat.crystals.kirillov_reshetikhin.PMDiagram([[1,2],[1,2],[1,1],[1,1],[1,1],[1]])3054sage: pm.inner_shape()3055[10, 7, 5, 3, 1]3056"""3057t = []3058ll = self._list3059for i in range(self.n):3060t.append(sum(ll[0:2*i+1]))3061return Partition(list(reversed(t)))30623063def outer_shape(self):3064"""3065Returns the outer shape of the pm diagram30663067EXAMPLES::30683069sage: pm=sage.combinat.crystals.kirillov_reshetikhin.PMDiagram([[0,1],[1,2],[1]])3070sage: pm.outer_shape()3071[4, 4]3072sage: pm=sage.combinat.crystals.kirillov_reshetikhin.PMDiagram([[1,2],[1,1],[1,1],[1,1],[1]])3073sage: pm.outer_shape()3074[8, 8, 4, 4]3075sage: pm=sage.combinat.crystals.kirillov_reshetikhin.PMDiagram([[1,2],[1,2],[1,1],[1,1],[1,1],[1]])3076sage: pm.outer_shape()3077[13, 8, 8, 4, 4]3078"""3079t = []3080ll = self._list3081for i in range((self.n)/2):3082t.append(sum(ll[0:4*i+4]))3083t.append(sum(ll[0:4*i+4]))3084if is_even(self.n+1):3085t.append(sum(ll[0:2*self.n+2]))3086return Partition(list(reversed(t)))30873088def intermediate_shape(self):3089"""3090Returns the intermediate shape of the pm diagram (inner shape plus positions of plusses)30913092EXAMPLES::30933094sage: pm=sage.combinat.crystals.kirillov_reshetikhin.PMDiagram([[0,1],[1,2],[1]])3095sage: pm.intermediate_shape()3096[4, 2]3097sage: pm=sage.combinat.crystals.kirillov_reshetikhin.PMDiagram([[1,2],[1,1],[1,1],[1,1],[1]])3098sage: pm.intermediate_shape()3099[8, 6, 4, 2]3100sage: pm=sage.combinat.crystals.kirillov_reshetikhin.PMDiagram([[1,2],[1,2],[1,1],[1,1],[1,1],[1]])3101sage: pm.intermediate_shape()3102[11, 8, 6, 4, 2]3103sage: pm=sage.combinat.crystals.kirillov_reshetikhin.PMDiagram([[1,0],[0,1],[2,0],[0,0],[0]])3104sage: pm.intermediate_shape()3105[4, 2, 2]3106sage: pm=sage.combinat.crystals.kirillov_reshetikhin.PMDiagram([[1, 0], [0, 0], [0, 0], [0, 0], [0]])3107sage: pm.intermediate_shape()3108[1]3109"""3110p = self.inner_shape()3111p = p + [0 for i in range(self.n)]3112ll = list(reversed(self._list))3113p = [ p[i]+ll[2*i+1] for i in range(self.n) ]3114return Partition(p)31153116def heights_of_minus(self):3117"""3118Returns a list with the heights of all minus in the `\pm` diagram.31193120EXAMPLES::31213122sage: pm=sage.combinat.crystals.kirillov_reshetikhin.PMDiagram([[1,2],[1,2],[1,1],[1,1],[1,1],[1]])3123sage: pm.heights_of_minus()3124[5, 5, 3, 3, 1, 1]3125sage: pm=sage.combinat.crystals.kirillov_reshetikhin.PMDiagram([[1,2],[1,1],[1,1],[1,1],[1]])3126sage: pm.heights_of_minus()3127[4, 4, 2, 2]3128"""3129n = self.n3130heights = []3131for i in range(int((n+1)/2)):3132heights += [n-2*i]*((self.outer_shape()+[0]*n)[n-2*i-1]-(self.intermediate_shape()+[0]*n)[n-2*i-1])3133return heights31343135def heights_of_addable_plus(self):3136"""3137Returns a list with the heights of all addable plus in the `\pm` diagram.31383139EXAMPLES::31403141sage: pm=sage.combinat.crystals.kirillov_reshetikhin.PMDiagram([[1,2],[1,2],[1,1],[1,1],[1,1],[1]])3142sage: pm.heights_of_addable_plus()3143[1, 1, 2, 3, 4, 5]3144sage: pm=sage.combinat.crystals.kirillov_reshetikhin.PMDiagram([[1,2],[1,1],[1,1],[1,1],[1]])3145sage: pm.heights_of_addable_plus()3146[1, 2, 3, 4]3147"""3148heights = []3149for i in range(1,self.n+1):3150heights += [i]*self.sigma().pm_diagram[i][0]3151return heights31523153def sigma(self):3154"""3155Returns sigma on pm diagrams as needed for the analogue of the Dynkin diagram automorphism3156that interchanges nodes `0` and `1` for type `D_n(1)`, `B_n(1)`, `A_{2n-1}(2)` for3157Kirillov-Reshetikhin crystals.31583159EXAMPLES::31603161sage: pm=sage.combinat.crystals.kirillov_reshetikhin.PMDiagram([[0,1],[1,2],[1]])3162sage: pm.sigma().pm_diagram3163[[1, 0], [2, 1], [1]]3164"""3165pm = self.pm_diagram3166return PMDiagram([list(reversed(a)) for a in pm])316731683169#####################################################################################31703171def partitions_in_box(r, s):3172"""3173Returns all partitions in a box of width s and height r.31743175EXAMPLES::31763177sage: sage.combinat.crystals.kirillov_reshetikhin.partitions_in_box(3,2)3178[[], [1], [2], [1, 1], [2, 1], [1, 1, 1], [2, 2], [2, 1, 1],3179[2, 2, 1], [2, 2, 2]]3180"""3181return [x for n in range(r*s+1) for x in Partitions(n,max_part=s,max_length=r)]31823183def vertical_dominoes_removed(r, s):3184"""3185Returns all partitions obtained from a rectangle of width s and height r by removing3186vertical dominoes.31873188EXAMPLES::31893190sage: sage.combinat.crystals.kirillov_reshetikhin.vertical_dominoes_removed(2,2)3191[[], [1, 1], [2, 2]]3192sage: sage.combinat.crystals.kirillov_reshetikhin.vertical_dominoes_removed(3,2)3193[[2], [2, 1, 1], [2, 2, 2]]3194sage: sage.combinat.crystals.kirillov_reshetikhin.vertical_dominoes_removed(4,2)3195[[], [1, 1], [1, 1, 1, 1], [2, 2], [2, 2, 1, 1], [2, 2, 2, 2]]3196"""3197return [x.conjugate() for x in horizontal_dominoes_removed(s,r)]31983199def horizontal_dominoes_removed(r, s):3200"""3201Returns all partitions obtained from a rectangle of width s and height r by removing3202horizontal dominoes.32033204EXAMPLES::32053206sage: sage.combinat.crystals.kirillov_reshetikhin.horizontal_dominoes_removed(2,2)3207[[], [2], [2, 2]]3208sage: sage.combinat.crystals.kirillov_reshetikhin.horizontal_dominoes_removed(3,2)3209[[], [2], [2, 2], [2, 2, 2]]3210"""3211list = [ [y for y in x] + [0 for i in range(r-x.length())] for x in partitions_in_box(r, int(s/2)) ]3212two = lambda x : 2*(x-int(s/2)) + s3213return [Partition([two(y) for y in x]) for x in list]321432153216