Ticket #14573: trac_14573-path_realizations-ts.patch

File trac_14573-path_realizations-ts.patch, 15.5 KB (added by tscrim, 8 years ago)
  • doc/en/reference/combinat/crystals.rst

    # HG changeset patch
    # User Travis Scrimshaw <tscrim@ucdavis.edu>
    # Date 1368428940 25200
    # Node ID 6c2806b7f16fe699439637f508ff3156a0fa7575
    # Parent 93d3ac3f86d8e1a94295e5a7fb734eaad457e2c9
    #14573: Implement path realization for affine crystals.
    
    diff --git a/doc/en/reference/combinat/crystals.rst b/doc/en/reference/combinat/crystals.rst
    a b Crystals 
    1212   ../sage/combinat/crystals/fast_crystals
    1313   ../sage/combinat/crystals/highest_weight_crystals
    1414   ../sage/combinat/crystals/kirillov_reshetikhin
     15   ../sage/combinat/crystals/kyoto_path_model
    1516   ../sage/combinat/crystals/littelmann_path
    1617   ../sage/combinat/crystals/alcove_path
    1718   ../sage/combinat/crystals/spins
  • sage/combinat/crystals/all.py

    diff --git a/sage/combinat/crystals/all.py b/sage/combinat/crystals/all.py
    a b from spins import CrystalOfSpinsPlus 
    44from spins import CrystalOfSpinsMinus
    55from tensor_product import TensorProductOfCrystals
    66from tensor_product import CrystalOfTableaux
     7from kyoto_path_model import KyotoPathModel
    78from fast_crystals import FastCrystal
    89from affine import AffineCrystalFromClassical
    910from affine import AffineCrystalFromClassicalAndPromotion
  • new file sage/combinat/crystals/kyoto_path_model.py

    diff --git a/sage/combinat/crystals/kyoto_path_model.py b/sage/combinat/crystals/kyoto_path_model.py
    new file mode 100644
    - +  
     1r"""
     2Kyoto Path Model for Affine Highest Weight Crystals
     3"""
     4
     5#*****************************************************************************
     6#       Copyright (C) 2013 Travis Scrimshaw <tscrim at ucdavis.edu>
     7#
     8#  Distributed under the terms of the GNU General Public License (GPL)
     9#
     10#    This code is distributed in the hope that it will be useful,
     11#    but WITHOUT ANY WARRANTY; without even the implied warranty of
     12#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13#    General Public License for more details.
     14#
     15#  The full text of the GPL is available at:
     16#
     17#                  http://www.gnu.org/licenses/
     18#****************************************************************************
     19
     20from sage.structure.parent import Parent
     21from sage.structure.unique_representation import UniqueRepresentation
     22from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets
     23from sage.categories.highest_weight_crystals import HighestWeightCrystals
     24from sage.combinat.crystals.tensor_product import TensorProductOfCrystals, \
     25    TensorProductOfRegularCrystalsElement
     26from sage.combinat.root_system.root_system import RootSystem
     27
     28class KyotoPathModel(TensorProductOfCrystals):
     29    r"""
     30    The Kyoto path model for an affine highest weight crystal.
     31
     32    .. NOTE::
     33
     34        Here we are using anti-Kashiwara notation and might differ from
     35        some of the literature.
     36
     37    Consider a Kac--Moody algebra `\mathfrak{g}` of affine Cartan type `X`,
     38    and we want to model the `U_q(\mathfrak{g})`-crystal `B(\lambda)`.
     39    First we consider the set of fundamental weights `\{\Lambda_i\}_{i \in I}`
     40    of `\mathfrak{g}` and let `\{\overline{\Lambda}_i\}_{i \in I_0}` be the
     41    corresponding fundamental weights of the corresponding classical Lie
     42    algebra `\mathfrak{g}_0`. To model `B(\lambda)`, we start with a sequence
     43    of perfect `U_q^{\prime}(\mathfrak{g})`-crystals `(B^{(i)})_i` of level
     44    `l` such that
     45
     46    .. MATH::
     47
     48        \lambda \in \overline{P}_l^+ = \left\{ \mu \in \overline{P}^+ \mid
     49        \langle c, \mu \rangle = l \right\}
     50
     51    where `c` is the canonical central element of `U_q(\mathfrak{g})`
     52    and `\overline{P}^+` is the nonnegative weight lattice spanned by
     53    `\{ \overline{\Lambda}_i \mid i \in I \}`.
     54
     55    Next we consider the crystal isomorphism `\Phi_0 : B(\lambda_0) \to B^{(0)}
     56    \otimes B(\lambda_1)` defined by `u_{\lambda_0} \mapsto b^{(0)}_{\lambda_0}
     57    \otimes u_{\lambda_1}` where `b^{(0)}_{\lambda_0}` is the unique element in
     58    `B^{(0)}` such that `\varphi\left( b^{(0)}_{\lambda_0} \right) = \lambda_0`
     59    and `\lambda_1 = \varepsilon\left( b^{(0)}_{\lambda_0} \right)` and
     60    `u_{\mu}` is the highest weight element in `B(\mu)`. Iterating this, we
     61    obtain the following isomorphism:
     62
     63    .. MATH::
     64
     65        \Phi_n : B(\lambda) \to B^{(0)} \otimes B^{(1)} \otimes \cdots
     66        \otimes B^{(N)} \otimes B(\lambda_{N+1}).
     67
     68    We note by Lemma 10.6.2 in [HK02]_ that for any `b \in B(\lambda)` there
     69    exists a finite `N` such that
     70
     71    .. MATH::
     72
     73        \Phi_N(b) = \left( \bigotimes_{k=0}^{N-1} b^{(k)} \right)
     74        \otimes u_{\lambda_N}.
     75
     76    Therefore we can model elements `b \in B(\lambda)` as a
     77    `U_q^{\prime}(\mathfrak{g})`-crystal by considering an infinite list of
     78    elements `b^{(k)} \in B^{(k)}` and defining the crystal structure by:
     79
     80    .. MATH::
     81
     82        \begin{aligned}
     83        \overline{\mathrm{wt}}(b) & = \lambda_N + \sum_{k=0}^{N-1}
     84        \overline{\mathrm{wt}}\left( b^{(k)} \right)
     85        \\ e_i(b) & = e_i\left( b^{\prime} \otimes b^{(N)} \right) \otimes
     86        u_{\lambda_N},
     87        \\ f_i(b) & = f_i\left( b^{\prime} \otimes b^{(N)} \right) \otimes
     88        u_{\lambda_N},
     89        \\ \varepsilon_i(b) & = \max\bigl( \varepsilon_i(b^{\prime}) -
     90        \varphi_i\left( b^{(N)} \right), 0 \bigr),
     91        \\ \varphi_i(b) & = \varphi_i(b^{\prime}) + \max\left(
     92        \varphi_i\left( b^{(N)} \right) - \varepsilon_i(b^{\prime}), 0 \right),
     93        \end{aligned}
     94
     95    where `b^{\prime} = b^{(0)} \otimes \cdots \otimes b^{(N-1)}`. To
     96    translate this into a finite list, we consider a finite sequence
     97    `b^{(0)} \otimes \cdots \otimes b^{(N-1)} \otimes b^{(N)}_{\lambda_N}`
     98    and if
     99
     100    .. MATH::
     101
     102        f_i\left( b^{(0)} \otimes \cdots b^{(N-1)} \otimes
     103        b^{(N)}_{\lambda_N} \right) = b_0 \otimes \cdots \otimes b^{(N-1)}
     104        \otimes f_i\left( b^{(N)}_{\lambda_N} \right),
     105
     106    then we take the image as `b^{(0)} \otimes \cdots \otimes f_i\left(
     107    b^{(N)}_{\lambda_N}\right) \otimes b^{(N+1)}_{\lambda_{N+1}}`. Similarly
     108    we remove `b^{(N)}_{\lambda_{N}}` if we have `b_0 \otimes \cdots
     109    \otimes b^{(N-1)} \otimes b^{(N-1)}_{\lambda_{N-1}} \otimes
     110    b^{(N)}_{\lambda_N}`. Additionally if
     111
     112    .. MATH::
     113
     114        e_i\left( b^{(0)} \otimes \cdots \otimes b^{(N-1)} \otimes
     115        b^{(N)}_{\lambda_N} \right) = b^{(0)} \otimes \cdots \otimes
     116        b^{(N-1)} \otimes e_i\left( b^{(N)}_{\lambda_N} \right),
     117
     118    then we consider this to be `0`.
     119
     120    REFERENCES:
     121
     122    .. [HK02] *Introduction to Quantum Groups and Crystal Bases.*
     123       Jin Hong and Seok-Jin Kang. 2002. Volume 42.
     124       Graduate Studies in Mathematics. American Mathematical Society.
     125
     126    INPUT:
     127
     128    - ``B`` -- A single or list of `U_q^{\prime}` perfect crystal(s) of
     129      level `l`
     130    - ``weight`` -- A weight in `\overline{P}_l^+`
     131
     132    EXAMPLES::
     133
     134        sage: B = KirillovReshetikhinCrystal(['A',2,1], 1,1)
     135        sage: L = RootSystem(['A',2,1]).weight_space()
     136        sage: C = KyotoPathModel(B, L.fundamental_weight(0))
     137        sage: mg = C.module_generators[0]; mg
     138        [[[3]]]
     139        sage: mg.f_string([0,1,2,2])
     140        [[[3]], [[3]], [[1]]]
     141
     142    An example of type `A_5^{(2)}`::
     143
     144        sage: B = KirillovReshetikhinCrystal(['A',5,2], 1,1)
     145        sage: L = RootSystem(['A',5,2]).weight_space()
     146        sage: C = KyotoPathModel(B, L.fundamental_weight(0))
     147        sage: mg = C.module_generators[0]; mg
     148        [[[-1]]]
     149        sage: mg.f_string([0,2,1,3])
     150        [[[-3]], [[2]], [[-1]]]
     151        sage: mg.f_string([0,2,3,1])
     152        [[[-3]], [[2]], [[-1]]]
     153
     154    An example of type `D_3^{(2)}`::
     155
     156        sage: B = KirillovReshetikhinCrystal(['D',3,2], 1,1)
     157        sage: L = RootSystem(['D',3,2]).weight_space()
     158        sage: C = KyotoPathModel(B, L.fundamental_weight(0))
     159        sage: mg = C.module_generators[0]; mg
     160        [[]]
     161        sage: mg.f_string([0,1,2,0])
     162        [[[0]], [[1]], []]
     163
     164    An example using multiple crystals of the same level::
     165
     166        sage: B1 = KirillovReshetikhinCrystal(['A',2,1], 1,1)
     167        sage: B2 = KirillovReshetikhinCrystal(['A',2,1], 2,1)
     168        sage: L = RootSystem(['A',2,1]).weight_space()
     169        sage: C = KyotoPathModel([B1, B2, B1], L.fundamental_weight(0))
     170        sage: mg = C.module_generators[0]; mg
     171        [[[3]]]
     172        sage: mg.f_string([0,1,2,2])
     173        [[[3]], [[1], [3]], [[3]]]
     174        sage: mg.f_string([0,1,2,2,2])
     175        sage: mg.f_string([0,1,2,2,1,0])
     176        [[[3]], [[2], [3]], [[1]], [[2]]]
     177        sage: mg.f_string([0,1,2,2,1,0,0,2])
     178        [[[3]], [[1], [2]], [[1]], [[3]], [[1], [3]]]
     179    """
     180    @staticmethod
     181    def __classcall_private__(cls, crystals, weight):
     182        """
     183        Normalize input to ensure a unique representation.
     184
     185        EXAMPLES::
     186
     187            sage: B = KirillovReshetikhinCrystal(['A',2,1], 1,1)
     188            sage: L = RootSystem(['A',2,1]).weight_space()
     189            sage: C = KyotoPathModel(B, L.fundamental_weight(0))
     190            sage: C2 = KyotoPathModel((B,), L.fundamental_weight(0))
     191            sage: C3 = KyotoPathModel([B], L.fundamental_weight(0))
     192            sage: C is C2 and C2 is C3
     193            True
     194        """
     195        if isinstance(crystals, list):
     196            crystals = tuple(crystals)
     197        elif not isinstance(crystals, tuple):
     198            crystals = (crystals,)
     199
     200        if any(not B.is_perfect() for B in crystals):
     201            raise ValueError("all crystals must be perfect")
     202        level = crystals[0].level()
     203        if any(B.level() != level for B in crystals[1:]):
     204            raise ValueError("all crystals must have the same level")
     205        ct = crystals[0].cartan_type()
     206        if sum( ct.dual().c()[i] * weight.scalar(h) for i,h in
     207                enumerate(RootSystem(ct).weight_space().simple_coroots()) ) != level:
     208            raise ValueError( "%s is not a level %s weight"%(weight, level) )
     209
     210        return super(KyotoPathModel, cls).__classcall__(cls, crystals, weight)
     211
     212    def __init__(self, crystals, weight):
     213        """
     214        Initialize ``self``.
     215
     216        EXAMPLES::
     217
     218            sage: B = KirillovReshetikhinCrystal(['A',2,1], 1,1)
     219            sage: L = RootSystem(['A',2,1]).weight_space()
     220            sage: C = KyotoPathModel(B, L.fundamental_weight(0))
     221            sage: TestSuite(C).run() # long time
     222        """
     223        Parent.__init__(self, category=(HighestWeightCrystals(), InfiniteEnumeratedSets()))
     224
     225        self._cartan_type = crystals[0].cartan_type()
     226        self.crystals = crystals # public for TensorProductOfCrystals
     227        self._weight = weight
     228        self._epsilon_dicts = [{b.Epsilon():b for b in B} for B in crystals]
     229        self._phi_dicts = [{b.Phi():b for b in B} for B in crystals]
     230        self.module_generators = (self.element_class(self, [self._phi_dicts[0][weight]]),)
     231
     232    def _repr_(self):
     233        """
     234        Return a string representation of ``self``.
     235
     236        EXAMPLES::
     237
     238            sage: B = KirillovReshetikhinCrystal(['A',2,1], 1,1)
     239            sage: L = RootSystem(['A',2,1]).weight_space()
     240            sage: KyotoPathModel(B, L.fundamental_weight(0))
     241            Kyoto path realization of B(Lambda[0]) using [Kirillov-Reshetikhin crystal of type ['A', 2, 1] with (r,s)=(1,1)]
     242        """
     243        return "Kyoto path realization of B(%s) using %s"%(self._weight, list(self.crystals))
     244
     245    class Element(TensorProductOfRegularCrystalsElement):
     246        """
     247        An element in the Kyoto path model.
     248        """
     249        # For simplicity (and safety), we use the regular crystals implementation
     250        def epsilon(self, i):
     251            r"""
     252            Return `\varepsilon_i` of ``self``.
     253
     254            EXAMPLES::
     255
     256                sage: B = KirillovReshetikhinCrystal(['A',2,1], 1,1)
     257                sage: L = RootSystem(['A',2,1]).weight_space()
     258                sage: C = KyotoPathModel(B, L.fundamental_weight(0))
     259                sage: mg = C.module_generators[0]
     260                sage: [mg.epsilon(i) for i in C.index_set()]
     261                [0, 0, 0]
     262                sage: elt = mg.f(0)
     263                sage: [elt.epsilon(i) for i in C.index_set()]
     264                [1, 0, 0]
     265                sage: elt = mg.f_string([0,1,2])
     266                sage: [elt.epsilon(i) for i in C.index_set()]
     267                [0, 0, 1]
     268                sage: elt = mg.f_string([0,1,2,2])
     269                sage: [elt.epsilon(i) for i in C.index_set()]
     270                [0, 0, 2]
     271            """
     272            x = self.e(i)
     273            eps = 0
     274            while x is not None:
     275                x = x.e(i)
     276                eps = eps + 1
     277            return eps
     278
     279        def phi(self, i):
     280            r"""
     281            Return `\varphi_i` of ``self``.
     282
     283            EXAMPLES::
     284
     285                sage: B = KirillovReshetikhinCrystal(['A',2,1], 1,1)
     286                sage: L = RootSystem(['A',2,1]).weight_space()
     287                sage: C = KyotoPathModel(B, L.fundamental_weight(0))
     288                sage: mg = C.module_generators[0]
     289                sage: [mg.phi(i) for i in C.index_set()]
     290                [1, 0, 0]
     291                sage: elt = mg.f(0)
     292                sage: [elt.phi(i) for i in C.index_set()]
     293                [0, 1, 1]
     294                sage: elt = mg.f_string([0,1])
     295                sage: [elt.phi(i) for i in C.index_set()]
     296                [0, 0, 2]
     297            """
     298            x = self.f(i)
     299            phi = 0
     300            while x is not None:
     301                x = x.f(i)
     302                phi = phi + 1
     303            return phi
     304
     305        def e(self, i):
     306            """
     307            Return the action of `e_i` on ``self``.
     308
     309            EXAMPLES::
     310
     311                sage: B = KirillovReshetikhinCrystal(['A',2,1], 1,1)
     312                sage: L = RootSystem(['A',2,1]).weight_space()
     313                sage: C = KyotoPathModel(B, L.fundamental_weight(0))
     314                sage: mg = C.module_generators[0]
     315                sage: all(mg.e(i) is None for i in C.index_set())
     316                True
     317                sage: mg.f(0).e(0) == mg
     318                True
     319            """
     320            position = self.positions_of_unmatched_plus(i)
     321            if position == []:
     322                return None
     323            k = position[0]
     324            if k == len(self)-1:
     325                return None
     326            crystal = self[k].e(i)
     327            if k == len(self)-2 and crystal.Epsilon() == self._list[-1].Phi():
     328                l = self._list[:-1]
     329                l[-1] = crystal
     330                return self.__class__(self.parent(), l)
     331            return self.set_index(k, crystal)
     332
     333        def f(self, i):
     334            """
     335            Return the action of `f_i` on ``self``.
     336
     337            EXAMPLES::
     338
     339                sage: B = KirillovReshetikhinCrystal(['A',2,1], 1,1)
     340                sage: L = RootSystem(['A',2,1]).weight_space()
     341                sage: C = KyotoPathModel(B, L.fundamental_weight(0))
     342                sage: mg = C.module_generators[0]
     343                sage: mg.f(2)
     344                sage: mg.f(0)
     345                [[[1]], [[2]]]
     346                sage: mg.f_string([0,1,2])
     347                [[[2]], [[3]], [[1]]]
     348            """
     349            position = self.positions_of_unmatched_minus(i)
     350            if position == []:
     351                return None
     352            k = position[len(position)-1]
     353            if k == len(self)-1:
     354                l = self._list[:]
     355                k = len(l) % len(self.parent().crystals)
     356                l.append(self.parent()._phi_dicts[k][ l[-1].Epsilon() ])
     357                l[-2] = l[-2].f(i)
     358                return self.__class__(self.parent(), l)
     359            return self.set_index(k, self[k].f(i))
     360