Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
r""" Kirillov-Reshetikhin Crystals """
#***************************************************************************** # Copyright (C) 2009 Anne Schilling <anne at math.ucdavis.edu> # 2014 Travis Scrimshaw <tscrim at ucdavis.edu> # # Distributed under the terms of the GNU General Public License (GPL) # # This code is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # The full text of the GPL is available at: # # http://www.gnu.org/licenses/ #**************************************************************************** # Acknowledgment: most of the design and implementation of this # library is heavily inspired from MuPAD-Combinat. #**************************************************************************** # python3 from __future__ import division, print_function from six.moves import range
from sage.misc.cachefunc import cached_method from sage.misc.lazy_attribute import lazy_attribute from sage.misc.functional import is_even, is_odd from sage.functions.other import floor from sage.combinat.combinat import CombinatorialObject from sage.structure.parent import Parent from sage.categories.crystals import CrystalMorphism from sage.categories.loop_crystals import KirillovReshetikhinCrystals from sage.categories.homset import Hom from sage.categories.map import Map from sage.rings.integer import Integer from sage.rings.all import QQ from sage.combinat.crystals.affine import (AffineCrystalFromClassical, AffineCrystalFromClassicalElement, AffineCrystalFromClassicalAndPromotion, AffineCrystalFromClassicalAndPromotionElement) from sage.combinat.crystals.highest_weight_crystals import HighestWeightCrystal from sage.combinat.crystals.littelmann_path import CrystalOfProjectedLevelZeroLSPaths from sage.combinat.crystals.direct_sum import DirectSumOfCrystals from sage.combinat.root_system.cartan_type import CartanType from sage.combinat.root_system.root_system import RootSystem from sage.combinat.crystals.tensor_product import CrystalOfTableaux from sage.combinat.tableau import Tableau from sage.combinat.partition import Partition, Partitions from sage.combinat.integer_vector import IntegerVectors
def KirillovReshetikhinCrystalFromLSPaths(cartan_type, r, s=1): r""" Single column Kirillov-Reshetikhin crystals.
This yields the single column Kirillov-Reshetikhin crystals from the projected level zero LS paths, see :class:`~sage.combinat.crystals.littelmann_path.CrystalOfLSPaths`. This works for all types (even exceptional types). The weight of the canonical element in this crystal is `\Lambda_r`. For other implementation see :func:`~sage.combinat.crystals.kirillov_reshetikhin.KirillovReshetikhinCrystal`.
EXAMPLES::
sage: K = crystals.kirillov_reshetikhin.LSPaths(['A',2,1],2) # indirect doctest sage: KR = crystals.KirillovReshetikhin(['A',2,1],2,1) sage: G = K.digraph() sage: GR = KR.digraph() sage: G.is_isomorphic(GR, edge_labels = True) True
sage: K = crystals.kirillov_reshetikhin.LSPaths(['C',3,1],2) sage: KR = crystals.KirillovReshetikhin(['C',3,1],2,1) sage: G = K.digraph() sage: GR = KR.digraph() sage: G.is_isomorphic(GR, edge_labels = True) True
sage: K = crystals.kirillov_reshetikhin.LSPaths(['E',6,1],1) sage: KR = crystals.KirillovReshetikhin(['E',6,1],1,1) sage: G = K.digraph() sage: GR = KR.digraph() sage: G.is_isomorphic(GR, edge_labels = True) True sage: K.cardinality() 27
sage: K = crystals.kirillov_reshetikhin.LSPaths(['G',2,1],1) sage: K.cardinality() 7
sage: K = crystals.kirillov_reshetikhin.LSPaths(['B',3,1],2) sage: KR = crystals.KirillovReshetikhin(['B',3,1],2,1) sage: KR.cardinality() 22 sage: K.cardinality() 22 sage: G = K.digraph() sage: GR = KR.digraph() sage: G.is_isomorphic(GR, edge_labels = True) True
TESTS::
sage: K = crystals.kirillov_reshetikhin.LSPaths(['G',2,1],2) sage: K.cardinality() 15
For `s > 1` these crystals yield `s`-fold tensor products of Kirillov-Reshetikhin crystals::
sage: K = crystals.kirillov_reshetikhin.LSPaths(['A',1,1],1,3) sage: B = crystals.KirillovReshetikhin(['A',1,1],1,1) sage: T = crystals.TensorProduct(B,B,B) sage: G = K.digraph() sage: GT = T.digraph() sage: G.is_isomorphic(GT, edge_labels = True) True
sage: K = crystals.kirillov_reshetikhin.LSPaths(['B',2,1],1,2) sage: B = crystals.KirillovReshetikhin(['B',2,1],1,1) sage: T = crystals.TensorProduct(B,B) sage: G = K.digraph() sage: GT = T.digraph() sage: G.is_isomorphic(GT, edge_labels = True) True
sage: K = crystals.kirillov_reshetikhin.LSPaths(['B',2,1],2,3) sage: B = crystals.KirillovReshetikhin(['B',2,1],2,1) sage: T = crystals.TensorProduct(B,B,B) sage: GT = T.digraph() sage: G = K.digraph() sage: G.is_isomorphic(GT, edge_labels = True) True """
def KirillovReshetikhinCrystal(cartan_type, r, s, model='KN'): r""" Return the Kirillov-Reshetikhin crystal `B^{r,s}` of the given type in the given model.
For more information about general crystals see :mod:`sage.combinat.crystals.crystals`.
There are a variety of models for Kirillov-Reshetikhin crystals. There is one using the classical crystal with :func:`Kashiwara-Nakashima tableaux <sage.combinat.crystals.kirillov_reshetikhin.KashiwaraNakashimaTableaux>`. There is one using :class:`rigged configurations <RiggedConfigurations>`. Another tableaux model comes from the bijection between rigged configurations and tensor products of tableaux called :class:`Kirillov-Reshetikhin tableaux <sage.combinat.rigged_configurations.kr_tableaux.KirillovReshetikhinTableaux>` Lastly there is a model of Kirillov-Reshetikhin crystals for `s = 1` from crystals of :func:`LS paths <sage.combinat.crystals.kirillov_reshetikhin.KirillovReshetikhinCrystalFromLSPaths>`.
INPUT:
- ``cartan_type`` -- an affine Cartan type
- ``r`` -- a label of finite Dynkin diagram
- ``s`` -- a positive integer
- ``model`` -- (default: ``'KN'``) can be one of the following:
* ``'KN'`` or ``'KashiwaraNakashimaTableaux'`` - use the Kashiwara-Nakashima tableaux model * ``'KR'`` or ``'KirillovReshetkihinTableaux'`` - use the Kirillov-Reshetkihin tableaux model * ``'RC'`` or ``'RiggedConfiguration'`` - use the rigged configuration model * ``'LSPaths'`` - use the LS path model
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['A',3,1], 2, 1) sage: K.index_set() (0, 1, 2, 3) sage: K.list() [[[1], [2]], [[1], [3]], [[2], [3]], [[1], [4]], [[2], [4]], [[3], [4]]] sage: b=K(rows=[[1],[2]]) sage: b.weight() -Lambda[0] + Lambda[2]
sage: K = crystals.KirillovReshetikhin(['A',3,1], 2,2) sage: K.automorphism(K.module_generators[0]) [[2, 2], [3, 3]] sage: K.module_generators[0].e(0) [[1, 2], [2, 4]] sage: K.module_generators[0].f(2) [[1, 1], [2, 3]] sage: K.module_generators[0].f(1) sage: K.module_generators[0].phi(0) 0 sage: K.module_generators[0].phi(1) 0 sage: K.module_generators[0].phi(2) 2 sage: K.module_generators[0].epsilon(0) 2 sage: K.module_generators[0].epsilon(1) 0 sage: K.module_generators[0].epsilon(2) 0 sage: b = K(rows=[[1,2],[2,3]]) sage: b [[1, 2], [2, 3]] sage: b.f(2) [[1, 2], [3, 3]]
sage: K = crystals.KirillovReshetikhin(['D',4,1], 2, 1) sage: K.cartan_type() ['D', 4, 1] sage: type(K.module_generators[0]) <class 'sage.combinat.crystals.kirillov_reshetikhin.KR_type_vertical_with_category.element_class'>
The following gives some tests with regards to Lemma 3.11 in [LOS12]_.
TESTS::
sage: K = crystals.KirillovReshetikhin(['A',4,2],2,1) sage: Lambda = K.weight_lattice_realization().fundamental_weights() sage: [b for b in K if b.Epsilon() == Lambda[0]] [[]]
sage: K = crystals.KirillovReshetikhin(['D',4,2],1,2) sage: Lambda = K.weight_lattice_realization().fundamental_weights() sage: [b for b in K if b.Epsilon() == 2*Lambda[0]] [[]] sage: [b for b in K if b.Epsilon() == 2*Lambda[3]] [[[3, -3]]] sage: K = crystals.KirillovReshetikhin(['D',4,2],1,1) sage: [b for b in K if b.Epsilon() == Lambda[3]] [[[0]]]
sage: K = crystals.KirillovReshetikhin(['B',3,1],2,1) sage: Lambda = K.weight_lattice_realization().fundamental_weights() sage: [b for b in K if b.Epsilon() == Lambda[0]] [[]] sage: [b for b in K if b.Epsilon() == Lambda[1]] [[[2], [-2]]] sage: K = crystals.KirillovReshetikhin(['B',3,1],2,2) sage: [b for b in K if b.Epsilon() == 2*Lambda[0]] [[]] sage: [b for b in K if b.Epsilon() == 2*Lambda[1]] [[[1, 2], [-2, -1]]] sage: K = crystals.KirillovReshetikhin(['B',3,1],2,3) sage: [b for b in K if b.Epsilon() == 3*Lambda[1]] # long time [[[1, 2, 2], [-2, -2, -1]]]
sage: K = crystals.KirillovReshetikhin(['D',4,1],2,2) sage: Lambda = K.weight_lattice_realization().fundamental_weights() sage: [b for b in K if b.Epsilon() == 2*Lambda[0]] # long time [[]] sage: [b for b in K if b.Epsilon() == 2*Lambda[4]] # long time [[[3, -4], [4, -3]]]
sage: K = crystals.KirillovReshetikhin(['B',3,1],3,1) sage: Lambda = K.weight_lattice_realization().fundamental_weights() sage: [b for b in K if b.Epsilon() == Lambda[0]] [[+++, []]] sage: [b for b in K if b.Epsilon() == Lambda[1]] [[-++, []]] sage: K = crystals.KirillovReshetikhin(['B',3,1],3,3) sage: [b for b in K if b.Epsilon() == 2*Lambda[0]] # long time [[+++, [[1]]]] sage: [b for b in K if b.Epsilon() == 2*Lambda[1]] # long time [[-++, [[-1]]]]
sage: K = crystals.KirillovReshetikhin(['B',4,1],4,1) sage: Lambda = K.weight_lattice_realization().fundamental_weights() sage: [b for b in K if b.Epsilon() == Lambda[0]] [[++++, []]] sage: [b for b in K if b.Epsilon() == Lambda[1]] [[-+++, []]]
sage: K = crystals.KirillovReshetikhin(['C',3,1],1,1) sage: Lambda = K.weight_lattice_realization().fundamental_weights() sage: [b for b in K if b.Epsilon() == Lambda[0]] [[[1]]] sage: [b for b in K if b.Epsilon() == Lambda[3]] [[[-3]]] sage: K = crystals.KirillovReshetikhin(['C',3,1],1,3) sage: [b for b in K if b.Epsilon() == 2*Lambda[3]] # long time [[[3, -3, -3]]] sage: [b for b in K if b.Epsilon() == 2*Lambda[0]] # long time [[[1]]]
We check the various models agree::
sage: KN = crystals.KirillovReshetikhin(['D',4,1], 2, 1) sage: KR = crystals.KirillovReshetikhin(['D',4,1], 2, 1, model='KR') sage: RC = crystals.KirillovReshetikhin(['D',4,1], 2, 1, model='RC') sage: LS = crystals.KirillovReshetikhin(['D',4,1], 2, 1, model='LSPaths') sage: G = KN.digraph() sage: G.is_isomorphic(KR.digraph(), edge_labels=True) True sage: G.is_isomorphic(RC.digraph(), edge_labels=True) True sage: G.is_isomorphic(LS.digraph(), edge_labels=True) True
sage: KN = crystals.KirillovReshetikhin(['D',4,1], 2, 1) sage: KN2 = crystals.KirillovReshetikhin(['D',4,1], 2, 1, model='KN') sage: KN3 = crystals.KirillovReshetikhin(['D',4,1], 2, 1, model='KashiwaraNakashimaTableaux') sage: KN is KN2 and KN is KN3 True
REFERENCES:
.. [Shimozono02] \M. Shimozono *Affine type A crystal structure on tensor products of rectangles, Demazure characters, and nilpotent varieties*, J. Algebraic Combin. **15** (2002). no. 2. 151-187. :arxiv:`math.QA/9804039`.
.. [Schilling08] \A. Schilling. "Combinatorial structure of Kirillov-Reshetikhin crystals of type `D_n(1)`, `B_n(1)`, `A_{2n-1}(2)`". J. Algebra. **319** (2008). 2938-2962. :arxiv:`0704.2046`.
.. [JS2010] \B. Jones, A. Schilling. "Affine structures and a tableau model for `E_6` crystals", J. Algebra. **324** (2010). 2512-2542. :doi:`10.1016/j.bbr.2011.03.031`, :arxiv:`0909.2442`.
.. [FOS09] \G. Fourier, M. Okado, A. Schilling. *Kirillov-Reshetikhin crystals for nonexceptional types*. Advances in Mathematics. **222** (2009). Issue 3. 1080-1116. :arxiv:`0810.5067`.
.. [LOS12] \C. Lecouvey, M. Okado, M. Shimozono. "Affine crystals, one-dimensional sums and parabolic Lusztig `q`-analogues". Mathematische Zeitschrift. **271** (2012). Issue 3-4. 819-865. :doi:`10.1007/s00209-011-0892-9`, :arxiv:`1002.3715`. """
raise ValueError("invalid model")
def KashiwaraNakashimaTableaux(cartan_type, r, s): """ Return the Kashiwara-Nakashima model for the Kirillov-Reshetikhin crystal `B^{r,s}` in the given type.
The Kashiwara-Nakashima (KN) model constructs the KR crystal from the KN tableaux model for the corresponding classical crystals. This model is named for the underlying KN tableaux.
Many Kirillov-Reshetikhin crystals are constructed from a classical crystal together with an automorphism `p` on the level of crystals which corresponds to a Dynkin diagram automorphism mapping node 0 to some other node `i`. The action of `f_0` and `e_0` is then constructed using `f_0 = p^{-1} \circ f_i \circ p`.
For example, for type `A_n^{(1)}` the Kirillov-Reshetikhin crystal `B^{r,s}` is obtained from the classical crystal `B(s \omega_r)` using the promotion operator. For other types, see [Shimozono02]_, [Schilling08]_, and [JS2010]_.
Other Kirillov-Reshetikhin crystals are constructed using similarity methods. See Section 4 of [FOS09]_.
For more information on Kirillov-Reshetikhin crystals, see :func:`~sage.combinat.crystals.kirillov_reshetikhin.KirillovReshetikhinCrystal`.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['A',3,1], 2, 1) sage: K2 = crystals.kirillov_reshetikhin.KashiwaraNakashimaTableaux(['A',3,1], 2, 1) sage: K is K2 True """ else: raise ValueError("wrong range of parameters") else: raise ValueError("wrong range of parameters") else: raise ValueError("wrong range of parameters") else: raise NotImplementedError else: else: raise ValueError("wrong range of parameters") raise NotImplementedError else: raise NotImplementedError
class KirillovReshetikhinGenericCrystal(AffineCrystalFromClassical): r""" Generic class for Kirillov-Reshetikhin crystal `B^{r,s}` of the given type.
Input is a Dynkin node ``r``, a positive integer ``s``, and a Cartan type ``cartan_type``. """
def __init__(self, cartan_type, r, s, dual=None): r""" Initializes a generic Kirillov-Reshetikhin crystal.
TESTS::
sage: K = crystals.KirillovReshetikhin(CartanType(['A',2,1]), 1, 1) sage: K Kirillov-Reshetikhin crystal of type ['A', 2, 1] with (r,s)=(1,1) sage: K.r() 1 sage: K.s() 1 """ # We need this here for the classic al_decomposition() call else: self._cartan_type = CartanType(cartan_type).dual() KirillovReshetikhinCrystals())
def _repr_(self): """ EXAMPLES::
sage: crystals.KirillovReshetikhin(CartanType(['A',2,1]), 1, 1) # indirect doctest Kirillov-Reshetikhin crystal of type ['A', 2, 1] with (r,s)=(1,1) """
def _element_constructor_(self, *args, **options): """ Construct an element of ``self`` from the input.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['A', 4, 1], 2, 1) sage: K(columns=[[2,1]]) [[1], [2]] """ # Check to make sure it can be converted or elt.parent().r() != self._r or elt.parent().s() != self._s: raise ValueError("the Kirillov-Reshetikhin tableau must have the same Cartan type and shape")
# val in classical weight is a pair (i, mult)
def module_generator(self): r""" Return the unique module generator of classical weight `s \Lambda_r` of a Kirillov-Reshetikhin crystal `B^{r,s}`
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['C',2,1],1,2) sage: K.module_generator() [[1, 1]] sage: K = crystals.KirillovReshetikhin(['E',6,1],1,1) sage: K.module_generator() [(1,)]
sage: K = crystals.KirillovReshetikhin(['D',4,1],2,1) sage: K.module_generator() [[1], [2]] """
def r(self): """ Return `r` of the underlying Kirillov-Reshetikhin crystal `B^{r,s}`.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['D',4,1], 2, 1) sage: K.r() 2 """
def s(self): """ Return `s` of the underlying Kirillov-Reshetikhin crystal `B^{r,s}`.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['D',4,1], 2, 1) sage: K.s() 1 """
@cached_method def classically_highest_weight_vectors(self): """ Return the classically highest weight vectors of ``self``.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['D', 4, 1], 2, 2) sage: K.classically_highest_weight_vectors() ([], [[1], [2]], [[1, 1], [2, 2]]) """ for mg in self.classical_decomposition().module_generators])
def kirillov_reshetikhin_tableaux(self): """ Return the corresponding set of :class:`~sage.combinat.rigged_configurations.kr_tableaux.KirillovReshetikhinTableaux`.
EXAMPLES::
sage: KRC = crystals.KirillovReshetikhin(['D', 4, 1], 2, 2) sage: KRC.kirillov_reshetikhin_tableaux() Kirillov-Reshetikhin tableaux of type ['D', 4, 1] and shape (2, 2) """
class KirillovReshetikhinGenericCrystalElement(AffineCrystalFromClassicalElement): """ Abstract class for all Kirillov-Reshetikhin crystal elements. """ def _repr_diagram(self): """ Return a string representation of ``self`` as a diagram.
EXAMPLES::
sage: C = crystals.KirillovReshetikhin(['D',4,1], 2,1) sage: print(C(2,1)._repr_diagram()) 1 2 """
def pp(self): """ Pretty print ``self``.
EXAMPLES::
sage: C = crystals.KirillovReshetikhin(['D',4,1], 2,1) sage: C(2,1).pp() 1 2 sage: C = crystals.KirillovReshetikhin(['B',3,1], 3,3) sage: C.module_generators[0].pp() + (X) 1 + + """
@cached_method def to_kirillov_reshetikhin_tableau(self): r""" Construct the corresponding :class:`~sage.combinat.rigged_configurations.kr_tableaux.KirillovReshetikhinTableauxElement` from ``self``.
We construct the Kirillov-Reshetikhin tableau element as follows:
1. Let `\lambda` be the shape of ``self``. 2. Determine a path `e_{i_1} e_{i_2} \cdots e_{i_k}` to the highest weight. 3. Apply `f_{i_k} \cdots f_{i_2} f_{i_1}` to a highest weight KR tableau from filling the shape `\lambda`.
EXAMPLES::
sage: KRC = crystals.KirillovReshetikhin(['A', 4, 1], 2, 1) sage: KRC(columns=[[2,1]]).to_kirillov_reshetikhin_tableau() [[1], [2]] sage: KRC = crystals.KirillovReshetikhin(['D', 4, 1], 2, 1) sage: KRC(rows=[]).to_kirillov_reshetikhin_tableau() [[1], [-1]] """
@cached_method def to_tableau(self): r""" Return the :class:`Tableau` corresponding to ``self``.
EXAMPLES::
sage: C = crystals.KirillovReshetikhin(['D',4,1], 2,1) sage: t = C(2,1).to_tableau(); t [[1], [2]] sage: type(t) <class 'sage.combinat.tableau.Tableaux_all_with_category.element_class'> """
def lusztig_involution(self): """ Return the classical Lusztig involution on ``self``.
EXAMPLES::
sage: KRC = crystals.KirillovReshetikhin(['D',4,1], 2,2) sage: elt = KRC(-1,2); elt [[2], [-1]] sage: elt.lusztig_involution() [[1], [-2]] """
KirillovReshetikhinGenericCrystal.Element = KirillovReshetikhinGenericCrystalElement
class KirillovReshetikhinCrystalFromPromotion(KirillovReshetikhinGenericCrystal, AffineCrystalFromClassicalAndPromotion): r""" This generic class assumes that the Kirillov-Reshetikhin crystal is constructed from a classical crystal using the ``classical_decomposition`` and an automorphism ``promotion`` and its inverse, which corresponds to a Dynkin diagram automorphism ``dynkin_diagram_automorphism``.
Each instance using this class needs to implement the methods:
- ``classical_decomposition`` - ``promotion`` - ``promotion_inverse`` - ``dynkin_diagram_automorphism`` """ def __init__(self, cartan_type, r, s): r""" TESTS::
sage: K = crystals.KirillovReshetikhin(['B',2,1], 1, 1) sage: K Kirillov-Reshetikhin crystal of type ['B', 2, 1] with (r,s)=(1,1) sage: TestSuite(K).run() """ self.classical_decomposition(), self.promotion(), self.promotion_inverse(), self.dynkin_diagram_automorphism(0), KirillovReshetikhinCrystals())
class KirillovReshetikhinCrystalFromPromotionElement(AffineCrystalFromClassicalAndPromotionElement, KirillovReshetikhinGenericCrystalElement): """ Element for a Kirillov-Reshetikhin crystal from promotion. """ pass
KirillovReshetikhinCrystalFromPromotion.Element = KirillovReshetikhinCrystalFromPromotionElement
class KR_type_A(KirillovReshetikhinCrystalFromPromotion): r""" Class of Kirillov-Reshetikhin crystals of type `A_n^{(1)}`.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['A',3,1], 2,2) sage: b = K(rows=[[1,2],[2,4]]) sage: b.f(0) [[1, 1], [2, 2]] """
def classical_decomposition(self): """ Specifies the classical crystal underlying the KR crystal of type A.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['A',3,1], 2,2) sage: K.classical_decomposition() The crystal of tableaux of type ['A', 3] and shape(s) [[2, 2]] """ shape=[self.s()]*self.r())
@cached_method def promotion(self): r""" Specifies the promotion operator used to construct the affine type `A` crystal.
For type `A` this corresponds to the Dynkin diagram automorphism which `i \mapsto i+1 \mod n+1`, where `n` is the rank.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['A',3,1], 2,2) sage: b = K.classical_decomposition()(rows=[[1,2],[3,4]]) sage: K.promotion()(b) [[1, 3], [2, 4]] """ lambda x: T(x.to_tableau().promotion(self._cartan_type[1])), cache=False)
@cached_method def promotion_inverse(self): r""" Specifies the inverse promotion operator used to construct the affine type `A` crystal.
For type `A` this corresponds to the Dynkin diagram automorphism which `i \mapsto i-1 \mod n+1`, where `n` is the rank.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['A',3,1], 2,2) sage: b = K.classical_decomposition()(rows=[[1,3],[2,4]]) sage: K.promotion_inverse()(b) [[1, 2], [3, 4]] sage: b = K.classical_decomposition()(rows=[[1,2],[3,3]]) sage: K.promotion_inverse()(K.promotion()(b)) [[1, 2], [3, 3]] """ lambda x: T(x.to_tableau().promotion_inverse(self._cartan_type[1])), cache=False)
def dynkin_diagram_automorphism(self, i): r""" Specifies the Dynkin diagram automorphism underlying the promotion action on the crystal elements. The automorphism needs to map node 0 to some other Dynkin node.
For type `A` we use the Dynkin diagram automorphism which `i \mapsto i+1 \mod n+1`, where `n` is the rank.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['A',3,1], 2,2) sage: K.dynkin_diagram_automorphism(0) 1 sage: K.dynkin_diagram_automorphism(3) 0 """
class KR_type_vertical(KirillovReshetikhinCrystalFromPromotion): r""" Class of Kirillov-Reshetikhin crystals `B^{r,s}` of type `D_n^{(1)}` for `r \le n-2`, `B_n^{(1)}` for `r < n`, and `A_{2n-1}^{(2)}` for `r \le n`.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['D',4,1], 2,2) sage: b = K(rows=[]) sage: b.f(0) [[1], [2]] sage: b.f(0).f(0) [[1, 1], [2, 2]] sage: b.e(0) [[-2], [-1]] sage: b.e(0).e(0) [[-2, -2], [-1, -1]]
sage: K = crystals.KirillovReshetikhin(['D',5,1], 3,1) sage: b = K(rows=[[1]]) sage: b.e(0) [[3], [-3], [-2]]
sage: K = crystals.KirillovReshetikhin(['B',3,1], 1,1) sage: [[b,b.f(0)] for b in K] [[[[1]], None], [[[2]], None], [[[3]], None], [[[0]], None], [[[-3]], None], [[[-2]], [[1]]], [[[-1]], [[2]]]]
sage: K = crystals.KirillovReshetikhin(['A',5,2], 1,1) sage: [[b,b.f(0)] for b in K] [[[[1]], None], [[[2]], None], [[[3]], None], [[[-3]], None], [[[-2]], [[1]]], [[[-1]], [[2]]]] """
def classical_decomposition(self): r""" Specifies the classical crystal underlying the Kirillov-Reshetikhin crystal of type `D_n^{(1)}`, `B_n^{(1)}`, and `A_{2n-1}^{(2)}`.
It is given by `B^{r,s} \cong \bigoplus_\Lambda B(\Lambda)`, where `\Lambda` are weights obtained from a rectangle of width `s` and height `r` by removing vertical dominoes. Here we identify the fundamental weight `\Lambda_i` with a column of height `i`.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['D',4,1], 2,2) sage: K.classical_decomposition() The crystal of tableaux of type ['D', 4] and shape(s) [[], [1, 1], [2, 2]] """ shapes=vertical_dominoes_removed(self.r(), self.s()))
@cached_method def promotion(self): """ Specifies the promotion operator used to construct the affine type `D_n^{(1)}` etc. crystal.
This corresponds to the Dynkin diagram automorphism which interchanges nodes 0 and 1, and leaves all other nodes unchanged. On the level of crystals it is constructed using `\pm` diagrams.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['D',4,1], 2,2) sage: promotion = K.promotion() sage: b = K.classical_decomposition()(rows=[]) sage: promotion(b) [[1, 2], [-2, -1]] sage: b = K.classical_decomposition()(rows=[[1,3],[2,-1]]) sage: promotion(b) [[1, 3], [2, -1]] sage: b = K.classical_decomposition()(rows=[[1],[-3]]) sage: promotion(b) [[2, -3], [-2, -1]] """
def promotion_inverse(self): """ Return inverse of promotion.
In this case promotion is an involution, so promotion inverse equals promotion.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['D',4,1], 2,2) sage: promotion = K.promotion() sage: promotion_inverse = K.promotion_inverse() sage: all( promotion_inverse(promotion(b.lift())) == b.lift() for b in K ) True """
def dynkin_diagram_automorphism(self, i): """ Specifies the Dynkin diagram automorphism underlying the promotion action on the crystal elements. The automorphism needs to map node 0 to some other Dynkin node.
Here we use the Dynkin diagram automorphism which interchanges nodes 0 and 1 and leaves all other nodes unchanged.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['D',4,1],1,1) sage: K.dynkin_diagram_automorphism(0) 1 sage: K.dynkin_diagram_automorphism(1) 0 sage: K.dynkin_diagram_automorphism(4) 4 """
def promotion_on_highest_weight_vector(self, b): """ Calculates promotion on a `{2,3,...,n}` highest weight vector ``b``.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['D',4,1], 2,2) sage: T = K.classical_decomposition() sage: hw = [ b for b in T if all(b.epsilon(i)==0 for i in [2,3,4]) ] sage: [K.promotion_on_highest_weight_vector(b) for b in hw] [[[1, 2], [-2, -1]], [[2, 2], [-2, -1]], [[1, 2], [3, -1]], [[2], [-2]], [[1, 2], [2, -2]], [[2, 2], [-1, -1]], [[2, 2], [3, -1]], [[2, 2], [3, 3]], [], [[1], [2]], [[1, 1], [2, 2]], [[2], [-1]], [[1, 2], [2, -1]], [[2], [3]], [[1, 2], [2, 3]]] """
def promotion_on_highest_weight_vectors(self): """ Calculates promotion on `{2,3,...,n}` highest weight vectors.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['D',4,1], 2,2) sage: T = K.classical_decomposition() sage: hw = [ b for b in T if all(b.epsilon(i)==0 for i in [2,3,4]) ] sage: f = K.promotion_on_highest_weight_vectors() doctest:...: DeprecationWarning: Call self.promotion_on_highest_weight_vector directly See http://trac.sagemath.org/22429 for details. sage: f(hw[0]) [[1, 2], [-2, -1]] """
def from_highest_weight_vector_to_pm_diagram(self, b): """ This gives the bijection between an element ``b`` in the classical decomposition of the KR crystal that is `{2, 3, \ldots, n}`-highest weight and `\pm` diagrams.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['D',4,1], 2,2) sage: T = K.classical_decomposition() sage: b = T(rows=[[2],[-2]]) sage: pm = K.from_highest_weight_vector_to_pm_diagram(b); pm [[1, 1], [0, 0], [0]] sage: pm.pp() + - sage: b = T(rows=[]) sage: pm=K.from_highest_weight_vector_to_pm_diagram(b); pm [[0, 2], [0, 0], [0]] sage: pm.pp()
sage: hw = [ b for b in T if all(b.epsilon(i)==0 for i in [2,3,4]) ] sage: all(K.from_pm_diagram_to_highest_weight_vector(K.from_highest_weight_vector_to_pm_diagram(b)) == b for b in hw) True """
def from_pm_diagram_to_highest_weight_vector(self, pm): """ This gives the bijection between a `\pm` diagram and an element ``b`` in the classical decomposition of the KR crystal that is `{2, 3, \ldots, n}`-highest weight.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['D',4,1], 2,2) sage: pm = sage.combinat.crystals.kirillov_reshetikhin.PMDiagram([[1, 1], [0, 0], [0]]) sage: K.from_pm_diagram_to_highest_weight_vector(pm) [[2], [-2]] """ if b.to_tableau().shape() == pm.outer_shape()][0] else:
class KR_type_E6(KirillovReshetikhinCrystalFromPromotion): r""" Class of Kirillov-Reshetikhin crystals of type `E_6^{(1)}` for `r=1,2,6`.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['E',6,1],2,1) sage: K.module_generator().e(0) [] sage: K.module_generator().e(0).f(0) [[(2, -1), (1,)]] sage: K = crystals.KirillovReshetikhin(['E',6,1], 1,1) sage: b = K.module_generator() sage: b [(1,)] sage: b.e(0) [(-2, 1)] sage: 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] sage: b [(-1, 3)] sage: b.e(0) [(-1, -2, 3)]
The elements of the Kirillov-Reshetikhin crystals can be constructed from a classical crystal element using :meth:`~sage.combinat.crystals.affine.AffineCrystalFromClassical.retract()`.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['E',6,1],2,1) sage: La = K.cartan_type().classical().root_system().weight_lattice().fundamental_weights() sage: H = crystals.HighestWeight(La[2]) sage: t = H.module_generator() sage: t [[(2, -1), (1,)]] sage: type(K.retract(t)) <class 'sage.combinat.crystals.kirillov_reshetikhin.KR_type_E6_with_category.element_class'> sage: K.retract(t).e(0) []
TESTS::
sage: K = crystals.KirillovReshetikhin(['E',6,1], 2,1) sage: La = K.weight_lattice_realization().fundamental_weights() sage: 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) True """
def classical_decomposition(self): """ Specifies the classical crystal underlying the KR crystal of type `E_6^{(1)}`.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['E',6,1], 2,2) sage: K.classical_decomposition() Direct 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]) sage: K = crystals.KirillovReshetikhin(['E',6,1], 1,2) sage: K.classical_decomposition() Direct sum of the crystals Family (Finite dimensional highest weight crystal of type ['E', 6] and highest weight 2*Lambda[1],) """ else: raise NotImplementedError for dominant_weight in dw], keepkey=False)
def dynkin_diagram_automorphism(self, i): r""" Specifies the Dynkin diagram automorphism underlying the promotion action on the crystal elements.
Here we use the Dynkin diagram automorphism of order 3 which maps node 0 to node 1.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['E',6,1],2,1) sage: [K.dynkin_diagram_automorphism(i) for i in K.index_set()] [1, 6, 3, 5, 4, 2, 0] """
def affine_weight(self, b): r""" Return the affine level zero weight corresponding to the element ``b`` of the classical crystal underlying ``self``.
For the coefficients to calculate the level, see Table Aff 1 in [Ka1990]_.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['E',6,1],2,1) sage: [K.affine_weight(x.lift()) for x in K ....: if all(x.epsilon(i) == 0 for i in [2,3,4,5])] [(0, 0, 0, 0, 0, 0, 0), (-2, 0, 1, 0, 0, 0, 0), (-1, -1, 0, 0, 0, 1, 0), (0, 0, 0, 0, 0, 0, 0), (0, 0, 0, 0, 0, 1, -2), (0, -1, 1, 0, 0, 0, -1), (-1, 0, 0, 1, 0, 0, -1), (-1, -1, 0, 0, 1, 0, -1), (0, 0, 0, 0, 0, 0, 0), (0, -2, 0, 1, 0, 0, 0)] """
@cached_method def hw_auxiliary(self): r""" Return the `{2,3,4,5}` highest weight elements of ``self``.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['E',6,1],2,1) sage: K.hw_auxiliary() ([], [[(2, -1), (1,)]], [[(5, -3), (-1, 3)]], [[(6, -2), (-6, 2)]], [[(5, -2, -6), (-6, 2)]], [[(-1,), (-6, 2)]], [[(3, -1, -6), (1,)]], [[(4, -3, -6), (-1, 3)]], [[(1, -3), (-1, 3)]], [[(-1,), (-1, 3)]]) """ if all(x.epsilon(i) == 0 for i in [2,3,4,5])])
@cached_method def highest_weight_dict(self): r""" Return a dictionary between `\{1,2,3,4,5\}`-highest weight elements, and a tuple of affine weights and its classical component.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['E',6,1],2,1) sage: sorted(K.highest_weight_dict().items(), key=str) [([[(2, -1), (1,)]], ((-2, 0, 1, 0, 0, 0, 0), 1)), ([[(3, -1, -6), (1,)]], ((-1, 0, 0, 1, 0, 0, -1), 1)), ([[(5, -2, -6), (-6, 2)]], ((0, 0, 0, 0, 0, 1, -2), 1)), ([[(6, -2), (-6, 2)]], ((0, 0, 0, 0, 0, 0, 0), 1)), ([], ((0, 0, 0, 0, 0, 0, 0), 0))] """
@cached_method def highest_weight_dict_inv(self): r""" Return a dictionary between a tuple of affine weights and a classical component, and `\{2,3,4,5,6\}`-highest weight elements.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['E',6,1],2,1) sage: K.highest_weight_dict_inv() {((-2, 0, 1, 0, 0, 0, 0), 1): [[(2, -1), (1,)]], ((-1, -1, 0, 0, 0, 1, 0), 1): [[(5, -3), (-1, 3)]], ((0, -2, 0, 1, 0, 0, 0), 1): [[(-1,), (-1, 3)]], ((0, 0, 0, 0, 0, 0, 0), 0): [], ((0, 0, 0, 0, 0, 0, 0), 1): [[(1, -3), (-1, 3)]]} """
def automorphism_on_affine_weight(self, weight): r""" Act with the Dynkin diagram automorphism on affine weights as outputted by the ``affine_weight`` method.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['E',6,1],2,1) sage: [[x[0], K.automorphism_on_affine_weight(x[0])] ....: for x in K.highest_weight_dict().values()] [[(-1, 0, 0, 1, 0, 0, -1), (-1, -1, 0, 0, 0, 1, 0)], [(0, 0, 0, 0, 0, 0, 0), (0, 0, 0, 0, 0, 0, 0)], [(0, 0, 0, 0, 0, 0, 0), (0, 0, 0, 0, 0, 0, 0)], [(-2, 0, 1, 0, 0, 0, 0), (0, -2, 0, 1, 0, 0, 0)], [(0, 0, 0, 0, 0, 1, -2), (-2, 0, 1, 0, 0, 0, 0)]] """
@cached_method def promotion_on_highest_weight_vectors(self): r""" Return a dictionary of the promotion map on `\{1,2,3,4,5\}`-highest weight elements to `\{2,3,4,5,6\}`-highest weight elements in ``self``.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['E',6,1], 2, 1) sage: dic = K.promotion_on_highest_weight_vectors() sage: sorted(dic.items(), key=str) [([[(2, -1), (1,)]], [[(-1,), (-1, 3)]]), ([[(3, -1, -6), (1,)]], [[(5, -3), (-1, 3)]]), ([[(5, -2, -6), (-6, 2)]], [[(2, -1), (1,)]]), ([[(6, -2), (-6, 2)]], []), ([], [[(1, -3), (-1, 3)]])] """ map_index((dic[x][1], dic_weight[dic[x][0]])) )
@cached_method def promotion_on_highest_weight_vectors_function(self): """ Return a lambda function on ``x`` defined by ``self.promotion_on_highest_weight_vectors()[x]``.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['E',6,1], 2, 1) sage: f = K.promotion_on_highest_weight_vectors_function() sage: f(K.module_generator().lift()) [[(-1,), (-1, 3)]] """
@cached_method def promotion(self): r""" Specifies the promotion operator used to construct the affine type `E_6^{(1)}` crystal.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['E',6,1], 2,1) sage: promotion = K.promotion() sage: all(promotion(promotion(promotion(b))) == b for b in K.classical_decomposition()) True sage: K = crystals.KirillovReshetikhin(['E',6,1],1,1) sage: promotion = K.promotion() sage: all(promotion(promotion(promotion(b))) == b for b in K.classical_decomposition()) True """ automorphism=self.dynkin_diagram_automorphism)
@cached_method def promotion_inverse(self): r""" Return the inverse promotion. Since promotion is of order 3, the inverse promotion is the same as promotion applied twice.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['E',6,1], 2,1) sage: p = K.promotion() sage: p_inv = K.promotion_inverse() sage: all(p_inv(p(b)) == b for b in K.classical_decomposition()) True """ #return lambda x : p(p(x))
class KR_type_C(KirillovReshetikhinGenericCrystal): r""" Class of Kirillov-Reshetikhin crystals `B^{r,s}` of type `C_n^{(1)}` for `r < n`.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['C',2,1], 1,2) sage: K Kirillov-Reshetikhin crystal of type ['C', 2, 1] with (r,s)=(1,2) sage: b = K(rows=[]) sage: b.f(0) [[1, 1]] sage: b.e(0) [[-1, -1]] """
def classical_decomposition(self): r""" Return the classical crystal underlying the Kirillov-Reshetikhin crystal of type `C_n^{(1)}`.
It is given by `B^{r,s} \cong \bigoplus_{\Lambda} B(\Lambda)`, where `\Lambda` are weights obtained from a rectangle of width `s` and height `r` by removing horizontal dominoes. Here we identify the fundamental weight `\Lambda_i` with a column of height `i`.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['C',3,1], 2,2) sage: K.classical_decomposition() The crystal of tableaux of type ['C', 3] and shape(s) [[], [2], [2, 2]] """ shapes=horizontal_dominoes_removed(self.r(), self.s()))
def ambient_crystal(self): r""" Return the ambient crystal `B^{r,s}` of type `A_{2n+1}^{(2)}` associated to the Kirillov-Reshetikhin crystal of type `C_n^{(1)}`.
This ambient crystal is used to construct the zero arrows.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['C',3,1], 2,3) sage: K.ambient_crystal() Kirillov-Reshetikhin crystal of type ['B', 4, 1]^* with (r,s)=(2,3) """ self.r(), self.s())
@cached_method def ambient_dict_pm_diagrams(self): r""" Return a dictionary of all self-dual `\pm` diagrams for the ambient crystal whose keys are their inner shape.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['C',2,1], 1,2) sage: K.ambient_dict_pm_diagrams() {[]: [[1, 1], [0]], [2]: [[0, 0], [2]]} sage: K = crystals.KirillovReshetikhin(['C',3,1], 2,2) sage: K.ambient_dict_pm_diagrams() {[]: [[1, 1], [0, 0], [0]], [2]: [[0, 0], [1, 1], [0]], [2, 2]: [[0, 0], [0, 0], [2]]} sage: K = crystals.KirillovReshetikhin(['C',3,1], 2,3) sage: K.ambient_dict_pm_diagrams() {[1, 1]: [[1, 1], [0, 0], [1]], [3, 1]: [[0, 0], [1, 1], [1]], [3, 3]: [[0, 0], [0, 0], [3]]} """
@cached_method def ambient_highest_weight_dict(self): r""" Return a dictionary of all `\{2,\ldots,n+1\}`-highest weight vectors in the ambient crystal.
The key is the inner shape of their corresponding `\pm` diagram, or equivalently, their `\{2,\ldots,n+1\}` weight.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['C',3,1], 2,2) sage: K.ambient_highest_weight_dict() {[]: [[2], [-2]], [2]: [[1, 2], [2, -1]], [2, 2]: [[2, 2], [3, 3]]} """ for key in A}
@cached_method def highest_weight_dict(self): r""" Return a dictionary of the classical highest weight vectors of ``self`` whose keys are their shape.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['C',3,1], 2,2) sage: K.highest_weight_dict() {[]: [], [2]: [[1, 1]], [2, 2]: [[1, 1], [2, 2]]} """
@cached_method def to_ambient_crystal(self): r""" Return a map from the Kirillov-Reshetikhin crystal of type `C_n^{(1)}` to the ambient crystal of type `A_{2n+1}^{(2)}`.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['C',3,1], 2,2) sage: b=K(rows=[[1,1]]) sage: K.to_ambient_crystal()(b) [[1, 2], [2, -1]] sage: b=K(rows=[]) sage: K.to_ambient_crystal()(b) [[2], [-2]] sage: K.to_ambient_crystal()(b).parent() Kirillov-Reshetikhin crystal of type ['B', 4, 1]^* with (r,s)=(2,2) """ automorphism=lambda i: i+1, cartan_type=classical, check=False)
@cached_method def from_ambient_crystal(self): r""" Return a map from the ambient crystal of type `A_{2n+1}^{(2)}` to the Kirillov-Reshetikhin crystal of type `C_n^{(1)}`.
Note that this map is only well-defined on type `C_n^{(1)}` elements that are in the image under :meth:`to_ambient_crystal`.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['C',3,1], 2,2) sage: b = K.ambient_crystal()(rows=[[2,2],[3,3]]) sage: K.from_ambient_crystal()(b) [[1, 1], [2, 2]] """ index_set=ind, automorphism=lambda i: i-1)
class KR_type_CElement(KirillovReshetikhinGenericCrystalElement): r""" Class for the elements in the Kirillov-Reshetikhin crystals `B^{r,s}` of type `C_n^{(1)}` for `r<n`.
EXAMPLES::
sage: K=crystals.KirillovReshetikhin(['C',3,1],1,2) sage: type(K.module_generators[0]) <class 'sage.combinat.crystals.kirillov_reshetikhin.KR_type_C_with_category.element_class'> """ def e0(self): r""" Return `e_0` on ``self`` by mapping ``self`` to the ambient crystal, calculating `e_1 e_0` there and pulling the element back.
EXAMPLES::
sage: K=crystals.KirillovReshetikhin(['C',3,1],1,2) sage: b = K(rows=[]) sage: b.e(0) # indirect doctest [[-1, -1]] """
def f0(self): r""" Return `f_0` on ``self`` by mapping ``self`` to the ambient crystal, calculating `f_1 f_0` there and pulling the element back.
EXAMPLES::
sage: K=crystals.KirillovReshetikhin(['C',3,1],1,2) sage: b = K(rows=[]) sage: b.f(0) # indirect doctest [[1, 1]] """
def epsilon0(self): r""" Calculate `\varepsilon_0` of ``self`` by mapping the element to the ambient crystal and calculating `\varepsilon_1` there.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['C',2,1], 1,2) sage: b=K(rows=[[1,1]]) sage: b.epsilon(0) # indirect doctest 2 """
def phi0(self): r""" Calculate `\varphi_0` of ``self`` by mapping the element to the ambient crystal and calculating `\varphi_1` there.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['C',2,1], 1,2) sage: b=K(rows=[[-1,-1]]) sage: b.phi(0) # indirect doctest 2 """
KR_type_C.Element = KR_type_CElement
class KR_type_A2(KirillovReshetikhinGenericCrystal): r""" Class of Kirillov-Reshetikhin crystals `B^{r,s}` of type `A_{2n}^{(2)}` for `1 \leq r \leq n` in the realization with classical subalgebra `B_n`. The Cartan type in this case is inputted as the dual of `A_{2n}^{(2)}`.
This is an alternative implementation to :class:`KR_type_box` that uses the classical decomposition into type `C_n` crystals.
EXAMPLES::
sage: C = CartanType(['A',4,2]).dual() sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 1, 1) sage: K Kirillov-Reshetikhin crystal of type ['BC', 2, 2]^* with (r,s)=(1,1) sage: b = K(rows=[[-1]]) sage: b.f(0) [[1]] sage: b.e(0)
We can now check whether the two KR crystals of type `A_4^{(2)}` (namely the KR crystal and its dual construction) are isomorphic up to relabelling of the edges::
sage: C = CartanType(['A',4,2]) sage: K = crystals.KirillovReshetikhin(C,1,1) sage: Kdual = crystals.KirillovReshetikhin(C.dual(),1,1) sage: G = K.digraph() sage: Gdual = Kdual.digraph() sage: f = {0:2, 1:1, 2:0} sage: Gnew = DiGraph(); Gnew.add_vertices(Gdual.vertices()); Gnew.add_edges([(u,v,f[i]) for (u,v,i) in Gdual.edges()]) sage: G.is_isomorphic(Gnew, edge_labels = True) True """ def module_generator(self): r""" Return the unique module generator of classical weight `s \Lambda_r` of a Kirillov-Reshetikhin crystal `B^{r,s}`.
EXAMPLES::
sage: ct = CartanType(['A',8,2]).dual() sage: K = crystals.KirillovReshetikhin(ct, 3, 5) sage: K.module_generator() [[1, 1, 1, 1, 1], [2, 2, 2, 2, 2], [3, 3, 3, 3, 3]]
TESTS:
Check that :trac:`23028` is fixed::
sage: ct = CartanType(['A',8,2]).dual() sage: K = crystals.KirillovReshetikhin(ct, 4, 3) sage: K.module_generator() [[1, 1, 1], [2, 2, 2], [3, 3, 3], [4, 4, 4]] sage: K = crystals.KirillovReshetikhin(ct, 4, 1) sage: K.module_generator() [[1], [2], [3], [4]] """
def classical_decomposition(self): r""" Return the classical crystal underlying the Kirillov-Reshetikhin crystal of type `A_{2n}^{(2)}` with `B_n` as classical subdiagram.
It is given by `B^{r,s} \cong \bigoplus_{\Lambda} B(\Lambda)`, where `B(\Lambda)` is a highest weight crystal of type `B_n` of highest weight `\Lambda`. The sum is over all weights `\Lambda` obtained from a rectangle of width `s` and height `r` by removing horizontal dominoes. Here we identify the fundamental weight `\Lambda_i` with a column of height `i`.
EXAMPLES::
sage: C = CartanType(['A',4,2]).dual() sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 2, 2) sage: K.classical_decomposition() The crystal of tableaux of type ['B', 2] and shape(s) [[], [2], [2, 2]] """ shapes = horizontal_dominoes_removed(self.r(),self.s()))
def ambient_crystal(self): r""" Return the ambient crystal `B^{r,s}` of type `B_{n+1}^{(1)}` associated to the Kirillov-Reshetikhin crystal of type `A_{2n}^{(2)}` dual.
This ambient crystal is used to construct the zero arrows.
EXAMPLES::
sage: C = CartanType(['A',4,2]).dual() sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 2, 3) sage: K.ambient_crystal() Kirillov-Reshetikhin crystal of type ['B', 3, 1] with (r,s)=(2,3) """
@cached_method def ambient_dict_pm_diagrams(self): r""" Return a dictionary of all self-dual `\pm` diagrams for the ambient crystal whose keys are their inner shape.
EXAMPLES::
sage: C = CartanType(['A',4,2]).dual() sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 1, 1) sage: K.ambient_dict_pm_diagrams() {[1]: [[0, 0], [1]]} sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 1, 2) sage: K.ambient_dict_pm_diagrams() {[]: [[1, 1], [0]], [2]: [[0, 0], [2]]} sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 2, 2) sage: K.ambient_dict_pm_diagrams() {[]: [[1, 1], [0, 0], [0]], [2]: [[0, 0], [1, 1], [0]], [2, 2]: [[0, 0], [0, 0], [2]]} """
@cached_method def ambient_highest_weight_dict(self): r""" Return a dictionary of all `\{2,\ldots,n+1\}`-highest weight vectors in the ambient crystal.
The key is the inner shape of their corresponding `\pm` diagram, or equivalently, their `\{2,\ldots,n+1\}` weight.
EXAMPLES::
sage: C = CartanType(['A',4,2]).dual() sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 1, 2) sage: K.ambient_highest_weight_dict() {[]: [[1, -1]], [2]: [[2, 2]]} """ for key in A}
@cached_method def highest_weight_dict(self): r""" Return a dictionary of the classical highest weight vectors of ``self`` whose keys are their shape.
EXAMPLES::
sage: C = CartanType(['A',4,2]).dual() sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 1, 2) sage: K.highest_weight_dict() {[]: [], [2]: [[1, 1]]} """
@cached_method def to_ambient_crystal(self): r""" Return a map from the Kirillov-Reshetikhin crystal of type `A_{2n}^{(2)}` to the ambient crystal of type `B_{n+1}^{(1)}`.
EXAMPLES::
sage: C = CartanType(['A',4,2]).dual() sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 1, 2) sage: b=K(rows=[[1,1]]) sage: K.to_ambient_crystal()(b) [[2, 2]] sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 2, 2) sage: b=K(rows=[[1,1]]) sage: K.to_ambient_crystal()(b) [[1, 2], [2, -1]] sage: K.to_ambient_crystal()(b).parent() Kirillov-Reshetikhin crystal of type ['B', 3, 1] with (r,s)=(2,2) """ automorphism=lambda i: i+1, cartan_type=classical, check=False)
@cached_method def from_ambient_crystal(self): r""" Return a map from the ambient crystal of type `B_{n+1}^{(1)}` to the Kirillov-Reshetikhin crystal of type `A_{2n}^{(2)}`.
Note that this map is only well-defined on type `A_{2n}^{(2)}` elements that are in the image under :meth:`to_ambient_crystal`.
EXAMPLES::
sage: C = CartanType(['A',4,2]).dual() sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 1, 2) sage: b = K.ambient_crystal()(rows=[[2,2]]) sage: K.from_ambient_crystal()(b) [[1, 1]] """ automorphism=lambda i: i-1)
class KR_type_A2Element(KirillovReshetikhinGenericCrystalElement): r""" Class for the elements in the Kirillov-Reshetikhin crystals `B^{r,s}` of type `A_{2n}^{(2)}` for `r<n` with underlying classical algebra `B_n`.
EXAMPLES::
sage: C = CartanType(['A',4,2]).dual() sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 1, 2) sage: type(K.module_generators[0]) <class 'sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2_with_category.element_class'> """
def e0(self): r""" Return `e_0` on ``self`` by mapping ``self`` to the ambient crystal, calculating `e_1 e_0` there and pulling the element back.
EXAMPLES::
sage: C = CartanType(['A',4,2]).dual() sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 1, 1) sage: b = K(rows=[[1]]) sage: b.e(0) # indirect doctest [[-1]] """
def f0(self): r""" Return `f_0` on ``self`` by mapping ``self`` to the ambient crystal, calculating `f_1 f_0` there and pulling the element back.
EXAMPLES::
sage: C = CartanType(['A',4,2]).dual() sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 1, 1) sage: b = K(rows=[[-1]]) sage: b.f(0) # indirect doctest [[1]] """
def epsilon0(self): r""" Calculate `\varepsilon_0` of ``self`` by mapping the element to the ambient crystal and calculating ``\varepsilon_1`` there.
EXAMPLES::
sage: C = CartanType(['A',4,2]).dual() sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 1, 1) sage: b=K(rows=[[1]]) sage: b.epsilon(0) # indirect doctest 1 """
def phi0(self): r""" Calculate `\varphi_0` of ``self`` by mapping the element to the ambient crystal and calculating `\varphi_1` there.
EXAMPLES::
sage: C = CartanType(['A',4,2]).dual() sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_A2(C, 1, 1) sage: b = K(rows=[[-1]]) sage: b.phi(0) # indirect doctest 1 """
KR_type_A2.Element = KR_type_A2Element
class KR_type_box(KirillovReshetikhinGenericCrystal, AffineCrystalFromClassical): r""" Class of Kirillov-Reshetikhin crystals `B^{r,s}` of type `A_{2n}^{(2)}` for `r\le n` and type `D_{n+1}^{(2)}` for `r<n`.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['A',4,2], 1,1) sage: K Kirillov-Reshetikhin crystal of type ['BC', 2, 2] with (r,s)=(1,1) sage: b = K(rows=[]) sage: b.f(0) [[1]] sage: b.e(0) [[-1]] """ def __init__(self, cartan_type, r, s): r""" Initializes a Kirillov-Reshetikhin crystal ``self``.
TESTS::
sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_box(['A',4,2], 1, 1) sage: K Kirillov-Reshetikhin crystal of type ['BC', 2, 2] with (r,s)=(1,1) sage: K = sage.combinat.crystals.kirillov_reshetikhin.KR_type_box(['D',4,2], 1, 1) sage: K Kirillov-Reshetikhin crystal of type ['C', 3, 1]^* with (r,s)=(1,1) sage: TestSuite(K).run() """ KirillovReshetikhinCrystals())
def classical_decomposition(self): r""" Return the classical crystal underlying the Kirillov-Reshetikhin crystal of type `A_{2n}^{(2)}` and `D_{n+1}^{(2)}`.
It is given by `B^{r,s} \cong \bigoplus_{\Lambda} B(\Lambda)`, where `\Lambda` are weights obtained from a rectangle of width `s` and height `r` by removing boxes. Here we identify the fundamental weight `\Lambda_i` with a column of height `i`.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['A',4,2], 2,2) sage: K.classical_decomposition() The crystal of tableaux of type ['C', 2] and shape(s) [[], [1], [2], [1, 1], [2, 1], [2, 2]] sage: K = crystals.KirillovReshetikhin(['D',4,2], 2,3) sage: K.classical_decomposition() The 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]] """ shapes = partitions_in_box(self.r(),self.s()))
def ambient_crystal(self): r""" Return the ambient crystal `B^{r,2s}` of type `C_n^{(1)}` associated to the Kirillov-Reshetikhin crystal.
The ambient crystal is used to construct the zero arrows.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['A',4,2], 2,2) sage: K.ambient_crystal() Kirillov-Reshetikhin crystal of type ['C', 2, 1] with (r,s)=(2,4) """ # calling KR_type_C instead of KirillovReshetikhin(['C',n,1],r,s) has the advantage that # that this also works for r=n for A_{2n}^{(2)}.
@cached_method def highest_weight_dict(self): r""" Return a dictionary of the classical highest weight vectors of ``self`` whose keys are 2 times their shape.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['A',6,2], 2,2) sage: K.highest_weight_dict() {[]: [], [2]: [[1]], [2, 2]: [[1], [2]], [4]: [[1, 1]], [4, 2]: [[1, 1], [2]], [4, 4]: [[1, 1], [2, 2]]} """ for x in self.module_generators}
@cached_method def ambient_highest_weight_dict(self): r""" Return a dictionary of the classical highest weight vectors of the ambient crystal of ``self`` whose keys are their shape.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['A',6,2], 2,2) sage: K.ambient_highest_weight_dict() {[]: [], [2]: [[1, 1]], [2, 2]: [[1, 1], [2, 2]], [4]: [[1, 1, 1, 1]], [4, 2]: [[1, 1, 1, 1], [2, 2]], [4, 4]: [[1, 1, 1, 1], [2, 2, 2, 2]]} """ for x in self.ambient_crystal().module_generators}
def similarity_factor(self): r""" Sets the similarity factor used to map to the ambient crystal.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['A',6,2], 2,2) sage: K.similarity_factor() {1: 2, 2: 2, 3: 2} sage: K = crystals.KirillovReshetikhin(['D',5,2], 1,1) sage: K.similarity_factor() {1: 2, 2: 2, 3: 2, 4: 1} """
@cached_method def to_ambient_crystal(self): r""" Return a map from ``self`` to the ambient crystal of type `C_n^{(1)}`.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['D',4,2], 1,1) sage: [K.to_ambient_crystal()(b) for b in K] [[], [[1, 1]], [[2, 2]], [[3, 3]], [[3, -3]], [[-3, -3]], [[-2, -2]], [[-1, -1]]] sage: K = crystals.KirillovReshetikhin(['A',4,2], 1,1) sage: [K.to_ambient_crystal()(b) for b in K] [[], [[1, 1]], [[2, 2]], [[-2, -2]], [[-1, -1]]] """ index_set=classical.index_set(), scaling_factors=self.similarity_factor(), cartan_type=classical, check=False )
@cached_method def from_ambient_crystal(self): r""" Return a map from the ambient crystal of type `C_n^{(1)}` to the Kirillov-Reshetikhin crystal ``self``.
Note that this map is only well-defined on elements that are in the image under :meth:`to_ambient_crystal`.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['D',4,2], 1,1) sage: b = K.ambient_crystal()(rows=[[3,-3]]) sage: K.from_ambient_crystal()(b) [[0]] sage: K = crystals.KirillovReshetikhin(['A',4,2], 1,1) sage: b = K.ambient_crystal()(rows=[]) sage: K.from_ambient_crystal()(b) [] """ index_set=self.cartan_type().classical().index_set(), similarity_factor_domain=self.similarity_factor() )
class KR_type_boxElement(KirillovReshetikhinGenericCrystalElement): r""" Class for the elements in the Kirillov-Reshetikhin crystals `B^{r,s}` of type `A_{2n}^{(2)}` for `r \leq n` and type `D_{n+1}^{(2)}` for `r < n`.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['A',4,2],1,2) sage: type(K.module_generators[0]) <class 'sage.combinat.crystals.kirillov_reshetikhin.KR_type_box_with_category.element_class'> """
def e0(self): r""" Return `e_0` on ``self`` by mapping ``self`` to the ambient crystal, calculating `e_0` there and pulling the element back.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['A',4,2],1,1) sage: b = K(rows=[]) sage: b.e(0) # indirect doctest [[-1]] """
def f0(self): r""" Return `f_0` on ``self`` by mapping ``self`` to the ambient crystal, calculating `f_0` there and pulling the element back.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['A',4,2],1,1) sage: b = K(rows=[]) sage: b.f(0) # indirect doctest [[1]] """
def epsilon0(self): r""" Return `\varepsilon_0` of ``self`` by mapping the element to the ambient crystal and calculating `\varepsilon_0` there.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['A',4,2], 1,1) sage: b = K(rows=[[1]]) sage: b.epsilon(0) # indirect doctest 2 """
def phi0(self): r""" Return `\varphi_0` of ``self`` by mapping the element to the ambient crystal and calculating `\varphi_0` there.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['D',3,2], 1,1) sage: b = K(rows=[[-1]]) sage: b.phi(0) # indirect doctest 2 """
KR_type_box.Element = KR_type_boxElement
class KR_type_Bn(KirillovReshetikhinGenericCrystal): r""" Class of Kirillov-Reshetikhin crystals `B^{n,s}` of type `B_{n}^{(1)}`.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['B',3,1],3,2) sage: K Kirillov-Reshetikhin crystal of type ['B', 3, 1] with (r,s)=(3,2) sage: b = K(rows=[[1],[2],[3]]) sage: b.f(0) sage: b.e(0) [[3]]
sage: K = crystals.KirillovReshetikhin(['B',3,1],3,2) sage: [b.weight() for b in K if b.is_highest_weight([1,2,3])] [-Lambda[0] + Lambda[1], -2*Lambda[0] + 2*Lambda[3]] sage: [b.weight() for b in K if b.is_highest_weight([0,2,3])] [Lambda[0] - Lambda[1], -2*Lambda[1] + 2*Lambda[3]] """ def _element_constructor_(self, *args, **options): """ Construct an element of ``self``.
TESTS::
sage: KRC = crystals.KirillovReshetikhin(['B',3,1], 3, 3) sage: KRT = crystals.KirillovReshetikhin(['B',3,1], 3, 3, model='KR') sage: elt = KRC.module_generators[1].f_string([3,2,3,1,3,3]); elt [++-, [[2], [0], [-3]]] sage: ret = KRT(elt); ret [[1, 1, 2], [2, 2, -3], [-3, -3, -1]] sage: test = KRC(ret); test [++-, [[2], [0], [-3]]] sage: test == elt True """ # Check to make sure it can be converted or elt.parent().r() != self._r or elt.parent().s() != self._s: raise ValueError("the Kirillov-Reshetikhin tableau must have the same Cartan type and shape")
raise ValueError("no matching highest weight element found")
def classical_decomposition(self): r""" Return the classical crystal underlying the Kirillov-Reshetikhin crystal `B^{n,s}` of type `B_n^{(1)}`.
It is the same as for `r < n`, given by `B^{n,s} \cong \bigoplus_{\Lambda} B(\Lambda)`, where `\Lambda` are weights obtained from a rectangle of width `s/2` and height `n` by removing horizontal dominoes. Here we identify the fundamental weight `\Lambda_i` with a column of height `i` for `i<n` and a column of width `1/2` for `i=n`.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['B',3,1], 3, 2) sage: K.classical_decomposition() The crystal of tableaux of type ['B', 3] and shape(s) [[1], [1, 1, 1]] sage: K = crystals.KirillovReshetikhin(['B',3,1], 3, 3) sage: K.classical_decomposition() The crystal of tableaux of type ['B', 3] and shape(s) [[3/2, 1/2, 1/2], [3/2, 3/2, 3/2]] """ for sh in shapes]
def ambient_crystal(self): r""" Return the ambient crystal `B^{n,s}` of type `A_{2n-1}^{(2)}` associated to the Kirillov-Reshetikhin crystal.
The ambient crystal is used to construct the zero arrows.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['B',3,1],3,2) sage: K.ambient_crystal() Kirillov-Reshetikhin crystal of type ['B', 3, 1]^* with (r,s)=(3,2) """ self.r(), self.s())
@cached_method def highest_weight_dict(self): r""" Return a dictionary of the classical highest weight vectors of ``self`` whose keys are 2 times their shape.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['B',3,1],3,2) sage: K.highest_weight_dict() {(2,): [[1]], (2, 2, 2): [[1], [2], [3]]} sage: K = crystals.KirillovReshetikhin(['B',3,1],3,3) sage: K.highest_weight_dict() {(3, 1, 1): [+++, [[1]]], (3, 3, 3): [+++, [[1], [2], [3]]]} """ for x in self.module_generators}
@cached_method def ambient_highest_weight_dict(self): r""" Return a dictionary of the classical highest weight vectors of the ambient crystal of ``self`` whose keys are their shape.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['B',3,1],3,2) sage: K.ambient_highest_weight_dict() {(2,): [[1, 1]], (2, 1, 1): [[1, 1], [2], [3]], (2, 2, 2): [[1, 1], [2, 2], [3, 3]]}
sage: K = crystals.KirillovReshetikhin(['B',3,1],3,3) sage: K.ambient_highest_weight_dict() {(3,): [[1, 1, 1]], (3, 1, 1): [[1, 1, 1], [2], [3]], (3, 2, 2): [[1, 1, 1], [2, 2], [3, 3]], (3, 3, 3): [[1, 1, 1], [2, 2, 2], [3, 3, 3]]} """ for x in self.ambient_crystal().module_generators}
def similarity_factor(self): r""" Sets the similarity factor used to map to the ambient crystal.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['B',3,1],3,2) sage: K.similarity_factor() {1: 2, 2: 2, 3: 1} """
@cached_method def to_ambient_crystal(self): r""" Return a map from self to the ambient crystal of type `A_{2n-1}^{(2)}`.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['B',3,1],3,1) sage: [K.to_ambient_crystal()(b) for b in K] [[[1], [2], [3]], [[1], [2], [-3]], [[1], [3], [-2]], [[2], [3], [-1]], [[1], [-3], [-2]], [[2], [-3], [-1]], [[3], [-2], [-1]], [[-3], [-2], [-1]]] """ index_set=classical.index_set(), scaling_factors=self.similarity_factor(), cartan_type=classical, check=False )
@cached_method def from_ambient_crystal(self): r""" Return a map from the ambient crystal of type `A_{2n-1}^{(2)}` to the Kirillov-Reshetikhin crystal ``self``.
Note that this map is only well-defined on elements that are in the image under :meth:`to_ambient_crystal`.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['B',3,1],3,1) sage: [b == K.from_ambient_crystal()(K.to_ambient_crystal()(b)) for b in K] [True, True, True, True, True, True, True, True] sage: b = K.ambient_crystal()(rows=[[1],[2],[-3]]) sage: K.from_ambient_crystal()(b) [++-, []] """ index_set=self.cartan_type().classical().index_set(), similarity_factor_domain=self.similarity_factor() )
class KR_type_BnElement(KirillovReshetikhinGenericCrystalElement): r""" Class for the elements in the Kirillov-Reshetikhin crystals `B^{n,s}` of type `B_n^{(1)}`.
EXAMPLES::
sage: K=crystals.KirillovReshetikhin(['B',3,1],3,2) sage: type(K.module_generators[0]) <class 'sage.combinat.crystals.kirillov_reshetikhin.KR_type_Bn_with_category.element_class'> """ def e0(self): r""" Return `e_0` on ``self`` by mapping ``self`` to the ambient crystal, calculating `e_0` there and pulling the element back.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['B',3,1],3,1) sage: b = K.module_generators[0] sage: b.e(0) # indirect doctest [--+, []] """
def f0(self): r""" Return `f_0` on ``self`` by mapping ``self`` to the ambient crystal, calculating `f_0` there and pulling the element back.
EXAMPLES::
sage: K=crystals.KirillovReshetikhin(['B',3,1],3,1) sage: b = K.module_generators[0] sage: b.f(0) # indirect doctest
"""
def epsilon0(self): r""" Calculate `\varepsilon_0` of ``self`` by mapping the element to the ambient crystal and calculating `\varepsilon_0` there.
EXAMPLES::
sage: K=crystals.KirillovReshetikhin(['B',3,1],3,1) sage: b = K.module_generators[0] sage: b.epsilon(0) # indirect doctest 1 """
def phi0(self): r""" Calculate `\varphi_0` of ``self`` by mapping the element to the ambient crystal and calculating `\varphi_0` there.
EXAMPLES::
sage: K=crystals.KirillovReshetikhin(['B',3,1],3,1) sage: b = K.module_generators[0] sage: b.phi(0) # indirect doctest 0 """
KR_type_Bn.Element = KR_type_BnElement
class KR_type_Cn(KirillovReshetikhinGenericCrystal): r""" Class of Kirillov-Reshetikhin crystals `B^{n,s}` of type `C_n^{(1)}`.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['C',3,1],3,1) sage: [[b,b.f(0)] for b in K] [[[[1], [2], [3]], None], [[[1], [2], [-3]], None], [[[1], [3], [-3]], None], [[[2], [3], [-3]], None], [[[1], [3], [-2]], None], [[[2], [3], [-2]], None], [[[2], [3], [-1]], [[1], [2], [3]]], [[[1], [-3], [-2]], None], [[[2], [-3], [-2]], None], [[[2], [-3], [-1]], [[1], [2], [-3]]], [[[3], [-3], [-2]], None], [[[3], [-3], [-1]], [[1], [3], [-3]]], [[[3], [-2], [-1]], [[1], [3], [-2]]], [[[-3], [-2], [-1]], [[1], [-3], [-2]]]] """
def classical_decomposition(self): r""" Specifies the classical crystal underlying the Kirillov-Reshetikhin crystal `B^{n,s}` of type `C_n^{(1)}`.
The classical decomposition is given by `B^{n,s} \cong B(s \Lambda_n)`.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['C',3,1],3,2) sage: K.classical_decomposition() The crystal of tableaux of type ['C', 3] and shape(s) [[2, 2, 2]] """
def from_highest_weight_vector_to_pm_diagram(self, b): """ This gives the bijection between an element ``b`` in the classical decomposition of the KR crystal that is `{2,3,..,n}`-highest weight and `\pm` diagrams.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['C',3,1],3,2) sage: T = K.classical_decomposition() sage: b = T(rows=[[2, 2], [3, 3], [-3, -1]]) sage: pm = K.from_highest_weight_vector_to_pm_diagram(b); pm [[0, 0], [1, 0], [0, 1], [0]] sage: pm.pp() . . . + - -
sage: hw = [ b for b in T if all(b.epsilon(i)==0 for i in [2,3]) ] sage: all(K.from_pm_diagram_to_highest_weight_vector(K.from_highest_weight_vector_to_pm_diagram(b)) == b for b in hw) True """
def from_pm_diagram_to_highest_weight_vector(self, pm): """ This gives the bijection between a `\pm` diagram and an element ``b`` in the classical decomposition of the KR crystal that is `\{2,3,..,n\}`-highest weight.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['C',3,1],3,2) sage: pm = sage.combinat.crystals.kirillov_reshetikhin.PMDiagram([[0, 0], [1, 0], [0, 1], [0]]) sage: K.from_pm_diagram_to_highest_weight_vector(pm) [[2, 2], [3, 3], [-3, -1]] """
class KR_type_CnElement(KirillovReshetikhinGenericCrystalElement): r""" Class for the elements in the Kirillov-Reshetikhin crystals `B^{n,s}` of type `C_n^{(1)}`.
EXAMPLES::
sage: K=crystals.KirillovReshetikhin(['C',3,1],3,2) sage: type(K.module_generators[0]) <class 'sage.combinat.crystals.kirillov_reshetikhin.KR_type_Cn_with_category.element_class'> """
def e0(self): r""" Return `e_0` on ``self`` by going to the `\pm`-diagram corresponding to the `\{2,...,n\}`-highest weight vector in the component of ``self``, then applying [Definition 6.1, 4], and pulling back from `\pm`-diagrams.
EXAMPLES::
sage: K=crystals.KirillovReshetikhin(['C',3,1],3,2) sage: b = K.module_generators[0] sage: b.e(0) # indirect doctest [[1, 2], [2, 3], [3, -1]] sage: b = K(rows=[[1,2],[2,3],[3,-1]]) sage: b.e(0) [[2, 2], [3, 3], [-1, -1]] sage: b=K(rows=[[1, -3], [3, -2], [-3, -1]]) sage: b.e(0) [[3, -3], [-3, -2], [-1, -1]] """ return None
def f0(self): r""" Return `e_0` on ``self`` by going to the `\pm`-diagram corresponding to the `\{2,...,n\}`-highest weight vector in the component of ``self``, then applying [Definition 6.1, 4], and pulling back from `\pm`-diagrams.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['C',3,1],3,1) sage: b = K.module_generators[0] sage: b.f(0) # indirect doctest """
def epsilon0(self): r""" Calculate `\varepsilon_0` of ``self`` using Lemma 6.1 of [4].
EXAMPLES::
sage: K=crystals.KirillovReshetikhin(['C',3,1],3,1) sage: b = K.module_generators[0] sage: b.epsilon(0) # indirect doctest 1 """
def phi0(self): r""" Calculate `\varphi_0` of ``self``.
EXAMPLES::
sage: K=crystals.KirillovReshetikhin(['C',3,1],3,1) sage: b = K.module_generators[0] sage: b.phi(0) # indirect doctest 0 """
KR_type_Cn.Element = KR_type_CnElement
class KR_type_Dn_twisted(KirillovReshetikhinGenericCrystal): r""" Class of Kirillov-Reshetikhin crystals `B^{n,s}` of type `D_{n+1}^{(2)}`.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['D',4,2],3,1) sage: [[b,b.f(0)] for b in K] [[[+++, []], None], [[++-, []], None], [[+-+, []], None], [[-++, []], [+++, []]], [[+--, []], None], [[-+-, []], [++-, []]], [[--+, []], [+-+, []]], [[---, []], [+--, []]]] """
def _element_constructor_(self, *args, **options): """ Construct an element of ``self``.
TESTS::
sage: KRC = crystals.KirillovReshetikhin(['D',4,1], 3, 3) sage: KRT = crystals.KirillovReshetikhin(['D',4,1], 3, 3, model='KR') sage: elt = KRC.module_generators[0].f_string([3,2,3,1,2,3]); elt [++-+, [[2], [3], [4], [-2]]] sage: ret = KRT(elt); ret [[1, 1, 2], [2, 3, 3], [4, 4, 4], [-3, -2, -1]] sage: test = KRC(ret); test [++-+, [[2], [3], [4], [-2]]] sage: test == elt True """ from sage.combinat.rigged_configurations.kr_tableaux import KirillovReshetikhinTableauxElement if isinstance(args[0], KirillovReshetikhinTableauxElement): elt = args[0] # Check to make sure it can be converted if elt.cartan_type() != self.cartan_type() \ or elt.parent().r() != self._r or elt.parent().s() != self._s: raise ValueError("the Kirillov-Reshetikhin tableau must have" " the same Cartan type and shape")
to_hw = elt.to_classical_highest_weight() wt = to_hw[0].classical_weight() f_str = reversed(to_hw[1]) for x in self.module_generators: if x.classical_weight() == wt: return x.f_string(f_str) raise ValueError("no matching highest weight element found") return KirillovReshetikhinGenericCrystal._element_constructor_(self, *args, **options)
def classical_decomposition(self): r""" Return the classical crystal underlying the Kirillov-Reshetikhin crystal `B^{n,s}` of type `D_{n+1}^{(2)}`.
The classical decomposition is given by `B^{n,s} \cong B(s \Lambda_n)`.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['D',4,2],3,1) sage: K.classical_decomposition() The crystal of tableaux of type ['B', 3] and shape(s) [[1/2, 1/2, 1/2]] sage: K = crystals.KirillovReshetikhin(['D',4,2],3,2) sage: K.classical_decomposition() The crystal of tableaux of type ['B', 3] and shape(s) [[1, 1, 1]] """ else:
def from_highest_weight_vector_to_pm_diagram(self, b): r""" This gives the bijection between an element ``b`` in the classical decomposition of the KR crystal that is `\{2,3,\ldots,n\}`-highest weight and `\pm` diagrams.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['D',4,2],3,1) sage: T = K.classical_decomposition() sage: hw = [ b for b in T if all(b.epsilon(i)==0 for i in [2,3]) ] sage: [K.from_highest_weight_vector_to_pm_diagram(b) for b in hw] [[[0, 0], [0, 0], [1, 0], [0]], [[0, 0], [0, 0], [0, 1], [0]]]
sage: K = crystals.KirillovReshetikhin(['D',4,2],3,2) sage: T = K.classical_decomposition() sage: hw = [ b for b in T if all(b.epsilon(i)==0 for i in [2,3]) ] sage: [K.from_highest_weight_vector_to_pm_diagram(b) for b in hw] [[[0, 0], [0, 0], [2, 0], [0]], [[0, 0], [0, 0], [0, 0], [2]], [[0, 0], [2, 0], [0, 0], [0]], [[0, 0], [0, 0], [0, 2], [0]]]
Note that, since the classical decomposition of this crystal is of type `B_n`, there can be (at most one) entry `0` in the `\{2,3,\ldots,n\}`-highest weight elements at height `n`. In the following implementation this is realized as an empty column of height `n` since this uniquely specifies the existence of the `0`.
EXAMPLES::
sage: b = hw[1] sage: pm = K.from_highest_weight_vector_to_pm_diagram(b) sage: pm.pp() . . . . . .
TESTS::
sage: all(K.from_pm_diagram_to_highest_weight_vector(K.from_highest_weight_vector_to_pm_diagram(b)) == b for b in hw) True sage: K = crystals.KirillovReshetikhin(['D',4,2],3,2) sage: T = K.classical_decomposition() sage: hw = [ b for b in T if all(b.epsilon(i)==0 for i in [2,3]) ] sage: all(K.from_pm_diagram_to_highest_weight_vector(K.from_highest_weight_vector_to_pm_diagram(b)) == b for b in hw) True sage: K = crystals.KirillovReshetikhin(['D',4,2],3,3) sage: T = K.classical_decomposition() sage: hw = [ b for b in T if all(b.epsilon(i)==0 for i in [2,3]) ] sage: all(K.from_pm_diagram_to_highest_weight_vector(K.from_highest_weight_vector_to_pm_diagram(b)) == b for b in hw) True
""" else: else:
def from_pm_diagram_to_highest_weight_vector(self, pm): r""" This gives the bijection between a `\pm` diagram and an element ``b`` in the classical decomposition of the KR crystal that is `\{2,3,\ldots,n\}`-highest weight.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['D',4,2],3,2) sage: pm = sage.combinat.crystals.kirillov_reshetikhin.PMDiagram([[0, 0], [0, 0], [0, 0], [2]]) sage: K.from_pm_diagram_to_highest_weight_vector(pm) [[2], [3], [0]] """
class KR_type_Dn_twistedElement(KirillovReshetikhinGenericCrystalElement): r""" Class for the elements in the Kirillov-Reshetikhin crystals `B^{n,s}` of type `D_{n+1}^{(2)}`.
EXAMPLES::
sage: K=crystals.KirillovReshetikhin(['D',4,2],3,2) sage: type(K.module_generators[0]) <class 'sage.combinat.crystals.kirillov_reshetikhin.KR_type_Dn_twisted_with_category.element_class'> """
def e0(self): r""" Return `e_0` on ``self`` by going to the `\pm`-diagram corresponding to the `\{2,\ldots,n\}`-highest weight vector in the component of ``self``, then applying [Definition 6.2, 4], and pulling back from `\pm`-diagrams.
EXAMPLES::
sage: K=crystals.KirillovReshetikhin(['D',4,2],3,3) sage: b = K.module_generators[0] sage: b.e(0) # indirect doctest [+++, [[2], [3], [0]]] """
def f0(self): r""" Return `e_0` on ``self`` by going to the `\pm`-diagram corresponding to the `\{2,\ldots,n\}`-highest weight vector in the component of ``self``, then applying [Definition 6.2, 4], and pulling back from `\pm`-diagrams.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['D',4,2],3,2) sage: b = K.module_generators[0] sage: b.f(0) # indirect doctest """
def epsilon0(self): r""" Calculate `\varepsilon_0` of ``self`` using Lemma 6.2 of [4].
EXAMPLES::
sage: K=crystals.KirillovReshetikhin(['D',4,2],3,1) sage: b = K.module_generators[0] sage: b.epsilon(0) # indirect doctest 1
TESTS:
Check that :trac:`19982` is fixed::
sage: K = crystals.KirillovReshetikhin(['D',3,2], 2,3) sage: def eps0_defn(elt): ....: x = elt.e(0) ....: eps = 0 ....: while x is not None: ....: x = x.e(0) ....: eps = eps + 1 ....: return eps sage: all(eps0_defn(x) == x.epsilon0() for x in K) True """
def phi0(self): r""" Calculate `\varphi_0` of ``self``.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['D',4,2],3,1) sage: b = K.module_generators[0] sage: b.phi(0) # indirect doctest 0
TESTS:
Check that :trac:`19982` is fixed::
sage: K = crystals.KirillovReshetikhin(['D',3,2], 2,3) sage: def phi0_defn(elt): ....: x = elt.f(0) ....: phi = 0 ....: while x is not None: ....: x = x.f(0) ....: phi = phi + 1 ....: return phi sage: all(phi0_defn(x) == x.phi0() for x in K) True """
KR_type_Dn_twisted.Element = KR_type_Dn_twistedElement
class KR_type_spin(KirillovReshetikhinCrystalFromPromotion): r""" Class of Kirillov-Reshetikhin crystals `B^{n,s}` of type `D_n^{(1)}`.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['D',4,1],4,1); K Kirillov-Reshetikhin crystal of type ['D', 4, 1] with (r,s)=(4,1) sage: [[b,b.f(0)] for b in K] [[[++++, []], None], [[++--, []], None], [[+-+-, []], None], [[-++-, []], None], [[+--+, []], None], [[-+-+, []], None], [[--++, []], [++++, []]], [[----, []], [++--, []]]]
sage: K = crystals.KirillovReshetikhin(['D',4,1],4,2); K Kirillov-Reshetikhin crystal of type ['D', 4, 1] with (r,s)=(4,2) sage: [[b,b.f(0)] for b in K] [[[[1], [2], [3], [4]], None], [[[1], [2], [-4], [4]], None], [[[1], [3], [-4], [4]], None], [[[2], [3], [-4], [4]], None], [[[1], [4], [-4], [4]], None], [[[2], [4], [-4], [4]], None], [[[3], [4], [-4], [4]], [[1], [2], [3], [4]]], [[[-4], [4], [-4], [4]], [[1], [2], [-4], [4]]], [[[-4], [4], [-4], [-3]], [[1], [2], [-4], [-3]]], [[[-4], [4], [-4], [-2]], [[1], [3], [-4], [-3]]], [[[-4], [4], [-4], [-1]], [[2], [3], [-4], [-3]]], [[[-4], [4], [-3], [-2]], [[1], [4], [-4], [-3]]], [[[-4], [4], [-3], [-1]], [[2], [4], [-4], [-3]]], [[[-4], [4], [-2], [-1]], [[-4], [4], [-4], [4]]], [[[-4], [-3], [-2], [-1]], [[-4], [4], [-4], [-3]]], [[[1], [2], [-4], [-3]], None], [[[1], [3], [-4], [-3]], None], [[[2], [3], [-4], [-3]], None], [[[1], [3], [-4], [-2]], None], [[[2], [3], [-4], [-2]], None], [[[2], [3], [-4], [-1]], None], [[[1], [4], [-4], [-3]], None], [[[2], [4], [-4], [-3]], None], [[[3], [4], [-4], [-3]], None], [[[3], [4], [-4], [-2]], [[1], [3], [-4], [4]]], [[[3], [4], [-4], [-1]], [[2], [3], [-4], [4]]], [[[1], [4], [-4], [-2]], None], [[[2], [4], [-4], [-2]], None], [[[2], [4], [-4], [-1]], None], [[[1], [4], [-3], [-2]], None], [[[2], [4], [-3], [-2]], None], [[[2], [4], [-3], [-1]], None], [[[3], [4], [-3], [-2]], [[1], [4], [-4], [4]]], [[[3], [4], [-3], [-1]], [[2], [4], [-4], [4]]], [[[3], [4], [-2], [-1]], [[3], [4], [-4], [4]]]]
TESTS::
sage: K = crystals.KirillovReshetikhin(['D',4,1],3,1) sage: all(b.e(0).f(0) == b for b in K if b.epsilon(0)>0) True
sage: K = crystals.KirillovReshetikhin(['D',5,1],5,2) sage: all(b.f(0).e(0) == b for b in K if b.phi(0)>0) True """ def _element_constructor_(self, *args, **options): """ Construct an element of ``self`` from the input.
EXAMPLES::
sage: KRT = crystals.KirillovReshetikhin(['D',4,1], 4, 3, model='KR') sage: KRC = crystals.KirillovReshetikhin(['D',4,1], 4, 3) sage: elt = KRT(-3,-4,2,1,-3,-4,2,1,-2,-4,3,1); elt [[1, 1, 1], [2, 2, 3], [-4, -4, -4], [-3, -3, -2]] sage: KRC(elt) # indirect doctest [++--, [[1], [3], [-4], [-3]]]
TESTS:
Spinor test::
sage: KRC = crystals.KirillovReshetikhin(['D',4,1], 4, 3) sage: KRT = crystals.KirillovReshetikhin(['D',4,1], 4, 3, model='KR') sage: elt = KRC.module_generator().f_string([4,2,4,3,4,1]); elt [++--, [[2], [4], [-4], [-3]]] sage: ret = KRT(elt); ret [[1, 1, 2], [2, 2, 4], [-4, -4, -3], [-3, -3, -1]] sage: test = KRC(ret); test [++--, [[2], [4], [-4], [-3]]] sage: test == elt True """ # Check to make sure it can be converted or elt.parent().r() != self._r or elt.parent().s() != self._s: raise ValueError("the Kirillov-Reshetikhin tableau must have the same Cartan type and shape")
return KirillovReshetikhinCrystalFromPromotion._element_constructor_(self, *args, **options)
def classical_decomposition(self): r""" Return the classical crystal underlying the Kirillov-Reshetikhin crystal `B^{r,s}` of type `D_n^{(1)}` for `r=n-1,n`.
The classical decomposition is given by `B^{n,s} \cong B(s \Lambda_r)`.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['D',4,1],4,1) sage: K.classical_decomposition() The crystal of tableaux of type ['D', 4] and shape(s) [[1/2, 1/2, 1/2, 1/2]] sage: K = crystals.KirillovReshetikhin(['D',4,1],3,1) sage: K.classical_decomposition() The crystal of tableaux of type ['D', 4] and shape(s) [[1/2, 1/2, 1/2, -1/2]] sage: K = crystals.KirillovReshetikhin(['D',4,1],3,2) sage: K.classical_decomposition() The crystal of tableaux of type ['D', 4] and shape(s) [[1, 1, 1, -1]]
TESTS:
Check that this is robust against python ints::
sage: K = crystals.KirillovReshetikhin(['D',4,1], 4, int(1)) sage: K.classical_crystal The crystal of tableaux of type ['D', 4] and shape(s) [[1/2, 1/2, 1/2, 1/2]] """ else:
def dynkin_diagram_automorphism(self, i): """ Specifies the Dynkin diagram automorphism underlying the promotion action on the crystal elements.
Here we use the Dynkin diagram automorphism which interchanges nodes 0 and 1 and leaves all other nodes unchanged.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['D',4,1],4,1) sage: K.dynkin_diagram_automorphism(0) 1 sage: K.dynkin_diagram_automorphism(1) 0 sage: K.dynkin_diagram_automorphism(4) 4 """
@cached_method def promotion_on_highest_weight_vectors(self): r""" Return the promotion operator on `\{2,3,\ldots,n\}`-highest weight vectors.
A `\{2,3,\ldots,n\}`-highest weight vector in `B(s\Lambda_n)` of weight `w = (w_1,\ldots,w_n)` is mapped to a `\{2,3,\ldots,n\}`-highest weight vector in `B(s\Lambda_{n-1})` of weight `(-w_1,w_2,\ldots,w_n)` and vice versa.
.. SEEALSO::
- :meth:`promotion_on_highest_weight_vectors_inverse` - :meth:`promotion`
EXAMPLES::
sage: KR = crystals.KirillovReshetikhin(['D',4,1],4,2) sage: prom = KR.promotion_on_highest_weight_vectors() sage: T = KR.classical_decomposition() sage: HW = [t for t in T if t.is_highest_weight([2,3,4])] sage: for t in HW: ....: print("{} {}".format(t, prom[t])) [[1], [2], [3], [4]] [[2], [3], [4], [-1]] [[2], [3], [-4], [4]] [[2], [3], [4], [-4]] [[2], [3], [-4], [-1]] [[1], [2], [3], [-4]]
sage: KR = crystals.KirillovReshetikhin(['D',4,1],4,1) sage: prom = KR.promotion_on_highest_weight_vectors() sage: T = KR.classical_decomposition() sage: HW = [t for t in T if t.is_highest_weight([2,3,4])] sage: for t in HW: ....: print("{} {}".format(t, prom[t])) [++++, []] [-+++, []] [-++-, []] [+++-, []] """
@cached_method def promotion_on_highest_weight_vectors_inverse(self): r""" Return the inverse promotion operator on `\{2,3,\ldots,n\}`-highest weight vectors.
.. SEEALSO::
- :meth:`promotion_on_highest_weight_vectors` - :meth:`promotion_inverse`
EXAMPLES::
sage: KR = crystals.KirillovReshetikhin(['D',4,1],3,2) sage: prom = KR.promotion_on_highest_weight_vectors() sage: prom_inv = KR.promotion_on_highest_weight_vectors_inverse() sage: T = KR.classical_decomposition() sage: HW = [t for t in T if t.is_highest_weight([2,3,4])] sage: all(prom_inv[prom[t]] == t for t in HW) True """
@cached_method def promotion(self): r""" Return the promotion operator on `B^{r,s}` of type `D_n^{(1)}` for `r = n-1,n`.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['D',4,1],3,1) sage: T = K.classical_decomposition() sage: promotion = K.promotion() sage: for t in T: ....: print("{} {}".format(t, promotion(t))) [+++-, []] [-++-, []] [++-+, []] [-+-+, []] [+-++, []] [--++, []] [-+++, []] [++++, []] [+---, []] [----, []] [-+--, []] [++--, []] [--+-, []] [+-+-, []] [---+, []] [+--+, []] """
@cached_method def promotion_inverse(self): r""" Return the inverse promotion operator on `B^{r,s}` of type `D_n^{(1)}` for `r=n-1,n`.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['D',4,1],3,1) sage: T = K.classical_decomposition() sage: promotion = K.promotion() sage: promotion_inverse = K.promotion_inverse() sage: all(promotion_inverse(promotion(t)) == t for t in T) True """
class KR_type_D_tri1(KirillovReshetikhinGenericCrystal): r""" Class of Kirillov-Reshetikhin crystals `B^{1,s}` of type `D_4^{(3)}`.
The crystal structure was defined in Section 4 of [KMOY07]_ using the coordinate representation.
REFERENCES:
.. [KMOY07] \M. Kashiwara, K. C. Misra, M. Okado, D. Yamada. *Perfect crystals for* `U_q(D_4^{(3)})`, J. Algebra. **317** (2007). """ def __init__(self, ct, s): r""" Initialize ``self``.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['D',4,3], 1, 2) sage: TestSuite(K).run() """
def classical_decomposition(self): """ Return the classical decomposition of ``self``.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['D',4,3], 1, 5) sage: K.classical_decomposition() The crystal of tableaux of type ['G', 2] and shape(s) [[], [1], [2], [3], [4], [5]] """
def from_coordinates(self, coords): r""" Return an element of ``self`` from the coordinates ``coords``.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['D',4,3], 1, 5) sage: K.from_coordinates((0, 2, 3, 1, 0, 1)) [[2, 2, 3, 0, -1]] """
+ [l(0)]*(coords[2]%2) + [l(-3)]*(coords[3]//2) + [l(-2)]*coords[4] + [l(-1)]*coords[5])
def _element_constructor_(self, *args, **options): """ Construct an element of ``self``.
TESTS::
sage: KRC = crystals.KirillovReshetikhin(['D',4,3], 1, 3) sage: KRT = crystals.KirillovReshetikhin(['D',4,3], 1, 3, model='KR') sage: elt = KRC.module_generators[2].f_string([1,1,2,1,2]); elt [[3, 0]] sage: ret = KRT(elt); ret [[3, 0, E]] sage: test = KRC(ret); test [[3, 0]] sage: test == elt True """ # Check to make sure it can be converted or elt.parent().r() != self._r or elt.parent().s() != self._s: raise ValueError("the Kirillov-Reshetikhin tableau must have the same Cartan type and shape")
# The classically HW element consists of 1, -1, and 'E' else:
class Element(KirillovReshetikhinGenericCrystalElement): @cached_method def coordinates(self): """ Return ``self`` as coordinates.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['D',4,3], 1, 3) sage: all(K.from_coordinates(x.coordinates()) == x for x in K) True """ 2*l.count(letters(3)) + l.count(letters(0)), 2*l.count(letters(-3)) + l.count(letters(0)), l.count(letters(-2)), l.count(letters(-1)) )
@lazy_attribute def _A(self): r""" Compute the vector `A = (0, z_1, z_1 + z_2, z_1 + z_2 + 3 z_4, z_1 + z_2 + z_3 + 3 z_4, 2 z_1 + z_2 + z_3 + 3 z_4)`, where `z_1 = \bar{x}_1 - x_1`, `z_2 = \bar{x}_2 - \bar{x}_3`, `z_3 = x_3 - x_2`, and `z_4 = (\bar{x}_3 - x_3) / 2`.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['D',4,3], 1,1) sage: [mg._A for mg in K.module_generators] [(0, 0, 0, 0, 0, 0), (0, -1, -1, -1, -1, -2)] """ coords[2] - coords[1], (coords[-3] - coords[2]) // 2] sum(z) + 2*z[3], sum(z) + z[0] + 2*z[3])
def e0(self): r""" Return the action of `e_0` on ``self``.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['D',4,3], 1,1) sage: [x.e0() for x in K] [[[-1]], [], [[-3]], [[-2]], None, None, None, None] """
def f0(self): r""" Return the action of `f_0` on ``self``.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['D',4,3], 1,1) sage: [x.f0() for x in K] [[[1]], None, None, None, None, [[2]], [[3]], []] """
def epsilon0(self): r""" Return `\varepsilon_0` of ``self``.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['D',4,3], 1, 5) sage: [mg.epsilon0() for mg in K.module_generators] [5, 6, 7, 8, 9, 10] """
def phi0(self): r""" Return `\varphi_0` of ``self``.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['D',4,3], 1, 5) sage: [mg.phi0() for mg in K.module_generators] [5, 4, 3, 2, 1, 0] """
#####################################################################
class PMDiagram(CombinatorialObject): """ Class of `\pm` diagrams. These diagrams are in one-to-one bijection with `X_{n-1}` highest weight vectors in an `X_n` highest weight crystal `X=B,C,D`. See Section 4.1 of [Schilling08]_.
The input is a list `pm = [[a_0,b_0], [a_1,b_1], ..., [a_{n-1},b_{n-1}], [b_n]]` of pairs and a last 1-tuple (or list of length 1). The pair `[a_i,b_i]` specifies the number of `a_i` `+` and `b_i` `-` in the `i`-th row of the `\pm` diagram if `n-i` is odd and the number of `a_i` `\pm` pairs above row `i` and `b_i` columns of height `i` not containing any `+` or `-` if `n-i` is even.
Setting the option ``from_shapes = True`` one can also input a `\pm` diagram in terms of its outer, intermediate, and inner shape by specifying a list ``[n, s, outer, intermediate, inner]`` where ``s`` is the width of the `\pm` diagram, and ``outer``, ``intermediate``, and ``inner`` are the outer, intermediate, and inner shapes, respectively.
EXAMPLES::
sage: from sage.combinat.crystals.kirillov_reshetikhin import PMDiagram sage: pm = PMDiagram([[0,1],[1,2],[1]]) sage: pm.pm_diagram [[0, 1], [1, 2], [1]] sage: pm._list [1, 1, 2, 0, 1] sage: pm.n 2 sage: pm.width 5 sage: pm.pp() . . . . . + - - sage: PMDiagram([2,5,[4,4],[4,2],[4,1]], from_shapes=True) [[0, 1], [1, 2], [1]]
TESTS::
sage: from sage.combinat.crystals.kirillov_reshetikhin import PMDiagram sage: pm = PMDiagram([[1,2],[1,1],[1,1],[1,1],[1]]) sage: PMDiagram([pm.n, pm.width, pm.outer_shape(), pm.intermediate_shape(), pm.inner_shape()], from_shapes=True) == pm True sage: pm = PMDiagram([[1,2],[1,2],[1,1],[1,1],[1,1],[1]]) sage: PMDiagram([pm.n, pm.width, pm.outer_shape(), pm.intermediate_shape(), pm.inner_shape()], from_shapes=True) == pm True """ def __init__(self, pm_diagram, from_shapes = None): r""" Initialize ``self``.
TESTS::
sage: from sage.combinat.crystals.kirillov_reshetikhin import PMDiagram sage: pm = PMDiagram([[0,1],[1,2],[1]]); pm [[0, 1], [1, 2], [1]] sage: PMDiagram([2,5,[4,4],[4,2],[4,1]], from_shapes=True) [[0, 1], [1, 2], [1]] sage: TestSuite(pm).run() """
def _repr_(self): """ Turning on pretty printing allows to display the `\pm` diagram as a tableau with the `+` and `-` displayed.
EXAMPLES::
sage: sage.combinat.crystals.kirillov_reshetikhin.PMDiagram([[1,0],[0,1],[2,0],[0,0],[0]]) [[1, 0], [0, 1], [2, 0], [0, 0], [0]] """
def _repr_diagram(self): """ Return a string representation of ``self`` as a diagram.
EXAMPLES::
sage: from sage.combinat.crystals.kirillov_reshetikhin import PMDiagram sage: pm = PMDiagram([[1,0],[0,1],[2,0],[0,0],[0]]) sage: print(pm._repr_diagram()) . . . + . . - - + + - - sage: pm = PMDiagram([[0,2], [0,0], [0]]) sage: print(pm._repr_diagram()) """
def pp(self): """ Pretty print ``self``.
EXAMPLES::
sage: from sage.combinat.crystals.kirillov_reshetikhin import PMDiagram sage: pm = PMDiagram([[1,0],[0,1],[2,0],[0,0],[0]]) sage: pm.pp() . . . + . . - - + + - - sage: pm = PMDiagram([[0,2], [0,0], [0]]) sage: pm.pp() """
def inner_shape(self): """ Return the inner shape of the pm diagram
EXAMPLES::
sage: from sage.combinat.crystals.kirillov_reshetikhin import PMDiagram sage: pm = PMDiagram([[0,1],[1,2],[1]]) sage: pm.inner_shape() [4, 1] sage: pm = PMDiagram([[1,2],[1,1],[1,1],[1,1],[1]]) sage: pm.inner_shape() [7, 5, 3, 1] sage: pm = PMDiagram([[1,2],[1,2],[1,1],[1,1],[1,1],[1]]) sage: pm.inner_shape() [10, 7, 5, 3, 1] """
def outer_shape(self): """ Return the outer shape of the `\pm` diagram
EXAMPLES::
sage: from sage.combinat.crystals.kirillov_reshetikhin import PMDiagram sage: pm = PMDiagram([[0,1],[1,2],[1]]) sage: pm.outer_shape() [4, 4] sage: pm = PMDiagram([[1,2],[1,1],[1,1],[1,1],[1]]) sage: pm.outer_shape() [8, 8, 4, 4] sage: pm = PMDiagram([[1,2],[1,2],[1,1],[1,1],[1,1],[1]]) sage: pm.outer_shape() [13, 8, 8, 4, 4] """
def intermediate_shape(self): """ Return the intermediate shape of the pm diagram (inner shape plus positions of plusses)
EXAMPLES::
sage: from sage.combinat.crystals.kirillov_reshetikhin import PMDiagram sage: pm = PMDiagram([[0,1],[1,2],[1]]) sage: pm.intermediate_shape() [4, 2] sage: pm = PMDiagram([[1,2],[1,1],[1,1],[1,1],[1]]) sage: pm.intermediate_shape() [8, 6, 4, 2] sage: pm = PMDiagram([[1,2],[1,2],[1,1],[1,1],[1,1],[1]]) sage: pm.intermediate_shape() [11, 8, 6, 4, 2] sage: pm = PMDiagram([[1,0],[0,1],[2,0],[0,0],[0]]) sage: pm.intermediate_shape() [4, 2, 2] sage: pm = PMDiagram([[1, 0], [0, 0], [0, 0], [0, 0], [0]]) sage: pm.intermediate_shape() [1] """
def heights_of_minus(self): """ Return a list with the heights of all minus in the `\pm` diagram.
EXAMPLES::
sage: from sage.combinat.crystals.kirillov_reshetikhin import PMDiagram sage: pm = PMDiagram([[1,2],[1,2],[1,1],[1,1],[1,1],[1]]) sage: pm.heights_of_minus() [5, 5, 3, 3, 1, 1] sage: pm = PMDiagram([[1,2],[1,1],[1,1],[1,1],[1]]) sage: pm.heights_of_minus() [4, 4, 2, 2] """
def heights_of_addable_plus(self): """ Return a list with the heights of all addable plus in the `\pm` diagram.
EXAMPLES::
sage: from sage.combinat.crystals.kirillov_reshetikhin import PMDiagram sage: pm = PMDiagram([[1,2],[1,2],[1,1],[1,1],[1,1],[1]]) sage: pm.heights_of_addable_plus() [1, 1, 2, 3, 4, 5] sage: pm = PMDiagram([[1,2],[1,1],[1,1],[1,1],[1]]) sage: pm.heights_of_addable_plus() [1, 2, 3, 4] """
def sigma(self): """ Return sigma on pm diagrams as needed for the analogue of the Dynkin diagram automorphism that interchanges nodes `0` and `1` for type `D_n(1)`, `B_n(1)`, `A_{2n-1}(2)` for Kirillov-Reshetikhin crystals.
EXAMPLES::
sage: pm = sage.combinat.crystals.kirillov_reshetikhin.PMDiagram([[0,1],[1,2],[1]]) sage: pm.sigma() [[1, 0], [2, 1], [1]] """
#####################################################################################
def partitions_in_box(r, s): """ Returns all partitions in a box of width s and height r.
EXAMPLES::
sage: sage.combinat.crystals.kirillov_reshetikhin.partitions_in_box(3,2) [[], [1], [2], [1, 1], [2, 1], [1, 1, 1], [2, 2], [2, 1, 1], [2, 2, 1], [2, 2, 2]] """
def vertical_dominoes_removed(r, s): """ Returns all partitions obtained from a rectangle of width s and height r by removing vertical dominoes.
EXAMPLES::
sage: sage.combinat.crystals.kirillov_reshetikhin.vertical_dominoes_removed(2,2) [[], [1, 1], [2, 2]] sage: sage.combinat.crystals.kirillov_reshetikhin.vertical_dominoes_removed(3,2) [[2], [2, 1, 1], [2, 2, 2]] sage: sage.combinat.crystals.kirillov_reshetikhin.vertical_dominoes_removed(4,2) [[], [1, 1], [1, 1, 1, 1], [2, 2], [2, 2, 1, 1], [2, 2, 2, 2]] """
def horizontal_dominoes_removed(r, s): """ Returns all partitions obtained from a rectangle of width s and height r by removing horizontal dominoes.
EXAMPLES::
sage: sage.combinat.crystals.kirillov_reshetikhin.horizontal_dominoes_removed(2,2) [[], [2], [2, 2]] sage: sage.combinat.crystals.kirillov_reshetikhin.horizontal_dominoes_removed(3,2) [[], [2], [2, 2], [2, 2, 2]] """
##################################################################### ## Morphisms
class AmbientRetractMap(Map): r""" The retraction map from the ambient crystal.
Consider a crystal embedding `\phi : X \to Y`, then the elements `X` can be considered as a subcrystal of the ambient crystal `Y`. The ambient retract is the partial map `\tilde{\phi} : Y \to X` such that `\tilde{\phi} \circ \phi` is the identity on `X`. """ def __init__(self, base, ambient, pdict_inv, index_set, similarity_factor_domain=None, automorphism=None): """ Initialize ``self``.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['B',3,1], 3,1) sage: phi = K.from_ambient_crystal() sage: TestSuite(phi).run(skip=['_test_category', '_test_pickling']) """
def _repr_type(self): """ Return a string describing ``self``.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['B',3,1], 3,1) sage: phi = K.from_ambient_crystal() sage: phi._repr_type() 'Ambient retract' """
def _call_(self, x): """ A fast map from the virtual image to the base crystal.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['B',3,1], 3,1) sage: phi = K.from_ambient_crystal() sage: b = K.ambient_crystal()(rows=[[1],[2],[-3]]) sage: phi(b) [++-, []] """ #now we know that x is hw
class CrystalDiagramAutomorphism(CrystalMorphism): """ The crystal automorphism induced from the diagram automorphism.
For example, in type `A_n^{(1)}` this is the promotion operator and in type `D_n^{(1)}`, this corresponds to the automorphism induced from interchanging the `0` and `1` nodes in the Dynkin diagram.
INPUT:
- ``C`` -- a crystal - ``on_hw`` -- a function for the images of the ``index_set``-highest weight elements - ``index_set`` -- (default: the empty set) the index set - ``automorphism`` -- (default: the identity) the twisting automorphism - ``cache`` -- (default: True) cache the result """ def __init__(self, C, on_hw, index_set=None, automorphism=None, cache=True): """ Construct the promotion operator.
TESTS::
sage: K = crystals.KirillovReshetikhin(['A',3,1], 2,2) sage: p = K.promotion() sage: TestSuite(p).run(skip=['_test_category', '_test_pickling']) """ else:
self._cache = cache
def _call_(self, x): """ Return the image of ``x`` under ``self``.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['A',3,1], 2,2) sage: p = K.promotion() sage: elt = K(3,1,3,1) sage: p(elt.lift()) [[2, 2], [4, 4]] """ # We do our own caching so we can take advantage of known images above us
else:
def _repr_type(self): """ Return a string describing ``self``.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['A',3,1], 2,2) sage: K.promotion()._repr_type() 'Diagram automorphism' """
def is_isomorphism(self): """ Return ``True`` as ``self`` is a crystal isomorphism.
EXAMPLES::
sage: K = crystals.KirillovReshetikhin(['A',3,1], 2,2) sage: K.promotion().is_isomorphism() True """
# All of these are consequences of being an isomorphism is_surjective = is_isomorphism is_embedding = is_isomorphism is_strict = is_isomorphism __bool__ = is_isomorphism __nonzero__ = is_isomorphism
|