Coxeter groups
Chevie.CoxGroups
FinitePosets.Poset
Base.length
Chevie.CoxGroups.bruhatless
Chevie.CoxGroups.coxeter_group
Chevie.CoxGroups.coxeter_hyperoctaedral_group
Chevie.CoxGroups.coxeter_matrix
Chevie.CoxGroups.coxeter_symmetric_group
Chevie.CoxGroups.firstleftdescent
Chevie.CoxGroups.isleftdescent
Chevie.CoxGroups.isrightdescent
Chevie.CoxGroups.leftdescents
Chevie.CoxGroups.longest
Chevie.CoxGroups.standard_parabolic_class
Chevie.PermRoot.cartan
Chevie.PermRoot.cartan
Chevie.PermRoot.reflection_subgroup
Chevie.PermRoot.reflection_subgroup
PermGroups.Groups.elements
PermGroups.Groups.word
PermGroups.Groups.words
PermGroups.Groups.words
PermGroups.reduced
Chevie.CoxGroups
— ModuleA suitable reference for the general theory of Coxeter groups is, for example, Bourbaki "Lie Groups and Lie Algebras" chapter 4.
A Coxeter group is a group which has the presentation $W=⟨S|(st)^{m(s,t)}=1\text{ for }s,t∈ S⟩$ for some symmetric integer matrix m(s,t)
called the Coxeter matrix, where m(s,t)>1
for s≠t
and m(s,s)=1
; m(s,t)=∞
is allowed meaning there is no relation between s
and t
. It is true (but a non-trivial theorem) that in a Coxeter group the order of st
is exactly m(s,t)
, thus a Coxeter group is the same as a Coxeter system, that is a pair (W,S)
of a group W
and a set S⊂W
of involutions, such that the group is presented by generators S
and relations describing the order of the product of two elements of S
.
A Coxeter group has a natural representation, its reflection representation, on a real vector space V
of dimension length(S)
(which is the Coxeter rank of W), where each element of S
acts as a reflection; the faithfulness of this representation (a theorem of Tits) is the main argument to prove that the order of st
is exactly m(s,t)
. This representation is defined as follows on a space V
with basis {eₛ}
for s∈ S
. The cartan matrix associated to the Coxeter matrix m(s,t)
is the matrix C
with entries C(s,t)=-2cos(π/m(s,t))
; we set C(s,t)=-2
if m(s,t)=∞
. Then the action of s∈ S
on V
is given by s(eₜ)=eₜ-C(s,t)eₛ
.
Thus, Coxeter groups are real reflection groups. The converse need not be true if the set of reflecting hyperplanes has bad topological properties, but it turns out that finite Coxeter groups are the same as finite real reflection groups. The possible Coxeter matrices for finite Coxeter groups have been completely classified, see Weyl
; the corresponding finite groups play a deep role in several areas of mathematics.
Coxeter groups have a nice solution to the word problem. The length l(w)
of an element w∈ W
is the minimum number of elements of S
of which it is a product (since the elements of S
are involutions, we do not need inverses). An expression of w
of minimum length is called a reduced word for w
. The main property of reduced words is the exchange lemma which states that if s₁…sₖ
is a reduced word for w
(thus k=l(w)
) and s∈ S
is such that l(sw)≤l(w)
then one of the sᵢ
in the word for w
can be deleted to obtain a reduced word for sw
. Thus given s∈ S
and w∈ W
, either l(sw)=l(w)+1
or l(sw)=l(w)-1
and in the latter case we say that s
belongs to the left descent set of w
. Computing a reduced word for an element, and other word problems, are easy if we know how to multiply elements and know left descent sets. In each of the Coxeter groups that we implement, the left descent set is easy to compute (see for example coxeter_symmetric_group
below), so this suggests how to deal with Coxeter groups generically:
The type CoxeterGroup
is an abstract type; an actual struct which implements it must define a function
isleftdescent(W,w,i)
which tells whether the i
-th element of S
is in the left descent set of w
.
the other functions needed in an instance of a Coxeter group are
gens(W)
which returns the setS
(the list of Coxeter generators)nref(W)
which returns the number of reflections ofW
, ifW
is finite ornothing
ifW
is infinite.
It should be noted that a Coxeter group can be any kind of group implementing the above functions.
Because of the easy solution of the word problem in Coxeter groups, a convenient way to represent their elements is as words in the Coxeter generators, that is lists of integers in 1:length(S)
. The functions 'word' and 'W(...)' do the conversion between Coxeter words and elements of the group.
Examples
julia> W=coxsym(4)
𝔖 ₄
julia> p=W(1,3,2,1,3)
(1,4)
julia> word(W,p)
5-element Vector{Int64}:
1
2
3
2
1
We notice that the word we started with and the one that we ended up with, are not the same, even though they represent the same element of W
. The reason is that there are several reduced words for an element of W
. The function 'word' calculates a lexicographically smallest word for w
. Below are some other possible computations using the same Coxeter group:
julia> word(W,longest(W)) # the (unique) longest element in W
6-element Vector{Int64}:
1
2
1
3
2
1
julia> w0=longest(W)
(1,4)(2,3)
julia> length(W,w0)
6
julia> map(w->word(W,w),refls(W,1:nref(W)))
6-element Vector{Vector{Int64}}:
[1]
[2]
[3]
[1, 2, 1]
[2, 3, 2]
[1, 2, 3, 2, 1]
julia> [length(elements(W,i)) for i in 0:nref(W)]
7-element Vector{Int64}:
1
3
5
6
5
3
1
The last list tells us that there is 1 element of length 0, there are 6 of length 3, …
For most basic functions the convention is that the input is an element of the group, rather than a Coxeter word. The reason for this is that for a Coxeter group which is a permutation group, using the low level functions for permutations is usually much faster than manipulating lists representing reduced expressions.
The only Coxeter group constructors implemented in this module are coxsym
and coxgroup
; the last constructor takes a Cartan matrix and builds the corresponding Coxeter group as a matrix group. The module Weyl
defines other methods for coxgroup
building a finite Coxeter group as a permutation group, given its type.
Chevie.CoxGroups.isleftdescent
— Methodisleftdescent(W::CoxeterGroup,w,i::Integer)
returns true
iff the i
-th generating reflection of the Coxeter group W
is in the left descent set of the element w
of W
, that is iff length(W,W(i)*w)<length(W,w)
.
julia> W=coxsym(3)
𝔖 ₃
julia> isleftdescent(W,Perm(1,2),1)
true
Chevie.CoxGroups.isrightdescent
— Functionisrightdescent(W::CoxeterGroup,w,i::Integer)
returns true
iff the i
-th generating reflection of the Coxeter group W
is in the right descent set of the element w
of W
, that is iff length(W,w*W(i))<length(W,w)
.
julia> W=coxsym(3)
𝔖 ₃
julia> isrightdescent(W,Perm(1,2),1)
true
Chevie.CoxGroups.firstleftdescent
— Functionfirstleftdescent(W,w)
returns the index in gens(W)
of the first element of the left descent set of w
–- that is, the first i
such that if s=W(i)
then l(sw)<l(w). It returns
nothingfor
one(W)`.
julia> W=coxsym(3)
𝔖 ₃
julia> firstleftdescent(W,Perm(2,3))
2
Chevie.CoxGroups.leftdescents
— Methodleftdescents(W,w)
The left descents of the element w
of the Coxeter group W
, that is the set of i
such that length(W,W(i)*w)<length(W,w)
.
julia> W=coxsym(3)
𝔖 ₃
julia> leftdescents(W,Perm(1,3))
2-element Vector{Int64}:
1
2
PermGroups.Groups.word
— Methodword(W::CoxeterGroup,w)
returns a reduced word in the standard generators of the Coxeter group W
for the element w
(represented as the vector of the corresponding generator indices).
julia> W=coxgroup(:A,3)
A₃
julia> w=perm"(1,11)(3,10)(4,9)(5,7)(6,12)"
(1,11)(3,10)(4,9)(5,7)(6,12)
julia> w in W
true
julia> word(W,w)
5-element Vector{Int64}:
1
2
3
2
1
The result of word
is the lexicographically smallest reduced word for w
(for the ordering of the Coxeter generators given by gens(W)
).
Base.length
— Methodlength(W::CoxeterGroup ,w)
returns the length of a reduced expression in the Coxeter generators of the element w
of W
.
julia> W=coxsym(4)
𝔖 ₄
julia> p=W(1,2,3,1,2,3)
(1,3)(2,4)
julia> length(W,p)
4
julia> word(W,p)
4-element Vector{Int64}:
2
1
3
2
Chevie.CoxGroups.longest
— Functionlongest(W)
If W
is finite, returns the unique element of maximal length of the Coxeter group W
. May loop infinitely otherwise.
julia> longest(coxsym(4))
(1,4)(2,3)
longest(W,I)
returns the longest element of the parabolic subgroup of W
generated by the generating reflections of indices in I
.
julia> longest(coxsym(4))
(1,4)(2,3)
PermGroups.Groups.elements
— Methodelements(W::CoxeterGroup[,l])
When l
is not given this works only if W
is finite; it returns the elements of W
sorted by increasing Coxeter length. If the second argument is an integer l
, the elements of W
of Coxeter length l
are returned.
julia> W=coxgroup(:G,2)
G₂
julia> e=elements(W,6)
1-element Vector{Perm{Int16}}:
(1,7)(2,8)(3,9)(4,10)(5,11)(6,12)
julia> e[1]==longest(W)
true
PermGroups.Groups.words
— Methodwords(W::CoxeterGroup,w)
returns the list of all reduced expressions of the element w
of the Coxeter group W
.
julia> W=coxgroup(:A,3)
A₃
julia> words(W,longest(W))
16-element Vector{Vector{Int64}}:
[1, 2, 1, 3, 2, 1]
[1, 2, 3, 1, 2, 1]
[1, 2, 3, 2, 1, 2]
[1, 3, 2, 1, 3, 2]
[1, 3, 2, 3, 1, 2]
[2, 1, 2, 3, 2, 1]
[2, 1, 3, 2, 1, 3]
[2, 1, 3, 2, 3, 1]
[2, 3, 1, 2, 1, 3]
[2, 3, 1, 2, 3, 1]
[2, 3, 2, 1, 2, 3]
[3, 1, 2, 1, 3, 2]
[3, 1, 2, 3, 1, 2]
[3, 2, 1, 2, 3, 2]
[3, 2, 1, 3, 2, 3]
[3, 2, 3, 1, 2, 3]
PermGroups.Groups.words
— Methodwords(W::CoxeterGroup[,l::Integer])
With one argument this works only if W
is finite; it returns the reduced Coxeter words of elements of W
by increasing length. If the second argument is an integer l
, only the elements of length l
are returned; this works for infinite Coxeter groups.
julia> W=coxgroup(:G,2)
G₂
julia> e=elements(W,6)
1-element Vector{Perm{Int16}}:
(1,7)(2,8)(3,9)(4,10)(5,11)(6,12)
julia> e[1]==longest(W)
true
Chevie.CoxGroups.bruhatless
— Functionbruhatless(W, x, y)
whether x≤y
in the Bruhat order, for x,y∈ W
. We have x≤y
if a reduced expression for x
can be extracted from one for w
. See (5.9) and (5.10) Humphreys1990 for properties of the Bruhat order.
julia> W=coxgroup(:H,3)
H₃
julia> w=W(1,2,1,3);
julia> b=filter(x->bruhatless(W,x,w),elements(W));
julia> word.(Ref(W),b)
12-element Vector{Vector{Int64}}:
[]
[1]
[2]
[3]
[1, 2]
[2, 1]
[1, 3]
[2, 3]
[1, 2, 1]
[1, 2, 3]
[2, 1, 3]
[1, 2, 1, 3]
bruhatless(W, y)
returns a vector whose i
-th element is the vector of elements of W
smaller for the Bruhat order than w
and of Coxeter length i-1
. Thus the first element of the returned list contains only one(W)
and the length(W,w)
-th element contains only w
.
julia> W=coxsym(3)
𝔖 ₃
julia> bruhatless(W,Perm(1,3))
4-element Vector{Vector{Perm{Int16}}}:
[()]
[(1,2), (2,3)]
[(1,2,3), (1,3,2)]
[(1,3)]
see also Poset
for Coxeter groups.
Chevie.CoxGroups.coxeter_matrix
— Functioncoxeter_matrix(m::AbstractMatrix)
or coxmat
returns the Coxeter matrix of the Coxeter group defined by the cartan matrix m
julia> C=cartan(:H,3)
3×3 Matrix{Cyc{Int64}}:
2 ζ₅²+ζ₅³ 0
ζ₅²+ζ₅³ 2 -1
0 -1 2
julia> coxmat(C)
3×3 Matrix{Int64}:
1 5 2
5 1 3
2 3 1
coxeter_matrix(W)
or coxmat
returns the Coxeter matrix of the Coxeter group W
, that is the matrix m
whose entry m[i,j]
contains the order of W(i)*W(j)
where W(i)
is the i
-th Coxeter generator of W
. An infinite order is represented by the entry 0
.
julia> W=coxsym(4)
𝔖 ₄
julia> coxmat(W)
3×3 Matrix{Int64}:
1 3 2
3 1 3
2 3 1
coxeter_matrix(type, rank [,bond])
or coxmat
Like cartan
, the function coxmat
can be defined from the type and rank of a finite Coxeter group.
Chevie.PermRoot.cartan
— Methodcartan(M::AbstractMatrix)
Cartan matrix from Coxeter matrix
The argument should be the Coxeter matrix M
for a Coxeter group W
and the result is the Cartan Matrix C
for the standard reflection representation of W
. We have C[s,t]=-2cos(π/M[s,t])
, where M[s,s]==1
and by convention π/M[s,t]==0
if M[s,t]==∞
, which we represent by M[s,t]==0
. Since M
is symmetric, the resulting C
is symmetric, meaning that all roots in the constructed reflection representation have same length.
julia> cartan([1 3;3 1])
2×2 Matrix{Cyc{Int64}}:
2 -1
-1 2
Chevie.CoxGroups.coxeter_symmetric_group
— Functioncoxeter_symmetric_group(n::Integer)
or coxeter_symmetric_group(m:n)
or coxsym
The symmetric group on the letters 1:n
(or if a m≤n
is given, on the letters m:n
) as a Coxeter group. The Coxeter generators are the Perm(i,i+1)
for i
in m:n-1
.
julia> W=coxsym(3)
𝔖 ₃
julia> gens(W)
2-element Vector{Perm{Int16}}:
(1,2)
(2,3)
julia> e=elements(W)
6-element Vector{Perm{Int16}}:
()
(1,2)
(2,3)
(1,3,2)
(1,2,3)
(1,3)
julia> length.(Ref(W),e) # length in the genrators of the elements
6-element Vector{Int64}:
0
1
1
2
2
3
Chevie.PermRoot.reflection_subgroup
— Methodreflection_subgroup(W::CoxSym,I)
The only reflection subgroups defined for coxsym(n)
are for I=1:m
for m≤n
Chevie.PermRoot.cartan
— Methodcartan(W::CoxeterGroup)
The Cartan matrix of W
.
Chevie.CoxGroups.coxeter_hyperoctaedral_group
— Functioncoxeter_hyperoctaedral_group(n)
or coxhyp(n)
The Hyperoctaedral group (the group of all signed permutations of ±1,…,±n) as a Coxeter group of type Bₙ
, with generators (1,-1)
and (i,i+1)(-i,-i-1)
.
julia> elements(coxhyp(2))
8-element Vector{SPerm{Int8}}:
()
(1,2)
(1,-1)
(1,2,-1,-2)
(1,-2,-1,2)
(2,-2)
(1,-2)
(1,-1)(2,-2)
Chevie.PermRoot.reflection_subgroup
— Methodreflection_subgroup(W::CoxHyp,I)
is defined only for I=1:m
for m≤ngens(W)
.
PermGroups.reduced
— Functionreduced(W,w)
The unique element of minimal length in the coset W.w. This makes sense when isleftdescent(W,u)
makes sense for u∈ W.w
which happens when w
is a Coxeter automorphism of W
or when w
lives in a Coxeter overgroup of W
.
julia> W=coxgroup(:G,2)
G₂
julia> H=reflection_subgroup(W,[2,6])
G₂₍₂₆₎=Ã₁×A₁
julia> word.(Ref(W),unique(reduced.(Ref(H),elements(W))))
3-element Vector{Vector{Int64}}:
[]
[1]
[1, 2]
reduced(H::CoxeterGroup,W::CoxeterGroup,i=nref(W))
The elements w∈ W
which are H
-reduced, and of length ≤i
(by default all of them), grouped by length.
julia> W=coxgroup(:G,2)
G₂
julia> H=reflection_subgroup(W,[2,6])
G₂₍₂₆₎=Ã₁×A₁
julia> [word(W,w) for S in reduced(H,W) for w in S]
3-element Vector{Vector{Int64}}:
[]
[1]
[1, 2]
Chevie.CoxGroups.standard_parabolic_class
— Functionstandard_parabolic_class(W,I)
I
should be a subset of eachindex(gens(W))
. The function returns the list of such subsets W
-conjugate to I
.
julia> CoxGroups.standard_parabolic_class(coxgroup(:E,8),[7,8])
7-element Vector{Vector{Int64}}:
[7, 8]
[6, 7]
[5, 6]
[4, 5]
[2, 4]
[3, 4]
[1, 3]
Chevie.CoxGroups.coxeter_group
— Methodcoxeter_group(m)
or coxgroup(m)
m
should be a square matrix of real cyclotomic numbers. It returns the Coxeter group whose Cartan matrix is m
. This is a matrix group W
constructed as follows. Let V
be a real vector space of dimension size(m,1)
, let eᵢ
be the canonical basis of V
. Then W
is the matrix group generated by the reflections sᵢ(eⱼ)=eⱼ-mᵢⱼ eᵢ
.
julia> W=coxgroup([2 -2;-2 2])
coxeter_group([2 -2; -2 2])
Above is a way to construct the affine Weyl group Ã₁
.
FinitePosets.Poset
— TypePoset(W::CoxeterGroup,w=longest(W))
returns as a poset the Bruhat interval [1,w]
of W
. If w
is not given, the whole Bruhat Poset of W
is returned (W
must then be finite).
julia> W=coxsym(3)
𝔖 ₃
julia> Poset(W)
.<1,2<21,12<121
The above poset is constructed efficiently by constructing the Hasse diagram, but it could be constructed naively as follows:
julia> p=Poset((x,y)->bruhatless(W,x,y),elements(W))
()<(1,2),(2,3)<(1,3,2),(1,2,3)<(1,3)
The output is not so nice, showing permutations instead of words. This can be fixed by defining:
julia> p.show_element=(io,x,n)->join(io,word(W,x.elements[n]));
julia> p
<1,2<12,21<121
julia> W=coxsym(4)
𝔖 ₄
julia> Poset(W,W(1,3))
.<3,1<13