Coxeter Groups As Matrix Groups#
This implements a general Coxeter group as a matrix group by using the reflection representation.
AUTHORS:
Travis Scrimshaw (2013-08-28): Initial version
- class sage.groups.matrix_gps.coxeter_group.CoxeterMatrixGroup(coxeter_matrix, base_ring, index_set)#
Bases:
UniqueRepresentation
,FinitelyGeneratedMatrixGroup_generic
A Coxeter group represented as a matrix group.
Let \((W, S)\) be a Coxeter system. We construct a vector space \(V\) over \(\RR\) with a basis of \(\{ \alpha_s \}_{s \in S}\) and inner product
\[B(\alpha_s, \alpha_t) = -\cos\left( \frac{\pi}{m_{st}} \right)\]where we have \(B(\alpha_s, \alpha_t) = -1\) if \(m_{st} = \infty\). Next we define a representation \(\sigma_s : V \to V\) by
\[\sigma_s \lambda = \lambda - 2 B(\alpha_s, \lambda) \alpha_s.\]This representation is faithful so we can represent the Coxeter group \(W\) by the set of matrices \(\sigma_s\) acting on \(V\).
INPUT:
data
– a Coxeter matrix or graph or a Cartan typebase_ring
– (default: the universal cyclotomic field or a number field) the base ring which contains all values \(\cos(\pi/m_{ij})\) where \((m_{ij})_{ij}\) is the Coxeter matrixindex_set
– (optional) an indexing set for the generators
For finite Coxeter groups, the default base ring is taken to be \(\QQ\) or a quadratic number field when possible.
For more on creating Coxeter groups, see
CoxeterGroup()
.Todo
Currently the label \(\infty\) is implemented as \(-1\) in the Coxeter matrix.
EXAMPLES:
We can create Coxeter groups from Coxeter matrices:
sage: # needs sage.rings.number_field sage: W = CoxeterGroup([[1, 6, 3], [6, 1, 10], [3, 10, 1]]); W Coxeter group over Universal Cyclotomic Field with Coxeter matrix: [ 1 6 3] [ 6 1 10] [ 3 10 1] sage: W.gens() ( [ -1 -E(12)^7 + E(12)^11 1] [ 0 1 0] [ 0 0 1], [ 1 0 0] [-E(12)^7 + E(12)^11 -1 E(20) - E(20)^9] [ 0 0 1], [ 1 0 0] [ 0 1 0] [ 1 E(20) - E(20)^9 -1] ) sage: m = matrix([[1,3,3,3], [3,1,3,2], [3,3,1,2], [3,2,2,1]]) sage: W = CoxeterGroup(m) sage: W.gens() ( [-1 1 1 1] [ 1 0 0 0] [ 1 0 0 0] [ 1 0 0 0] [ 0 1 0 0] [ 1 -1 1 0] [ 0 1 0 0] [ 0 1 0 0] [ 0 0 1 0] [ 0 0 1 0] [ 1 1 -1 0] [ 0 0 1 0] [ 0 0 0 1], [ 0 0 0 1], [ 0 0 0 1], [ 1 0 0 -1] ) sage: a,b,c,d = W.gens() sage: (a*b*c)^3 [ 5 1 -5 7] [ 5 0 -4 5] [ 4 1 -4 4] [ 0 0 0 1] sage: (a*b)^3 [1 0 0 0] [0 1 0 0] [0 0 1 0] [0 0 0 1] sage: b*d == d*b True sage: a*c*a == c*a*c True
We can create the matrix representation over different base rings and with different index sets. Note that the base ring must contain all \(2*\cos(\pi/m_{ij})\) where \((m_{ij})_{ij}\) is the Coxeter matrix:
sage: W = CoxeterGroup(m, base_ring=RR, index_set=['a','b','c','d']) sage: W.base_ring() Real Field with 53 bits of precision sage: W.index_set() ('a', 'b', 'c', 'd') sage: CoxeterGroup(m, base_ring=ZZ) Coxeter group over Integer Ring with Coxeter matrix: [1 3 3 3] [3 1 3 2] [3 3 1 2] [3 2 2 1] sage: CoxeterGroup([[1,4],[4,1]], base_ring=QQ) # needs sage.symbolic Traceback (most recent call last): ... TypeError: unable to convert sqrt(2) to a rational
Using the well-known conversion between Coxeter matrices and Coxeter graphs, we can input a Coxeter graph. Following the standard convention, edges with no label (i.e. labelled by
None
) are treated as 3:sage: # needs sage.rings.number_field sage: G = Graph([(0,3,None), (1,3,15), (2,3,7), (0,1,3)]) sage: W = CoxeterGroup(G); W Coxeter group over Universal Cyclotomic Field with Coxeter matrix: [ 1 3 2 3] [ 3 1 2 15] [ 2 2 1 7] [ 3 15 7 1] sage: G2 = W.coxeter_diagram() sage: CoxeterGroup(G2) is W True
Because there currently is no class for \(\ZZ \cup \{ \infty \}\), labels of \(\infty\) are given by \(-1\) in the Coxeter matrix:
sage: # needs sage.rings.number_field sage: G = Graph([(0,1,None), (1,2,4), (0,2,oo)]) sage: W = CoxeterGroup(G) sage: W.coxeter_matrix() [ 1 3 -1] [ 3 1 4] [-1 4 1]
We can also create Coxeter groups from Cartan types using the
implementation
keyword:sage: W = CoxeterGroup(['D',5], implementation="reflection"); W Finite Coxeter group over Integer Ring with Coxeter matrix: [1 3 2 2 2] [3 1 3 2 2] [2 3 1 3 3] [2 2 3 1 2] [2 2 3 2 1] sage: W = CoxeterGroup(['H',3], implementation="reflection"); W # needs sage.rings.number_field Finite Coxeter group over Number Field in a with defining polynomial x^2 - 5 with a = 2.236067977499790? with Coxeter matrix: [1 3 2] [3 1 5] [2 5 1]
- class Element#
Bases:
MatrixGroupElement_generic
A Coxeter group element.
- action_on_root_indices(i, side='left')#
Return the action on the set of roots.
The roots are ordered as in the output of the method
roots()
.EXAMPLES:
sage: W = CoxeterGroup(['A',3], implementation="reflection") sage: w = W.w0 sage: w.action_on_root_indices(0) 11
- canonical_matrix()#
Return the matrix of
self
in the canonical faithful representation, which isself
as a matrix.EXAMPLES:
sage: W = CoxeterGroup(['A',3], implementation="reflection") sage: a,b,c = W.gens() sage: elt = a*b*c sage: elt.canonical_matrix() [ 0 0 -1] [ 1 0 -1] [ 0 1 -1]
- descents(side='right', index_set=None, positive=False)#
Return the descents of
self
, as a list of elements of theindex_set
.INPUT:
index_set
– (default: all of them) a subset (as a list or iterable) of the nodes of the Dynkin diagramside
– (default:'right'
)'left'
or'right'
positive
– (default:False
) boolean
EXAMPLES:
sage: W = CoxeterGroup(['A',3], implementation="reflection") sage: a,b,c = W.gens() sage: elt = b*a*c sage: elt.descents() [1, 3] sage: elt.descents(positive=True) [2] sage: elt.descents(index_set=[1,2]) [1] sage: elt.descents(side='left') [2]
- first_descent(side='right', index_set=None, positive=False)#
Return the first left (resp. right) descent of
self
, as ane element ofindex_set
, orNone
if there is none.See
descents()
for a description of the options.EXAMPLES:
sage: W = CoxeterGroup(['A',3], implementation="reflection") sage: a,b,c = W.gens() sage: elt = b*a*c sage: elt.first_descent() 1 sage: elt.first_descent(side='left') 2
- has_right_descent(i)#
Return whether
i
is a right descent ofself
.A Coxeter system \((W, S)\) has a root system defined as \(\{ w(\alpha_s) \}_{w \in W}\) and we define the positive (resp. negative) roots \(\alpha = \sum_{s \in S} c_s \alpha_s\) by all \(c_s \geq 0\) (resp. \(c_s \leq 0\)). In particular, we note that if \(\ell(w s) > \ell(w)\) then \(w(\alpha_s) > 0\) and if \(\ell(ws) < \ell(w)\) then \(w(\alpha_s) < 0\). Thus \(i \in I\) is a right descent if \(w(\alpha_{s_i}) < 0\) or equivalently if the matrix representing \(w\) has all entries of the \(i\)-th column being non-positive.
INPUT:
i
– an element in the index set
EXAMPLES:
sage: W = CoxeterGroup(['A',3], implementation="reflection") sage: a,b,c = W.gens() sage: elt = b*a*c sage: [elt.has_right_descent(i) for i in [1, 2, 3]] [True, False, True]
- bilinear_form()#
Return the bilinear form associated to
self
.Given a Coxeter group \(G\) with Coxeter matrix \(M = (m_{ij})_{ij}\), the associated bilinear form \(A = (a_{ij})_{ij}\) is given by
\[a_{ij} = -\cos\left( \frac{\pi}{m_{ij}} \right).\]If \(A\) is positive definite, then \(G\) is of finite type (and so the associated Coxeter group is a finite group). If \(A\) is positive semidefinite, then \(G\) is affine type.
EXAMPLES:
sage: W = CoxeterGroup(['D',4]) sage: W.bilinear_form() # needs sage.symbolic [ 1 -1/2 0 0] [-1/2 1 -1/2 -1/2] [ 0 -1/2 1 0] [ 0 -1/2 0 1]
- canonical_representation()#
Return the canonical faithful representation of
self
, which isself
.EXAMPLES:
sage: W = CoxeterGroup([[1,3],[3,1]]) sage: W.canonical_representation() is W True
- coxeter_matrix()#
Return the Coxeter matrix of
self
.EXAMPLES:
sage: W = CoxeterGroup([[1,3],[3,1]]) sage: W.coxeter_matrix() [1 3] [3 1] sage: W = CoxeterGroup(['H',3]) # needs sage.rings.number_field sage: W.coxeter_matrix() [1 3 2] [3 1 5] [2 5 1]
- fundamental_weight(i)#
Return the fundamental weight with index
i
.See also
EXAMPLES:
sage: W = CoxeterGroup(['A',3], implementation='reflection') sage: W.fundamental_weight(1) # needs sage.symbolic (3/2, 1, 1/2)
- fundamental_weights()#
Return the fundamental weights for
self
.This is the dual basis to the basis of simple roots.
The base ring must be a field.
See also
EXAMPLES:
sage: W = CoxeterGroup(['A',3], implementation='reflection') sage: W.fundamental_weights() # needs sage.symbolic Finite family {1: (3/2, 1, 1/2), 2: (1, 2, 1), 3: (1/2, 1, 3/2)}
- is_commutative()#
Return whether
self
is commutative.EXAMPLES:
sage: CoxeterGroup(['A', 2]).is_commutative() False sage: W = CoxeterGroup(['I',2]) sage: W.is_commutative() True
- is_finite()#
Return
True
if this group is finite.EXAMPLES:
sage: # needs sage.rings.number_field sage: [l for l in range(2, 9) if ....: CoxeterGroup([[1,3,2],[3,1,l],[2,l,1]]).is_finite()] [2, 3, 4, 5] sage: [l for l in range(2, 9) if ....: CoxeterGroup([[1,3,2,2],[3,1,l,2],[2,l,1,3],[2,2,3,1]]).is_finite()] [2, 3, 4] sage: [l for l in range(2, 9) if ....: CoxeterGroup([[1,3,2,2,2], [3,1,3,3,2], [2,3,1,2,2], ....: [2,3,2,1,l], [2,2,2,l,1]]).is_finite()] [2, 3] sage: [l for l in range(2, 9) if ....: CoxeterGroup([[1,3,2,2,2], [3,1,2,3,3], [2,2,1,l,2], ....: [2,3,l,1,2], [2,3,2,2,1]]).is_finite()] [2, 3] sage: [l for l in range(2, 9) if ....: CoxeterGroup([[1,3,2,2,2,2], [3,1,l,2,2,2], [2,l,1,3,l,2], ....: [2,2,3,1,2,2], [2,2,l,2,1,3], [2,2,2,2,3,1]]).is_finite()] [2, 3]
- order()#
Return the order of
self
.If the Coxeter group is finite, this uses an iterator.
EXAMPLES:
sage: # needs sage.rings.number_field sage: W = CoxeterGroup([[1,3],[3,1]]) sage: W.order() 6 sage: W = CoxeterGroup([[1,-1],[-1,1]]) sage: W.order() +Infinity
- positive_roots()#
Return the positive roots.
These are roots in the Coxeter sense, that all have the same norm. They are given by their coefficients in the base of simple roots, also taken to have all the same norm.
See also
EXAMPLES:
sage: W = CoxeterGroup(['A',3], implementation='reflection') sage: W.positive_roots() ((1, 0, 0), (1, 1, 0), (0, 1, 0), (1, 1, 1), (0, 1, 1), (0, 0, 1)) sage: # needs sage.rings.number_field sage: W = CoxeterGroup(['I',5], implementation='reflection') sage: W.positive_roots() ((1, 0), (-E(5)^2 - E(5)^3, 1), (-E(5)^2 - E(5)^3, -E(5)^2 - E(5)^3), (1, -E(5)^2 - E(5)^3), (0, 1))
- reflections()#
Return the set of reflections.
The order is the one given by
positive_roots()
.EXAMPLES:
sage: W = CoxeterGroup(['A',2], implementation='reflection') sage: list(W.reflections()) [ [-1 1] [ 0 -1] [ 1 0] [ 0 1], [-1 0], [ 1 -1] ]
- roots()#
Return the roots.
These are roots in the Coxeter sense, that all have the same norm. They are given by their coefficients in the base of simple roots, also taken to have all the same norm.
The positive roots are listed first, then the negative roots in the same order. The order is the one given by
roots()
.EXAMPLES:
sage: W = CoxeterGroup(['A',3], implementation='reflection') sage: W.roots() ((1, 0, 0), (1, 1, 0), (0, 1, 0), (1, 1, 1), (0, 1, 1), (0, 0, 1), (-1, 0, 0), (-1, -1, 0), (0, -1, 0), (-1, -1, -1), (0, -1, -1), (0, 0, -1)) sage: # needs sage.rings.number_field sage: W = CoxeterGroup(['I',5], implementation='reflection') sage: len(W.roots()) 10
- simple_reflection(i)#
Return the simple reflection \(s_i\).
INPUT:
i
– an element from the index set
EXAMPLES:
sage: W = CoxeterGroup(['A',3], implementation="reflection") sage: W.simple_reflection(1) [-1 1 0] [ 0 1 0] [ 0 0 1] sage: W.simple_reflection(2) [ 1 0 0] [ 1 -1 1] [ 0 0 1] sage: W.simple_reflection(3) [ 1 0 0] [ 0 1 0] [ 0 1 -1]