Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/algebras/iwahori_hecke_algebra.py
8818 views
1
"""
2
Iwahori-Hecke Algebras
3
4
AUTHORS:
5
6
- Daniel Bump, Nicolas Thiery (2010): Initial version
7
8
- Brant Jones, Travis Scrimshaw, Andrew Mathas (2013):
9
Moved into the category framework and implemented the
10
Kazhdan-Lusztig `C` and `C^{\prime}` bases
11
"""
12
#*****************************************************************************
13
# Copyright (C) 2013 Brant Jones <brant at math.jmu.edu>
14
# Daniel Bump <bump at match.stanford.edu>
15
# Nicolas M. Thiery <nthiery at users.sf.net>
16
#
17
# Distributed under the terms of the GNU General Public License (GPL)
18
# http://www.gnu.org/licenses/
19
#*****************************************************************************
20
21
from sage.misc.abstract_method import abstract_method
22
from sage.misc.cachefunc import cached_method
23
from sage.misc.bindable_class import BindableClass
24
from sage.structure.parent import Parent
25
from sage.structure.unique_representation import UniqueRepresentation
26
from sage.structure.element import parent
27
from sage.categories.realizations import Realizations, Category_realization_of_parent
28
from sage.categories.all import AlgebrasWithBasis, FiniteDimensionalAlgebrasWithBasis, CoxeterGroups
29
from sage.rings.all import ZZ
30
from sage.rings.polynomial.laurent_polynomial_ring import LaurentPolynomialRing
31
from sage.rings.polynomial.polydict import ETuple
32
from sage.rings.arith import is_square
33
from sage.combinat.root_system.weyl_group import WeylGroup
34
from sage.combinat.family import Family
35
from sage.combinat.free_module import CombinatorialFreeModule, CombinatorialFreeModuleElement
36
37
def normalized_laurent_polynomial(R, p):
38
r"""
39
Returns a normalized version of the (Laurent polynomial) ``p`` in the
40
ring ``R``.
41
42
Various ring operations in ``sage`` return an element of the field of
43
fractions of the parent ring even though the element is "known" to belong to
44
the base ring. This function is a hack to recover from this. This occurs
45
somewhat haphazardly with Laurent polynomial rings::
46
47
sage: R.<q>=LaurentPolynomialRing(ZZ)
48
sage: [type(c) for c in (q**-1).coefficients()]
49
[<type 'sage.rings.rational.Rational'>]
50
51
It also happens in any ring when dividing by units::
52
53
sage: type ( 3/1 )
54
<type 'sage.rings.rational.Rational'>
55
sage: type ( -1/-1 )
56
<type 'sage.rings.rational.Rational'>
57
58
This function is a variation on a suggested workaround of Nils Bruin.
59
60
EXAMPLES::
61
62
sage: from sage.algebras.iwahori_hecke_algebra import normalized_laurent_polynomial
63
sage: type ( normalized_laurent_polynomial(ZZ, 3/1) )
64
<type 'sage.rings.integer.Integer'>
65
sage: R.<q>=LaurentPolynomialRing(ZZ)
66
sage: [type(c) for c in normalized_laurent_polynomial(R, q**-1).coefficients()]
67
[<type 'sage.rings.integer.Integer'>]
68
sage: R.<u,v>=LaurentPolynomialRing(ZZ,2)
69
sage: p=normalized_laurent_polynomial(R, 2*u**-1*v**-1+u*v)
70
sage: ui=normalized_laurent_polynomial(R, u^-1)
71
sage: vi=normalized_laurent_polynomial(R, v^-1)
72
sage: p(ui,vi)
73
2*u*v + u^-1*v^-1
74
sage: q= u+v+ui
75
sage: q(ui,vi)
76
u + v^-1 + u^-1
77
"""
78
try:
79
return R({k:R._base(c) for k,c in p.dict().iteritems()})
80
except (AttributeError,TypeError):
81
return R(p)
82
83
def index_cmp(x, y):
84
"""
85
Compare two term indices ``x`` and ``y`` by Bruhat order, then by word
86
length, and then by the generic comparison.
87
88
EXAMPLES::
89
90
sage: from sage.algebras.iwahori_hecke_algebra import index_cmp
91
sage: W = WeylGroup(['A',2,1])
92
sage: x = W.from_reduced_word([0,1])
93
sage: y = W.from_reduced_word([0,2,1])
94
sage: x.bruhat_le(y)
95
True
96
sage: index_cmp(x, y)
97
1
98
"""
99
if x.bruhat_le(y) or x.length() < y.length():
100
return 1
101
if y.bruhat_le(x) or x.length() > y.length():
102
return -1
103
return cmp(x, y) # Fallback total ordering
104
105
class IwahoriHeckeAlgebra(Parent, UniqueRepresentation):
106
r"""
107
Returns the Iwahori-Hecke algebra of the Coxeter group ``W``
108
with the specified parameters.
109
110
INPUT:
111
112
- ``W`` -- a Coxeter group or Cartan type
113
- ``q1`` -- a parameter
114
115
OPTIONAL ARGUMENTS:
116
117
- ``q2`` -- (default ``-1``) another parameter
118
- ``base_ring`` -- (default ``q1.parent()``) a ring containing ``q1``
119
and ``q2``
120
121
The Iwahori-Hecke algebra [I64]_ is a deformation of the group algebra of
122
a Weyl group or, more generally, a Coxeter group. These algebras are
123
defined by generators and relations and they depend on a deformation
124
parameter `q`. Taking `q = 1`, as in the following example, gives a ring
125
isomorphic to the group algebra of the corresponding Coxeter group.
126
127
Let `(W, S)` be a Coxeter system and let `R` be a commutative ring
128
containing elements `q_1` and `q_2`. Then the *Iwahori-Hecke algebra*
129
`H = H_{q_1,q_2}(W,S)` of `(W,S)` with parameters `q_1` and `q_2` is the
130
unital associative algebra with generators `\{T_s \mid s\in S\}` and
131
relations:
132
133
.. MATH::
134
135
\begin{aligned}
136
(T_s - q_1)(T_s - q_2) &= 0\\
137
T_r T_s T_r \cdots &= T_s T_r T_s \cdots,
138
\end{aligned}
139
140
where the number of terms on either side of the second relations (the braid
141
relations) is the order of `rs` in the Coxeter group `W`, for `r,s \in S`.
142
143
Iwahori-Hecke algebras are fundamental in many areas of mathematics,
144
ranging from the representation theory of Lie groups and quantum groups,
145
to knot theory and statistical mechanics. For more information see,
146
for example, [KL79]_, [HKP]_, [J87]_ and
147
:wikipedia:`Iwahori-Hecke_algebra`.
148
149
.. RUBRIC:: Bases
150
151
A reduced expression for an element `w \in W` is any minimal length
152
word `w = s_1 \cdots s_k`, with `s_i \in S`. If `w = s_1 \cdots s_k` is a
153
reduced expression for `w` then Matsumoto's Monoid Lemma implies that
154
`T_w = T_{s_1} \cdots T_{s_k}` depends on `w` and not on the choice of
155
reduced expressions. Moreover, `\{ T_w \mid w\in W \}` is a basis for the
156
Iwahori-Hecke algebra `H` and
157
158
.. MATH::
159
160
T_s T_w = \begin{cases}
161
T_{sw}, & \text{if } \ell(sw) = \ell(w)+1,\\
162
(q_1+q_2)T_w -q_1q_2 T_{sw}, & \text{if } \ell(sw) = \ell(w)-1.
163
\end{cases}
164
165
The `T`-basis of `H` is implemented for any choice of parameters
166
``q_1`` and ``q_2``::
167
168
sage: R.<u,v> = LaurentPolynomialRing(ZZ,2)
169
sage: H = IwahoriHeckeAlgebra('A3', u,v)
170
sage: T = H.T()
171
sage: T[1]
172
T[1]
173
sage: T[1,2,1] + T[2]
174
T[1,2,1] + T[2]
175
sage: T[1] * T[1,2,1]
176
(u+v)*T[1,2,1] + (-u*v)*T[2,1]
177
sage: T[1]^-1
178
(-u^-1*v^-1)*T[1] + (v^-1+u^-1)
179
180
Working over the Laurent polynomial ring `Z[q^{\pm 1/2}]` Kazhdan and
181
Lusztig proved that there exist two distinguished bases
182
`\{ C^{\prime}_w \mid w \in W \}` and `\{ C_w \mid w \in W \}` of `H`
183
which are uniquely determined by the properties that they are invariant
184
under the bar involution on `H` and have triangular transitions matrices
185
with polynomial entries of a certain form with the `T`-basis;
186
see [KL79]_ for a precise statement.
187
188
It turns out that the Kazhdan-Lusztig bases can be defined (by
189
specialization) in `H` whenever `-q_1 q_2` is a square in the base ring.
190
The Kazhdan-Lusztig bases are implemented inside `H` whenever `-q_1 q_2`
191
has a square root::
192
193
sage: H = IwahoriHeckeAlgebra('A3', u^2,-v^2)
194
sage: T=H.T(); Cp= H.Cp(); C=H.C()
195
sage: T(Cp[1])
196
(u^-1*v^-1)*T[1] + (u^-1*v)
197
sage: T(C[1])
198
(u^-1*v^-1)*T[1] + (-u*v^-1)
199
sage: Cp(C[1])
200
Cp[1] + (-u*v^-1-u^-1*v)
201
sage: elt = Cp[2]*Cp[3]+C[1]; elt
202
Cp[2,3] + Cp[1] + (-u*v^-1-u^-1*v)
203
sage: c = C(elt); c
204
C[2,3] + C[1] + (u*v^-1+u^-1*v)*C[2] + (u*v^-1+u^-1*v)*C[3] + (u^2*v^-2+2+u^-2*v^2)
205
sage: t = T(c); t
206
(u^-2*v^-2)*T[2,3] + (u^-1*v^-1)*T[1] + (u^-2)*T[2] + (u^-2)*T[3] + (-u*v^-1+u^-2*v^2)
207
sage: Cp(t)
208
Cp[2,3] + Cp[1] + (-u*v^-1-u^-1*v)
209
sage: Cp(c)
210
Cp[2,3] + Cp[1] + (-u*v^-1-u^-1*v)
211
212
The conversions to and from the Kazhdan-Lusztig bases are done behind the
213
scenes whenever the Kazhdan-Lusztig bases are well-defined. Once a suitable
214
Iwahori-Hecke algebra is defined they will work without further
215
intervention.
216
217
For example, with the "standard parameters", so that
218
`(T_r-q^2)(T_r+1) = 0`::
219
220
sage: R.<q> = LaurentPolynomialRing(ZZ)
221
sage: H = IwahoriHeckeAlgebra('A3', q^2)
222
sage: T=H.T(); Cp=H.Cp(); C=H.C()
223
sage: C(T[1])
224
q*C[1] + q^2
225
sage: elt = Cp(T[1,2,1]); elt
226
q^3*Cp[1,2,1] + (-q^2)*Cp[1,2] + (-q^2)*Cp[2,1] + q*Cp[1] + q*Cp[2] + (-1)
227
sage: C(elt)
228
q^3*C[1,2,1] + q^4*C[1,2] + q^4*C[2,1] + q^5*C[1] + q^5*C[2] + q^6
229
230
With the "normalized presentation", so that `(T_r-q)(T_r+q^{-1}) = 0`::
231
232
sage: R.<q> = LaurentPolynomialRing(ZZ)
233
sage: H = IwahoriHeckeAlgebra('A3', q, -q^-1)
234
sage: T=H.T(); Cp=H.Cp(); C=H.C()
235
sage: C(T[1])
236
C[1] + q
237
sage: elt = Cp(T[1,2,1]); elt
238
Cp[1,2,1] + (-q^-1)*Cp[1,2] + (-q^-1)*Cp[2,1] + (q^-2)*Cp[1] + (q^-2)*Cp[2] + (-q^-3)
239
sage: C(elt)
240
C[1,2,1] + q*C[1,2] + q*C[2,1] + q^2*C[1] + q^2*C[2] + q^3
241
242
In the group algebra, so that `(T_r-1)(T_r+1) = 0`::
243
244
sage: H = IwahoriHeckeAlgebra('A3', 1)
245
sage: T=H.T(); Cp=H.Cp(); C=H.C()
246
sage: C(T[1])
247
C[1] + 1
248
sage: Cp(T[1,2,1])
249
Cp[1,2,1] - Cp[1,2] - Cp[2,1] + Cp[1] + Cp[2] - 1
250
sage: C(_)
251
C[1,2,1] + C[1,2] + C[2,1] + C[1] + C[2] + 1
252
253
On the other hand, if the Kazhdan-Lusztig bases are not well-defined (when
254
`-q_1 q_2` is not a square), attempting to use the Kazhdan-Lusztig bases
255
triggers an error::
256
257
sage: R.<q>=LaurentPolynomialRing(ZZ)
258
sage: H = IwahoriHeckeAlgebra('A3', q)
259
sage: C=H.C()
260
Traceback (most recent call last):
261
...
262
ValueError: The Kazhdan_Lusztig bases are defined only when -q_1*q_2 is a square
263
264
We give an example in affine type::
265
266
sage: R.<v> = LaurentPolynomialRing(ZZ)
267
sage: H = IwahoriHeckeAlgebra(['A',2,1], v^2)
268
sage: T=H.T(); Cp=H.Cp(); C=H.C()
269
sage: C(T[1,0,2])
270
v^3*C[1,0,2] + v^4*C[1,0] + v^4*C[0,2] + v^4*C[1,2]
271
+ v^5*C[0] + v^5*C[2] + v^5*C[1] + v^6
272
sage: Cp(T[1,0,2])
273
v^3*Cp[1,0,2] + (-v^2)*Cp[1,0] + (-v^2)*Cp[0,2] + (-v^2)*Cp[1,2]
274
+ v*Cp[0] + v*Cp[2] + v*Cp[1] + (-1)
275
sage: T(C[1,0,2])
276
(v^-3)*T[1,0,2] + (-v^-1)*T[1,0] + (-v^-1)*T[0,2] + (-v^-1)*T[1,2]
277
+ v*T[0] + v*T[2] + v*T[1] + (-v^3)
278
sage: T(Cp[1,0,2])
279
(v^-3)*T[1,0,2] + (v^-3)*T[1,0] + (v^-3)*T[0,2] + (v^-3)*T[1,2]
280
+ (v^-3)*T[0] + (v^-3)*T[2] + (v^-3)*T[1] + (v^-3)
281
282
REFERENCES:
283
284
.. [I64] N. Iwahori, On the structure of a Hecke ring of a
285
Chevalley group over a finite field, J. Fac. Sci. Univ. Tokyo Sect.
286
I, 10 (1964), 215--236 (1964). :mathscinet:`MR0165016`
287
288
.. [HKP] T. J. Haines, R. E. Kottwitz, A. Prasad,
289
Iwahori-Hecke Algebras, J. Ramanujan Math. Soc., 25 (2010), 113--145.
290
:arxiv:`0309168v3` :mathscinet:`MR2642451`
291
292
.. [J87] V. Jones, Hecke algebra representations of braid groups and
293
link polynomials. Ann. of Math. (2) 126 (1987), no. 2, 335--388.
294
:doi:`10.2307/1971403` :mathscinet:`MR0908150`
295
296
EXAMPLES:
297
298
We start by creating a Iwahori-Hecke algebra together with the three bases
299
for these algebras that are currently supported::
300
301
sage: R.<v> = LaurentPolynomialRing(QQ, 'v')
302
sage: H = IwahoriHeckeAlgebra('A3', v**2)
303
sage: T = H.T()
304
sage: C = H.C()
305
sage: Cp = H.Cp()
306
307
It is also possible to define these three bases quickly using
308
the :meth:`inject_shorthands` method.
309
310
Next we create our generators for the `T`-basis and do some basic
311
computations and conversions between the bases::
312
313
sage: T1,T2,T3 = T.algebra_generators()
314
sage: T1 == T[1]
315
True
316
sage: T1*T2 == T[1,2]
317
True
318
sage: T1 + T2
319
T[1] + T[2]
320
sage: T1*T1
321
(v^2-1)*T[1] + v^2
322
sage: (T1 + T2)*T3 + T1*T1 - (v + v^-1)*T2
323
T[3,1] + T[2,3] + (v^2-1)*T[1] + (-v-v^-1)*T[2] + v^2
324
sage: Cp(T1)
325
v*Cp[1] + (-1)
326
sage: Cp((v^1 - 1)*T1*T2 - T3)
327
(v^3-v^2)*Cp[1,2] + (-v^2+v)*Cp[1] + (-v^2+v)*Cp[2] + (-v)*Cp[3] + v
328
sage: C(T1)
329
v*C[1] + v^2
330
sage: p = C(T2*T3 - v*T1); p
331
v^2*C[2,3] + (-v^2)*C[1] + v^3*C[2] + v^3*C[3] + (v^4-v^3)
332
sage: Cp(p)
333
v^2*Cp[2,3] + (-v^2)*Cp[1] + (-v)*Cp[2] + (-v)*Cp[3] + (v+1)
334
sage: Cp(T2*T3 - v*T1)
335
v^2*Cp[2,3] + (-v^2)*Cp[1] + (-v)*Cp[2] + (-v)*Cp[3] + (v+1)
336
337
In addition to explicitly creating generators, we have two shortcuts to
338
basis elements. The first is by using elements of the underlying Coxeter
339
group, the other is by using reduced words::
340
341
sage: s1,s2,s3 = H.coxeter_group().gens()
342
sage: T[s1*s2*s1*s3] == T[1,2,1,3]
343
True
344
sage: T[1,2,1,3] == T1*T2*T1*T3
345
True
346
347
TESTS:
348
349
We check the defining properties of the bases::
350
351
sage: R.<v> = LaurentPolynomialRing(QQ, 'v')
352
sage: H = IwahoriHeckeAlgebra('A3', v**2)
353
sage: W = H.coxeter_group()
354
sage: T = H.T()
355
sage: C = H.C()
356
sage: Cp = H.Cp()
357
sage: T(Cp[1])
358
(v^-1)*T[1] + (v^-1)
359
sage: T(C[1])
360
(v^-1)*T[1] + (-v)
361
sage: C(Cp[1])
362
C[1] + (v+v^-1)
363
sage: Cp(C[1])
364
Cp[1] + (-v-v^-1)
365
sage: all(C[x] == C[x].bar() for x in W) # long time
366
True
367
sage: all(Cp[x] == Cp[x].bar() for x in W) # long time
368
True
369
sage: all(T(C[x]).bar() == T(C[x]) for x in W) # long time
370
True
371
sage: all(T(Cp[x]).bar() == T(Cp[x]) for x in W) # long time
372
True
373
sage: KL = KazhdanLusztigPolynomial(W, v)
374
sage: term = lambda x,y: (-1)^y.length() * v^(-2*y.length()) * KL.P(y, x).substitute(v=v^-2)*T[y]
375
sage: all(T(C[x]) == (-v)^x.length()*sum(term(x,y) for y in W) for x in W) # long time
376
True
377
sage: all(T(Cp[x]) == v^-x.length()*sum(KL.P(y,x).substitute(v=v^2)*T[y] for y in W) for x in W) # long time
378
True
379
380
We check conversion between the bases for type `B_2` as well as some of
381
the defining properties::
382
383
sage: H = IwahoriHeckeAlgebra(['B',2], v**2)
384
sage: W = H.coxeter_group()
385
sage: T = H.T()
386
sage: C = H.C()
387
sage: Cp = H.Cp()
388
sage: all(T[x] == T(C(T[x])) for x in W) # long time
389
True
390
sage: all(T[x] == T(Cp(T[x])) for x in W) # long time
391
True
392
sage: all(C[x] == C(T(C[x])) for x in W) # long time
393
True
394
sage: all(C[x] == C(Cp(C[x])) for x in W) # long time
395
True
396
sage: all(Cp[x] == Cp(T(Cp[x])) for x in W) # long time
397
True
398
sage: all(Cp[x] == Cp(C(Cp[x])) for x in W) # long time
399
True
400
sage: all(T(C[x]).bar() == T(C[x]) for x in W) # long time
401
True
402
sage: all(T(Cp[x]).bar() == T(Cp[x]) for x in W) # long time
403
True
404
sage: KL = KazhdanLusztigPolynomial(W, v)
405
sage: term = lambda x,y: (-1)^y.length() * v^(-2*y.length()) * KL.P(y, x).substitute(v=v^-2)*T[y]
406
sage: all(T(C[x]) == (-v)^x.length()*sum(term(x,y) for y in W) for x in W) # long time
407
True
408
sage: all(T(Cp[x]) == v^-x.length()*sum(KL.P(y,x).substitute(v=v^2)*T[y] for y in W) for x in W) # long time
409
True
410
411
.. TODO::
412
413
Implement multi-parameter Iwahori-Hecke algebras together with their
414
Kazhdan-Lusztig bases. That is, Iwahori-Hecke algebras with (possibly)
415
different parameters for each conjugacy class of simple reflections
416
in the underlying Coxeter group.
417
418
.. TODO::
419
420
When given "generic parameters" we should return the generic
421
Iwahori-Hecke algebra with these parameters and allow the user to
422
work inside this algebra rather than doing calculations behind the
423
scenes in a copy of the generic Iwahori-Hecke algebra. The main
424
problem is that it is not clear how to recognise when the
425
parameters are "generic".
426
"""
427
@staticmethod
428
def __classcall_private__(cls, W, q1, q2=-1, base_ring=None):
429
r"""
430
TESTS::
431
432
sage: H = IwahoriHeckeAlgebra("A2", 1)
433
sage: H.coxeter_group() == WeylGroup("A2")
434
True
435
sage: H.cartan_type() == CartanType("A2")
436
True
437
sage: H._q2 == -1
438
True
439
sage: H2 = IwahoriHeckeAlgebra(WeylGroup("A2"), QQ(1), base_ring=ZZ)
440
sage: H is H2
441
True
442
"""
443
if W not in CoxeterGroups():
444
W = WeylGroup(W)
445
if base_ring is None:
446
base_ring = q1.parent()
447
else:
448
q1 = base_ring(q1)
449
q2 = base_ring(q2)
450
return super(IwahoriHeckeAlgebra, cls).__classcall__(cls, W, q1, q2, base_ring)
451
452
def __init__(self, W, q1, q2, base_ring):
453
r"""
454
Initialize and return the two parameter Iwahori-Hecke algebra ``self``.
455
456
EXAMPLES::
457
458
sage: R.<q1,q2> = QQ[]
459
sage: H = IwahoriHeckeAlgebra("A2", q1, q2=q2, base_ring=Frac(R))
460
sage: TestSuite(H).run()
461
"""
462
self._W = W
463
self._cartan_type = W.cartan_type()
464
465
self._q1 = q1
466
self._q2 = q2
467
468
# Used when multiplying generators: minor speed-up as it avoids the
469
# need to constantly add and multiply the parameters when applying the
470
# quadratic relation: T^2 = (q1+q2)T - q1*q2
471
self._q_sum = q1+q2
472
self._q_prod = -q1*q2
473
474
# If -q1*q2 is a square then it makes sense to talk of he Kazhdan-Lusztig
475
# basis of the Iwhaori-Hecke algebra. In this case we set
476
# self._root=\sqrt{q1*q2}. The Kazhdan-Lusztig bases will be computed in
477
# the generic case behind the scenes and then specialized to this # algebra.
478
is_Square, root = is_square(self._q_prod, root=True)
479
if is_Square:
480
# Attach the generic Hecke algebra and the basis change maps
481
self._root = root
482
self._generic_iwahori_hecke_algebra = IwahoriHeckeAlgebra_nonstandard(W)
483
self._shorthands = ['C', 'Cp', 'T']
484
else:
485
# Can we actually remove the bases C and Cp in this case?
486
self._root = None
487
self._shorthands = ['T']
488
489
if W.is_finite():
490
self._category = FiniteDimensionalAlgebrasWithBasis(base_ring)
491
else:
492
self._category = AlgebrasWithBasis(base_ring)
493
Parent.__init__(self, base=base_ring, category=self._category.WithRealizations())
494
495
self._is_generic=False # needed for initialisation of _KLHeckeBasis
496
497
# The following is used by the bar involution = self._bar_on_coefficients
498
try:
499
self._inverse_base_ring_generators = { g: self.base_ring()(g).__pow__(-1)
500
for g in self.base_ring().variable_names()}
501
except TypeError:
502
self._inverse_base_ring_generators = {}
503
504
def _repr_(self):
505
r"""
506
EXAMPLES::
507
508
sage: R.<q1,q2> = QQ[]
509
sage: IwahoriHeckeAlgebra("A2", q1**2, q2**2, base_ring=Frac(R))
510
Iwahori-Hecke algebra of type A2 in q1^2,q2^2 over Fraction Field of Multivariate Polynomial Ring in q1, q2 over Rational Field
511
"""
512
return "Iwahori-Hecke algebra of type {} in {},{} over {}".format(
513
self._cartan_type._repr_(compact=True), self._q1, self._q2, self.base_ring())
514
515
def _bar_on_coefficients(self, c):
516
r"""
517
Given a Laurent polynomial ``c`` return the Laurent polynomial obtained
518
by applying the (generic) bar involution to `c``. This is the ring
519
homomorphism of Laurent polynomial in `ZZ[u,u^{-1},v,v^{-1}]` which
520
sends `u` to `u^{-1}` and `v` to `v^{-1}.
521
522
EXAMPLES::
523
524
sage: R.<q>=LaurentPolynomialRing(ZZ)
525
sage: H = IwahoriHeckeAlgebra("A3",q^2)
526
sage: H._bar_on_coefficients(q)
527
q^-1
528
"""
529
return normalized_laurent_polynomial(self._base, c).substitute(**self._inverse_base_ring_generators)
530
531
def cartan_type(self):
532
r"""
533
Return the Cartan type of ``self``.
534
535
EXAMPLES::
536
537
sage: IwahoriHeckeAlgebra("D4", 1).cartan_type()
538
['D', 4]
539
"""
540
return self._cartan_type
541
542
def coxeter_group(self):
543
r"""
544
Return the Coxeter group of ``self``.
545
546
EXAMPLES::
547
548
sage: IwahoriHeckeAlgebra("B2", 1).coxeter_group()
549
Weyl Group of type ['B', 2] (as a matrix group acting on the ambient space)
550
"""
551
return self._W
552
553
def a_realization(self):
554
r"""
555
Return a particular realization of ``self`` (the `T`-basis).
556
557
EXAMPLES::
558
559
sage: H = IwahoriHeckeAlgebra("B2", 1)
560
sage: H.a_realization()
561
Iwahori-Hecke algebra of type B2 in 1,-1 over Integer Ring in the T-basis
562
"""
563
return self.T()
564
565
def q1(self):
566
"""
567
Return the parameter `q_1` of ``self``.
568
569
EXAMPLES::
570
571
sage: H = IwahoriHeckeAlgebra("B2", 1)
572
sage: H.q1()
573
1
574
"""
575
return self._q1
576
577
def q2(self):
578
"""
579
Return the parameter `q_2` of ``self``.
580
581
EXAMPLES::
582
583
sage: H = IwahoriHeckeAlgebra("B2", 1)
584
sage: H.q2()
585
-1
586
"""
587
return self._q2
588
589
class _BasesCategory(Category_realization_of_parent):
590
r"""
591
The category of bases of a Iwahori-Hecke algebra.
592
"""
593
def __init__(self, base):
594
r"""
595
Initialize the bases of a Iwahori-Hecke algebra.
596
597
INPUT:
598
599
- ``base`` -- a Iwahori-Hecke algebra
600
601
TESTS::
602
603
sage: H = IwahoriHeckeAlgebra("B2", 1)
604
sage: bases = H._BasesCategory()
605
sage: H.T() in bases
606
True
607
"""
608
Category_realization_of_parent.__init__(self, base)
609
610
def super_categories(self):
611
r"""
612
The super categories of ``self``.
613
614
EXAMPLES::
615
616
sage: H = IwahoriHeckeAlgebra("B2", 1)
617
sage: bases = H._BasesCategory()
618
sage: bases.super_categories()
619
[Category of realizations of Iwahori-Hecke algebra of type B2 in 1,-1 over Integer Ring,
620
Category of finite dimensional algebras with basis over Integer Ring]
621
"""
622
return [Realizations(self.base()), self.base()._category]
623
624
def _repr_(self):
625
r"""
626
Return the representation of ``self``.
627
628
EXAMPLES::
629
630
sage: H = IwahoriHeckeAlgebra("B2", 1)
631
sage: H._BasesCategory()
632
Category of bases of Iwahori-Hecke algebra of type B2 in 1,-1 over Integer Ring
633
"""
634
return "Category of bases of %s" % self.base()
635
636
class ParentMethods:
637
r"""
638
This class collects code common to all the various bases. In most
639
cases, these are just default implementations that will get
640
specialized in a basis.
641
"""
642
def _repr_(self):
643
"""
644
Text representation of this basis of Iwahori-Hecke algebra.
645
646
EXAMPLES::
647
648
sage: H = IwahoriHeckeAlgebra("B2", 1)
649
sage: H.T()
650
Iwahori-Hecke algebra of type B2 in 1,-1 over Integer Ring in the T-basis
651
sage: H.C()
652
Iwahori-Hecke algebra of type B2 in 1,-1 over Integer Ring in the C-basis
653
sage: H.Cp()
654
Iwahori-Hecke algebra of type B2 in 1,-1 over Integer Ring in the Cp-basis
655
"""
656
return "%s in the %s-basis"%(self.realization_of(), self._basis_name)
657
658
def __getitem__(self, i):
659
"""
660
Return the basis element indexed by ``i``.
661
662
INPUT:
663
664
- ``i`` -- either an element of the Coxeter group or a
665
reduced word
666
667
.. WARNING::
668
669
If `i`` is not a reduced expression then the basis element
670
indexed by the corresponding element of the algebra is
671
returned rather than the corresponding product of the
672
generators::
673
674
sage: R.<v> = LaurentPolynomialRing(QQ, 'v')
675
sage: T = IwahoriHeckeAlgebra('A3', v**2).T()
676
sage: T[1,1] == T[1] * T[1]
677
False
678
679
EXAMPLES::
680
681
sage: H = IwahoriHeckeAlgebra("B2", 1)
682
sage: T = H.T()
683
sage: G = WeylGroup("B2")
684
sage: T[G.one()]
685
1
686
sage: T[G.simple_reflection(1)]
687
T[1]
688
sage: T[G.from_reduced_word([1,2,1])]
689
T[1,2,1]
690
sage: T[[]]
691
1
692
sage: T[1]
693
T[1]
694
sage: T[1,2,1]
695
T[1,2,1]
696
"""
697
W = self.realization_of().coxeter_group()
698
if i in ZZ:
699
return self(W.simple_reflection(i))
700
if i in W:
701
return self(i)
702
if i == []:
703
return self.one()
704
return self(W.from_reduced_word(i))
705
706
def is_field(self, proof=True):
707
"""
708
Return whether this Iwahori-Hecke algebra is a field.
709
710
EXAMPLES::
711
712
sage: T = IwahoriHeckeAlgebra("B2", 1).T()
713
sage: T.is_field()
714
False
715
"""
716
return False
717
718
def is_commutative(self):
719
"""
720
Return whether this Iwahori-Hecke algebra is commutative.
721
722
EXAMPLES::
723
724
sage: T = IwahoriHeckeAlgebra("B2", 1).T()
725
sage: T.is_commutative()
726
False
727
"""
728
return self.base_ring().is_commutative() \
729
and self.realization_of().coxeter_group().is_commutative()
730
731
@cached_method
732
def one_basis(self):
733
r"""
734
Return the identity element in the Weyl group, as per
735
``AlgebrasWithBasis.ParentMethods.one_basis``.
736
737
EXAMPLES::
738
739
sage: H = IwahoriHeckeAlgebra("B2", 1)
740
sage: H.T().one_basis()
741
[1 0]
742
[0 1]
743
"""
744
return self.realization_of().coxeter_group().one()
745
746
def index_set(self):
747
r"""
748
Return the index set of ``self``.
749
750
EXAMPLES::
751
752
sage: IwahoriHeckeAlgebra("B2", 1).T().index_set()
753
(1, 2)
754
"""
755
return self.realization_of().coxeter_group().index_set()
756
757
@cached_method
758
def algebra_generators(self):
759
r"""
760
Return the generators.
761
762
They do not have order two but satisfy a quadratic relation.
763
They coincide with the simple reflections in the Coxeter group
764
when `q_1 = 1` and `q_2 = -1`. In this special case,
765
the Iwahori-Hecke algebra is identified with the group algebra
766
of the Coxeter group.
767
768
EXAMPLES:
769
770
In the standard basis::
771
772
sage: R.<q> = QQ[]
773
sage: H = IwahoriHeckeAlgebra("A3", q).T()
774
sage: T = H.algebra_generators(); T
775
Finite family {1: T[1], 2: T[2], 3: T[3]}
776
sage: T.list()
777
[T[1], T[2], T[3]]
778
sage: [T[i] for i in [1,2,3]]
779
[T[1], T[2], T[3]]
780
sage: T1,T2,T3 = H.algebra_generators()
781
sage: T1
782
T[1]
783
sage: H = IwahoriHeckeAlgebra(['A',2,1], q).T()
784
sage: T = H.algebra_generators(); T
785
Finite family {0: T[0], 1: T[1], 2: T[2]}
786
sage: T.list()
787
[T[0], T[1], T[2]]
788
sage: [T[i] for i in [0,1,2]]
789
[T[0], T[1], T[2]]
790
sage: [T0, T1, T2] = H.algebra_generators()
791
sage: T0
792
T[0]
793
794
In the Kazhdan-Lusztig basis::
795
796
sage: R = LaurentPolynomialRing(QQ, 'v')
797
sage: v = R.gen(0)
798
sage: H = IwahoriHeckeAlgebra('A5', v**2)
799
sage: C = H.C()
800
sage: C.algebra_generators()
801
Finite family {1: C[1], 2: C[2], 3: C[3], 4: C[4], 5: C[5]}
802
sage: C.algebra_generators().list()
803
[C[1], C[2], C[3], C[4], C[5]]
804
"""
805
return self.basis().keys().simple_reflections().map(self.monomial)
806
807
def algebra_generator(self, i):
808
r"""
809
Return the `i`-th generator of ``self``.
810
811
EXAMPLES:
812
813
In the standard basis::
814
815
sage: R.<q>=QQ[]
816
sage: H = IwahoriHeckeAlgebra("A3", q).T()
817
sage: [H.algebra_generator(i) for i in H.index_set()]
818
[T[1], T[2], T[3]]
819
820
In the Kazhdan-Lusztig basis::
821
822
sage: R = LaurentPolynomialRing(QQ, 'v')
823
sage: v = R.gen(0)
824
sage: H = IwahoriHeckeAlgebra('A5', v**2)
825
sage: C = H.C()
826
sage: [C.algebra_generator(i) for i in H.coxeter_group().index_set()]
827
[C[1], C[2], C[3], C[4], C[5]]
828
"""
829
return self.algebra_generators()[i]
830
831
@abstract_method(optional=True)
832
def bar_on_basis(self, w):
833
"""
834
Return the bar involution on the basis element of ``self``
835
indexed by ``w``.
836
837
EXAMPLES::
838
839
sage: R.<v> = LaurentPolynomialRing(QQ)
840
sage: H = IwahoriHeckeAlgebra('A3', v**2)
841
sage: W = H.coxeter_group()
842
sage: s1,s2,s3 = W.simple_reflections()
843
sage: Cp = H.Cp()
844
sage: Cp.bar_on_basis(s1*s2*s1*s3)
845
Cp[1,2,3,1]
846
"""
847
848
@abstract_method(optional=True)
849
def hash_involution_on_basis(self, w):
850
"""
851
Return the bar involution on the basis element of ``self``
852
indexed by ``w``.
853
854
EXAMPLES::
855
856
sage: R.<v> = LaurentPolynomialRing(QQ)
857
sage: H = IwahoriHeckeAlgebra('A3', v**2)
858
sage: W = H.coxeter_group()
859
sage: s1,s2,s3 = W.simple_reflections()
860
sage: Cp = H.Cp()
861
sage: C = H.C()
862
sage: C(Cp.hash_involution_on_basis(s1*s2*s1*s3))
863
C[1,2,3,1]
864
"""
865
866
class ElementMethods:
867
def bar(self):
868
"""
869
Return the bar involution of ``self``.
870
871
The bar involution `\overline{\phantom{x}}` is an antilinear
872
`\ZZ`-algebra involution defined by the identity on `\ZZ`,
873
sending `q^{1/2} \mapsto q^{-1/2}`, and `\overline{T_w} =
874
T_{w^{-1}}^{-1}`.
875
876
REFERENCES:
877
878
- :wikipedia:`Iwahori%E2%80%93Hecke_algebra#Canonical_basis`
879
880
EXAMPLES:
881
882
We first test on a single generator::
883
884
sage: R.<q> = LaurentPolynomialRing(QQ)
885
sage: H = IwahoriHeckeAlgebra('A3', q)
886
sage: T = H.T()
887
sage: T1,T2,T3 = T.algebra_generators()
888
sage: T1.bar()
889
(q^-1)*T[1] + (-1+q^-1)
890
sage: T1.bar().bar() == T1
891
True
892
893
Next on a multiple of generators::
894
895
sage: b = (T1*T2*T1).bar(); b
896
(q^-3)*T[1,2,1]
897
+ (-q^-2+q^-3)*T[1,2]
898
+ (-q^-2+q^-3)*T[2,1]
899
+ (q^-1-2*q^-2+q^-3)*T[1]
900
+ (q^-1-2*q^-2+q^-3)*T[2]
901
+ (-1+2*q^-1-2*q^-2+q^-3)
902
sage: b.bar() == T1*T2*T1
903
True
904
905
A sum::
906
907
sage: s = T1 + T2
908
sage: b = s.bar(); b
909
(q^-1)*T[1] + (q^-1)*T[2] + (-2+2*q^-1)
910
sage: b.bar() == s
911
True
912
913
A more complicated example::
914
915
sage: p = T1*T2 + (1-q+q^-1)*T3 - q^3*T1*T3
916
sage: p.bar()
917
(q^-2)*T[1,2]
918
+ (-q^-5)*T[3,1]
919
+ (-q^-1+q^-2+q^-4-q^-5)*T[1]
920
+ (-q^-1+q^-2)*T[2]
921
+ (1+q^-1-q^-2+q^-4-q^-5)*T[3]
922
+ (-q+1-q^-3+2*q^-4-q^-5)
923
sage: p.bar().bar() == p
924
True
925
926
This also works for arbitrary ``q1`` and ``q2``::
927
928
sage: R.<q1,q2> = LaurentPolynomialRing(QQ)
929
sage: H = IwahoriHeckeAlgebra('A3', q1, q2=-q2)
930
sage: T = H.T()
931
sage: T1,T2,T3 = T.algebra_generators()
932
sage: p = T1*T3 + T2
933
sage: p.bar()
934
(q1^-2*q2^-2)*T[3,1]
935
+ (-q1^-1*q2^-2+q1^-2*q2^-1)*T[1]
936
+ (q1^-1*q2^-1)*T[2]
937
+ (-q1^-1*q2^-2+q1^-2*q2^-1)*T[3]
938
+ (-q2^-1+q1^-1+q2^-2-2*q1^-1*q2^-1+q1^-2)
939
sage: p.bar().bar() == p
940
True
941
942
Next we have an example in the `C` basis::
943
944
sage: R.<v> = LaurentPolynomialRing(QQ)
945
sage: H = IwahoriHeckeAlgebra('A3', v**2)
946
sage: C = H.C()
947
sage: p = C[1]*C[3] + C[2]
948
sage: p.bar()
949
C[3,1] + C[2]
950
sage: p.bar().bar() == p
951
True
952
953
For the `C^{\prime}` basis as well::
954
955
sage: R.<v> = LaurentPolynomialRing(QQ)
956
sage: H = IwahoriHeckeAlgebra('A3', v**2)
957
sage: Cp = H.Cp()
958
sage: p = Cp[1]*Cp[3] + Cp[2]
959
sage: p.bar()
960
Cp[3,1] + Cp[2]
961
962
TESTS:
963
964
We check that doing the computations explicitly in the `T`
965
basis gives the same results and with bar invariant
966
coefficients::
967
968
sage: R.<v> = LaurentPolynomialRing(QQ)
969
sage: H = IwahoriHeckeAlgebra('A3', v**2)
970
sage: Cp = H.Cp()
971
sage: T = H.T()
972
sage: Cp(T(Cp[1,2,1])) == Cp[1,2,1]
973
True
974
sage: p = 4*Cp[1]*Cp[3] + (v^2 + v^-2 - 2)*Cp[2]
975
sage: Cp(T(p).bar()) == p
976
True
977
"""
978
B = self.parent()
979
if B.bar_on_basis is NotImplemented:
980
T = B.realization_of().T()
981
return B(T(self).bar())
982
H=B.realization_of()
983
return sum(H._bar_on_coefficients(c) * B.bar_on_basis(w) for (w,c) in self)
984
985
def hash_involution(self):
986
r"""
987
Return the hash involution of ``self``.
988
989
The hash involution `\alpha` is a `\ZZ`-algebra
990
involution of the Iwahori-Hecke algebra determined by
991
`q^{1/2} \mapsto q^{-1/2}`, and `T_w \mapsto -1^{\ell(w)}
992
(q_1 q_2)^{-\ell(w)} T_w`, for `w` an element of the
993
corresponding Coxeter group.
994
995
This map is defined in [KL79]_ and it is used to
996
change between the `C` and `C^{\prime}` bases because
997
`\alpha(C_w) = (-1)^{\ell(w)} C_w'`.
998
999
EXAMPLES::
1000
1001
sage: R.<v> = LaurentPolynomialRing(QQ)
1002
sage: H = IwahoriHeckeAlgebra('A3', v**2)
1003
sage: T = H.T()
1004
sage: T1,T2,T3 = T.algebra_generators()
1005
sage: elt = T1.hash_involution(); elt
1006
(-v^-2)*T[1]
1007
sage: elt.hash_involution()
1008
T[1]
1009
sage: elt = T1*T2 + (v^3 - v^-1 + 2)*T3*T1*T2*T3
1010
sage: elt.hash_involution()
1011
(-v^-7+2*v^-8+v^-11)*T[1,2,3,2] + (v^-4)*T[1,2]
1012
sage: elt.hash_involution().hash_involution() == elt
1013
True
1014
1015
With the Kazhdan-Lusztig `C^{\prime}` basis::
1016
1017
sage: Cp = H.Cp()
1018
sage: p = Cp[1]*Cp[3] + Cp[2]
1019
sage: q = p.hash_involution(); q
1020
Cp[3,1] + (-v-v^-1)*Cp[1] + (-1)*Cp[2] + (-v-v^-1)*Cp[3] + (v^2+v+2+v^-1+v^-2)
1021
sage: q.hash_involution() == p
1022
True
1023
1024
With the Kazhdan-Lusztig `C` basis::
1025
1026
sage: C = H.C()
1027
sage: p = C[1]*C[3] + C[2]
1028
sage: q = p.hash_involution(); q
1029
C[3,1] + (v+v^-1)*C[1] + (-1)*C[2] + (v+v^-1)*C[3] + (v^2-v+2-v^-1+v^-2)
1030
sage: q.hash_involution() == p
1031
True
1032
"""
1033
B = self.parent()
1034
if B.hash_involution_on_basis is NotImplemented:
1035
T = B.realization_of().T()
1036
return B(T(self).hash_involution())
1037
1038
H = B.realization_of()
1039
return B(sum(H._bar_on_coefficients(c) * B.hash_involution_on_basis(w) for (w,c) in self))
1040
1041
def specialize_to(self, new_hecke, num_vars=2):
1042
r"""
1043
Return the element in the Iwahori-Hecke algebra ``new_hecke``
1044
with respect to the same basis which is obtained from ``self``
1045
by specializing the generic parameters in this algebra to the
1046
parameters of ``new_hecke``.
1047
1048
INPUT:
1049
1050
- ``new_hecke`` -- the Hecke algebra in specialized parameters
1051
- ``num_vars`` -- the number of variables to specialize
1052
1053
.. WARNING::
1054
1055
This is not always defined. In particular, the number of
1056
generators must match ``num_vars``
1057
1058
EXAMPLES::
1059
1060
sage: R.<a,b> = LaurentPolynomialRing(ZZ)
1061
sage: H = IwahoriHeckeAlgebra("A3", a^2, -b^2)
1062
sage: T = H.T()
1063
sage: elt = T[1,2,1] + 3*T[1] - a*b*T[3]
1064
sage: S.<q> = LaurentPolynomialRing(ZZ)
1065
sage: HS = IwahoriHeckeAlgebra("A3", q^2, -1)
1066
sage: selt = elt.specialize_to(HS); selt
1067
T[1,2,1] + 3*T[1] + q^2*T[3]
1068
sage: GA = IwahoriHeckeAlgebra("A3", 1, -1)
1069
sage: elt.specialize_to(GA)
1070
T[1,2,1] + 3*T[1] + T[3]
1071
1072
We need to specify that we are only specializing
1073
one argument::
1074
1075
sage: selt.specialize_to(GA)
1076
Traceback (most recent call last):
1077
...
1078
TypeError: number of arguments does not match the number of generators in parent.
1079
sage: selt.specialize_to(GA, 1)
1080
T[1,2,1] + 3*T[1] + T[3]
1081
"""
1082
hecke = self.parent().realization_of()
1083
q1 = new_hecke._q1
1084
q2 = new_hecke._q2
1085
new_basis = getattr(new_hecke, self.parent()._basis_name)()
1086
1087
# is there an easier way that this to covert the coefficients to
1088
# the correct base ring for new_hecke?
1089
if num_vars == 2:
1090
args = (q1, q2)
1091
elif num_vars == 1:
1092
args = (q1,)
1093
else:
1094
return new_basis._from_dict(dict( (w, new_hecke._base(c))
1095
for (w,c) in self ))
1096
1097
new_coeff = lambda c: new_hecke._base(c(args))
1098
return new_basis._from_dict(dict( (w, new_coeff(c)) for (w,c) in self ))
1099
1100
class _Basis(CombinatorialFreeModule, BindableClass):
1101
r"""
1102
Technical methods (i.e., not mathematical) that are inherited by each
1103
basis of the algebra. These methods cannot be defined in the category.
1104
"""
1105
def __init__(self, algebra, prefix=None):
1106
r"""
1107
Initialises a basis class for the Iwahori-Hecke algebra ``algebra``.
1108
Optionally, a ``prefix`` can be set which is used when printing the
1109
basis elements. The prefix defaults to ``self._basis-name``, which
1110
is the name of the basis class.
1111
1112
EXAMPLES::
1113
1114
sage: H = IwahoriHeckeAlgebra("G2",1)
1115
sage: t = H.T(prefix="t")
1116
sage: t[1]
1117
t[1]
1118
"""
1119
if prefix is None:
1120
self._prefix = self._basis_name
1121
else:
1122
self._prefix = prefix
1123
1124
CombinatorialFreeModule.__init__(self,
1125
algebra.base_ring(),
1126
algebra._W,
1127
category=algebra._BasesCategory(),
1128
monomial_cmp=index_cmp,
1129
prefix=self._prefix)
1130
1131
# This **must** match the name of the class in order for
1132
# specialize_to() to work
1133
_basis_name = None
1134
1135
def _repr_term(self, t):
1136
r"""
1137
Return the string representation of the term indexed by ``t``.
1138
1139
EXAMPLES::
1140
1141
sage: R.<q> = QQ[]
1142
sage: H = IwahoriHeckeAlgebra("A3", q)
1143
sage: W = H.coxeter_group()
1144
sage: H.T()._repr_term(W.from_reduced_word([1,2,3]))
1145
'T[1,2,3]'
1146
"""
1147
redword = t.reduced_word()
1148
if len(redword) == 0:
1149
return "1"
1150
return self._print_options['prefix'] + '[%s]'%','.join('%d'%i for i in redword)
1151
1152
def _latex_term(self, t):
1153
r"""
1154
Return latex for the term indexed by ``t``.
1155
1156
EXAMPLES::
1157
1158
sage: R.<v> = QQ[]
1159
sage: H = IwahoriHeckeAlgebra("A3", q1=v**2, q2=-1)
1160
sage: W = H.coxeter_group()
1161
sage: H.T()._latex_term(W.from_reduced_word([1,2,3]))
1162
'T_{1}T_{2}T_{3}'
1163
"""
1164
redword = t.reduced_word()
1165
if len(redword) == 0:
1166
return '1'
1167
return ''.join("%s_{%d}"%(self._print_options['prefix'], i) for i in redword)
1168
1169
1170
class T(_Basis):
1171
r"""
1172
The standard basis of Iwahori-Hecke algebra.
1173
1174
For every simple reflection `s_i` of the Coxeter group, there is a
1175
corresponding generator `T_i` of Iwahori-Hecke algebra. These
1176
are subject to the relations:
1177
1178
.. MATH::
1179
1180
(T_i - q_1) (T_i - q_2) = 0
1181
1182
together with the braid relations:
1183
1184
.. MATH::
1185
1186
T_i T_j T_i \cdots = T_j T_i T_j \cdots,
1187
1188
where the number of terms on each of the two sides is the order of
1189
`s_i s_j` in the Coxeter group.
1190
1191
Weyl group elements form a basis of Iwahori-Hecke algebra `H`
1192
with the property that if `w_1` and `w_2` are Coxeter group elements
1193
such that `\ell(w_1 w_2) = \ell(w_1) + \ell(w_2)` then
1194
`T_{w_1 w_2} = T_{w_1} T_{w_2}`.
1195
1196
With the default value `q_2 = -1` and with `q_1 = q` the
1197
generating relation may be written
1198
`T_i^2 = (q-1) \cdot T_i + q \cdot 1` as in [I64]_.
1199
1200
EXAMPLES::
1201
1202
sage: H = IwahoriHeckeAlgebra("A3", 1)
1203
sage: T = H.T()
1204
sage: T1,T2,T3 = T.algebra_generators()
1205
sage: T1*T2*T3*T1*T2*T1 == T3*T2*T1*T3*T2*T3
1206
True
1207
sage: w0 = T(H.coxeter_group().long_element())
1208
sage: w0
1209
T[1,2,3,1,2,1]
1210
sage: T = H.T(prefix="s")
1211
sage: T.an_element()
1212
s[1,2,3,1,2,1] + 2*s[1,2,3,1,2] + 3*s[1,2,3,2,1] + s[1,2,3]
1213
1214
TESTS::
1215
1216
sage: R.<v> = LaurentPolynomialRing(QQ, 'v')
1217
sage: H = IwahoriHeckeAlgebra('A3', v**2)
1218
sage: W = H.coxeter_group()
1219
sage: T = H.T()
1220
sage: C = H.C()
1221
sage: Cp = H.Cp()
1222
sage: all(T(C(T[x])) == T[x] for x in W) # long time
1223
True
1224
sage: all(T(Cp(T[x])) == T[x] for x in W) # long time
1225
True
1226
1227
We check a property of the bar involution and `R`-polynomials::
1228
1229
sage: KL = KazhdanLusztigPolynomial(W, v)
1230
sage: all(T[x].bar() == sum(v^(-2*y.length()) * KL.R(y, x).substitute(v=v^-2) * T[y] for y in W) for x in W) # long time
1231
True
1232
"""
1233
_basis_name = "T" # this is used, for example, by specialize_to and is the default prefix
1234
1235
def inverse_generator(self, i):
1236
r"""
1237
Return the inverse of the `i`-th generator, if it exists.
1238
1239
This method is only available if the Iwahori-Hecke algebra
1240
parameters ``q1`` and ``q2`` are both invertible. In this case,
1241
the algebra generators are also invertible and this method returns
1242
the inverse of ``self.algebra_generator(i)``.
1243
1244
EXAMPLES::
1245
1246
sage: P.<q1, q2>=QQ[]
1247
sage: F = Frac(P)
1248
sage: H = IwahoriHeckeAlgebra("A2", q1, q2=q2, base_ring=F).T()
1249
sage: H.base_ring()
1250
Fraction Field of Multivariate Polynomial Ring in q1, q2 over Rational Field
1251
sage: H.inverse_generator(1)
1252
-1/(q1*q2)*T[1] + ((q1+q2)/(q1*q2))
1253
sage: H = IwahoriHeckeAlgebra("A2", q1, base_ring=F).T()
1254
sage: H.inverse_generator(2)
1255
-(1/(-q1))*T[2] + ((q1-1)/(-q1))
1256
sage: P1.<r1, r2> = LaurentPolynomialRing(QQ)
1257
sage: H1 = IwahoriHeckeAlgebra("B2", r1, q2=r2, base_ring=P1).T()
1258
sage: H1.base_ring()
1259
Multivariate Laurent Polynomial Ring in r1, r2 over Rational Field
1260
sage: H1.inverse_generator(2)
1261
(-r1^-1*r2^-1)*T[2] + (r2^-1+r1^-1)
1262
sage: H2 = IwahoriHeckeAlgebra("C2", r1, base_ring=P1).T()
1263
sage: H2.inverse_generator(2)
1264
(r1^-1)*T[2] + (-1+r1^-1)
1265
"""
1266
A = self.realization_of()
1267
try:
1268
# This currently works better than ~(self._q1) if
1269
# self.base_ring() is a Laurent polynomial ring since it
1270
# avoids accidental coercion into a field of fractions.
1271
i1 = normalized_laurent_polynomial(A._base, A._q1.__pow__(-1))
1272
i2 = normalized_laurent_polynomial(A._base, A._q2.__pow__(-1))
1273
except Exception:
1274
raise ValueError("%s and %s must be invertible."%(A._q1, A._q2))
1275
return (-i1*i2)*self.algebra_generator(i)+(i1+i2)
1276
1277
@cached_method
1278
def inverse_generators(self):
1279
r"""
1280
Return the inverses of all the generators, if they exist.
1281
1282
This method is only available if ``q1`` and ``q2`` are invertible.
1283
In that case, the algebra generators are also invertible.
1284
1285
EXAMPLES::
1286
1287
sage: P.<q> = PolynomialRing(QQ)
1288
sage: F = Frac(P)
1289
sage: H = IwahoriHeckeAlgebra("A2", q, base_ring=F).T()
1290
sage: T1,T2 = H.algebra_generators()
1291
sage: U1,U2 = H.inverse_generators()
1292
sage: U1*T1,T1*U1
1293
(1, 1)
1294
sage: P1.<q> = LaurentPolynomialRing(QQ)
1295
sage: H1 = IwahoriHeckeAlgebra("A2", q, base_ring=P1).T(prefix="V")
1296
sage: V1,V2 = H1.algebra_generators()
1297
sage: W1,W2 = H1.inverse_generators()
1298
sage: [W1,W2]
1299
[(q^-1)*V[1] + (-1+q^-1), (q^-1)*V[2] + (-1+q^-1)]
1300
sage: V1*W1, W2*V2
1301
(1, 1)
1302
"""
1303
return Family(self.index_set(), self.inverse_generator)
1304
1305
def product_on_basis(self, w1, w2):
1306
r"""
1307
Return `T_{w_1} T_{w_2}`, where `w_1` and `w_2` are words in the
1308
Coxeter group.
1309
1310
EXAMPLES::
1311
1312
sage: R.<q> = QQ[]; H = IwahoriHeckeAlgebra("A2", q)
1313
sage: T = H.T()
1314
sage: s1,s2 = H.coxeter_group().simple_reflections()
1315
sage: [T.product_on_basis(s1,x) for x in [s1,s2]]
1316
[(q-1)*T[1] + q, T[1,2]]
1317
"""
1318
result = self.monomial(w1)
1319
for i in w2.reduced_word():
1320
result = self.product_by_generator(result, i)
1321
return result
1322
1323
def product_by_generator_on_basis(self, w, i, side="right"):
1324
r"""
1325
Return the product `T_w T_i` (resp. `T_i T_w`) if ``side`` is
1326
``'right'`` (resp. ``'left'``).
1327
1328
If the quadratic relation is `(T_i-u)(T_i-v) = 0`, then we have
1329
1330
.. MATH::
1331
1332
T_w T_i = \begin{cases}
1333
T_{ws_i} & \text{if } \ell(ws_i) = \ell(w) + 1, \\
1334
(u+v) T_{ws_i} - uv T_w & \text{if } \ell(w s_i) = \ell(w)-1.
1335
\end{cases}
1336
1337
The left action is similar.
1338
1339
INPUT:
1340
1341
- ``w`` -- an element of the Coxeter group
1342
- ``i`` -- an element of the index set
1343
- ``side`` -- ``'right'`` (default) or ``'left'``
1344
1345
EXAMPLES::
1346
1347
sage: R.<q> = QQ[]; H = IwahoriHeckeAlgebra("A2", q)
1348
sage: T = H.T()
1349
sage: s1,s2 = H.coxeter_group().simple_reflections()
1350
sage: [T.product_by_generator_on_basis(w, 1) for w in [s1,s2,s1*s2]]
1351
[(q-1)*T[1] + q, T[2,1], T[1,2,1]]
1352
sage: [T.product_by_generator_on_basis(w, 1, side="left") for w in [s1,s2,s1*s2]]
1353
[(q-1)*T[1] + q, T[1,2], (q-1)*T[1,2] + q*T[2]]
1354
"""
1355
wi = w.apply_simple_reflection(i, side = side)
1356
A = self.realization_of()
1357
if w.has_descent(i, side = side):
1358
# 10% faster than a plain addition on the example of #12528
1359
return self.sum_of_terms(((w , A._q_sum), (wi, A._q_prod)), distinct=True)
1360
else:
1361
return self.monomial(wi)
1362
1363
def product_by_generator(self, x, i, side="right"):
1364
r"""
1365
Return `T_i \cdot x`, where `T_i` is the `i`-th generator. This is
1366
coded individually for use in ``x._mul_()``.
1367
1368
EXAMPLES::
1369
1370
sage: R.<q> = QQ[]; H = IwahoriHeckeAlgebra("A2", q).T()
1371
sage: T1, T2 = H.algebra_generators()
1372
sage: [H.product_by_generator(x, 1) for x in [T1,T2]]
1373
[(q-1)*T[1] + q, T[2,1]]
1374
sage: [H.product_by_generator(x, 1, side = "left") for x in [T1,T2]]
1375
[(q-1)*T[1] + q, T[1,2]]
1376
"""
1377
return self.linear_combination((self.product_by_generator_on_basis(w, i, side), c)
1378
for (w,c) in x)
1379
1380
def to_C_basis(self, w):
1381
r"""
1382
Return `T_w` as a linear combination of `C`-basis elements.
1383
1384
EXAMPLES::
1385
1386
sage: R = LaurentPolynomialRing(QQ, 'v')
1387
sage: v = R.gen(0)
1388
sage: H = IwahoriHeckeAlgebra('A2', v**2)
1389
sage: s1,s2 = H.coxeter_group().simple_reflections()
1390
sage: T = H.T()
1391
sage: C = H.C()
1392
sage: T.to_C_basis(s1)
1393
v*T[1] + v^2
1394
sage: C(T(s1))
1395
v*C[1] + v^2
1396
sage: C(v^-1*T(s1) - v)
1397
C[1]
1398
sage: C(T(s1*s2)+T(s1)+T(s2)+1)
1399
v^2*C[1,2] + (v^3+v)*C[1] + (v^3+v)*C[2] + (v^4+2*v^2+1)
1400
sage: C(T(s1*s2*s1))
1401
v^3*C[1,2,1] + v^4*C[1,2] + v^4*C[2,1] + v^5*C[1] + v^5*C[2] + v^6
1402
"""
1403
H = self.realization_of()
1404
generic_T = H._generic_iwahori_hecke_algebra.T()
1405
return generic_T.to_C_basis(w).specialize_to(H)
1406
1407
def to_Cp_basis(self, w):
1408
r"""
1409
Return `T_w` as a linear combination of `C^{\prime}`-basis
1410
elements.
1411
1412
EXAMPLES::
1413
1414
sage: R.<v> = LaurentPolynomialRing(QQ)
1415
sage: H = IwahoriHeckeAlgebra('A2', v**2)
1416
sage: s1,s2 = H.coxeter_group().simple_reflections()
1417
sage: T = H.T()
1418
sage: Cp = H.Cp()
1419
sage: T.to_Cp_basis(s1)
1420
v*Cp[1] + (-1)
1421
sage: Cp(T(s1))
1422
v*Cp[1] + (-1)
1423
sage: Cp(T(s1)+1)
1424
v*Cp[1]
1425
sage: Cp(T(s1*s2)+T(s1)+T(s2)+1)
1426
v^2*Cp[1,2]
1427
sage: Cp(T(s1*s2*s1))
1428
v^3*Cp[1,2,1] + (-v^2)*Cp[1,2] + (-v^2)*Cp[2,1] + v*Cp[1] + v*Cp[2] + (-1)
1429
"""
1430
H = self.realization_of()
1431
generic_T = H._generic_iwahori_hecke_algebra.T()
1432
return generic_T.to_Cp_basis(w).specialize_to(H)
1433
1434
def bar_on_basis(self, w):
1435
"""
1436
Return the bar involution of `T_w`, which is `T^{-1}_{w^-1}`.
1437
1438
EXAMPLES::
1439
1440
sage: R.<v> = LaurentPolynomialRing(QQ)
1441
sage: H = IwahoriHeckeAlgebra('A3', v**2)
1442
sage: W = H.coxeter_group()
1443
sage: s1,s2,s3 = W.simple_reflections()
1444
sage: T = H.T()
1445
sage: b = T.bar_on_basis(s1*s2*s3); b
1446
(v^-6)*T[1,2,3]
1447
+ (-v^-4+v^-6)*T[1,2]
1448
+ (-v^-4+v^-6)*T[3,1]
1449
+ (-v^-4+v^-6)*T[2,3]
1450
+ (v^-2-2*v^-4+v^-6)*T[1]
1451
+ (v^-2-2*v^-4+v^-6)*T[2]
1452
+ (v^-2-2*v^-4+v^-6)*T[3]
1453
+ (-1+3*v^-2-3*v^-4+v^-6)
1454
sage: b.bar()
1455
T[1,2,3]
1456
"""
1457
return self.monomial(w.inverse()).inverse()
1458
1459
def hash_involution_on_basis(self, w):
1460
r"""
1461
Return the hash involution on the basis element ``self[w]``.
1462
1463
The hash involution `\alpha` is a `\ZZ`-algebra
1464
involution of the Iwahori-Hecke algebra determined by
1465
`q^{1/2} \mapsto q^{-1/2}`, and `T_w \mapsto -1^{\ell(w)}
1466
(q_1 q_2)^{-\ell(w)} T_w`, for `w` an element of the
1467
corresponding Coxeter group.
1468
1469
This map is defined in [KL79]_ and it is used to change between
1470
the `C` and `C^{\prime}` bases because
1471
`\alpha(C_w) = (-1)^{\ell(w)}C^{\prime}_w`.
1472
1473
This function is not intended to be called directly. Instead, use
1474
:meth:`hash_involution`.
1475
1476
EXAMPLES::
1477
1478
sage: R.<v> = LaurentPolynomialRing(QQ, 'v')
1479
sage: H = IwahoriHeckeAlgebra('A3', v**2)
1480
sage: T=H.T()
1481
sage: s=H.coxeter_group().simple_reflection(1)
1482
sage: T.hash_involution_on_basis(s)
1483
(-v^-2)*T[1]
1484
sage: T[s].hash_involution()
1485
(-v^-2)*T[1]
1486
sage: h = T[1]*T[2] + (v^3 - v^-1 + 2)*T[3,1,2,3]
1487
sage: h.hash_involution()
1488
(-v^-7+2*v^-8+v^-11)*T[1,2,3,2] + (v^-4)*T[1,2]
1489
sage: h.hash_involution().hash_involution() == h
1490
True
1491
"""
1492
H = self.realization_of()
1493
return (-H._q_prod)**(-w.length())*self.monomial(w)
1494
1495
class Element(CombinatorialFreeModuleElement):
1496
r"""
1497
A class for elements of an Iwahori-Hecke algebra in the `T` basis.
1498
1499
TESTS::
1500
1501
sage: R.<q> = QQ[]
1502
sage: H = IwahoriHeckeAlgebra("B3",q).T()
1503
sage: T1,T2,T3 = H.algebra_generators()
1504
sage: T1+2*T2*T3
1505
2*T[2,3] + T[1]
1506
sage: T1*T1
1507
(q-1)*T[1] + q
1508
1509
sage: R.<q1,q2> = QQ[]
1510
sage: H = IwahoriHeckeAlgebra("A2", q1, q2=q2).T(prefix="x")
1511
sage: sum(H.algebra_generators())^2
1512
x[1,2] + x[2,1] + (q1+q2)*x[1] + (q1+q2)*x[2] + (-2*q1*q2)
1513
1514
sage: H = IwahoriHeckeAlgebra("A2", q1, q2=q2).T(prefix="t")
1515
sage: t1,t2 = H.algebra_generators()
1516
sage: (t1-t2)^3
1517
(q1^2-q1*q2+q2^2)*t[1] + (-q1^2+q1*q2-q2^2)*t[2]
1518
1519
sage: R.<q> = QQ[]
1520
sage: H = IwahoriHeckeAlgebra("G2", q).T()
1521
sage: [T1, T2] = H.algebra_generators()
1522
sage: T1*T2*T1*T2*T1*T2 == T2*T1*T2*T1*T2*T1
1523
True
1524
sage: T1*T2*T1 == T2*T1*T2
1525
False
1526
1527
sage: H = IwahoriHeckeAlgebra("A2", 1).T()
1528
sage: [T1,T2] = H.algebra_generators()
1529
sage: T1+T2
1530
T[1] + T[2]
1531
1532
sage: -(T1+T2)
1533
-T[1] - T[2]
1534
sage: 1-T1
1535
-T[1] + 1
1536
1537
sage: T1.parent()
1538
Iwahori-Hecke algebra of type A2 in 1,-1 over Integer Ring in the T-basis
1539
"""
1540
def inverse(self):
1541
r"""
1542
Return the inverse if ``self`` is a basis element.
1543
1544
An element is a basis element if it is `T_w` where `w` is in
1545
the Weyl group. The base ring must be a field or Laurent
1546
polynomial ring. Other elements of the ring have inverses but
1547
the inverse method is only implemented for the basis elements.
1548
1549
EXAMPLES::
1550
1551
sage: R.<q> = LaurentPolynomialRing(QQ)
1552
sage: H = IwahoriHeckeAlgebra("A2", q).T()
1553
sage: [T1,T2] = H.algebra_generators()
1554
sage: x = (T1*T2).inverse(); x
1555
(q^-2)*T[2,1] + (-q^-1+q^-2)*T[1] + (-q^-1+q^-2)*T[2] + (1-2*q^-1+q^-2)
1556
sage: x*T1*T2
1557
1
1558
1559
TESTS:
1560
1561
We check some alternative forms of input for inverting
1562
an element::
1563
1564
sage: R.<q> = LaurentPolynomialRing(QQ)
1565
sage: H = IwahoriHeckeAlgebra("A2", q).T()
1566
sage: T1,T2 = H.algebra_generators()
1567
sage: ~(T1*T2)
1568
(q^-2)*T[2,1] + (-q^-1+q^-2)*T[1] + (-q^-1+q^-2)*T[2] + (1-2*q^-1+q^-2)
1569
sage: (T1*T2)^(-1)
1570
(q^-2)*T[2,1] + (-q^-1+q^-2)*T[1] + (-q^-1+q^-2)*T[2] + (1-2*q^-1+q^-2)
1571
"""
1572
if len(self) != 1:
1573
raise NotImplementedError("inverse only implemented for basis elements (monomials in the generators)"%self)
1574
H = self.parent()
1575
w = self.support_of_term()
1576
1577
return H.prod(H.inverse_generator(i) for i in reversed(w.reduced_word()))
1578
1579
__invert__ = inverse
1580
1581
standard = T
1582
1583
class _KLHeckeBasis(_Basis):
1584
r"""
1585
Abstract class for the common methods for the Kazhdan-Lusztig `C` and
1586
`C^{\prime}` bases.
1587
"""
1588
def __init__(self, IHAlgebra, prefix=None):
1589
r"""
1590
Returns the Kazhdan-Lusztig basis of the Iwahori-Hecke algebra
1591
``IHAlgebra``.
1592
1593
EXAMPLES::
1594
1595
sage: R.<v> = LaurentPolynomialRing(QQ)
1596
sage: H = IwahoriHeckeAlgebra('A3', v**2)
1597
sage: Cp = H.Cp()
1598
sage: C = H.C()
1599
"""
1600
if IHAlgebra._root is None:
1601
raise ValueError('The Kazhdan_Lusztig bases are defined only when -q_1*q_2 is a square')
1602
1603
if IHAlgebra._is_generic:
1604
klbasis=IwahoriHeckeAlgebra_nonstandard._KLHeckeBasis
1605
else:
1606
klbasis=IwahoriHeckeAlgebra._KLHeckeBasis
1607
super(klbasis, self).__init__(IHAlgebra, prefix)
1608
1609
# Define conversion from the KL-basis to the T-basis via
1610
# specialization from the generic Hecke algebra
1611
self.module_morphism(self.to_T_basis, codomain=IHAlgebra.T(), category=self.category()
1612
).register_as_coercion()
1613
1614
# ...and from the T_basis to the KL-basis.
1615
T = IHAlgebra.T()
1616
T.module_morphism(getattr(T, 'to_{}_basis'.format(self._basis_name)),
1617
codomain=self, category=self.category()
1618
).register_as_coercion()
1619
1620
def product_on_basis(self, w1, w2):
1621
r"""
1622
Return the product of the two Kazhdan-Lusztig basis elements
1623
indexed by ``w1`` and ``w2``. The computation is actually done by
1624
converting to the `T`-basis, multiplying and then converting back.
1625
1626
EXAMPLES::
1627
1628
sage: R = LaurentPolynomialRing(QQ, 'v')
1629
sage: v = R.gen(0)
1630
sage: H = IwahoriHeckeAlgebra('A2', v**2)
1631
sage: s1,s2 = H.coxeter_group().simple_reflections()
1632
sage: [H.Cp().product_on_basis(s1,x) for x in [s1,s2]]
1633
[(v+v^-1)*Cp[1], Cp[1,2]]
1634
sage: [H.C().product_on_basis(s1,x) for x in [s1,s2]]
1635
[(-v-v^-1)*C[1], C[1,2]]
1636
"""
1637
return self(self.to_T_basis(w1) * self.to_T_basis(w2))
1638
1639
def bar_on_basis(self, w):
1640
r"""
1641
Return the bar involution on the Kazhdan-Lusztig basis element
1642
indexed by ``w``. By definition, all Kazhdan-Lusztig basis elements
1643
are fixed by the bar involution.
1644
1645
EXAMPLES::
1646
1647
sage: R.<v> = LaurentPolynomialRing(QQ)
1648
sage: H = IwahoriHeckeAlgebra('A3', v**2)
1649
sage: W = H.coxeter_group()
1650
sage: s1,s2,s3 = W.simple_reflections()
1651
sage: Cp = H.Cp()
1652
sage: Cp.bar_on_basis(s1*s2*s1*s3)
1653
Cp[1,2,3,1]
1654
"""
1655
return self.monomial(w)
1656
1657
def to_T_basis(self, w):
1658
r"""
1659
Returns the Kazhdan-Lusztig basis elememt ``self[w]`` as a linear
1660
combination of ``T``-bais elements.
1661
1662
EXAMPLES::
1663
1664
sage: H=IwahoriHeckeAlgebra("A3",1); Cp=H.Cp(); C=H.C()
1665
sage: s=H.coxeter_group().simple_reflection(1)
1666
sage: C.to_T_basis(s)
1667
T[1] - 1
1668
sage: Cp.to_T_basis(s)
1669
T[1] + 1
1670
"""
1671
H = self.realization_of()
1672
generic_KL = getattr(H._generic_iwahori_hecke_algebra, self._basis_name)()
1673
return generic_KL.to_T_basis(w).specialize_to(H)
1674
1675
class Cp(_KLHeckeBasis):
1676
r"""
1677
The `C^{\prime}` Kazhdan-Lusztig basis of Iwahori-Hecke algebra.
1678
1679
Assuming the standard quadratic relations of `(T_r-q)(T_r+1)=0`, for
1680
every element `w` in the Coxeter group, there is a unique element
1681
`C^{\prime}_w` in the Iwahori-Hecke algebra which is uniquely determined
1682
by the two properties:
1683
1684
.. MATH::
1685
1686
\begin{aligned}
1687
\overline{ C^{\prime}_w } &= C^{\prime}_w\\
1688
C^{\prime}_w &= q^{-\ell(w)/2}
1689
\sum_{v \leq w} P_{v,w}(q) T_v
1690
\end{aligned}
1691
1692
where `\leq` is the Bruhat order on the underlying Coxeter group and
1693
`P_{v,w}(q) \in \ZZ[q,q^{-1}]` are polynomials in `\ZZ[q]` such that
1694
`P_{w,w}(q) = 1` and if `v < w` then `\deg P_{v,w}(q) \leq
1695
\frac{1}{2}(\ell(w)-\ell(v)-1)`.
1696
1697
More generally, if the quadratic relations are of the form
1698
(T_s-q_1)(T_s-q_2)=0` and `\sqrt{-q_1q_2}` exists then for a simple
1699
reflection `s` then the corresponding Kazhdan-Lusztig basis element is:
1700
1701
.. MATH::
1702
1703
C^{\prime}_s = (-q_1 q_2)^{-1/2} (T_s + 1).
1704
1705
See [KL79]_ for more details.
1706
1707
EXAMPLES::
1708
1709
sage: R = LaurentPolynomialRing(QQ, 'v')
1710
sage: v = R.gen(0)
1711
sage: H = IwahoriHeckeAlgebra('A5', v**2)
1712
sage: W = H.coxeter_group()
1713
sage: s1,s2,s3,s4,s5 = W.simple_reflections()
1714
sage: T = H.T()
1715
sage: Cp = H.Cp()
1716
sage: T(s1)**2
1717
(v^2-1)*T[1] + v^2
1718
sage: T(Cp(s1))
1719
(v^-1)*T[1] + (v^-1)
1720
sage: T(Cp(s1)*Cp(s2)*Cp(s1))
1721
(v^-3)*T[1,2,1] + (v^-3)*T[1,2] + (v^-3)*T[2,1] + (v^-1+v^-3)*T[1] + (v^-3)*T[2] + (v^-1+v^-3)
1722
1723
::
1724
1725
sage: R = LaurentPolynomialRing(QQ, 'v')
1726
sage: v = R.gen(0)
1727
sage: H = IwahoriHeckeAlgebra('A3', v**2)
1728
sage: W = H.coxeter_group()
1729
sage: s1,s2,s3 = W.simple_reflections()
1730
sage: Cp = H.Cp()
1731
sage: Cp(s1*s2*s1)
1732
Cp[1,2,1]
1733
sage: Cp(s1)**2
1734
(v+v^-1)*Cp[1]
1735
sage: Cp(s1)*Cp(s2)*Cp(s1)
1736
Cp[1,2,1] + Cp[1]
1737
sage: Cp(s1)*Cp(s2)*Cp(s3)*Cp(s1)*Cp(s2) # long time
1738
Cp[1,2,3,1,2] + Cp[1,2,1] + Cp[3,1,2]
1739
1740
TESTS::
1741
1742
sage: R.<v> = LaurentPolynomialRing(QQ, 'v')
1743
sage: H = IwahoriHeckeAlgebra('A3', v**2)
1744
sage: W = H.coxeter_group()
1745
sage: T = H.T()
1746
sage: C = H.C()
1747
sage: Cp = H.Cp()
1748
sage: all(Cp(T(Cp[x])) == Cp[x] for x in W) # long time
1749
True
1750
sage: all(Cp(C(Cp[x])) == Cp[x] for x in W) # long time
1751
True
1752
"""
1753
_basis_name = 'Cp' # this is used, for example, by specialize_to and is the default prefix
1754
1755
def hash_involution_on_basis(self, w):
1756
r"""
1757
Return the effect of applying the hash involution to the basis
1758
element ``self[w]``.
1759
1760
This function is not intended to be called directly. Instead, use
1761
:meth:`hash_involution`.
1762
1763
EXAMPLES::
1764
1765
sage: R.<v> = LaurentPolynomialRing(QQ, 'v')
1766
sage: H = IwahoriHeckeAlgebra('A3', v**2)
1767
sage: Cp=H.Cp()
1768
sage: s=H.coxeter_group().simple_reflection(1)
1769
sage: Cp.hash_involution_on_basis(s)
1770
(-1)*Cp[1] + (v+v^-1)
1771
sage: Cp[s].hash_involution()
1772
(-1)*Cp[1] + (v+v^-1)
1773
"""
1774
return (-1)**w.length()*self( self.realization_of().C().monomial(w) )
1775
1776
C_prime = Cp
1777
1778
class C(_KLHeckeBasis):
1779
r"""
1780
The Kazhdan-Lusztig `C`-basis of Iwahori-Hecke algebra.
1781
1782
Assuming the standard quadratic relations of `(T_r-q)(T_r+1)=0`, for
1783
every element `w` in the Coxeter group, there is a unique element
1784
`C_w` in the Iwahori-Hecke algebra which is uniquely determined
1785
by the two properties:
1786
1787
.. MATH::
1788
1789
\begin{aligned}
1790
\overline{C_w} &= C_w \\
1791
C_w &= (-1)^{\ell(w)} q^{\ell(w)/2}
1792
\sum_{v \leq w} (-q)^{-\ell(v)}\overline{P_{v,w}(q)} T_v
1793
\end{aligned}
1794
1795
where `\leq` is the Bruhat order on the underlying Coxeter group and
1796
`P_{v,w}(q)\in\ZZ[q,q^{-1}]` are polynomials in `\ZZ[q]` such that
1797
`P_{w,w}(q) = 1` and if `v < w` then
1798
`\deg P_{v,w}(q) \leq \frac{1}{2}(\ell(w) - \ell(v) - 1)`.
1799
1800
More generally, if the quadratic relations are of the form
1801
(T_s-q_1)(T_s-q_2)=0` and `\sqrt{-q_1q_2}` exists then for a simple
1802
reflection `s` then the corresponding Kazhdan-Lusztig basis element is:
1803
1804
.. MATH::
1805
1806
C_s = (-q_1 q_2)^{1/2} (1 - (-q_1 q_2)^{-1/2} T_s).
1807
1808
This is related to the `C^{\prime}` Kazhdan-Lusztig basis by `C_i =
1809
-\alpha(C_i^{\prime})` where `\alpha` is the `\ZZ`-linear Hecke
1810
involution defined by `q^{1/2} \mapsto q^{-1/2}` and `\alpha(T_i) =
1811
-(q_1 q_2)^{-1/2} T_i`.
1812
1813
See [KL79]_ for more details.
1814
1815
EXAMPLES::
1816
1817
sage: R.<v> = LaurentPolynomialRing(QQ)
1818
sage: H = IwahoriHeckeAlgebra('A5', v**2)
1819
sage: W = H.coxeter_group()
1820
sage: s1,s2,s3,s4,s5 = W.simple_reflections()
1821
sage: T = H.T()
1822
sage: C = H.C()
1823
sage: T(s1)**2
1824
(v^2-1)*T[1] + v^2
1825
sage: T(C(s1))
1826
(v^-1)*T[1] + (-v)
1827
sage: T(C(s1)*C(s2)*C(s1))
1828
(v^-3)*T[1,2,1] + (-v^-1)*T[1,2] + (-v^-1)*T[2,1] + (v+v^-1)*T[1] + v*T[2] + (-v^3-v)
1829
1830
::
1831
1832
sage: R.<v> = LaurentPolynomialRing(QQ)
1833
sage: H = IwahoriHeckeAlgebra('A3', v**2)
1834
sage: W = H.coxeter_group()
1835
sage: s1,s2,s3 = W.simple_reflections()
1836
sage: C = H.C()
1837
sage: C(s1*s2*s1)
1838
C[1,2,1]
1839
sage: C(s1)**2
1840
(-v-v^-1)*C[1]
1841
sage: C(s1)*C(s2)*C(s1)
1842
C[1,2,1] + C[1]
1843
1844
TESTS::
1845
1846
sage: R.<v> = LaurentPolynomialRing(QQ, 'v')
1847
sage: H = IwahoriHeckeAlgebra('A3', v**2)
1848
sage: W = H.coxeter_group()
1849
sage: T = H.T()
1850
sage: C = H.C()
1851
sage: Cp = H.Cp()
1852
sage: all(C(T(C[x])) == C[x] for x in W) # long time
1853
True
1854
sage: all(C(Cp(C[x])) == C[x] for x in W) # long time
1855
True
1856
1857
Check the defining property between `C` and `C^{\prime}`::
1858
1859
sage: T(C[1])
1860
(v^-1)*T[1] + (-v)
1861
sage: -T(Cp[1]).hash_involution()
1862
(v^-1)*T[1] + (-v)
1863
sage: T(Cp[1] + Cp[2]).hash_involution()
1864
(-v^-1)*T[1] + (-v^-1)*T[2] + 2*v
1865
sage: -T(C[1] + C[2])
1866
(-v^-1)*T[1] + (-v^-1)*T[2] + 2*v
1867
sage: Cp(-C[1].hash_involution())
1868
Cp[1]
1869
sage: Cp(-C[1,2,3].hash_involution())
1870
Cp[1,2,3]
1871
sage: Cp(C[1,2,1,3].hash_involution())
1872
Cp[1,2,3,1]
1873
sage: all(C((-1)**x.length()*Cp[x].hash_involution()) == C[x] for x in W) # long time
1874
True
1875
"""
1876
_basis_name = "C" # this is used, for example, by specialize_to and is the default prefix
1877
1878
def hash_involution_on_basis(self, w):
1879
r"""
1880
Return the effect of applying the hash involution to the basis
1881
element ``self[w]``.
1882
1883
This function is not intended to be called directly. Instead, use
1884
:meth:`hash_involution`.
1885
1886
EXAMPLES::
1887
1888
sage: R.<v> = LaurentPolynomialRing(QQ, 'v')
1889
sage: H = IwahoriHeckeAlgebra('A3', v**2)
1890
sage: C=H.C()
1891
sage: s=H.coxeter_group().simple_reflection(1)
1892
sage: C.hash_involution_on_basis(s)
1893
(-1)*C[1] + (-v-v^-1)
1894
sage: C[s].hash_involution()
1895
(-1)*C[1] + (-v-v^-1)
1896
"""
1897
return (-1)**w.length()*self( self.realization_of().Cp().monomial(w) )
1898
1899
# This **must** have the same basis classes as the IwahoriHeckeAlgebra class
1900
# with the same name and they should inherit from the respecitive basis class
1901
class IwahoriHeckeAlgebra_nonstandard(IwahoriHeckeAlgebra):
1902
r"""
1903
This is a class which is used behind the scenes by
1904
:class:`IwahoriHeckeAlgebra` to compute the Kazhdan-Lusztig bases. It is
1905
not meant to be used directly. It implements the slightly idiosyncratic
1906
(but convenient) Iwahori-Hecke algebra with two parameters which is
1907
defined over the Laurent polynomial ring `\ZZ[u,u^{-1},v,v^{-1}]` in
1908
two variables and has quadratic relations:
1909
1910
.. MATH::
1911
1912
(T_r - u)(T_r + v^2/u) = 0.
1913
1914
The point of these relations is that the product of the two parameters is
1915
`v^2` which is a square in `\ZZ[u,u^{-1},v,v^{-1}]`. Consequently, the
1916
Kazhdan-Lusztig bases are defined for this algebra.
1917
1918
More generally, if we have a Iwahori-Hecke algebra with two parameters
1919
which has quadratic relations of the form:
1920
1921
.. MATH::
1922
1923
(T_r - q_1)(T_r - q_2) = 0
1924
1925
where `-q_1 q_2` is a square then the Kazhdan-Lusztig bases are
1926
well-defined for this algebra. Moreover, these bases be computed by
1927
specialization from the generic Iwahori-Hecke algebra using the
1928
specialization which sends `u \mapsto q_1` and `v \mapsto \sqrt{-q_1 q_2}`,
1929
so that `v^2 / u \mapsto -q_2`.
1930
1931
For example, if `q_1 = q = Q^2` and `q_2 = -1` then `u \mapsto q` and
1932
`v \mapsto \sqrt{q} = Q`; this is the standard presentation of the
1933
Iwahori-Hecke algebra with `(T_r - q)(T_r + 1) = 0`. On the other hand,
1934
when `q_1 = q` and `q_2 = -q^{-1}` then `u \mapsto q` and `v \mapsto 1`.
1935
This is the normalized presentation with `(T_r - v)(T_r + v^{-1}) = 0`.
1936
1937
.. WARNING::
1938
1939
This class uses non-standard parameters for the Iwahori-Hecke algebra
1940
and are related to the standard parameters by an outer automorphism
1941
that is non-trivial on the `T`-basis.
1942
"""
1943
@staticmethod
1944
def __classcall_private__(cls, W):
1945
r"""
1946
TESTS::
1947
1948
sage: H1 = sage.algebras.iwahori_hecke_algebra.IwahoriHeckeAlgebra_nonstandard("A2")
1949
sage: H2 = sage.algebras.iwahori_hecke_algebra.IwahoriHeckeAlgebra_nonstandard(WeylGroup("A2"))
1950
sage: H1 is H2
1951
True
1952
"""
1953
if W not in CoxeterGroups():
1954
W = WeylGroup(W)
1955
return super(IwahoriHeckeAlgebra_nonstandard, cls).__classcall__(cls,W)
1956
1957
def __init__(self, W):
1958
r"""
1959
EXAMPLES::
1960
1961
sage: H = sage.algebras.iwahori_hecke_algebra.IwahoriHeckeAlgebra_nonstandard("A2")
1962
sage: TestSuite(H).run()
1963
"""
1964
self._W = W
1965
self._cartan_type = W.cartan_type()
1966
1967
base_ring = LaurentPolynomialRing(ZZ, 'u,v')
1968
u,v = base_ring.gens()
1969
1970
# We don't want to call IwahoriHeckeAlgebra.__init__ because this would
1971
# try and attach a generic Hecke algebra to this algebra leading to
1972
# an infinite loop.
1973
self._q1 = u
1974
self._q2 = normalized_laurent_polynomial(base_ring, -v**2*u**-1)
1975
self._root = v
1976
1977
# Used when multiplying generators: minor speed-up as it avoids the
1978
# need to constantly add and multiply the parameters when applying the
1979
# quadratic relation: T^2 = (q1+q2)T - q1*q2
1980
self._q_sum = normalized_laurent_polynomial(base_ring, self._q1+self._q2)
1981
self._q_prod = normalized_laurent_polynomial(base_ring, -self._q1*self._q2)
1982
1983
self.u_inv = normalized_laurent_polynomial(base_ring, u**-1)
1984
self.v_inv = normalized_laurent_polynomial(base_ring, v**-1)
1985
1986
self._shorthands = ['C', 'Cp', 'T']
1987
1988
if W.is_finite():
1989
self._category = FiniteDimensionalAlgebrasWithBasis(base_ring)
1990
else:
1991
self._category = AlgebrasWithBasis(base_ring)
1992
Parent.__init__(self, base=base_ring, category=self._category.WithRealizations())
1993
self._is_generic = True # needed for initialising _KLHeckeBasis
1994
1995
def _repr_(self):
1996
r"""
1997
EXAMPLES::
1998
1999
sage: sage.algebras.iwahori_hecke_algebra.IwahoriHeckeAlgebra_nonstandard("A2")
2000
A generic Iwahori-Hecke algebra of type A2 in u,-u^-1*v^2 over
2001
Multivariate Laurent Polynomial Ring in u, v over Integer Ring
2002
"""
2003
return "A generic Iwahori-Hecke algebra of type {} in {},{} over {}".format(
2004
self._cartan_type._repr_(compact=True), self._q1, self._q2, self.base_ring())
2005
2006
def _bar_on_coefficients(self, c):
2007
r"""
2008
Given a Laurent polynomial ``c`` return the Laurent polynomial obtained
2009
by applying the (generic) bar involution to `c``. This is the ring
2010
homomorphism of Laurent polynomial in `ZZ[u,u^{-1},v,v^{-1}]` which
2011
sends `u` to `u^{-1}` and `v` to `v^{-1}.
2012
2013
EXAMPLES::
2014
2015
sage: R.<q>=LaurentPolynomialRing(ZZ)
2016
sage: H=IwahoriHeckeAlgebra("A3",q^2)
2017
sage: GH=H._generic_iwahori_hecke_algebra
2018
sage: GH._bar_on_coefficients(GH.u_inv)
2019
u
2020
sage: GH._bar_on_coefficients(GH.v_inv)
2021
v
2022
"""
2023
return normalized_laurent_polynomial(self._base,c)(self.u_inv,self.v_inv)
2024
2025
class _BasesCategory(IwahoriHeckeAlgebra._BasesCategory):
2026
"""
2027
Category of bases for a generic Iwahori-Hecke algebra.
2028
"""
2029
def super_categories(self):
2030
r"""
2031
The super categories of ``self``.
2032
2033
EXAMPLES::
2034
2035
sage: H = sage.algebras.iwahori_hecke_algebra.IwahoriHeckeAlgebra_nonstandard("B2")
2036
sage: H._BasesCategory().super_categories()
2037
[Category of bases of A generic Iwahori-Hecke algebra of type B2 in u,-u^-1*v^2 over
2038
Multivariate Laurent Polynomial Ring in u, v over Integer Ring]
2039
"""
2040
return [IwahoriHeckeAlgebra._BasesCategory(self.base())]
2041
2042
class ElementMethods:
2043
def specialize_to(self, new_hecke):
2044
r"""
2045
Return the element in the Iwahori-Hecke algebra ``new_hecke``
2046
with respect to the same basis which is obtained from ``self``
2047
by specializing the generic parameters in this algebra to the
2048
parameters of ``new_hecke``.
2049
2050
The generic Iwahori-Hecke algebra is defined over
2051
`\ZZ[u^\pm, v^\pm]` and has parameters ``u`` and
2052
``-v^2/u``. The specialization map sends ``u`` to
2053
``new_hecke._q1`` and ``v`` to ``new_hecke._root`` which is
2054
thesquare root of ``-new_hecke._q1*new_hecke._q2``, so
2055
`-v^2/u` is sent to ``new_hecke._q2``.
2056
2057
This function is not intended to be called directly. Rather it
2058
is called behind the scenes to convert between the
2059
Kazhdan-Lusztig and standard bases of the Iwahori-Hecke
2060
algebras.
2061
2062
EXAMPLES::
2063
2064
sage: R.<a,b>=LaurentPolynomialRing(ZZ,2)
2065
sage: H=IwahoriHeckeAlgebra("A3",a^2,-b^2)
2066
sage: GH=H._generic_iwahori_hecke_algebra
2067
sage: GH.T()(GH.C()[1])
2068
(v^-1)*T[1] + (-u*v^-1)
2069
sage: ( GH.T()(GH.C()[1]) ).specialize_to(H)
2070
(a^-1*b^-1)*T[1] + (-a*b^-1)
2071
sage: GH.C()( GH.T()[1] )
2072
v*C[1] + u
2073
sage: GH.C()( GH.T()[1] ).specialize_to(H)
2074
a*b*C[1] + a^2
2075
sage: H.C()( H.T()[1] )
2076
a*b*C[1] + a^2
2077
"""
2078
hecke = self.parent().realization_of()
2079
q1 = new_hecke._q1
2080
root = new_hecke._root
2081
# is there an easier way that this to covert the coefficients to
2082
# the correct base ring for new_hecke?
2083
new_coeff = lambda c: new_hecke._base(normalized_laurent_polynomial(hecke._base, c)(q1,root))
2084
new_basis = getattr(new_hecke, self.parent()._basis_name)()
2085
return new_basis._from_dict(dict( (w, new_coeff(c)) for (w,c) in self ))
2086
2087
class T(IwahoriHeckeAlgebra.T):
2088
r"""
2089
The `T`-basis for the generic Iwahori-Hecke algebra.
2090
"""
2091
@cached_method
2092
def to_Cp_basis(self, w):
2093
r"""
2094
Return `T_w` as a linear combination of `C^{\prime}`-basis
2095
elements.
2096
2097
EXAMPLES::
2098
2099
sage: H = sage.algebras.iwahori_hecke_algebra.IwahoriHeckeAlgebra_nonstandard("A2")
2100
sage: s1,s2 = H.coxeter_group().simple_reflections()
2101
sage: T = H.T()
2102
sage: Cp = H.Cp()
2103
sage: T.to_Cp_basis(s1)
2104
v*Cp[1] + (-u^-1*v^2)
2105
sage: Cp(T(s1))
2106
v*Cp[1] + (-u^-1*v^2)
2107
sage: Cp(T(s1)+1)
2108
v*Cp[1] + (-u^-1*v^2+1)
2109
sage: Cp(T(s1*s2)+T(s1)+T(s2)+1)
2110
v^2*Cp[1,2] + (-u^-1*v^3+v)*Cp[1] + (-u^-1*v^3+v)*Cp[2] + (u^-2*v^4-2*u^-1*v^2+1)
2111
sage: Cp(T(s1*s2*s1))
2112
v^3*Cp[1,2,1] + (-u^-1*v^4)*Cp[1,2] + (-u^-1*v^4)*Cp[2,1]
2113
+ (u^-2*v^5)*Cp[1] + (u^-2*v^5)*Cp[2] + (-u^-3*v^6)
2114
"""
2115
A = self.realization_of()
2116
Cp = A.Cp()
2117
2118
if w == A._W.one(): # the identity element of the Coxeter group
2119
return Cp.one()
2120
2121
T0 = self.zero()
2122
inp = self.monomial(w)
2123
result = Cp.zero()
2124
while inp != T0:
2125
(x,c) = inp.trailing_item(index_cmp)
2126
inp = inp - c * A._root**x.length() * Cp.to_T_basis(x)
2127
result = result + c * A._root**x.length() * Cp.monomial(x)
2128
2129
return result
2130
2131
@cached_method
2132
def to_C_basis(self, w):
2133
r"""
2134
Return `T_w` as a linear combination of `C`-basis elements.
2135
2136
To compute this we piggy back off the `C^{\prime}`-basis
2137
conversion using the observation that the hash involution sends
2138
`T_w` to `(-q_1 q_1)^{\ell(w)} T_w` and `C_w` to
2139
`(-1)^{\ell(w)} C^{\prime}_w`. Therefore, if
2140
2141
.. MATH::
2142
2143
T_w = \sum_v a_{vw} C^{\prime}_v
2144
2145
then
2146
2147
.. MATH::
2148
2149
T_w = (-q_1 q_2)^{\ell(w)} \Big( \sum_v a_{vw} C^{\prime}_v
2150
\Big)^\#
2151
= \sum_v (-1)^{\ell(v)} \overline{a_{vw}} C_v
2152
2153
Note that we cannot just apply :meth:`hash_involution` here because
2154
this involution always returns the answer with respect to the
2155
same basis.
2156
2157
EXAMPLES::
2158
2159
sage: H = sage.algebras.iwahori_hecke_algebra.IwahoriHeckeAlgebra_nonstandard("A2")
2160
sage: s1,s2 = H.coxeter_group().simple_reflections()
2161
sage: T = H.T()
2162
sage: C = H.C()
2163
sage: T.to_C_basis(s1)
2164
v*T[1] + u
2165
sage: C(T(s1))
2166
v*C[1] + u
2167
sage: C(T( C[1] ))
2168
C[1]
2169
sage: C(T(s1*s2)+T(s1)+T(s2)+1)
2170
v^2*C[1,2] + (u*v+v)*C[1] + (u*v+v)*C[2] + (u^2+2*u+1)
2171
sage: C(T(s1*s2*s1))
2172
v^3*C[1,2,1] + u*v^2*C[1,2] + u*v^2*C[2,1] + u^2*v*C[1] + u^2*v*C[2] + u^3
2173
"""
2174
H = self.realization_of()
2175
q_w = (-H._q_prod)**w.length()
2176
return self.sum_of_terms((v, (-1)**v.length()*q_w*H._bar_on_coefficients(c))
2177
for (v,c) in self.to_Cp_basis(w))
2178
2179
class Cp(IwahoriHeckeAlgebra.Cp):
2180
r"""
2181
The Kazhdan-Lusztig `C^{\prime}`-basis for the generic Iwahori-Hecke
2182
algebra.
2183
"""
2184
@cached_method
2185
def to_T_basis(self, w):
2186
r"""
2187
Return `C^{\prime}_w` as a linear combination of `T`-basis
2188
elements.
2189
2190
EXAMPLES::
2191
2192
sage: H = sage.algebras.iwahori_hecke_algebra.IwahoriHeckeAlgebra_nonstandard("A3")
2193
sage: s1,s2,s3 = H.coxeter_group().simple_reflections()
2194
sage: T = H.T()
2195
sage: Cp = H.Cp()
2196
sage: Cp.to_T_basis(s1)
2197
(v^-1)*T[1] + (u^-1*v)
2198
sage: Cp.to_T_basis(s1*s2)
2199
(v^-2)*T[1,2] + (u^-1)*T[1] + (u^-1)*T[2] + (u^-2*v^2)
2200
sage: Cp.to_T_basis(s1*s2*s1)
2201
(v^-3)*T[1,2,1] + (u^-1*v^-1)*T[1,2] + (u^-1*v^-1)*T[2,1]
2202
+ (u^-2*v)*T[1] + (u^-2*v)*T[2] + (u^-3*v^3)
2203
sage: T(Cp(s1*s2*s1))
2204
(v^-3)*T[1,2,1] + (u^-1*v^-1)*T[1,2] + (u^-1*v^-1)*T[2,1]
2205
+ (u^-2*v)*T[1] + (u^-2*v)*T[2] + (u^-3*v^3)
2206
sage: T(Cp(s2*s1*s3*s2))
2207
(v^-4)*T[2,3,1,2] + (u^-1*v^-2)*T[1,2,1] + (u^-1*v^-2)*T[3,1,2]
2208
+ (u^-1*v^-2)*T[2,3,1] + (u^-1*v^-2)*T[2,3,2] + (u^-2)*T[1,2]
2209
+ (u^-2)*T[2,1] + (u^-2)*T[3,1] + (u^-2)*T[2,3]
2210
+ (u^-2)*T[3,2] + (u^-3*v^2)*T[1] + (u^-1+u^-3*v^2)*T[2]
2211
+ (u^-3*v^2)*T[3] + (u^-2*v^2+u^-4*v^4)
2212
"""
2213
A = self.realization_of()
2214
T = A.T()
2215
Ts = T.algebra_generators()
2216
2217
if w == A._W.one(): # the identity element of the Coxeter group
2218
return T.one()
2219
2220
s = w.first_descent()
2221
ws = w.apply_simple_reflection(s)
2222
2223
cpw_s = self.to_T_basis(ws) * A.v_inv *(Ts[s] - A._q2*T.one())
2224
2225
i = 1
2226
cmp_func = lambda x,y: index_cmp(x.leading_support(), y.leading_support())
2227
while i < len(cpw_s):
2228
(x,c) = sorted(cpw_s.terms(), cmp=cmp_func)[i].leading_item()
2229
mu=normalized_laurent_polynomial(A._base,c)[0,-x.length()] # the coefficient of v^-len(x)
2230
if mu!=0:
2231
cpw_s-=mu*self.to_T_basis(x)
2232
else:
2233
i+=1
2234
2235
return cpw_s
2236
2237
C_prime = Cp
2238
2239
class C(IwahoriHeckeAlgebra.C):
2240
r"""
2241
The Kazhdan-Lusztig `C`-basis for the generic Iwahori-Hecke algebra.
2242
"""
2243
@cached_method
2244
def to_T_basis(self, w):
2245
r"""
2246
Return `C_w` as a linear combination of `T`-basis elements.
2247
2248
EXAMPLES::
2249
2250
sage: H = sage.algebras.iwahori_hecke_algebra.IwahoriHeckeAlgebra_nonstandard("A3")
2251
sage: s1,s2,s3 = H.coxeter_group().simple_reflections()
2252
sage: T = H.T()
2253
sage: C = H.C()
2254
sage: C.to_T_basis(s1)
2255
(v^-1)*T[1] + (-u*v^-1)
2256
sage: C.to_T_basis(s1*s2)
2257
(v^-2)*T[1,2] + (-u*v^-2)*T[1] + (-u*v^-2)*T[2] + (u^2*v^-2)
2258
sage: C.to_T_basis(s1*s2*s1)
2259
(v^-3)*T[1,2,1] + (-u*v^-3)*T[1,2] + (-u*v^-3)*T[2,1]
2260
+ (u^2*v^-3)*T[1] + (u^2*v^-3)*T[2] + (-u^3*v^-3)
2261
sage: T(C(s1*s2*s1))
2262
(v^-3)*T[1,2,1] + (-u*v^-3)*T[1,2] + (-u*v^-3)*T[2,1]
2263
+ (u^2*v^-3)*T[1] + (u^2*v^-3)*T[2] + (-u^3*v^-3)
2264
sage: T(C(s2*s1*s3*s2))
2265
(v^-4)*T[2,3,1,2] + (-u*v^-4)*T[1,2,1] + (-u*v^-4)*T[3,1,2]
2266
+ (-u*v^-4)*T[2,3,1] + (-u*v^-4)*T[2,3,2] + (u^2*v^-4)*T[1,2]
2267
+ (u^2*v^-4)*T[2,1] + (u^2*v^-4)*T[3,1] + (u^2*v^-4)*T[2,3]
2268
+ (u^2*v^-4)*T[3,2] + (-u^3*v^-4)*T[1]
2269
+ (-u^3*v^-4-u*v^-2)*T[2] + (-u^3*v^-4)*T[3]
2270
+ (u^4*v^-4+u^2*v^-2)
2271
"""
2272
# Treat our index as an index for the C'-basis, convert to the T-basis and
2273
# then apply the Hecke involution to the result. This gives the
2274
# desired result because C_w = (-1)^{len(w)) \tau( C_w' ), where
2275
# \tau is the Hecke involution.
2276
return (-1)**w.length()*self.realization_of().Cp().to_T_basis(w).hash_involution()
2277
2278
def IwahoriHeckeAlgebraT(W, q1, q2=-1, base_ring=None, prefix="T"):
2279
"""
2280
TESTS::
2281
2282
sage: H = IwahoriHeckeAlgebraT("A2", 1)
2283
doctest:...: DeprecationWarning: this class is deprecated. Use IwahoriHeckeAlgebra().T instead
2284
See http://trac.sagemath.org/14261 for details.
2285
"""
2286
from sage.misc.superseded import deprecation
2287
deprecation(14261,'this class is deprecated. Use IwahoriHeckeAlgebra().T instead')
2288
if W not in CoxeterGroups():
2289
W = WeylGroup(W)
2290
if base_ring is None:
2291
base_ring = q1.parent()
2292
q2 = base_ring(q2)
2293
return IwahoriHeckeAlgebra(W, q1=q1, q2=q2, base_ring=base_ring).T(prefix=prefix)
2294
2295
from sage.structure.sage_object import register_unpickle_override
2296
register_unpickle_override('sage.algebras.iwahori_hecke_algebra',
2297
'IwahoriHeckeAlgebraT', IwahoriHeckeAlgebraT)
2298
2299
2300