1 | initial version |

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

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.

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.

2 | No.2 Revision |

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

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.
~~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.

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.

3 | No.3 Revision |

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

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 ~~(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.

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.

Copyright Sage, 2010. Some rights reserved under creative commons license. Content on this site is licensed under a Creative Commons Attribution Share Alike 3.0 license.