Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/combinat/kazhdan_lusztig.py
4108 views
1
"""
2
Kazhdan-Lusztig Polynomials
3
"""
4
#*****************************************************************************
5
# Copyright (C) 2008 Daniel Bump <bump at match.stanford.edu>,
6
#
7
# Distributed under the terms of the GNU General Public License (GPL)
8
#
9
# http://www.gnu.org/licenses/
10
#*****************************************************************************
11
12
from sage.rings.all import is_Polynomial
13
from sage.functions.other import floor
14
from sage.misc.cachefunc import cached_method
15
from sage.rings.polynomial.laurent_polynomial import LaurentPolynomial_mpair
16
from sage.structure.sage_object import SageObject
17
18
class KazhdanLusztigPolynomial(SageObject):
19
def __init__(self, W, q, trace=False):
20
"""
21
A class for Kazhdan-Lusztig polynomials
22
23
INPUT:
24
25
- ``W`` - a Weyl Group.
26
- ``q`` - an indeterminate.
27
28
OPTIONAL:
29
30
- trace
31
32
The parent of q may be a PolynomialRing or a LaurentPolynomialRing.
33
34
Set trace=True in order to see intermediate results. This is fun
35
and instructive.
36
37
EXAMPLES ::
38
39
sage: W = WeylGroup("B3",prefix="s")
40
sage: [s1,s2,s3]=W.simple_reflections()
41
sage: R.<q>=LaurentPolynomialRing(QQ)
42
sage: KL=KazhdanLusztigPolynomial(W,q)
43
sage: KL.P(s2,s3*s2*s3*s1*s2)
44
q + 1
45
46
"""
47
self._coxeter_group = W
48
self._q = q
49
self._trace = trace
50
self._one = W.one()
51
self._base_ring = q.parent()
52
if is_Polynomial(q):
53
self._base_ring_type = "polynomial"
54
elif isinstance(q, LaurentPolynomial_mpair):
55
self._base_ring_type = "laurent"
56
else:
57
self._base_ring_type = "unknown"
58
59
@cached_method
60
def R(self, x, y):
61
"""
62
Returns the Kazhdan-Lusztig R polynomial.
63
64
EXAMPLES ::
65
66
sage: R.<q>=QQ[]
67
sage: W = WeylGroup("A2", prefix="s")
68
sage: [s1,s2]=W.simple_reflections()
69
sage: KL = KazhdanLusztigPolynomial(W, q)
70
sage: [KL.R(x,s2*s1) for x in [1,s1,s2,s1*s2]]
71
[q^2 - 2*q + 1, q - 1, q - 1, 0]
72
73
"""
74
if x == 1:
75
x = self._one
76
if y == 1:
77
y = self._one
78
if x == y:
79
return 1
80
if not x.bruhat_le(y):
81
return 0
82
if y.length() == 0:
83
if x.length() == 0:
84
return 1
85
else:
86
return 0
87
s = self._coxeter_group.simple_reflection(y.first_descent(side="left"))
88
if (s*x).length() < x.length():
89
ret = self.R(s*x,s*y)
90
if self._trace:
91
print " R(%s,%s)=%s"%(x, y, ret)
92
return ret
93
else:
94
ret = (self._q-1)*self.R(s*x,y)+self._q*self.R(s*x,s*y)
95
if self._trace:
96
print " R(%s,%s)=%s"%(x, y, ret)
97
return ret
98
99
@cached_method
100
def P(self, x, y):
101
"""
102
Returns the Kazhdan-Lusztig P polynomial. If the rank is large,
103
this runs slowly at first but speeds up as you do repeated calculations
104
due to the caching.
105
106
EXAMPLES ::
107
108
sage: R.<q>=QQ[]
109
sage: W = WeylGroup("A3", prefix="s")
110
sage: [s1,s2,s3]=W.simple_reflections()
111
sage: KL = KazhdanLusztigPolynomial(W, q)
112
sage: KL.P(s2,s2*s1*s3*s2)
113
q + 1
114
"""
115
if x == 1:
116
x = self._one
117
if y == 1:
118
y = self._one
119
if x == y:
120
return 1
121
if not x.bruhat_le(y):
122
return 0
123
if y.length() == 0:
124
if x.length() == 0:
125
return 1
126
else:
127
return 0
128
p = sum(-self.R(x,t)*self.P(t,y) for t in self._coxeter_group.bruhat_interval(x,y) if t != x)
129
tr = floor((y.length()-x.length()+1)/2)
130
try:
131
ret = p.truncate(tr)
132
except:
133
ret = laurent_polynomial_truncate(p, tr)
134
if self._trace:
135
print " P(%s,%s)=%s"%(x, y, ret)
136
return ret
137
138
def laurent_polynomial_truncate(p, n):
139
"""
140
Truncates the Laurent polynomial p, returning only terms
141
of degree <n, similar to the truncate method for polynomials.
142
143
EXAMPLES ::
144
145
sage: from sage.combinat.kazhdan_lusztig import laurent_polynomial_truncate
146
sage: P.<q> = LaurentPolynomialRing(QQ)
147
sage: laurent_polynomial_truncate((q+q^-1)^3+q^2*(q+q^-1)^4,3)
148
6*q^2 + 3*q + 4 + 3*q^-1 + q^-2 + q^-3
149
"""
150
pdict = p._dict()
151
dict = {}
152
for k in pdict:
153
if k[0] < n:
154
dict[k] = pdict[k]
155
return p.parent()(dict)
156
157
158
159
160