# What is a 'CoxeterGroup'?

Hi, I'm trying to implement a certain Coxeter group in Sage, for the purpose of building the corresponding Iwahori-Hecke algebra over it using sage.algebras.iwahori_hecke_algebra.IwahoriHeckeAlgebra. In the documentation of the constructor of this class, it says that it takes a "Coxeter group" as an argument. However, Coxeter groups as generated by sage.combinat.root_system.coxeter_group.CoxeterGroup aren't actually instances of a common superclass.

Afaict, the methods of IwahoriHeckeAlgebra simply implicitly assume the existence of certain instance methods (like W.is_finite or W.from_reduced_word), probably also with some implicitly assumed semantics of said methods. So, my question is whether the behaviour of being a "Coxeter group" are actually anywhere formally documented, or whether I'm stuck piecing together the required methods & semantics through trial and error.

edit retag close merge delete

1

You may want to look at src/sage/groups/matrix_gps/coxeter_group.py and src/sage/categories/coxeter_groups.py and src/sage/categories/examples/finite_coxeter_groups.py:

( 2018-09-06 11:01:28 -0500 )edit

Sort by » oldest newest most voted

Here are some equivalent ways to introduce the Iwahori-Hecke algebra, in this particular example for the type $A_3$.

sage: R.<q> = LaurentPolynomialRing(QQ)
sage: Q = q^2
sage: IHA1 = IwahoriHeckeAlgebra( 'A3', Q )
sage: IHA2 = IwahoriHeckeAlgebra( RootSystem('A3'), Q )
sage: IHA3 = IwahoriHeckeAlgebra( CoxeterGroup( 'A3' ), Q )
sage: IHA1 == IHA2
True
sage: IHA1 == IHA3
True

sage: T = IHA1.T()
sage: [ (T[k]-Q)*(T[k]+1) for k in (1,2,3) ]
[0, 0, 0]
sage: T1, T2, T3 = T.algebra_generators()
sage: [ (Tk-Q)*(Tk+1) for Tk in (T1,T2,T3) ]
[0, 0, 0]
sage: T2*T1*T2
T[1,2,1]
sage: T1*T2*T1
T[1,2,1]


I also tried

sage: IHA4 = IwahoriHeckeAlgebra( WeylGroup('A3'), Q )
sage: IHA1 == IHA4
False

sage: IHA1 = IwahoriHeckeAlgebra( 'A3', Q )
sage: IHA5 = IwahoriHeckeAlgebra( CartanType('A3'), Q )
sage: IHA1 == IHA5
True


The equality with IHA4 fails maybe for reasons of internal representation. But one can also work in IHA4.

sage: TT = IHA4.T()
sage: TT[1]^2
-(1-q^2)*T[1] + q^2
sage: TT[1]*TT[2]*TT[1] - TT[2]*TT[1]*TT[2]
0


If the needed research theme / application points to a Coxeter group not listed among the $A,B,C,D,E,F,\dots$ types, then we need to know the Coxeter group in the original post. (How it is constructed, or at least mathematically defined.)

more

This does not seem to answer my question.

( 2018-09-07 08:33:59 -0500 )edit

Okay, here are the minimal steps that you need to take (for a complete working example, see here):

## Create a class representing the group

This class should look as follows:

class MyCoxeterGroup(UniqueRepresentation, FinitelyGeneratedMatrixGroup_generic):
Element = MyCoxeterGroupElement
def index_set(self):
...
def simple_reflection(self, i):
...
def is_finite(self):
...
def __repr__(self):
...
def __contains__(self, x):
...
def coxeter_matrix(self):
...


The requirements on the semantics of these methods are implicit, but can be gathered quite easily from the source file of sage.categories.coxeter_groups and other related ones. Subclassing from FinitelyGeneratedMatrixGroup_generic isn't strictly necessary, but if your Coxeter group has anything to do with matrices, you probably want to subclass from it.

Subclassing from UniqueRepresentation is necessary, at least if you plan on building the corresponding Iwahori-Hecke algebra over it. The reason for this is that if you don't subclass from UniqueRepresentation, the object returned by

CombinatorialFreeModule(ZZ, W).basis().keys()


(given that W is an instance of MyCoxeterGroup) will not be an instance of MyCoxeterGroup. For this reason, also the following command will fail

IwahoriHeckeAlgebra(W, 0, 0, ZZ).T().algebra_generators()


I don't exactly know how subclassing from UniqueRepresentation fixes that problem, but it seems to have to do with the magic that Sage uses when dynamically creating classes.

## Create a class representing elements of the group

This should look like this:

class MyCoxeterGroupElement(MatrixGroupElement_generic):
def __eq__(self, other):
...
def __mul__(self, other):
...
def has_left_descent(self, i):
...


I won't go into all details here, but __eq__ should be the equality test for elements of your group, __mul__ should at least implement multiplication of two instances of type MyCoxeterGroupElement, and has_left_descent should for a given index i (which should be one of the elements returned by MyCoxeterGroup.index_set) returned a boolean (!) specifying whether the simple reflection corresponding to i lies in the left descent set of the element in question (self). In other words, has_left_descent(self, i) should evaluate to True iff l(s_i w) < l(w).

Note that it's really important that has_left_descent returns a boolean and not a more general truth object, as the default implementation of has_descent will make a test of the form

has_left_descent(i) != False


which can evaluate to True even if has_left_descent(i) is a truth object representing falsehood.

more