Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/combinat/crystals/kyoto_path_model.py
8817 views
1
r"""
2
Kyoto 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
20
from sage.structure.parent import Parent
21
from sage.structure.unique_representation import UniqueRepresentation
22
from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets
23
from sage.categories.highest_weight_crystals import HighestWeightCrystals
24
from sage.combinat.crystals.tensor_product import TensorProductOfCrystals, \
25
TensorProductOfRegularCrystalsElement
26
from sage.combinat.root_system.root_system import RootSystem
27
28
class 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
361
362