Path: blob/master/src/sage/algebras/iwahori_hecke_algebra.py
8818 views
"""1Iwahori-Hecke Algebras23AUTHORS:45- Daniel Bump, Nicolas Thiery (2010): Initial version67- Brant Jones, Travis Scrimshaw, Andrew Mathas (2013):8Moved into the category framework and implemented the9Kazhdan-Lusztig `C` and `C^{\prime}` bases10"""11#*****************************************************************************12# Copyright (C) 2013 Brant Jones <brant at math.jmu.edu>13# Daniel Bump <bump at match.stanford.edu>14# Nicolas M. Thiery <nthiery at users.sf.net>15#16# Distributed under the terms of the GNU General Public License (GPL)17# http://www.gnu.org/licenses/18#*****************************************************************************1920from sage.misc.abstract_method import abstract_method21from sage.misc.cachefunc import cached_method22from sage.misc.bindable_class import BindableClass23from sage.structure.parent import Parent24from sage.structure.unique_representation import UniqueRepresentation25from sage.structure.element import parent26from sage.categories.realizations import Realizations, Category_realization_of_parent27from sage.categories.all import AlgebrasWithBasis, FiniteDimensionalAlgebrasWithBasis, CoxeterGroups28from sage.rings.all import ZZ29from sage.rings.polynomial.laurent_polynomial_ring import LaurentPolynomialRing30from sage.rings.polynomial.polydict import ETuple31from sage.rings.arith import is_square32from sage.combinat.root_system.weyl_group import WeylGroup33from sage.combinat.family import Family34from sage.combinat.free_module import CombinatorialFreeModule, CombinatorialFreeModuleElement3536def normalized_laurent_polynomial(R, p):37r"""38Returns a normalized version of the (Laurent polynomial) ``p`` in the39ring ``R``.4041Various ring operations in ``sage`` return an element of the field of42fractions of the parent ring even though the element is "known" to belong to43the base ring. This function is a hack to recover from this. This occurs44somewhat haphazardly with Laurent polynomial rings::4546sage: R.<q>=LaurentPolynomialRing(ZZ)47sage: [type(c) for c in (q**-1).coefficients()]48[<type 'sage.rings.rational.Rational'>]4950It also happens in any ring when dividing by units::5152sage: type ( 3/1 )53<type 'sage.rings.rational.Rational'>54sage: type ( -1/-1 )55<type 'sage.rings.rational.Rational'>5657This function is a variation on a suggested workaround of Nils Bruin.5859EXAMPLES::6061sage: from sage.algebras.iwahori_hecke_algebra import normalized_laurent_polynomial62sage: type ( normalized_laurent_polynomial(ZZ, 3/1) )63<type 'sage.rings.integer.Integer'>64sage: R.<q>=LaurentPolynomialRing(ZZ)65sage: [type(c) for c in normalized_laurent_polynomial(R, q**-1).coefficients()]66[<type 'sage.rings.integer.Integer'>]67sage: R.<u,v>=LaurentPolynomialRing(ZZ,2)68sage: p=normalized_laurent_polynomial(R, 2*u**-1*v**-1+u*v)69sage: ui=normalized_laurent_polynomial(R, u^-1)70sage: vi=normalized_laurent_polynomial(R, v^-1)71sage: p(ui,vi)722*u*v + u^-1*v^-173sage: q= u+v+ui74sage: q(ui,vi)75u + v^-1 + u^-176"""77try:78return R({k:R._base(c) for k,c in p.dict().iteritems()})79except (AttributeError,TypeError):80return R(p)8182def index_cmp(x, y):83"""84Compare two term indices ``x`` and ``y`` by Bruhat order, then by word85length, and then by the generic comparison.8687EXAMPLES::8889sage: from sage.algebras.iwahori_hecke_algebra import index_cmp90sage: W = WeylGroup(['A',2,1])91sage: x = W.from_reduced_word([0,1])92sage: y = W.from_reduced_word([0,2,1])93sage: x.bruhat_le(y)94True95sage: index_cmp(x, y)96197"""98if x.bruhat_le(y) or x.length() < y.length():99return 1100if y.bruhat_le(x) or x.length() > y.length():101return -1102return cmp(x, y) # Fallback total ordering103104class IwahoriHeckeAlgebra(Parent, UniqueRepresentation):105r"""106Returns the Iwahori-Hecke algebra of the Coxeter group ``W``107with the specified parameters.108109INPUT:110111- ``W`` -- a Coxeter group or Cartan type112- ``q1`` -- a parameter113114OPTIONAL ARGUMENTS:115116- ``q2`` -- (default ``-1``) another parameter117- ``base_ring`` -- (default ``q1.parent()``) a ring containing ``q1``118and ``q2``119120The Iwahori-Hecke algebra [I64]_ is a deformation of the group algebra of121a Weyl group or, more generally, a Coxeter group. These algebras are122defined by generators and relations and they depend on a deformation123parameter `q`. Taking `q = 1`, as in the following example, gives a ring124isomorphic to the group algebra of the corresponding Coxeter group.125126Let `(W, S)` be a Coxeter system and let `R` be a commutative ring127containing elements `q_1` and `q_2`. Then the *Iwahori-Hecke algebra*128`H = H_{q_1,q_2}(W,S)` of `(W,S)` with parameters `q_1` and `q_2` is the129unital associative algebra with generators `\{T_s \mid s\in S\}` and130relations:131132.. MATH::133134\begin{aligned}135(T_s - q_1)(T_s - q_2) &= 0\\136T_r T_s T_r \cdots &= T_s T_r T_s \cdots,137\end{aligned}138139where the number of terms on either side of the second relations (the braid140relations) is the order of `rs` in the Coxeter group `W`, for `r,s \in S`.141142Iwahori-Hecke algebras are fundamental in many areas of mathematics,143ranging from the representation theory of Lie groups and quantum groups,144to knot theory and statistical mechanics. For more information see,145for example, [KL79]_, [HKP]_, [J87]_ and146:wikipedia:`Iwahori-Hecke_algebra`.147148.. RUBRIC:: Bases149150A reduced expression for an element `w \in W` is any minimal length151word `w = s_1 \cdots s_k`, with `s_i \in S`. If `w = s_1 \cdots s_k` is a152reduced expression for `w` then Matsumoto's Monoid Lemma implies that153`T_w = T_{s_1} \cdots T_{s_k}` depends on `w` and not on the choice of154reduced expressions. Moreover, `\{ T_w \mid w\in W \}` is a basis for the155Iwahori-Hecke algebra `H` and156157.. MATH::158159T_s T_w = \begin{cases}160T_{sw}, & \text{if } \ell(sw) = \ell(w)+1,\\161(q_1+q_2)T_w -q_1q_2 T_{sw}, & \text{if } \ell(sw) = \ell(w)-1.162\end{cases}163164The `T`-basis of `H` is implemented for any choice of parameters165``q_1`` and ``q_2``::166167sage: R.<u,v> = LaurentPolynomialRing(ZZ,2)168sage: H = IwahoriHeckeAlgebra('A3', u,v)169sage: T = H.T()170sage: T[1]171T[1]172sage: T[1,2,1] + T[2]173T[1,2,1] + T[2]174sage: T[1] * T[1,2,1]175(u+v)*T[1,2,1] + (-u*v)*T[2,1]176sage: T[1]^-1177(-u^-1*v^-1)*T[1] + (v^-1+u^-1)178179Working over the Laurent polynomial ring `Z[q^{\pm 1/2}]` Kazhdan and180Lusztig proved that there exist two distinguished bases181`\{ C^{\prime}_w \mid w \in W \}` and `\{ C_w \mid w \in W \}` of `H`182which are uniquely determined by the properties that they are invariant183under the bar involution on `H` and have triangular transitions matrices184with polynomial entries of a certain form with the `T`-basis;185see [KL79]_ for a precise statement.186187It turns out that the Kazhdan-Lusztig bases can be defined (by188specialization) in `H` whenever `-q_1 q_2` is a square in the base ring.189The Kazhdan-Lusztig bases are implemented inside `H` whenever `-q_1 q_2`190has a square root::191192sage: H = IwahoriHeckeAlgebra('A3', u^2,-v^2)193sage: T=H.T(); Cp= H.Cp(); C=H.C()194sage: T(Cp[1])195(u^-1*v^-1)*T[1] + (u^-1*v)196sage: T(C[1])197(u^-1*v^-1)*T[1] + (-u*v^-1)198sage: Cp(C[1])199Cp[1] + (-u*v^-1-u^-1*v)200sage: elt = Cp[2]*Cp[3]+C[1]; elt201Cp[2,3] + Cp[1] + (-u*v^-1-u^-1*v)202sage: c = C(elt); c203C[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)204sage: t = T(c); t205(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)206sage: Cp(t)207Cp[2,3] + Cp[1] + (-u*v^-1-u^-1*v)208sage: Cp(c)209Cp[2,3] + Cp[1] + (-u*v^-1-u^-1*v)210211The conversions to and from the Kazhdan-Lusztig bases are done behind the212scenes whenever the Kazhdan-Lusztig bases are well-defined. Once a suitable213Iwahori-Hecke algebra is defined they will work without further214intervention.215216For example, with the "standard parameters", so that217`(T_r-q^2)(T_r+1) = 0`::218219sage: R.<q> = LaurentPolynomialRing(ZZ)220sage: H = IwahoriHeckeAlgebra('A3', q^2)221sage: T=H.T(); Cp=H.Cp(); C=H.C()222sage: C(T[1])223q*C[1] + q^2224sage: elt = Cp(T[1,2,1]); elt225q^3*Cp[1,2,1] + (-q^2)*Cp[1,2] + (-q^2)*Cp[2,1] + q*Cp[1] + q*Cp[2] + (-1)226sage: C(elt)227q^3*C[1,2,1] + q^4*C[1,2] + q^4*C[2,1] + q^5*C[1] + q^5*C[2] + q^6228229With the "normalized presentation", so that `(T_r-q)(T_r+q^{-1}) = 0`::230231sage: R.<q> = LaurentPolynomialRing(ZZ)232sage: H = IwahoriHeckeAlgebra('A3', q, -q^-1)233sage: T=H.T(); Cp=H.Cp(); C=H.C()234sage: C(T[1])235C[1] + q236sage: elt = Cp(T[1,2,1]); elt237Cp[1,2,1] + (-q^-1)*Cp[1,2] + (-q^-1)*Cp[2,1] + (q^-2)*Cp[1] + (q^-2)*Cp[2] + (-q^-3)238sage: C(elt)239C[1,2,1] + q*C[1,2] + q*C[2,1] + q^2*C[1] + q^2*C[2] + q^3240241In the group algebra, so that `(T_r-1)(T_r+1) = 0`::242243sage: H = IwahoriHeckeAlgebra('A3', 1)244sage: T=H.T(); Cp=H.Cp(); C=H.C()245sage: C(T[1])246C[1] + 1247sage: Cp(T[1,2,1])248Cp[1,2,1] - Cp[1,2] - Cp[2,1] + Cp[1] + Cp[2] - 1249sage: C(_)250C[1,2,1] + C[1,2] + C[2,1] + C[1] + C[2] + 1251252On the other hand, if the Kazhdan-Lusztig bases are not well-defined (when253`-q_1 q_2` is not a square), attempting to use the Kazhdan-Lusztig bases254triggers an error::255256sage: R.<q>=LaurentPolynomialRing(ZZ)257sage: H = IwahoriHeckeAlgebra('A3', q)258sage: C=H.C()259Traceback (most recent call last):260...261ValueError: The Kazhdan_Lusztig bases are defined only when -q_1*q_2 is a square262263We give an example in affine type::264265sage: R.<v> = LaurentPolynomialRing(ZZ)266sage: H = IwahoriHeckeAlgebra(['A',2,1], v^2)267sage: T=H.T(); Cp=H.Cp(); C=H.C()268sage: C(T[1,0,2])269v^3*C[1,0,2] + v^4*C[1,0] + v^4*C[0,2] + v^4*C[1,2]270+ v^5*C[0] + v^5*C[2] + v^5*C[1] + v^6271sage: Cp(T[1,0,2])272v^3*Cp[1,0,2] + (-v^2)*Cp[1,0] + (-v^2)*Cp[0,2] + (-v^2)*Cp[1,2]273+ v*Cp[0] + v*Cp[2] + v*Cp[1] + (-1)274sage: T(C[1,0,2])275(v^-3)*T[1,0,2] + (-v^-1)*T[1,0] + (-v^-1)*T[0,2] + (-v^-1)*T[1,2]276+ v*T[0] + v*T[2] + v*T[1] + (-v^3)277sage: T(Cp[1,0,2])278(v^-3)*T[1,0,2] + (v^-3)*T[1,0] + (v^-3)*T[0,2] + (v^-3)*T[1,2]279+ (v^-3)*T[0] + (v^-3)*T[2] + (v^-3)*T[1] + (v^-3)280281REFERENCES:282283.. [I64] N. Iwahori, On the structure of a Hecke ring of a284Chevalley group over a finite field, J. Fac. Sci. Univ. Tokyo Sect.285I, 10 (1964), 215--236 (1964). :mathscinet:`MR0165016`286287.. [HKP] T. J. Haines, R. E. Kottwitz, A. Prasad,288Iwahori-Hecke Algebras, J. Ramanujan Math. Soc., 25 (2010), 113--145.289:arxiv:`0309168v3` :mathscinet:`MR2642451`290291.. [J87] V. Jones, Hecke algebra representations of braid groups and292link polynomials. Ann. of Math. (2) 126 (1987), no. 2, 335--388.293:doi:`10.2307/1971403` :mathscinet:`MR0908150`294295EXAMPLES:296297We start by creating a Iwahori-Hecke algebra together with the three bases298for these algebras that are currently supported::299300sage: R.<v> = LaurentPolynomialRing(QQ, 'v')301sage: H = IwahoriHeckeAlgebra('A3', v**2)302sage: T = H.T()303sage: C = H.C()304sage: Cp = H.Cp()305306It is also possible to define these three bases quickly using307the :meth:`inject_shorthands` method.308309Next we create our generators for the `T`-basis and do some basic310computations and conversions between the bases::311312sage: T1,T2,T3 = T.algebra_generators()313sage: T1 == T[1]314True315sage: T1*T2 == T[1,2]316True317sage: T1 + T2318T[1] + T[2]319sage: T1*T1320(v^2-1)*T[1] + v^2321sage: (T1 + T2)*T3 + T1*T1 - (v + v^-1)*T2322T[3,1] + T[2,3] + (v^2-1)*T[1] + (-v-v^-1)*T[2] + v^2323sage: Cp(T1)324v*Cp[1] + (-1)325sage: Cp((v^1 - 1)*T1*T2 - T3)326(v^3-v^2)*Cp[1,2] + (-v^2+v)*Cp[1] + (-v^2+v)*Cp[2] + (-v)*Cp[3] + v327sage: C(T1)328v*C[1] + v^2329sage: p = C(T2*T3 - v*T1); p330v^2*C[2,3] + (-v^2)*C[1] + v^3*C[2] + v^3*C[3] + (v^4-v^3)331sage: Cp(p)332v^2*Cp[2,3] + (-v^2)*Cp[1] + (-v)*Cp[2] + (-v)*Cp[3] + (v+1)333sage: Cp(T2*T3 - v*T1)334v^2*Cp[2,3] + (-v^2)*Cp[1] + (-v)*Cp[2] + (-v)*Cp[3] + (v+1)335336In addition to explicitly creating generators, we have two shortcuts to337basis elements. The first is by using elements of the underlying Coxeter338group, the other is by using reduced words::339340sage: s1,s2,s3 = H.coxeter_group().gens()341sage: T[s1*s2*s1*s3] == T[1,2,1,3]342True343sage: T[1,2,1,3] == T1*T2*T1*T3344True345346TESTS:347348We check the defining properties of the bases::349350sage: R.<v> = LaurentPolynomialRing(QQ, 'v')351sage: H = IwahoriHeckeAlgebra('A3', v**2)352sage: W = H.coxeter_group()353sage: T = H.T()354sage: C = H.C()355sage: Cp = H.Cp()356sage: T(Cp[1])357(v^-1)*T[1] + (v^-1)358sage: T(C[1])359(v^-1)*T[1] + (-v)360sage: C(Cp[1])361C[1] + (v+v^-1)362sage: Cp(C[1])363Cp[1] + (-v-v^-1)364sage: all(C[x] == C[x].bar() for x in W) # long time365True366sage: all(Cp[x] == Cp[x].bar() for x in W) # long time367True368sage: all(T(C[x]).bar() == T(C[x]) for x in W) # long time369True370sage: all(T(Cp[x]).bar() == T(Cp[x]) for x in W) # long time371True372sage: KL = KazhdanLusztigPolynomial(W, v)373sage: term = lambda x,y: (-1)^y.length() * v^(-2*y.length()) * KL.P(y, x).substitute(v=v^-2)*T[y]374sage: all(T(C[x]) == (-v)^x.length()*sum(term(x,y) for y in W) for x in W) # long time375True376sage: 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 time377True378379We check conversion between the bases for type `B_2` as well as some of380the defining properties::381382sage: H = IwahoriHeckeAlgebra(['B',2], v**2)383sage: W = H.coxeter_group()384sage: T = H.T()385sage: C = H.C()386sage: Cp = H.Cp()387sage: all(T[x] == T(C(T[x])) for x in W) # long time388True389sage: all(T[x] == T(Cp(T[x])) for x in W) # long time390True391sage: all(C[x] == C(T(C[x])) for x in W) # long time392True393sage: all(C[x] == C(Cp(C[x])) for x in W) # long time394True395sage: all(Cp[x] == Cp(T(Cp[x])) for x in W) # long time396True397sage: all(Cp[x] == Cp(C(Cp[x])) for x in W) # long time398True399sage: all(T(C[x]).bar() == T(C[x]) for x in W) # long time400True401sage: all(T(Cp[x]).bar() == T(Cp[x]) for x in W) # long time402True403sage: KL = KazhdanLusztigPolynomial(W, v)404sage: term = lambda x,y: (-1)^y.length() * v^(-2*y.length()) * KL.P(y, x).substitute(v=v^-2)*T[y]405sage: all(T(C[x]) == (-v)^x.length()*sum(term(x,y) for y in W) for x in W) # long time406True407sage: 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 time408True409410.. TODO::411412Implement multi-parameter Iwahori-Hecke algebras together with their413Kazhdan-Lusztig bases. That is, Iwahori-Hecke algebras with (possibly)414different parameters for each conjugacy class of simple reflections415in the underlying Coxeter group.416417.. TODO::418419When given "generic parameters" we should return the generic420Iwahori-Hecke algebra with these parameters and allow the user to421work inside this algebra rather than doing calculations behind the422scenes in a copy of the generic Iwahori-Hecke algebra. The main423problem is that it is not clear how to recognise when the424parameters are "generic".425"""426@staticmethod427def __classcall_private__(cls, W, q1, q2=-1, base_ring=None):428r"""429TESTS::430431sage: H = IwahoriHeckeAlgebra("A2", 1)432sage: H.coxeter_group() == WeylGroup("A2")433True434sage: H.cartan_type() == CartanType("A2")435True436sage: H._q2 == -1437True438sage: H2 = IwahoriHeckeAlgebra(WeylGroup("A2"), QQ(1), base_ring=ZZ)439sage: H is H2440True441"""442if W not in CoxeterGroups():443W = WeylGroup(W)444if base_ring is None:445base_ring = q1.parent()446else:447q1 = base_ring(q1)448q2 = base_ring(q2)449return super(IwahoriHeckeAlgebra, cls).__classcall__(cls, W, q1, q2, base_ring)450451def __init__(self, W, q1, q2, base_ring):452r"""453Initialize and return the two parameter Iwahori-Hecke algebra ``self``.454455EXAMPLES::456457sage: R.<q1,q2> = QQ[]458sage: H = IwahoriHeckeAlgebra("A2", q1, q2=q2, base_ring=Frac(R))459sage: TestSuite(H).run()460"""461self._W = W462self._cartan_type = W.cartan_type()463464self._q1 = q1465self._q2 = q2466467# Used when multiplying generators: minor speed-up as it avoids the468# need to constantly add and multiply the parameters when applying the469# quadratic relation: T^2 = (q1+q2)T - q1*q2470self._q_sum = q1+q2471self._q_prod = -q1*q2472473# If -q1*q2 is a square then it makes sense to talk of he Kazhdan-Lusztig474# basis of the Iwhaori-Hecke algebra. In this case we set475# self._root=\sqrt{q1*q2}. The Kazhdan-Lusztig bases will be computed in476# the generic case behind the scenes and then specialized to this # algebra.477is_Square, root = is_square(self._q_prod, root=True)478if is_Square:479# Attach the generic Hecke algebra and the basis change maps480self._root = root481self._generic_iwahori_hecke_algebra = IwahoriHeckeAlgebra_nonstandard(W)482self._shorthands = ['C', 'Cp', 'T']483else:484# Can we actually remove the bases C and Cp in this case?485self._root = None486self._shorthands = ['T']487488if W.is_finite():489self._category = FiniteDimensionalAlgebrasWithBasis(base_ring)490else:491self._category = AlgebrasWithBasis(base_ring)492Parent.__init__(self, base=base_ring, category=self._category.WithRealizations())493494self._is_generic=False # needed for initialisation of _KLHeckeBasis495496# The following is used by the bar involution = self._bar_on_coefficients497try:498self._inverse_base_ring_generators = { g: self.base_ring()(g).__pow__(-1)499for g in self.base_ring().variable_names()}500except TypeError:501self._inverse_base_ring_generators = {}502503def _repr_(self):504r"""505EXAMPLES::506507sage: R.<q1,q2> = QQ[]508sage: IwahoriHeckeAlgebra("A2", q1**2, q2**2, base_ring=Frac(R))509Iwahori-Hecke algebra of type A2 in q1^2,q2^2 over Fraction Field of Multivariate Polynomial Ring in q1, q2 over Rational Field510"""511return "Iwahori-Hecke algebra of type {} in {},{} over {}".format(512self._cartan_type._repr_(compact=True), self._q1, self._q2, self.base_ring())513514def _bar_on_coefficients(self, c):515r"""516Given a Laurent polynomial ``c`` return the Laurent polynomial obtained517by applying the (generic) bar involution to `c``. This is the ring518homomorphism of Laurent polynomial in `ZZ[u,u^{-1},v,v^{-1}]` which519sends `u` to `u^{-1}` and `v` to `v^{-1}.520521EXAMPLES::522523sage: R.<q>=LaurentPolynomialRing(ZZ)524sage: H = IwahoriHeckeAlgebra("A3",q^2)525sage: H._bar_on_coefficients(q)526q^-1527"""528return normalized_laurent_polynomial(self._base, c).substitute(**self._inverse_base_ring_generators)529530def cartan_type(self):531r"""532Return the Cartan type of ``self``.533534EXAMPLES::535536sage: IwahoriHeckeAlgebra("D4", 1).cartan_type()537['D', 4]538"""539return self._cartan_type540541def coxeter_group(self):542r"""543Return the Coxeter group of ``self``.544545EXAMPLES::546547sage: IwahoriHeckeAlgebra("B2", 1).coxeter_group()548Weyl Group of type ['B', 2] (as a matrix group acting on the ambient space)549"""550return self._W551552def a_realization(self):553r"""554Return a particular realization of ``self`` (the `T`-basis).555556EXAMPLES::557558sage: H = IwahoriHeckeAlgebra("B2", 1)559sage: H.a_realization()560Iwahori-Hecke algebra of type B2 in 1,-1 over Integer Ring in the T-basis561"""562return self.T()563564def q1(self):565"""566Return the parameter `q_1` of ``self``.567568EXAMPLES::569570sage: H = IwahoriHeckeAlgebra("B2", 1)571sage: H.q1()5721573"""574return self._q1575576def q2(self):577"""578Return the parameter `q_2` of ``self``.579580EXAMPLES::581582sage: H = IwahoriHeckeAlgebra("B2", 1)583sage: H.q2()584-1585"""586return self._q2587588class _BasesCategory(Category_realization_of_parent):589r"""590The category of bases of a Iwahori-Hecke algebra.591"""592def __init__(self, base):593r"""594Initialize the bases of a Iwahori-Hecke algebra.595596INPUT:597598- ``base`` -- a Iwahori-Hecke algebra599600TESTS::601602sage: H = IwahoriHeckeAlgebra("B2", 1)603sage: bases = H._BasesCategory()604sage: H.T() in bases605True606"""607Category_realization_of_parent.__init__(self, base)608609def super_categories(self):610r"""611The super categories of ``self``.612613EXAMPLES::614615sage: H = IwahoriHeckeAlgebra("B2", 1)616sage: bases = H._BasesCategory()617sage: bases.super_categories()618[Category of realizations of Iwahori-Hecke algebra of type B2 in 1,-1 over Integer Ring,619Category of finite dimensional algebras with basis over Integer Ring]620"""621return [Realizations(self.base()), self.base()._category]622623def _repr_(self):624r"""625Return the representation of ``self``.626627EXAMPLES::628629sage: H = IwahoriHeckeAlgebra("B2", 1)630sage: H._BasesCategory()631Category of bases of Iwahori-Hecke algebra of type B2 in 1,-1 over Integer Ring632"""633return "Category of bases of %s" % self.base()634635class ParentMethods:636r"""637This class collects code common to all the various bases. In most638cases, these are just default implementations that will get639specialized in a basis.640"""641def _repr_(self):642"""643Text representation of this basis of Iwahori-Hecke algebra.644645EXAMPLES::646647sage: H = IwahoriHeckeAlgebra("B2", 1)648sage: H.T()649Iwahori-Hecke algebra of type B2 in 1,-1 over Integer Ring in the T-basis650sage: H.C()651Iwahori-Hecke algebra of type B2 in 1,-1 over Integer Ring in the C-basis652sage: H.Cp()653Iwahori-Hecke algebra of type B2 in 1,-1 over Integer Ring in the Cp-basis654"""655return "%s in the %s-basis"%(self.realization_of(), self._basis_name)656657def __getitem__(self, i):658"""659Return the basis element indexed by ``i``.660661INPUT:662663- ``i`` -- either an element of the Coxeter group or a664reduced word665666.. WARNING::667668If `i`` is not a reduced expression then the basis element669indexed by the corresponding element of the algebra is670returned rather than the corresponding product of the671generators::672673sage: R.<v> = LaurentPolynomialRing(QQ, 'v')674sage: T = IwahoriHeckeAlgebra('A3', v**2).T()675sage: T[1,1] == T[1] * T[1]676False677678EXAMPLES::679680sage: H = IwahoriHeckeAlgebra("B2", 1)681sage: T = H.T()682sage: G = WeylGroup("B2")683sage: T[G.one()]6841685sage: T[G.simple_reflection(1)]686T[1]687sage: T[G.from_reduced_word([1,2,1])]688T[1,2,1]689sage: T[[]]6901691sage: T[1]692T[1]693sage: T[1,2,1]694T[1,2,1]695"""696W = self.realization_of().coxeter_group()697if i in ZZ:698return self(W.simple_reflection(i))699if i in W:700return self(i)701if i == []:702return self.one()703return self(W.from_reduced_word(i))704705def is_field(self, proof=True):706"""707Return whether this Iwahori-Hecke algebra is a field.708709EXAMPLES::710711sage: T = IwahoriHeckeAlgebra("B2", 1).T()712sage: T.is_field()713False714"""715return False716717def is_commutative(self):718"""719Return whether this Iwahori-Hecke algebra is commutative.720721EXAMPLES::722723sage: T = IwahoriHeckeAlgebra("B2", 1).T()724sage: T.is_commutative()725False726"""727return self.base_ring().is_commutative() \728and self.realization_of().coxeter_group().is_commutative()729730@cached_method731def one_basis(self):732r"""733Return the identity element in the Weyl group, as per734``AlgebrasWithBasis.ParentMethods.one_basis``.735736EXAMPLES::737738sage: H = IwahoriHeckeAlgebra("B2", 1)739sage: H.T().one_basis()740[1 0]741[0 1]742"""743return self.realization_of().coxeter_group().one()744745def index_set(self):746r"""747Return the index set of ``self``.748749EXAMPLES::750751sage: IwahoriHeckeAlgebra("B2", 1).T().index_set()752(1, 2)753"""754return self.realization_of().coxeter_group().index_set()755756@cached_method757def algebra_generators(self):758r"""759Return the generators.760761They do not have order two but satisfy a quadratic relation.762They coincide with the simple reflections in the Coxeter group763when `q_1 = 1` and `q_2 = -1`. In this special case,764the Iwahori-Hecke algebra is identified with the group algebra765of the Coxeter group.766767EXAMPLES:768769In the standard basis::770771sage: R.<q> = QQ[]772sage: H = IwahoriHeckeAlgebra("A3", q).T()773sage: T = H.algebra_generators(); T774Finite family {1: T[1], 2: T[2], 3: T[3]}775sage: T.list()776[T[1], T[2], T[3]]777sage: [T[i] for i in [1,2,3]]778[T[1], T[2], T[3]]779sage: T1,T2,T3 = H.algebra_generators()780sage: T1781T[1]782sage: H = IwahoriHeckeAlgebra(['A',2,1], q).T()783sage: T = H.algebra_generators(); T784Finite family {0: T[0], 1: T[1], 2: T[2]}785sage: T.list()786[T[0], T[1], T[2]]787sage: [T[i] for i in [0,1,2]]788[T[0], T[1], T[2]]789sage: [T0, T1, T2] = H.algebra_generators()790sage: T0791T[0]792793In the Kazhdan-Lusztig basis::794795sage: R = LaurentPolynomialRing(QQ, 'v')796sage: v = R.gen(0)797sage: H = IwahoriHeckeAlgebra('A5', v**2)798sage: C = H.C()799sage: C.algebra_generators()800Finite family {1: C[1], 2: C[2], 3: C[3], 4: C[4], 5: C[5]}801sage: C.algebra_generators().list()802[C[1], C[2], C[3], C[4], C[5]]803"""804return self.basis().keys().simple_reflections().map(self.monomial)805806def algebra_generator(self, i):807r"""808Return the `i`-th generator of ``self``.809810EXAMPLES:811812In the standard basis::813814sage: R.<q>=QQ[]815sage: H = IwahoriHeckeAlgebra("A3", q).T()816sage: [H.algebra_generator(i) for i in H.index_set()]817[T[1], T[2], T[3]]818819In the Kazhdan-Lusztig basis::820821sage: R = LaurentPolynomialRing(QQ, 'v')822sage: v = R.gen(0)823sage: H = IwahoriHeckeAlgebra('A5', v**2)824sage: C = H.C()825sage: [C.algebra_generator(i) for i in H.coxeter_group().index_set()]826[C[1], C[2], C[3], C[4], C[5]]827"""828return self.algebra_generators()[i]829830@abstract_method(optional=True)831def bar_on_basis(self, w):832"""833Return the bar involution on the basis element of ``self``834indexed by ``w``.835836EXAMPLES::837838sage: R.<v> = LaurentPolynomialRing(QQ)839sage: H = IwahoriHeckeAlgebra('A3', v**2)840sage: W = H.coxeter_group()841sage: s1,s2,s3 = W.simple_reflections()842sage: Cp = H.Cp()843sage: Cp.bar_on_basis(s1*s2*s1*s3)844Cp[1,2,3,1]845"""846847@abstract_method(optional=True)848def hash_involution_on_basis(self, w):849"""850Return the bar involution on the basis element of ``self``851indexed by ``w``.852853EXAMPLES::854855sage: R.<v> = LaurentPolynomialRing(QQ)856sage: H = IwahoriHeckeAlgebra('A3', v**2)857sage: W = H.coxeter_group()858sage: s1,s2,s3 = W.simple_reflections()859sage: Cp = H.Cp()860sage: C = H.C()861sage: C(Cp.hash_involution_on_basis(s1*s2*s1*s3))862C[1,2,3,1]863"""864865class ElementMethods:866def bar(self):867"""868Return the bar involution of ``self``.869870The bar involution `\overline{\phantom{x}}` is an antilinear871`\ZZ`-algebra involution defined by the identity on `\ZZ`,872sending `q^{1/2} \mapsto q^{-1/2}`, and `\overline{T_w} =873T_{w^{-1}}^{-1}`.874875REFERENCES:876877- :wikipedia:`Iwahori%E2%80%93Hecke_algebra#Canonical_basis`878879EXAMPLES:880881We first test on a single generator::882883sage: R.<q> = LaurentPolynomialRing(QQ)884sage: H = IwahoriHeckeAlgebra('A3', q)885sage: T = H.T()886sage: T1,T2,T3 = T.algebra_generators()887sage: T1.bar()888(q^-1)*T[1] + (-1+q^-1)889sage: T1.bar().bar() == T1890True891892Next on a multiple of generators::893894sage: b = (T1*T2*T1).bar(); b895(q^-3)*T[1,2,1]896+ (-q^-2+q^-3)*T[1,2]897+ (-q^-2+q^-3)*T[2,1]898+ (q^-1-2*q^-2+q^-3)*T[1]899+ (q^-1-2*q^-2+q^-3)*T[2]900+ (-1+2*q^-1-2*q^-2+q^-3)901sage: b.bar() == T1*T2*T1902True903904A sum::905906sage: s = T1 + T2907sage: b = s.bar(); b908(q^-1)*T[1] + (q^-1)*T[2] + (-2+2*q^-1)909sage: b.bar() == s910True911912A more complicated example::913914sage: p = T1*T2 + (1-q+q^-1)*T3 - q^3*T1*T3915sage: p.bar()916(q^-2)*T[1,2]917+ (-q^-5)*T[3,1]918+ (-q^-1+q^-2+q^-4-q^-5)*T[1]919+ (-q^-1+q^-2)*T[2]920+ (1+q^-1-q^-2+q^-4-q^-5)*T[3]921+ (-q+1-q^-3+2*q^-4-q^-5)922sage: p.bar().bar() == p923True924925This also works for arbitrary ``q1`` and ``q2``::926927sage: R.<q1,q2> = LaurentPolynomialRing(QQ)928sage: H = IwahoriHeckeAlgebra('A3', q1, q2=-q2)929sage: T = H.T()930sage: T1,T2,T3 = T.algebra_generators()931sage: p = T1*T3 + T2932sage: p.bar()933(q1^-2*q2^-2)*T[3,1]934+ (-q1^-1*q2^-2+q1^-2*q2^-1)*T[1]935+ (q1^-1*q2^-1)*T[2]936+ (-q1^-1*q2^-2+q1^-2*q2^-1)*T[3]937+ (-q2^-1+q1^-1+q2^-2-2*q1^-1*q2^-1+q1^-2)938sage: p.bar().bar() == p939True940941Next we have an example in the `C` basis::942943sage: R.<v> = LaurentPolynomialRing(QQ)944sage: H = IwahoriHeckeAlgebra('A3', v**2)945sage: C = H.C()946sage: p = C[1]*C[3] + C[2]947sage: p.bar()948C[3,1] + C[2]949sage: p.bar().bar() == p950True951952For the `C^{\prime}` basis as well::953954sage: R.<v> = LaurentPolynomialRing(QQ)955sage: H = IwahoriHeckeAlgebra('A3', v**2)956sage: Cp = H.Cp()957sage: p = Cp[1]*Cp[3] + Cp[2]958sage: p.bar()959Cp[3,1] + Cp[2]960961TESTS:962963We check that doing the computations explicitly in the `T`964basis gives the same results and with bar invariant965coefficients::966967sage: R.<v> = LaurentPolynomialRing(QQ)968sage: H = IwahoriHeckeAlgebra('A3', v**2)969sage: Cp = H.Cp()970sage: T = H.T()971sage: Cp(T(Cp[1,2,1])) == Cp[1,2,1]972True973sage: p = 4*Cp[1]*Cp[3] + (v^2 + v^-2 - 2)*Cp[2]974sage: Cp(T(p).bar()) == p975True976"""977B = self.parent()978if B.bar_on_basis is NotImplemented:979T = B.realization_of().T()980return B(T(self).bar())981H=B.realization_of()982return sum(H._bar_on_coefficients(c) * B.bar_on_basis(w) for (w,c) in self)983984def hash_involution(self):985r"""986Return the hash involution of ``self``.987988The hash involution `\alpha` is a `\ZZ`-algebra989involution of the Iwahori-Hecke algebra determined by990`q^{1/2} \mapsto q^{-1/2}`, and `T_w \mapsto -1^{\ell(w)}991(q_1 q_2)^{-\ell(w)} T_w`, for `w` an element of the992corresponding Coxeter group.993994This map is defined in [KL79]_ and it is used to995change between the `C` and `C^{\prime}` bases because996`\alpha(C_w) = (-1)^{\ell(w)} C_w'`.997998EXAMPLES::9991000sage: R.<v> = LaurentPolynomialRing(QQ)1001sage: H = IwahoriHeckeAlgebra('A3', v**2)1002sage: T = H.T()1003sage: T1,T2,T3 = T.algebra_generators()1004sage: elt = T1.hash_involution(); elt1005(-v^-2)*T[1]1006sage: elt.hash_involution()1007T[1]1008sage: elt = T1*T2 + (v^3 - v^-1 + 2)*T3*T1*T2*T31009sage: elt.hash_involution()1010(-v^-7+2*v^-8+v^-11)*T[1,2,3,2] + (v^-4)*T[1,2]1011sage: elt.hash_involution().hash_involution() == elt1012True10131014With the Kazhdan-Lusztig `C^{\prime}` basis::10151016sage: Cp = H.Cp()1017sage: p = Cp[1]*Cp[3] + Cp[2]1018sage: q = p.hash_involution(); q1019Cp[3,1] + (-v-v^-1)*Cp[1] + (-1)*Cp[2] + (-v-v^-1)*Cp[3] + (v^2+v+2+v^-1+v^-2)1020sage: q.hash_involution() == p1021True10221023With the Kazhdan-Lusztig `C` basis::10241025sage: C = H.C()1026sage: p = C[1]*C[3] + C[2]1027sage: q = p.hash_involution(); q1028C[3,1] + (v+v^-1)*C[1] + (-1)*C[2] + (v+v^-1)*C[3] + (v^2-v+2-v^-1+v^-2)1029sage: q.hash_involution() == p1030True1031"""1032B = self.parent()1033if B.hash_involution_on_basis is NotImplemented:1034T = B.realization_of().T()1035return B(T(self).hash_involution())10361037H = B.realization_of()1038return B(sum(H._bar_on_coefficients(c) * B.hash_involution_on_basis(w) for (w,c) in self))10391040def specialize_to(self, new_hecke, num_vars=2):1041r"""1042Return the element in the Iwahori-Hecke algebra ``new_hecke``1043with respect to the same basis which is obtained from ``self``1044by specializing the generic parameters in this algebra to the1045parameters of ``new_hecke``.10461047INPUT:10481049- ``new_hecke`` -- the Hecke algebra in specialized parameters1050- ``num_vars`` -- the number of variables to specialize10511052.. WARNING::10531054This is not always defined. In particular, the number of1055generators must match ``num_vars``10561057EXAMPLES::10581059sage: R.<a,b> = LaurentPolynomialRing(ZZ)1060sage: H = IwahoriHeckeAlgebra("A3", a^2, -b^2)1061sage: T = H.T()1062sage: elt = T[1,2,1] + 3*T[1] - a*b*T[3]1063sage: S.<q> = LaurentPolynomialRing(ZZ)1064sage: HS = IwahoriHeckeAlgebra("A3", q^2, -1)1065sage: selt = elt.specialize_to(HS); selt1066T[1,2,1] + 3*T[1] + q^2*T[3]1067sage: GA = IwahoriHeckeAlgebra("A3", 1, -1)1068sage: elt.specialize_to(GA)1069T[1,2,1] + 3*T[1] + T[3]10701071We need to specify that we are only specializing1072one argument::10731074sage: selt.specialize_to(GA)1075Traceback (most recent call last):1076...1077TypeError: number of arguments does not match the number of generators in parent.1078sage: selt.specialize_to(GA, 1)1079T[1,2,1] + 3*T[1] + T[3]1080"""1081hecke = self.parent().realization_of()1082q1 = new_hecke._q11083q2 = new_hecke._q21084new_basis = getattr(new_hecke, self.parent()._basis_name)()10851086# is there an easier way that this to covert the coefficients to1087# the correct base ring for new_hecke?1088if num_vars == 2:1089args = (q1, q2)1090elif num_vars == 1:1091args = (q1,)1092else:1093return new_basis._from_dict(dict( (w, new_hecke._base(c))1094for (w,c) in self ))10951096new_coeff = lambda c: new_hecke._base(c(args))1097return new_basis._from_dict(dict( (w, new_coeff(c)) for (w,c) in self ))10981099class _Basis(CombinatorialFreeModule, BindableClass):1100r"""1101Technical methods (i.e., not mathematical) that are inherited by each1102basis of the algebra. These methods cannot be defined in the category.1103"""1104def __init__(self, algebra, prefix=None):1105r"""1106Initialises a basis class for the Iwahori-Hecke algebra ``algebra``.1107Optionally, a ``prefix`` can be set which is used when printing the1108basis elements. The prefix defaults to ``self._basis-name``, which1109is the name of the basis class.11101111EXAMPLES::11121113sage: H = IwahoriHeckeAlgebra("G2",1)1114sage: t = H.T(prefix="t")1115sage: t[1]1116t[1]1117"""1118if prefix is None:1119self._prefix = self._basis_name1120else:1121self._prefix = prefix11221123CombinatorialFreeModule.__init__(self,1124algebra.base_ring(),1125algebra._W,1126category=algebra._BasesCategory(),1127monomial_cmp=index_cmp,1128prefix=self._prefix)11291130# This **must** match the name of the class in order for1131# specialize_to() to work1132_basis_name = None11331134def _repr_term(self, t):1135r"""1136Return the string representation of the term indexed by ``t``.11371138EXAMPLES::11391140sage: R.<q> = QQ[]1141sage: H = IwahoriHeckeAlgebra("A3", q)1142sage: W = H.coxeter_group()1143sage: H.T()._repr_term(W.from_reduced_word([1,2,3]))1144'T[1,2,3]'1145"""1146redword = t.reduced_word()1147if len(redword) == 0:1148return "1"1149return self._print_options['prefix'] + '[%s]'%','.join('%d'%i for i in redword)11501151def _latex_term(self, t):1152r"""1153Return latex for the term indexed by ``t``.11541155EXAMPLES::11561157sage: R.<v> = QQ[]1158sage: H = IwahoriHeckeAlgebra("A3", q1=v**2, q2=-1)1159sage: W = H.coxeter_group()1160sage: H.T()._latex_term(W.from_reduced_word([1,2,3]))1161'T_{1}T_{2}T_{3}'1162"""1163redword = t.reduced_word()1164if len(redword) == 0:1165return '1'1166return ''.join("%s_{%d}"%(self._print_options['prefix'], i) for i in redword)116711681169class T(_Basis):1170r"""1171The standard basis of Iwahori-Hecke algebra.11721173For every simple reflection `s_i` of the Coxeter group, there is a1174corresponding generator `T_i` of Iwahori-Hecke algebra. These1175are subject to the relations:11761177.. MATH::11781179(T_i - q_1) (T_i - q_2) = 011801181together with the braid relations:11821183.. MATH::11841185T_i T_j T_i \cdots = T_j T_i T_j \cdots,11861187where the number of terms on each of the two sides is the order of1188`s_i s_j` in the Coxeter group.11891190Weyl group elements form a basis of Iwahori-Hecke algebra `H`1191with the property that if `w_1` and `w_2` are Coxeter group elements1192such that `\ell(w_1 w_2) = \ell(w_1) + \ell(w_2)` then1193`T_{w_1 w_2} = T_{w_1} T_{w_2}`.11941195With the default value `q_2 = -1` and with `q_1 = q` the1196generating relation may be written1197`T_i^2 = (q-1) \cdot T_i + q \cdot 1` as in [I64]_.11981199EXAMPLES::12001201sage: H = IwahoriHeckeAlgebra("A3", 1)1202sage: T = H.T()1203sage: T1,T2,T3 = T.algebra_generators()1204sage: T1*T2*T3*T1*T2*T1 == T3*T2*T1*T3*T2*T31205True1206sage: w0 = T(H.coxeter_group().long_element())1207sage: w01208T[1,2,3,1,2,1]1209sage: T = H.T(prefix="s")1210sage: T.an_element()1211s[1,2,3,1,2,1] + 2*s[1,2,3,1,2] + 3*s[1,2,3,2,1] + s[1,2,3]12121213TESTS::12141215sage: R.<v> = LaurentPolynomialRing(QQ, 'v')1216sage: H = IwahoriHeckeAlgebra('A3', v**2)1217sage: W = H.coxeter_group()1218sage: T = H.T()1219sage: C = H.C()1220sage: Cp = H.Cp()1221sage: all(T(C(T[x])) == T[x] for x in W) # long time1222True1223sage: all(T(Cp(T[x])) == T[x] for x in W) # long time1224True12251226We check a property of the bar involution and `R`-polynomials::12271228sage: KL = KazhdanLusztigPolynomial(W, v)1229sage: 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 time1230True1231"""1232_basis_name = "T" # this is used, for example, by specialize_to and is the default prefix12331234def inverse_generator(self, i):1235r"""1236Return the inverse of the `i`-th generator, if it exists.12371238This method is only available if the Iwahori-Hecke algebra1239parameters ``q1`` and ``q2`` are both invertible. In this case,1240the algebra generators are also invertible and this method returns1241the inverse of ``self.algebra_generator(i)``.12421243EXAMPLES::12441245sage: P.<q1, q2>=QQ[]1246sage: F = Frac(P)1247sage: H = IwahoriHeckeAlgebra("A2", q1, q2=q2, base_ring=F).T()1248sage: H.base_ring()1249Fraction Field of Multivariate Polynomial Ring in q1, q2 over Rational Field1250sage: H.inverse_generator(1)1251-1/(q1*q2)*T[1] + ((q1+q2)/(q1*q2))1252sage: H = IwahoriHeckeAlgebra("A2", q1, base_ring=F).T()1253sage: H.inverse_generator(2)1254-(1/(-q1))*T[2] + ((q1-1)/(-q1))1255sage: P1.<r1, r2> = LaurentPolynomialRing(QQ)1256sage: H1 = IwahoriHeckeAlgebra("B2", r1, q2=r2, base_ring=P1).T()1257sage: H1.base_ring()1258Multivariate Laurent Polynomial Ring in r1, r2 over Rational Field1259sage: H1.inverse_generator(2)1260(-r1^-1*r2^-1)*T[2] + (r2^-1+r1^-1)1261sage: H2 = IwahoriHeckeAlgebra("C2", r1, base_ring=P1).T()1262sage: H2.inverse_generator(2)1263(r1^-1)*T[2] + (-1+r1^-1)1264"""1265A = self.realization_of()1266try:1267# This currently works better than ~(self._q1) if1268# self.base_ring() is a Laurent polynomial ring since it1269# avoids accidental coercion into a field of fractions.1270i1 = normalized_laurent_polynomial(A._base, A._q1.__pow__(-1))1271i2 = normalized_laurent_polynomial(A._base, A._q2.__pow__(-1))1272except Exception:1273raise ValueError("%s and %s must be invertible."%(A._q1, A._q2))1274return (-i1*i2)*self.algebra_generator(i)+(i1+i2)12751276@cached_method1277def inverse_generators(self):1278r"""1279Return the inverses of all the generators, if they exist.12801281This method is only available if ``q1`` and ``q2`` are invertible.1282In that case, the algebra generators are also invertible.12831284EXAMPLES::12851286sage: P.<q> = PolynomialRing(QQ)1287sage: F = Frac(P)1288sage: H = IwahoriHeckeAlgebra("A2", q, base_ring=F).T()1289sage: T1,T2 = H.algebra_generators()1290sage: U1,U2 = H.inverse_generators()1291sage: U1*T1,T1*U11292(1, 1)1293sage: P1.<q> = LaurentPolynomialRing(QQ)1294sage: H1 = IwahoriHeckeAlgebra("A2", q, base_ring=P1).T(prefix="V")1295sage: V1,V2 = H1.algebra_generators()1296sage: W1,W2 = H1.inverse_generators()1297sage: [W1,W2]1298[(q^-1)*V[1] + (-1+q^-1), (q^-1)*V[2] + (-1+q^-1)]1299sage: V1*W1, W2*V21300(1, 1)1301"""1302return Family(self.index_set(), self.inverse_generator)13031304def product_on_basis(self, w1, w2):1305r"""1306Return `T_{w_1} T_{w_2}`, where `w_1` and `w_2` are words in the1307Coxeter group.13081309EXAMPLES::13101311sage: R.<q> = QQ[]; H = IwahoriHeckeAlgebra("A2", q)1312sage: T = H.T()1313sage: s1,s2 = H.coxeter_group().simple_reflections()1314sage: [T.product_on_basis(s1,x) for x in [s1,s2]]1315[(q-1)*T[1] + q, T[1,2]]1316"""1317result = self.monomial(w1)1318for i in w2.reduced_word():1319result = self.product_by_generator(result, i)1320return result13211322def product_by_generator_on_basis(self, w, i, side="right"):1323r"""1324Return the product `T_w T_i` (resp. `T_i T_w`) if ``side`` is1325``'right'`` (resp. ``'left'``).13261327If the quadratic relation is `(T_i-u)(T_i-v) = 0`, then we have13281329.. MATH::13301331T_w T_i = \begin{cases}1332T_{ws_i} & \text{if } \ell(ws_i) = \ell(w) + 1, \\1333(u+v) T_{ws_i} - uv T_w & \text{if } \ell(w s_i) = \ell(w)-1.1334\end{cases}13351336The left action is similar.13371338INPUT:13391340- ``w`` -- an element of the Coxeter group1341- ``i`` -- an element of the index set1342- ``side`` -- ``'right'`` (default) or ``'left'``13431344EXAMPLES::13451346sage: R.<q> = QQ[]; H = IwahoriHeckeAlgebra("A2", q)1347sage: T = H.T()1348sage: s1,s2 = H.coxeter_group().simple_reflections()1349sage: [T.product_by_generator_on_basis(w, 1) for w in [s1,s2,s1*s2]]1350[(q-1)*T[1] + q, T[2,1], T[1,2,1]]1351sage: [T.product_by_generator_on_basis(w, 1, side="left") for w in [s1,s2,s1*s2]]1352[(q-1)*T[1] + q, T[1,2], (q-1)*T[1,2] + q*T[2]]1353"""1354wi = w.apply_simple_reflection(i, side = side)1355A = self.realization_of()1356if w.has_descent(i, side = side):1357# 10% faster than a plain addition on the example of #125281358return self.sum_of_terms(((w , A._q_sum), (wi, A._q_prod)), distinct=True)1359else:1360return self.monomial(wi)13611362def product_by_generator(self, x, i, side="right"):1363r"""1364Return `T_i \cdot x`, where `T_i` is the `i`-th generator. This is1365coded individually for use in ``x._mul_()``.13661367EXAMPLES::13681369sage: R.<q> = QQ[]; H = IwahoriHeckeAlgebra("A2", q).T()1370sage: T1, T2 = H.algebra_generators()1371sage: [H.product_by_generator(x, 1) for x in [T1,T2]]1372[(q-1)*T[1] + q, T[2,1]]1373sage: [H.product_by_generator(x, 1, side = "left") for x in [T1,T2]]1374[(q-1)*T[1] + q, T[1,2]]1375"""1376return self.linear_combination((self.product_by_generator_on_basis(w, i, side), c)1377for (w,c) in x)13781379def to_C_basis(self, w):1380r"""1381Return `T_w` as a linear combination of `C`-basis elements.13821383EXAMPLES::13841385sage: R = LaurentPolynomialRing(QQ, 'v')1386sage: v = R.gen(0)1387sage: H = IwahoriHeckeAlgebra('A2', v**2)1388sage: s1,s2 = H.coxeter_group().simple_reflections()1389sage: T = H.T()1390sage: C = H.C()1391sage: T.to_C_basis(s1)1392v*T[1] + v^21393sage: C(T(s1))1394v*C[1] + v^21395sage: C(v^-1*T(s1) - v)1396C[1]1397sage: C(T(s1*s2)+T(s1)+T(s2)+1)1398v^2*C[1,2] + (v^3+v)*C[1] + (v^3+v)*C[2] + (v^4+2*v^2+1)1399sage: C(T(s1*s2*s1))1400v^3*C[1,2,1] + v^4*C[1,2] + v^4*C[2,1] + v^5*C[1] + v^5*C[2] + v^61401"""1402H = self.realization_of()1403generic_T = H._generic_iwahori_hecke_algebra.T()1404return generic_T.to_C_basis(w).specialize_to(H)14051406def to_Cp_basis(self, w):1407r"""1408Return `T_w` as a linear combination of `C^{\prime}`-basis1409elements.14101411EXAMPLES::14121413sage: R.<v> = LaurentPolynomialRing(QQ)1414sage: H = IwahoriHeckeAlgebra('A2', v**2)1415sage: s1,s2 = H.coxeter_group().simple_reflections()1416sage: T = H.T()1417sage: Cp = H.Cp()1418sage: T.to_Cp_basis(s1)1419v*Cp[1] + (-1)1420sage: Cp(T(s1))1421v*Cp[1] + (-1)1422sage: Cp(T(s1)+1)1423v*Cp[1]1424sage: Cp(T(s1*s2)+T(s1)+T(s2)+1)1425v^2*Cp[1,2]1426sage: Cp(T(s1*s2*s1))1427v^3*Cp[1,2,1] + (-v^2)*Cp[1,2] + (-v^2)*Cp[2,1] + v*Cp[1] + v*Cp[2] + (-1)1428"""1429H = self.realization_of()1430generic_T = H._generic_iwahori_hecke_algebra.T()1431return generic_T.to_Cp_basis(w).specialize_to(H)14321433def bar_on_basis(self, w):1434"""1435Return the bar involution of `T_w`, which is `T^{-1}_{w^-1}`.14361437EXAMPLES::14381439sage: R.<v> = LaurentPolynomialRing(QQ)1440sage: H = IwahoriHeckeAlgebra('A3', v**2)1441sage: W = H.coxeter_group()1442sage: s1,s2,s3 = W.simple_reflections()1443sage: T = H.T()1444sage: b = T.bar_on_basis(s1*s2*s3); b1445(v^-6)*T[1,2,3]1446+ (-v^-4+v^-6)*T[1,2]1447+ (-v^-4+v^-6)*T[3,1]1448+ (-v^-4+v^-6)*T[2,3]1449+ (v^-2-2*v^-4+v^-6)*T[1]1450+ (v^-2-2*v^-4+v^-6)*T[2]1451+ (v^-2-2*v^-4+v^-6)*T[3]1452+ (-1+3*v^-2-3*v^-4+v^-6)1453sage: b.bar()1454T[1,2,3]1455"""1456return self.monomial(w.inverse()).inverse()14571458def hash_involution_on_basis(self, w):1459r"""1460Return the hash involution on the basis element ``self[w]``.14611462The hash involution `\alpha` is a `\ZZ`-algebra1463involution of the Iwahori-Hecke algebra determined by1464`q^{1/2} \mapsto q^{-1/2}`, and `T_w \mapsto -1^{\ell(w)}1465(q_1 q_2)^{-\ell(w)} T_w`, for `w` an element of the1466corresponding Coxeter group.14671468This map is defined in [KL79]_ and it is used to change between1469the `C` and `C^{\prime}` bases because1470`\alpha(C_w) = (-1)^{\ell(w)}C^{\prime}_w`.14711472This function is not intended to be called directly. Instead, use1473:meth:`hash_involution`.14741475EXAMPLES::14761477sage: R.<v> = LaurentPolynomialRing(QQ, 'v')1478sage: H = IwahoriHeckeAlgebra('A3', v**2)1479sage: T=H.T()1480sage: s=H.coxeter_group().simple_reflection(1)1481sage: T.hash_involution_on_basis(s)1482(-v^-2)*T[1]1483sage: T[s].hash_involution()1484(-v^-2)*T[1]1485sage: h = T[1]*T[2] + (v^3 - v^-1 + 2)*T[3,1,2,3]1486sage: h.hash_involution()1487(-v^-7+2*v^-8+v^-11)*T[1,2,3,2] + (v^-4)*T[1,2]1488sage: h.hash_involution().hash_involution() == h1489True1490"""1491H = self.realization_of()1492return (-H._q_prod)**(-w.length())*self.monomial(w)14931494class Element(CombinatorialFreeModuleElement):1495r"""1496A class for elements of an Iwahori-Hecke algebra in the `T` basis.14971498TESTS::14991500sage: R.<q> = QQ[]1501sage: H = IwahoriHeckeAlgebra("B3",q).T()1502sage: T1,T2,T3 = H.algebra_generators()1503sage: T1+2*T2*T315042*T[2,3] + T[1]1505sage: T1*T11506(q-1)*T[1] + q15071508sage: R.<q1,q2> = QQ[]1509sage: H = IwahoriHeckeAlgebra("A2", q1, q2=q2).T(prefix="x")1510sage: sum(H.algebra_generators())^21511x[1,2] + x[2,1] + (q1+q2)*x[1] + (q1+q2)*x[2] + (-2*q1*q2)15121513sage: H = IwahoriHeckeAlgebra("A2", q1, q2=q2).T(prefix="t")1514sage: t1,t2 = H.algebra_generators()1515sage: (t1-t2)^31516(q1^2-q1*q2+q2^2)*t[1] + (-q1^2+q1*q2-q2^2)*t[2]15171518sage: R.<q> = QQ[]1519sage: H = IwahoriHeckeAlgebra("G2", q).T()1520sage: [T1, T2] = H.algebra_generators()1521sage: T1*T2*T1*T2*T1*T2 == T2*T1*T2*T1*T2*T11522True1523sage: T1*T2*T1 == T2*T1*T21524False15251526sage: H = IwahoriHeckeAlgebra("A2", 1).T()1527sage: [T1,T2] = H.algebra_generators()1528sage: T1+T21529T[1] + T[2]15301531sage: -(T1+T2)1532-T[1] - T[2]1533sage: 1-T11534-T[1] + 115351536sage: T1.parent()1537Iwahori-Hecke algebra of type A2 in 1,-1 over Integer Ring in the T-basis1538"""1539def inverse(self):1540r"""1541Return the inverse if ``self`` is a basis element.15421543An element is a basis element if it is `T_w` where `w` is in1544the Weyl group. The base ring must be a field or Laurent1545polynomial ring. Other elements of the ring have inverses but1546the inverse method is only implemented for the basis elements.15471548EXAMPLES::15491550sage: R.<q> = LaurentPolynomialRing(QQ)1551sage: H = IwahoriHeckeAlgebra("A2", q).T()1552sage: [T1,T2] = H.algebra_generators()1553sage: x = (T1*T2).inverse(); x1554(q^-2)*T[2,1] + (-q^-1+q^-2)*T[1] + (-q^-1+q^-2)*T[2] + (1-2*q^-1+q^-2)1555sage: x*T1*T21556115571558TESTS:15591560We check some alternative forms of input for inverting1561an element::15621563sage: R.<q> = LaurentPolynomialRing(QQ)1564sage: H = IwahoriHeckeAlgebra("A2", q).T()1565sage: T1,T2 = H.algebra_generators()1566sage: ~(T1*T2)1567(q^-2)*T[2,1] + (-q^-1+q^-2)*T[1] + (-q^-1+q^-2)*T[2] + (1-2*q^-1+q^-2)1568sage: (T1*T2)^(-1)1569(q^-2)*T[2,1] + (-q^-1+q^-2)*T[1] + (-q^-1+q^-2)*T[2] + (1-2*q^-1+q^-2)1570"""1571if len(self) != 1:1572raise NotImplementedError("inverse only implemented for basis elements (monomials in the generators)"%self)1573H = self.parent()1574w = self.support_of_term()15751576return H.prod(H.inverse_generator(i) for i in reversed(w.reduced_word()))15771578__invert__ = inverse15791580standard = T15811582class _KLHeckeBasis(_Basis):1583r"""1584Abstract class for the common methods for the Kazhdan-Lusztig `C` and1585`C^{\prime}` bases.1586"""1587def __init__(self, IHAlgebra, prefix=None):1588r"""1589Returns the Kazhdan-Lusztig basis of the Iwahori-Hecke algebra1590``IHAlgebra``.15911592EXAMPLES::15931594sage: R.<v> = LaurentPolynomialRing(QQ)1595sage: H = IwahoriHeckeAlgebra('A3', v**2)1596sage: Cp = H.Cp()1597sage: C = H.C()1598"""1599if IHAlgebra._root is None:1600raise ValueError('The Kazhdan_Lusztig bases are defined only when -q_1*q_2 is a square')16011602if IHAlgebra._is_generic:1603klbasis=IwahoriHeckeAlgebra_nonstandard._KLHeckeBasis1604else:1605klbasis=IwahoriHeckeAlgebra._KLHeckeBasis1606super(klbasis, self).__init__(IHAlgebra, prefix)16071608# Define conversion from the KL-basis to the T-basis via1609# specialization from the generic Hecke algebra1610self.module_morphism(self.to_T_basis, codomain=IHAlgebra.T(), category=self.category()1611).register_as_coercion()16121613# ...and from the T_basis to the KL-basis.1614T = IHAlgebra.T()1615T.module_morphism(getattr(T, 'to_{}_basis'.format(self._basis_name)),1616codomain=self, category=self.category()1617).register_as_coercion()16181619def product_on_basis(self, w1, w2):1620r"""1621Return the product of the two Kazhdan-Lusztig basis elements1622indexed by ``w1`` and ``w2``. The computation is actually done by1623converting to the `T`-basis, multiplying and then converting back.16241625EXAMPLES::16261627sage: R = LaurentPolynomialRing(QQ, 'v')1628sage: v = R.gen(0)1629sage: H = IwahoriHeckeAlgebra('A2', v**2)1630sage: s1,s2 = H.coxeter_group().simple_reflections()1631sage: [H.Cp().product_on_basis(s1,x) for x in [s1,s2]]1632[(v+v^-1)*Cp[1], Cp[1,2]]1633sage: [H.C().product_on_basis(s1,x) for x in [s1,s2]]1634[(-v-v^-1)*C[1], C[1,2]]1635"""1636return self(self.to_T_basis(w1) * self.to_T_basis(w2))16371638def bar_on_basis(self, w):1639r"""1640Return the bar involution on the Kazhdan-Lusztig basis element1641indexed by ``w``. By definition, all Kazhdan-Lusztig basis elements1642are fixed by the bar involution.16431644EXAMPLES::16451646sage: R.<v> = LaurentPolynomialRing(QQ)1647sage: H = IwahoriHeckeAlgebra('A3', v**2)1648sage: W = H.coxeter_group()1649sage: s1,s2,s3 = W.simple_reflections()1650sage: Cp = H.Cp()1651sage: Cp.bar_on_basis(s1*s2*s1*s3)1652Cp[1,2,3,1]1653"""1654return self.monomial(w)16551656def to_T_basis(self, w):1657r"""1658Returns the Kazhdan-Lusztig basis elememt ``self[w]`` as a linear1659combination of ``T``-bais elements.16601661EXAMPLES::16621663sage: H=IwahoriHeckeAlgebra("A3",1); Cp=H.Cp(); C=H.C()1664sage: s=H.coxeter_group().simple_reflection(1)1665sage: C.to_T_basis(s)1666T[1] - 11667sage: Cp.to_T_basis(s)1668T[1] + 11669"""1670H = self.realization_of()1671generic_KL = getattr(H._generic_iwahori_hecke_algebra, self._basis_name)()1672return generic_KL.to_T_basis(w).specialize_to(H)16731674class Cp(_KLHeckeBasis):1675r"""1676The `C^{\prime}` Kazhdan-Lusztig basis of Iwahori-Hecke algebra.16771678Assuming the standard quadratic relations of `(T_r-q)(T_r+1)=0`, for1679every element `w` in the Coxeter group, there is a unique element1680`C^{\prime}_w` in the Iwahori-Hecke algebra which is uniquely determined1681by the two properties:16821683.. MATH::16841685\begin{aligned}1686\overline{ C^{\prime}_w } &= C^{\prime}_w\\1687C^{\prime}_w &= q^{-\ell(w)/2}1688\sum_{v \leq w} P_{v,w}(q) T_v1689\end{aligned}16901691where `\leq` is the Bruhat order on the underlying Coxeter group and1692`P_{v,w}(q) \in \ZZ[q,q^{-1}]` are polynomials in `\ZZ[q]` such that1693`P_{w,w}(q) = 1` and if `v < w` then `\deg P_{v,w}(q) \leq1694\frac{1}{2}(\ell(w)-\ell(v)-1)`.16951696More generally, if the quadratic relations are of the form1697(T_s-q_1)(T_s-q_2)=0` and `\sqrt{-q_1q_2}` exists then for a simple1698reflection `s` then the corresponding Kazhdan-Lusztig basis element is:16991700.. MATH::17011702C^{\prime}_s = (-q_1 q_2)^{-1/2} (T_s + 1).17031704See [KL79]_ for more details.17051706EXAMPLES::17071708sage: R = LaurentPolynomialRing(QQ, 'v')1709sage: v = R.gen(0)1710sage: H = IwahoriHeckeAlgebra('A5', v**2)1711sage: W = H.coxeter_group()1712sage: s1,s2,s3,s4,s5 = W.simple_reflections()1713sage: T = H.T()1714sage: Cp = H.Cp()1715sage: T(s1)**21716(v^2-1)*T[1] + v^21717sage: T(Cp(s1))1718(v^-1)*T[1] + (v^-1)1719sage: T(Cp(s1)*Cp(s2)*Cp(s1))1720(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)17211722::17231724sage: R = LaurentPolynomialRing(QQ, 'v')1725sage: v = R.gen(0)1726sage: H = IwahoriHeckeAlgebra('A3', v**2)1727sage: W = H.coxeter_group()1728sage: s1,s2,s3 = W.simple_reflections()1729sage: Cp = H.Cp()1730sage: Cp(s1*s2*s1)1731Cp[1,2,1]1732sage: Cp(s1)**21733(v+v^-1)*Cp[1]1734sage: Cp(s1)*Cp(s2)*Cp(s1)1735Cp[1,2,1] + Cp[1]1736sage: Cp(s1)*Cp(s2)*Cp(s3)*Cp(s1)*Cp(s2) # long time1737Cp[1,2,3,1,2] + Cp[1,2,1] + Cp[3,1,2]17381739TESTS::17401741sage: R.<v> = LaurentPolynomialRing(QQ, 'v')1742sage: H = IwahoriHeckeAlgebra('A3', v**2)1743sage: W = H.coxeter_group()1744sage: T = H.T()1745sage: C = H.C()1746sage: Cp = H.Cp()1747sage: all(Cp(T(Cp[x])) == Cp[x] for x in W) # long time1748True1749sage: all(Cp(C(Cp[x])) == Cp[x] for x in W) # long time1750True1751"""1752_basis_name = 'Cp' # this is used, for example, by specialize_to and is the default prefix17531754def hash_involution_on_basis(self, w):1755r"""1756Return the effect of applying the hash involution to the basis1757element ``self[w]``.17581759This function is not intended to be called directly. Instead, use1760:meth:`hash_involution`.17611762EXAMPLES::17631764sage: R.<v> = LaurentPolynomialRing(QQ, 'v')1765sage: H = IwahoriHeckeAlgebra('A3', v**2)1766sage: Cp=H.Cp()1767sage: s=H.coxeter_group().simple_reflection(1)1768sage: Cp.hash_involution_on_basis(s)1769(-1)*Cp[1] + (v+v^-1)1770sage: Cp[s].hash_involution()1771(-1)*Cp[1] + (v+v^-1)1772"""1773return (-1)**w.length()*self( self.realization_of().C().monomial(w) )17741775C_prime = Cp17761777class C(_KLHeckeBasis):1778r"""1779The Kazhdan-Lusztig `C`-basis of Iwahori-Hecke algebra.17801781Assuming the standard quadratic relations of `(T_r-q)(T_r+1)=0`, for1782every element `w` in the Coxeter group, there is a unique element1783`C_w` in the Iwahori-Hecke algebra which is uniquely determined1784by the two properties:17851786.. MATH::17871788\begin{aligned}1789\overline{C_w} &= C_w \\1790C_w &= (-1)^{\ell(w)} q^{\ell(w)/2}1791\sum_{v \leq w} (-q)^{-\ell(v)}\overline{P_{v,w}(q)} T_v1792\end{aligned}17931794where `\leq` is the Bruhat order on the underlying Coxeter group and1795`P_{v,w}(q)\in\ZZ[q,q^{-1}]` are polynomials in `\ZZ[q]` such that1796`P_{w,w}(q) = 1` and if `v < w` then1797`\deg P_{v,w}(q) \leq \frac{1}{2}(\ell(w) - \ell(v) - 1)`.17981799More generally, if the quadratic relations are of the form1800(T_s-q_1)(T_s-q_2)=0` and `\sqrt{-q_1q_2}` exists then for a simple1801reflection `s` then the corresponding Kazhdan-Lusztig basis element is:18021803.. MATH::18041805C_s = (-q_1 q_2)^{1/2} (1 - (-q_1 q_2)^{-1/2} T_s).18061807This is related to the `C^{\prime}` Kazhdan-Lusztig basis by `C_i =1808-\alpha(C_i^{\prime})` where `\alpha` is the `\ZZ`-linear Hecke1809involution defined by `q^{1/2} \mapsto q^{-1/2}` and `\alpha(T_i) =1810-(q_1 q_2)^{-1/2} T_i`.18111812See [KL79]_ for more details.18131814EXAMPLES::18151816sage: R.<v> = LaurentPolynomialRing(QQ)1817sage: H = IwahoriHeckeAlgebra('A5', v**2)1818sage: W = H.coxeter_group()1819sage: s1,s2,s3,s4,s5 = W.simple_reflections()1820sage: T = H.T()1821sage: C = H.C()1822sage: T(s1)**21823(v^2-1)*T[1] + v^21824sage: T(C(s1))1825(v^-1)*T[1] + (-v)1826sage: T(C(s1)*C(s2)*C(s1))1827(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)18281829::18301831sage: R.<v> = LaurentPolynomialRing(QQ)1832sage: H = IwahoriHeckeAlgebra('A3', v**2)1833sage: W = H.coxeter_group()1834sage: s1,s2,s3 = W.simple_reflections()1835sage: C = H.C()1836sage: C(s1*s2*s1)1837C[1,2,1]1838sage: C(s1)**21839(-v-v^-1)*C[1]1840sage: C(s1)*C(s2)*C(s1)1841C[1,2,1] + C[1]18421843TESTS::18441845sage: R.<v> = LaurentPolynomialRing(QQ, 'v')1846sage: H = IwahoriHeckeAlgebra('A3', v**2)1847sage: W = H.coxeter_group()1848sage: T = H.T()1849sage: C = H.C()1850sage: Cp = H.Cp()1851sage: all(C(T(C[x])) == C[x] for x in W) # long time1852True1853sage: all(C(Cp(C[x])) == C[x] for x in W) # long time1854True18551856Check the defining property between `C` and `C^{\prime}`::18571858sage: T(C[1])1859(v^-1)*T[1] + (-v)1860sage: -T(Cp[1]).hash_involution()1861(v^-1)*T[1] + (-v)1862sage: T(Cp[1] + Cp[2]).hash_involution()1863(-v^-1)*T[1] + (-v^-1)*T[2] + 2*v1864sage: -T(C[1] + C[2])1865(-v^-1)*T[1] + (-v^-1)*T[2] + 2*v1866sage: Cp(-C[1].hash_involution())1867Cp[1]1868sage: Cp(-C[1,2,3].hash_involution())1869Cp[1,2,3]1870sage: Cp(C[1,2,1,3].hash_involution())1871Cp[1,2,3,1]1872sage: all(C((-1)**x.length()*Cp[x].hash_involution()) == C[x] for x in W) # long time1873True1874"""1875_basis_name = "C" # this is used, for example, by specialize_to and is the default prefix18761877def hash_involution_on_basis(self, w):1878r"""1879Return the effect of applying the hash involution to the basis1880element ``self[w]``.18811882This function is not intended to be called directly. Instead, use1883:meth:`hash_involution`.18841885EXAMPLES::18861887sage: R.<v> = LaurentPolynomialRing(QQ, 'v')1888sage: H = IwahoriHeckeAlgebra('A3', v**2)1889sage: C=H.C()1890sage: s=H.coxeter_group().simple_reflection(1)1891sage: C.hash_involution_on_basis(s)1892(-1)*C[1] + (-v-v^-1)1893sage: C[s].hash_involution()1894(-1)*C[1] + (-v-v^-1)1895"""1896return (-1)**w.length()*self( self.realization_of().Cp().monomial(w) )18971898# This **must** have the same basis classes as the IwahoriHeckeAlgebra class1899# with the same name and they should inherit from the respecitive basis class1900class IwahoriHeckeAlgebra_nonstandard(IwahoriHeckeAlgebra):1901r"""1902This is a class which is used behind the scenes by1903:class:`IwahoriHeckeAlgebra` to compute the Kazhdan-Lusztig bases. It is1904not meant to be used directly. It implements the slightly idiosyncratic1905(but convenient) Iwahori-Hecke algebra with two parameters which is1906defined over the Laurent polynomial ring `\ZZ[u,u^{-1},v,v^{-1}]` in1907two variables and has quadratic relations:19081909.. MATH::19101911(T_r - u)(T_r + v^2/u) = 0.19121913The point of these relations is that the product of the two parameters is1914`v^2` which is a square in `\ZZ[u,u^{-1},v,v^{-1}]`. Consequently, the1915Kazhdan-Lusztig bases are defined for this algebra.19161917More generally, if we have a Iwahori-Hecke algebra with two parameters1918which has quadratic relations of the form:19191920.. MATH::19211922(T_r - q_1)(T_r - q_2) = 019231924where `-q_1 q_2` is a square then the Kazhdan-Lusztig bases are1925well-defined for this algebra. Moreover, these bases be computed by1926specialization from the generic Iwahori-Hecke algebra using the1927specialization which sends `u \mapsto q_1` and `v \mapsto \sqrt{-q_1 q_2}`,1928so that `v^2 / u \mapsto -q_2`.19291930For example, if `q_1 = q = Q^2` and `q_2 = -1` then `u \mapsto q` and1931`v \mapsto \sqrt{q} = Q`; this is the standard presentation of the1932Iwahori-Hecke algebra with `(T_r - q)(T_r + 1) = 0`. On the other hand,1933when `q_1 = q` and `q_2 = -q^{-1}` then `u \mapsto q` and `v \mapsto 1`.1934This is the normalized presentation with `(T_r - v)(T_r + v^{-1}) = 0`.19351936.. WARNING::19371938This class uses non-standard parameters for the Iwahori-Hecke algebra1939and are related to the standard parameters by an outer automorphism1940that is non-trivial on the `T`-basis.1941"""1942@staticmethod1943def __classcall_private__(cls, W):1944r"""1945TESTS::19461947sage: H1 = sage.algebras.iwahori_hecke_algebra.IwahoriHeckeAlgebra_nonstandard("A2")1948sage: H2 = sage.algebras.iwahori_hecke_algebra.IwahoriHeckeAlgebra_nonstandard(WeylGroup("A2"))1949sage: H1 is H21950True1951"""1952if W not in CoxeterGroups():1953W = WeylGroup(W)1954return super(IwahoriHeckeAlgebra_nonstandard, cls).__classcall__(cls,W)19551956def __init__(self, W):1957r"""1958EXAMPLES::19591960sage: H = sage.algebras.iwahori_hecke_algebra.IwahoriHeckeAlgebra_nonstandard("A2")1961sage: TestSuite(H).run()1962"""1963self._W = W1964self._cartan_type = W.cartan_type()19651966base_ring = LaurentPolynomialRing(ZZ, 'u,v')1967u,v = base_ring.gens()19681969# We don't want to call IwahoriHeckeAlgebra.__init__ because this would1970# try and attach a generic Hecke algebra to this algebra leading to1971# an infinite loop.1972self._q1 = u1973self._q2 = normalized_laurent_polynomial(base_ring, -v**2*u**-1)1974self._root = v19751976# Used when multiplying generators: minor speed-up as it avoids the1977# need to constantly add and multiply the parameters when applying the1978# quadratic relation: T^2 = (q1+q2)T - q1*q21979self._q_sum = normalized_laurent_polynomial(base_ring, self._q1+self._q2)1980self._q_prod = normalized_laurent_polynomial(base_ring, -self._q1*self._q2)19811982self.u_inv = normalized_laurent_polynomial(base_ring, u**-1)1983self.v_inv = normalized_laurent_polynomial(base_ring, v**-1)19841985self._shorthands = ['C', 'Cp', 'T']19861987if W.is_finite():1988self._category = FiniteDimensionalAlgebrasWithBasis(base_ring)1989else:1990self._category = AlgebrasWithBasis(base_ring)1991Parent.__init__(self, base=base_ring, category=self._category.WithRealizations())1992self._is_generic = True # needed for initialising _KLHeckeBasis19931994def _repr_(self):1995r"""1996EXAMPLES::19971998sage: sage.algebras.iwahori_hecke_algebra.IwahoriHeckeAlgebra_nonstandard("A2")1999A generic Iwahori-Hecke algebra of type A2 in u,-u^-1*v^2 over2000Multivariate Laurent Polynomial Ring in u, v over Integer Ring2001"""2002return "A generic Iwahori-Hecke algebra of type {} in {},{} over {}".format(2003self._cartan_type._repr_(compact=True), self._q1, self._q2, self.base_ring())20042005def _bar_on_coefficients(self, c):2006r"""2007Given a Laurent polynomial ``c`` return the Laurent polynomial obtained2008by applying the (generic) bar involution to `c``. This is the ring2009homomorphism of Laurent polynomial in `ZZ[u,u^{-1},v,v^{-1}]` which2010sends `u` to `u^{-1}` and `v` to `v^{-1}.20112012EXAMPLES::20132014sage: R.<q>=LaurentPolynomialRing(ZZ)2015sage: H=IwahoriHeckeAlgebra("A3",q^2)2016sage: GH=H._generic_iwahori_hecke_algebra2017sage: GH._bar_on_coefficients(GH.u_inv)2018u2019sage: GH._bar_on_coefficients(GH.v_inv)2020v2021"""2022return normalized_laurent_polynomial(self._base,c)(self.u_inv,self.v_inv)20232024class _BasesCategory(IwahoriHeckeAlgebra._BasesCategory):2025"""2026Category of bases for a generic Iwahori-Hecke algebra.2027"""2028def super_categories(self):2029r"""2030The super categories of ``self``.20312032EXAMPLES::20332034sage: H = sage.algebras.iwahori_hecke_algebra.IwahoriHeckeAlgebra_nonstandard("B2")2035sage: H._BasesCategory().super_categories()2036[Category of bases of A generic Iwahori-Hecke algebra of type B2 in u,-u^-1*v^2 over2037Multivariate Laurent Polynomial Ring in u, v over Integer Ring]2038"""2039return [IwahoriHeckeAlgebra._BasesCategory(self.base())]20402041class ElementMethods:2042def specialize_to(self, new_hecke):2043r"""2044Return the element in the Iwahori-Hecke algebra ``new_hecke``2045with respect to the same basis which is obtained from ``self``2046by specializing the generic parameters in this algebra to the2047parameters of ``new_hecke``.20482049The generic Iwahori-Hecke algebra is defined over2050`\ZZ[u^\pm, v^\pm]` and has parameters ``u`` and2051``-v^2/u``. The specialization map sends ``u`` to2052``new_hecke._q1`` and ``v`` to ``new_hecke._root`` which is2053thesquare root of ``-new_hecke._q1*new_hecke._q2``, so2054`-v^2/u` is sent to ``new_hecke._q2``.20552056This function is not intended to be called directly. Rather it2057is called behind the scenes to convert between the2058Kazhdan-Lusztig and standard bases of the Iwahori-Hecke2059algebras.20602061EXAMPLES::20622063sage: R.<a,b>=LaurentPolynomialRing(ZZ,2)2064sage: H=IwahoriHeckeAlgebra("A3",a^2,-b^2)2065sage: GH=H._generic_iwahori_hecke_algebra2066sage: GH.T()(GH.C()[1])2067(v^-1)*T[1] + (-u*v^-1)2068sage: ( GH.T()(GH.C()[1]) ).specialize_to(H)2069(a^-1*b^-1)*T[1] + (-a*b^-1)2070sage: GH.C()( GH.T()[1] )2071v*C[1] + u2072sage: GH.C()( GH.T()[1] ).specialize_to(H)2073a*b*C[1] + a^22074sage: H.C()( H.T()[1] )2075a*b*C[1] + a^22076"""2077hecke = self.parent().realization_of()2078q1 = new_hecke._q12079root = new_hecke._root2080# is there an easier way that this to covert the coefficients to2081# the correct base ring for new_hecke?2082new_coeff = lambda c: new_hecke._base(normalized_laurent_polynomial(hecke._base, c)(q1,root))2083new_basis = getattr(new_hecke, self.parent()._basis_name)()2084return new_basis._from_dict(dict( (w, new_coeff(c)) for (w,c) in self ))20852086class T(IwahoriHeckeAlgebra.T):2087r"""2088The `T`-basis for the generic Iwahori-Hecke algebra.2089"""2090@cached_method2091def to_Cp_basis(self, w):2092r"""2093Return `T_w` as a linear combination of `C^{\prime}`-basis2094elements.20952096EXAMPLES::20972098sage: H = sage.algebras.iwahori_hecke_algebra.IwahoriHeckeAlgebra_nonstandard("A2")2099sage: s1,s2 = H.coxeter_group().simple_reflections()2100sage: T = H.T()2101sage: Cp = H.Cp()2102sage: T.to_Cp_basis(s1)2103v*Cp[1] + (-u^-1*v^2)2104sage: Cp(T(s1))2105v*Cp[1] + (-u^-1*v^2)2106sage: Cp(T(s1)+1)2107v*Cp[1] + (-u^-1*v^2+1)2108sage: Cp(T(s1*s2)+T(s1)+T(s2)+1)2109v^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)2110sage: Cp(T(s1*s2*s1))2111v^3*Cp[1,2,1] + (-u^-1*v^4)*Cp[1,2] + (-u^-1*v^4)*Cp[2,1]2112+ (u^-2*v^5)*Cp[1] + (u^-2*v^5)*Cp[2] + (-u^-3*v^6)2113"""2114A = self.realization_of()2115Cp = A.Cp()21162117if w == A._W.one(): # the identity element of the Coxeter group2118return Cp.one()21192120T0 = self.zero()2121inp = self.monomial(w)2122result = Cp.zero()2123while inp != T0:2124(x,c) = inp.trailing_item(index_cmp)2125inp = inp - c * A._root**x.length() * Cp.to_T_basis(x)2126result = result + c * A._root**x.length() * Cp.monomial(x)21272128return result21292130@cached_method2131def to_C_basis(self, w):2132r"""2133Return `T_w` as a linear combination of `C`-basis elements.21342135To compute this we piggy back off the `C^{\prime}`-basis2136conversion using the observation that the hash involution sends2137`T_w` to `(-q_1 q_1)^{\ell(w)} T_w` and `C_w` to2138`(-1)^{\ell(w)} C^{\prime}_w`. Therefore, if21392140.. MATH::21412142T_w = \sum_v a_{vw} C^{\prime}_v21432144then21452146.. MATH::21472148T_w = (-q_1 q_2)^{\ell(w)} \Big( \sum_v a_{vw} C^{\prime}_v2149\Big)^\#2150= \sum_v (-1)^{\ell(v)} \overline{a_{vw}} C_v21512152Note that we cannot just apply :meth:`hash_involution` here because2153this involution always returns the answer with respect to the2154same basis.21552156EXAMPLES::21572158sage: H = sage.algebras.iwahori_hecke_algebra.IwahoriHeckeAlgebra_nonstandard("A2")2159sage: s1,s2 = H.coxeter_group().simple_reflections()2160sage: T = H.T()2161sage: C = H.C()2162sage: T.to_C_basis(s1)2163v*T[1] + u2164sage: C(T(s1))2165v*C[1] + u2166sage: C(T( C[1] ))2167C[1]2168sage: C(T(s1*s2)+T(s1)+T(s2)+1)2169v^2*C[1,2] + (u*v+v)*C[1] + (u*v+v)*C[2] + (u^2+2*u+1)2170sage: C(T(s1*s2*s1))2171v^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^32172"""2173H = self.realization_of()2174q_w = (-H._q_prod)**w.length()2175return self.sum_of_terms((v, (-1)**v.length()*q_w*H._bar_on_coefficients(c))2176for (v,c) in self.to_Cp_basis(w))21772178class Cp(IwahoriHeckeAlgebra.Cp):2179r"""2180The Kazhdan-Lusztig `C^{\prime}`-basis for the generic Iwahori-Hecke2181algebra.2182"""2183@cached_method2184def to_T_basis(self, w):2185r"""2186Return `C^{\prime}_w` as a linear combination of `T`-basis2187elements.21882189EXAMPLES::21902191sage: H = sage.algebras.iwahori_hecke_algebra.IwahoriHeckeAlgebra_nonstandard("A3")2192sage: s1,s2,s3 = H.coxeter_group().simple_reflections()2193sage: T = H.T()2194sage: Cp = H.Cp()2195sage: Cp.to_T_basis(s1)2196(v^-1)*T[1] + (u^-1*v)2197sage: Cp.to_T_basis(s1*s2)2198(v^-2)*T[1,2] + (u^-1)*T[1] + (u^-1)*T[2] + (u^-2*v^2)2199sage: Cp.to_T_basis(s1*s2*s1)2200(v^-3)*T[1,2,1] + (u^-1*v^-1)*T[1,2] + (u^-1*v^-1)*T[2,1]2201+ (u^-2*v)*T[1] + (u^-2*v)*T[2] + (u^-3*v^3)2202sage: T(Cp(s1*s2*s1))2203(v^-3)*T[1,2,1] + (u^-1*v^-1)*T[1,2] + (u^-1*v^-1)*T[2,1]2204+ (u^-2*v)*T[1] + (u^-2*v)*T[2] + (u^-3*v^3)2205sage: T(Cp(s2*s1*s3*s2))2206(v^-4)*T[2,3,1,2] + (u^-1*v^-2)*T[1,2,1] + (u^-1*v^-2)*T[3,1,2]2207+ (u^-1*v^-2)*T[2,3,1] + (u^-1*v^-2)*T[2,3,2] + (u^-2)*T[1,2]2208+ (u^-2)*T[2,1] + (u^-2)*T[3,1] + (u^-2)*T[2,3]2209+ (u^-2)*T[3,2] + (u^-3*v^2)*T[1] + (u^-1+u^-3*v^2)*T[2]2210+ (u^-3*v^2)*T[3] + (u^-2*v^2+u^-4*v^4)2211"""2212A = self.realization_of()2213T = A.T()2214Ts = T.algebra_generators()22152216if w == A._W.one(): # the identity element of the Coxeter group2217return T.one()22182219s = w.first_descent()2220ws = w.apply_simple_reflection(s)22212222cpw_s = self.to_T_basis(ws) * A.v_inv *(Ts[s] - A._q2*T.one())22232224i = 12225cmp_func = lambda x,y: index_cmp(x.leading_support(), y.leading_support())2226while i < len(cpw_s):2227(x,c) = sorted(cpw_s.terms(), cmp=cmp_func)[i].leading_item()2228mu=normalized_laurent_polynomial(A._base,c)[0,-x.length()] # the coefficient of v^-len(x)2229if mu!=0:2230cpw_s-=mu*self.to_T_basis(x)2231else:2232i+=122332234return cpw_s22352236C_prime = Cp22372238class C(IwahoriHeckeAlgebra.C):2239r"""2240The Kazhdan-Lusztig `C`-basis for the generic Iwahori-Hecke algebra.2241"""2242@cached_method2243def to_T_basis(self, w):2244r"""2245Return `C_w` as a linear combination of `T`-basis elements.22462247EXAMPLES::22482249sage: H = sage.algebras.iwahori_hecke_algebra.IwahoriHeckeAlgebra_nonstandard("A3")2250sage: s1,s2,s3 = H.coxeter_group().simple_reflections()2251sage: T = H.T()2252sage: C = H.C()2253sage: C.to_T_basis(s1)2254(v^-1)*T[1] + (-u*v^-1)2255sage: C.to_T_basis(s1*s2)2256(v^-2)*T[1,2] + (-u*v^-2)*T[1] + (-u*v^-2)*T[2] + (u^2*v^-2)2257sage: C.to_T_basis(s1*s2*s1)2258(v^-3)*T[1,2,1] + (-u*v^-3)*T[1,2] + (-u*v^-3)*T[2,1]2259+ (u^2*v^-3)*T[1] + (u^2*v^-3)*T[2] + (-u^3*v^-3)2260sage: T(C(s1*s2*s1))2261(v^-3)*T[1,2,1] + (-u*v^-3)*T[1,2] + (-u*v^-3)*T[2,1]2262+ (u^2*v^-3)*T[1] + (u^2*v^-3)*T[2] + (-u^3*v^-3)2263sage: T(C(s2*s1*s3*s2))2264(v^-4)*T[2,3,1,2] + (-u*v^-4)*T[1,2,1] + (-u*v^-4)*T[3,1,2]2265+ (-u*v^-4)*T[2,3,1] + (-u*v^-4)*T[2,3,2] + (u^2*v^-4)*T[1,2]2266+ (u^2*v^-4)*T[2,1] + (u^2*v^-4)*T[3,1] + (u^2*v^-4)*T[2,3]2267+ (u^2*v^-4)*T[3,2] + (-u^3*v^-4)*T[1]2268+ (-u^3*v^-4-u*v^-2)*T[2] + (-u^3*v^-4)*T[3]2269+ (u^4*v^-4+u^2*v^-2)2270"""2271# Treat our index as an index for the C'-basis, convert to the T-basis and2272# then apply the Hecke involution to the result. This gives the2273# desired result because C_w = (-1)^{len(w)) \tau( C_w' ), where2274# \tau is the Hecke involution.2275return (-1)**w.length()*self.realization_of().Cp().to_T_basis(w).hash_involution()22762277def IwahoriHeckeAlgebraT(W, q1, q2=-1, base_ring=None, prefix="T"):2278"""2279TESTS::22802281sage: H = IwahoriHeckeAlgebraT("A2", 1)2282doctest:...: DeprecationWarning: this class is deprecated. Use IwahoriHeckeAlgebra().T instead2283See http://trac.sagemath.org/14261 for details.2284"""2285from sage.misc.superseded import deprecation2286deprecation(14261,'this class is deprecated. Use IwahoriHeckeAlgebra().T instead')2287if W not in CoxeterGroups():2288W = WeylGroup(W)2289if base_ring is None:2290base_ring = q1.parent()2291q2 = base_ring(q2)2292return IwahoriHeckeAlgebra(W, q1=q1, q2=q2, base_ring=base_ring).T(prefix=prefix)22932294from sage.structure.sage_object import register_unpickle_override2295register_unpickle_override('sage.algebras.iwahori_hecke_algebra',2296'IwahoriHeckeAlgebraT', IwahoriHeckeAlgebraT)2297229822992300