Path: blob/master/src/sage/combinat/crystals/kyoto_path_model.py
8817 views
r"""1Kyoto Path Model for Affine Highest Weight Crystals2"""34#*****************************************************************************5# Copyright (C) 2013 Travis Scrimshaw <tscrim at 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#****************************************************************************1819from sage.structure.parent import Parent20from sage.structure.unique_representation import UniqueRepresentation21from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets22from sage.categories.highest_weight_crystals import HighestWeightCrystals23from sage.combinat.crystals.tensor_product import TensorProductOfCrystals, \24TensorProductOfRegularCrystalsElement25from sage.combinat.root_system.root_system import RootSystem2627class KyotoPathModel(TensorProductOfCrystals):28r"""29The Kyoto path model for an affine highest weight crystal.3031.. NOTE::3233Here we are using anti-Kashiwara notation and might differ from34some of the literature.3536Consider a Kac--Moody algebra `\mathfrak{g}` of affine Cartan type `X`,37and we want to model the `U_q(\mathfrak{g})`-crystal `B(\lambda)`.38First we consider the set of fundamental weights `\{\Lambda_i\}_{i \in I}`39of `\mathfrak{g}` and let `\{\overline{\Lambda}_i\}_{i \in I_0}` be the40corresponding fundamental weights of the corresponding classical Lie41algebra `\mathfrak{g}_0`. To model `B(\lambda)`, we start with a sequence42of perfect `U_q^{\prime}(\mathfrak{g})`-crystals `(B^{(i)})_i` of level43`l` such that4445.. MATH::4647\lambda \in \overline{P}_l^+ = \left\{ \mu \in \overline{P}^+ \mid48\langle c, \mu \rangle = l \right\}4950where `c` is the canonical central element of `U_q(\mathfrak{g})`51and `\overline{P}^+` is the nonnegative weight lattice spanned by52`\{ \overline{\Lambda}_i \mid i \in I \}`.5354Next we consider the crystal isomorphism `\Phi_0 : B(\lambda_0) \to B^{(0)}55\otimes B(\lambda_1)` defined by `u_{\lambda_0} \mapsto b^{(0)}_{\lambda_0}56\otimes u_{\lambda_1}` where `b^{(0)}_{\lambda_0}` is the unique element in57`B^{(0)}` such that `\varphi\left( b^{(0)}_{\lambda_0} \right) = \lambda_0`58and `\lambda_1 = \varepsilon\left( b^{(0)}_{\lambda_0} \right)` and59`u_{\mu}` is the highest weight element in `B(\mu)`. Iterating this, we60obtain the following isomorphism:6162.. MATH::6364\Phi_n : B(\lambda) \to B^{(0)} \otimes B^{(1)} \otimes \cdots65\otimes B^{(N)} \otimes B(\lambda_{N+1}).6667We note by Lemma 10.6.2 in [HK02]_ that for any `b \in B(\lambda)` there68exists a finite `N` such that6970.. MATH::7172\Phi_N(b) = \left( \bigotimes_{k=0}^{N-1} b^{(k)} \right)73\otimes u_{\lambda_N}.7475Therefore we can model elements `b \in B(\lambda)` as a76`U_q^{\prime}(\mathfrak{g})`-crystal by considering an infinite list of77elements `b^{(k)} \in B^{(k)}` and defining the crystal structure by:7879.. MATH::8081\begin{aligned}82\overline{\mathrm{wt}}(b) & = \lambda_N + \sum_{k=0}^{N-1}83\overline{\mathrm{wt}}\left( b^{(k)} \right)84\\ e_i(b) & = e_i\left( b^{\prime} \otimes b^{(N)} \right) \otimes85u_{\lambda_N},86\\ f_i(b) & = f_i\left( b^{\prime} \otimes b^{(N)} \right) \otimes87u_{\lambda_N},88\\ \varepsilon_i(b) & = \max\bigl( \varepsilon_i(b^{\prime}) -89\varphi_i\left( b^{(N)} \right), 0 \bigr),90\\ \varphi_i(b) & = \varphi_i(b^{\prime}) + \max\left(91\varphi_i\left( b^{(N)} \right) - \varepsilon_i(b^{\prime}), 0 \right),92\end{aligned}9394where `b^{\prime} = b^{(0)} \otimes \cdots \otimes b^{(N-1)}`. To95translate this into a finite list, we consider a finite sequence96`b^{(0)} \otimes \cdots \otimes b^{(N-1)} \otimes b^{(N)}_{\lambda_N}`97and if9899.. MATH::100101f_i\left( b^{(0)} \otimes \cdots b^{(N-1)} \otimes102b^{(N)}_{\lambda_N} \right) = b_0 \otimes \cdots \otimes b^{(N-1)}103\otimes f_i\left( b^{(N)}_{\lambda_N} \right),104105then we take the image as `b^{(0)} \otimes \cdots \otimes f_i\left(106b^{(N)}_{\lambda_N}\right) \otimes b^{(N+1)}_{\lambda_{N+1}}`. Similarly107we remove `b^{(N)}_{\lambda_{N}}` if we have `b_0 \otimes \cdots108\otimes b^{(N-1)} \otimes b^{(N-1)}_{\lambda_{N-1}} \otimes109b^{(N)}_{\lambda_N}`. Additionally if110111.. MATH::112113e_i\left( b^{(0)} \otimes \cdots \otimes b^{(N-1)} \otimes114b^{(N)}_{\lambda_N} \right) = b^{(0)} \otimes \cdots \otimes115b^{(N-1)} \otimes e_i\left( b^{(N)}_{\lambda_N} \right),116117then we consider this to be `0`.118119REFERENCES:120121.. [HK02] *Introduction to Quantum Groups and Crystal Bases.*122Jin Hong and Seok-Jin Kang. 2002. Volume 42.123Graduate Studies in Mathematics. American Mathematical Society.124125INPUT:126127- ``B`` -- A single or list of `U_q^{\prime}` perfect crystal(s) of128level `l`129- ``weight`` -- A weight in `\overline{P}_l^+`130131EXAMPLES::132133sage: B = KirillovReshetikhinCrystal(['A',2,1], 1,1)134sage: L = RootSystem(['A',2,1]).weight_space()135sage: C = KyotoPathModel(B, L.fundamental_weight(0))136sage: mg = C.module_generators[0]; mg137[[[3]]]138sage: mg.f_string([0,1,2,2])139[[[3]], [[3]], [[1]]]140141An example of type `A_5^{(2)}`::142143sage: B = KirillovReshetikhinCrystal(['A',5,2], 1,1)144sage: L = RootSystem(['A',5,2]).weight_space()145sage: C = KyotoPathModel(B, L.fundamental_weight(0))146sage: mg = C.module_generators[0]; mg147[[[-1]]]148sage: mg.f_string([0,2,1,3])149[[[-3]], [[2]], [[-1]]]150sage: mg.f_string([0,2,3,1])151[[[-3]], [[2]], [[-1]]]152153An example of type `D_3^{(2)}`::154155sage: B = KirillovReshetikhinCrystal(['D',3,2], 1,1)156sage: L = RootSystem(['D',3,2]).weight_space()157sage: C = KyotoPathModel(B, L.fundamental_weight(0))158sage: mg = C.module_generators[0]; mg159[[]]160sage: mg.f_string([0,1,2,0])161[[[0]], [[1]], []]162163An example using multiple crystals of the same level::164165sage: B1 = KirillovReshetikhinCrystal(['A',2,1], 1,1)166sage: B2 = KirillovReshetikhinCrystal(['A',2,1], 2,1)167sage: L = RootSystem(['A',2,1]).weight_space()168sage: C = KyotoPathModel([B1, B2, B1], L.fundamental_weight(0))169sage: mg = C.module_generators[0]; mg170[[[3]]]171sage: mg.f_string([0,1,2,2])172[[[3]], [[1], [3]], [[3]]]173sage: mg.f_string([0,1,2,2,2])174sage: mg.f_string([0,1,2,2,1,0])175[[[3]], [[2], [3]], [[1]], [[2]]]176sage: mg.f_string([0,1,2,2,1,0,0,2])177[[[3]], [[1], [2]], [[1]], [[3]], [[1], [3]]]178"""179@staticmethod180def __classcall_private__(cls, crystals, weight):181"""182Normalize input to ensure a unique representation.183184EXAMPLES::185186sage: B = KirillovReshetikhinCrystal(['A',2,1], 1,1)187sage: L = RootSystem(['A',2,1]).weight_space()188sage: C = KyotoPathModel(B, L.fundamental_weight(0))189sage: C2 = KyotoPathModel((B,), L.fundamental_weight(0))190sage: C3 = KyotoPathModel([B], L.fundamental_weight(0))191sage: C is C2 and C2 is C3192True193"""194if isinstance(crystals, list):195crystals = tuple(crystals)196elif not isinstance(crystals, tuple):197crystals = (crystals,)198199if any(not B.is_perfect() for B in crystals):200raise ValueError("all crystals must be perfect")201level = crystals[0].level()202if any(B.level() != level for B in crystals[1:]):203raise ValueError("all crystals must have the same level")204ct = crystals[0].cartan_type()205if sum( ct.dual().c()[i] * weight.scalar(h) for i,h in206enumerate(RootSystem(ct).weight_space().simple_coroots()) ) != level:207raise ValueError( "%s is not a level %s weight"%(weight, level) )208209return super(KyotoPathModel, cls).__classcall__(cls, crystals, weight)210211def __init__(self, crystals, weight):212"""213Initialize ``self``.214215EXAMPLES::216217sage: B = KirillovReshetikhinCrystal(['A',2,1], 1,1)218sage: L = RootSystem(['A',2,1]).weight_space()219sage: C = KyotoPathModel(B, L.fundamental_weight(0))220sage: TestSuite(C).run() # long time221"""222Parent.__init__(self, category=(HighestWeightCrystals(), InfiniteEnumeratedSets()))223224self._cartan_type = crystals[0].cartan_type()225self.crystals = crystals # public for TensorProductOfCrystals226self._weight = weight227self._epsilon_dicts = [{b.Epsilon():b for b in B} for B in crystals]228self._phi_dicts = [{b.Phi():b for b in B} for B in crystals]229self.module_generators = (self.element_class(self, [self._phi_dicts[0][weight]]),)230231def _repr_(self):232"""233Return a string representation of ``self``.234235EXAMPLES::236237sage: B = KirillovReshetikhinCrystal(['A',2,1], 1,1)238sage: L = RootSystem(['A',2,1]).weight_space()239sage: KyotoPathModel(B, L.fundamental_weight(0))240Kyoto path realization of B(Lambda[0]) using [Kirillov-Reshetikhin crystal of type ['A', 2, 1] with (r,s)=(1,1)]241"""242return "Kyoto path realization of B(%s) using %s"%(self._weight, list(self.crystals))243244class Element(TensorProductOfRegularCrystalsElement):245"""246An element in the Kyoto path model.247"""248# For simplicity (and safety), we use the regular crystals implementation249def epsilon(self, i):250r"""251Return `\varepsilon_i` of ``self``.252253EXAMPLES::254255sage: B = KirillovReshetikhinCrystal(['A',2,1], 1,1)256sage: L = RootSystem(['A',2,1]).weight_space()257sage: C = KyotoPathModel(B, L.fundamental_weight(0))258sage: mg = C.module_generators[0]259sage: [mg.epsilon(i) for i in C.index_set()]260[0, 0, 0]261sage: elt = mg.f(0)262sage: [elt.epsilon(i) for i in C.index_set()]263[1, 0, 0]264sage: elt = mg.f_string([0,1,2])265sage: [elt.epsilon(i) for i in C.index_set()]266[0, 0, 1]267sage: elt = mg.f_string([0,1,2,2])268sage: [elt.epsilon(i) for i in C.index_set()]269[0, 0, 2]270"""271x = self.e(i)272eps = 0273while x is not None:274x = x.e(i)275eps = eps + 1276return eps277278def phi(self, i):279r"""280Return `\varphi_i` of ``self``.281282EXAMPLES::283284sage: B = KirillovReshetikhinCrystal(['A',2,1], 1,1)285sage: L = RootSystem(['A',2,1]).weight_space()286sage: C = KyotoPathModel(B, L.fundamental_weight(0))287sage: mg = C.module_generators[0]288sage: [mg.phi(i) for i in C.index_set()]289[1, 0, 0]290sage: elt = mg.f(0)291sage: [elt.phi(i) for i in C.index_set()]292[0, 1, 1]293sage: elt = mg.f_string([0,1])294sage: [elt.phi(i) for i in C.index_set()]295[0, 0, 2]296"""297x = self.f(i)298phi = 0299while x is not None:300x = x.f(i)301phi = phi + 1302return phi303304def e(self, i):305"""306Return the action of `e_i` on ``self``.307308EXAMPLES::309310sage: B = KirillovReshetikhinCrystal(['A',2,1], 1,1)311sage: L = RootSystem(['A',2,1]).weight_space()312sage: C = KyotoPathModel(B, L.fundamental_weight(0))313sage: mg = C.module_generators[0]314sage: all(mg.e(i) is None for i in C.index_set())315True316sage: mg.f(0).e(0) == mg317True318"""319position = self.positions_of_unmatched_plus(i)320if position == []:321return None322k = position[0]323if k == len(self)-1:324return None325crystal = self[k].e(i)326if k == len(self)-2 and crystal.Epsilon() == self._list[-1].Phi():327l = self._list[:-1]328l[-1] = crystal329return self.__class__(self.parent(), l)330return self.set_index(k, crystal)331332def f(self, i):333"""334Return the action of `f_i` on ``self``.335336EXAMPLES::337338sage: B = KirillovReshetikhinCrystal(['A',2,1], 1,1)339sage: L = RootSystem(['A',2,1]).weight_space()340sage: C = KyotoPathModel(B, L.fundamental_weight(0))341sage: mg = C.module_generators[0]342sage: mg.f(2)343sage: mg.f(0)344[[[1]], [[2]]]345sage: mg.f_string([0,1,2])346[[[2]], [[3]], [[1]]]347"""348position = self.positions_of_unmatched_minus(i)349if position == []:350return None351k = position[len(position)-1]352if k == len(self)-1:353l = self._list[:]354k = len(l) % len(self.parent().crystals)355l.append(self.parent()._phi_dicts[k][ l[-1].Epsilon() ])356l[-2] = l[-2].f(i)357return self.__class__(self.parent(), l)358return self.set_index(k, self[k].f(i))359360361362