Weyl Groups¶
AUTHORS:
- Daniel Bump (2008): initial version
- Mike Hansen (2008): initial version
- Anne Schilling (2008): initial version
- Nicolas Thiery (2008): initial version
- Volker Braun (2013): LibGAP-based matrix groups
EXAMPLES:
More examples on Weyl Groups should be added here...
The Cayley graph of the Weyl Group of type [‘A’, 3]:
sage: w = WeylGroup(['A',3])
sage: d = w.cayley_graph(); d
Digraph on 24 vertices
sage: d.show3d(color_by_label=True, edge_size=0.01, vertex_size=0.03)
The Cayley graph of the Weyl Group of type [‘D’, 4]:
sage: w = WeylGroup(['D',4])
sage: d = w.cayley_graph(); d
Digraph on 192 vertices
sage: d.show3d(color_by_label=True, edge_size=0.01, vertex_size=0.03) #long time (less than one minute)
-
class
sage.combinat.root_system.weyl_group.
ClassicalWeylSubgroup
(domain, prefix)¶ Bases:
sage.combinat.root_system.weyl_group.WeylGroup_gens
A class for Classical Weyl Subgroup of an affine Weyl Group
EXAMPLES:
sage: G = WeylGroup(["A",3,1]).classical() sage: G Parabolic Subgroup of the Weyl Group of type ['A', 3, 1] (as a matrix group acting on the root space) sage: G.category() Category of finite weyl groups sage: G.cardinality() 24 sage: G.index_set() (1, 2, 3) sage: TestSuite(G).run()
TESTS:
sage: from sage.combinat.root_system.weyl_group import ClassicalWeylSubgroup sage: H = ClassicalWeylSubgroup(RootSystem(["A", 3, 1]).root_space(), prefix=None) sage: H is G True
Caveat: the interface is likely to change. The current main application is for plots.
Todo
implement:
- Parabolic subrootsystems
- Parabolic subgroups with a set of nodes as argument
-
cartan_type
()¶ EXAMPLES:
sage: WeylGroup(['A',3,1]).classical().cartan_type() ['A', 3] sage: WeylGroup(['A',3,1]).classical().index_set() (1, 2, 3)
Note: won’t be needed, once the lattice will be a parabolic sub root system
-
simple_reflections
()¶ EXAMPLES:
sage: WeylGroup(['A',2,1]).classical().simple_reflections() Finite family {1: [ 1 0 0] [ 1 -1 1] [ 0 0 1], 2: [ 1 0 0] [ 0 1 0] [ 1 1 -1]}
Note: won’t be needed, once the lattice will be a parabolic sub root system
-
weyl_group
(prefix='hereditary')¶ Return the Weyl group associated to the parabolic subgroup.
EXAMPLES:
sage: WeylGroup(['A',4,1]).classical().weyl_group() Weyl Group of type ['A', 4, 1] (as a matrix group acting on the root space) sage: WeylGroup(['C',4,1]).classical().weyl_group() Weyl Group of type ['C', 4, 1] (as a matrix group acting on the root space) sage: WeylGroup(['E',8,1]).classical().weyl_group() Weyl Group of type ['E', 8, 1] (as a matrix group acting on the root space)
-
sage.combinat.root_system.weyl_group.
WeylGroup
(x, prefix=None)¶ Returns the Weyl group of the root system defined by the Cartan type (or matrix)
ct
.INPUT:
x
- a root system or a Cartan type (or matrix)
OPTIONAL:
prefix
– changes the representation of elements from matrices to products of simple reflections
EXAMPLES:
The following constructions yield the same result, namely a weight lattice and its corresponding Weyl group:
sage: G = WeylGroup(['F',4]) sage: L = G.domain()
or alternatively and equivalently:
sage: L = RootSystem(['F',4]).ambient_space() sage: G = L.weyl_group() sage: W = WeylGroup(L)
Either produces a weight lattice, with access to its roots and weights.
sage: G = WeylGroup(['F',4]) sage: G.order() 1152 sage: [s1,s2,s3,s4] = G.simple_reflections() sage: w = s1*s2*s3*s4; w [ 1/2 1/2 1/2 1/2] [-1/2 1/2 1/2 -1/2] [ 1/2 1/2 -1/2 -1/2] [ 1/2 -1/2 1/2 -1/2] sage: type(w) == G.element_class True sage: w.order() 12 sage: w.length() # length function on Weyl group 4
The default representation of Weyl group elements is as matrices. If you prefer, you may specify a prefix, in which case the elements are represented as products of simple reflections.
sage: W=WeylGroup("C3",prefix="s") sage: [s1,s2,s3]=W.simple_reflections() # lets Sage parse its own output sage: s2*s1*s2*s3 s1*s2*s3*s1 sage: s2*s1*s2*s3 == s1*s2*s3*s1 True sage: (s2*s3)^2==(s3*s2)^2 True sage: (s1*s2*s3*s1).matrix() [ 0 0 -1] [ 0 1 0] [ 1 0 0]
sage: L = G.domain() sage: fw = L.fundamental_weights(); fw Finite family {1: (1, 1, 0, 0), 2: (2, 1, 1, 0), 3: (3/2, 1/2, 1/2, 1/2), 4: (1, 0, 0, 0)} sage: rho = sum(fw); rho (11/2, 5/2, 3/2, 1/2) sage: w.action(rho) # action of G on weight lattice (5, -1, 3, 2)
We can also do the same for arbitrary Cartan matrices:
sage: cm = CartanMatrix([[2,-5,0],[-2,2,-1],[0,-1,2]]) sage: W = WeylGroup(cm) sage: W.gens() ( [-1 5 0] [ 1 0 0] [ 1 0 0] [ 0 1 0] [ 2 -1 1] [ 0 1 0] [ 0 0 1], [ 0 0 1], [ 0 1 -1] ) sage: s0,s1,s2 = W.gens() sage: s1*s2*s1 [ 1 0 0] [ 2 0 -1] [ 2 -1 0] sage: s2*s1*s2 [ 1 0 0] [ 2 0 -1] [ 2 -1 0] sage: s0*s1*s0*s2*s0 [ 9 0 -5] [ 2 0 -1] [ 0 1 -1]
Same Cartan matrix, but with a prefix to display using simple reflections:
sage: W = WeylGroup(cm, prefix='s') sage: s0,s1,s2 = W.gens() sage: s0*s2*s1 s2*s0*s1 sage: (s1*s2)^3 1 sage: (s0*s1)^5 s0*s1*s0*s1*s0*s1*s0*s1*s0*s1 sage: s0*s1*s2*s1*s2 s2*s0*s1 sage: s0*s1*s2*s0*s2 s0*s1*s0
TESTS:
sage: TestSuite(WeylGroup(["A",3])).run() sage: TestSuite(WeylGroup(["A",3,1])).run() # long time sage: W = WeylGroup(['A',3,1]) sage: s = W.simple_reflections() sage: w = s[0]*s[1]*s[2] sage: w.reduced_word() [0, 1, 2] sage: w = s[0]*s[2] sage: w.reduced_word() [2, 0] sage: W = groups.misc.WeylGroup(['A',3,1])
-
class
sage.combinat.root_system.weyl_group.
WeylGroupElement
(parent, g, check=False)¶ Bases:
sage.groups.matrix_gps.group_element.MatrixGroupElement_gap
Class for a Weyl Group elements
-
action
(v)¶ Returns the action of self on the vector v.
- EXAMPLES::
sage: W = WeylGroup([‘A’,2]) sage: s = W.simple_reflections() sage: v = W.domain()([1,0,0]) sage: s[1].action(v) (0, 1, 0)
sage: W = WeylGroup(RootSystem([‘A’,2]).root_lattice()) sage: s = W.simple_reflections() sage: alpha = W.domain().simple_roots() sage: s[1].action(alpha[1]) -alpha[1]
sage: W=WeylGroup([‘A’,2,1]) sage: alpha = W.domain().simple_roots() sage: s = W.simple_reflections() sage: s[1].action(alpha[1]) -alpha[1] sage: s[1].action(alpha[0]) alpha[0] + alpha[1]
-
apply_simple_reflection
(i, side='right')¶
-
domain
()¶ Returns the ambient lattice associated with self.
EXAMPLES:
sage: W = WeylGroup(['A',2]) sage: s1 = W.simple_reflection(1) sage: s1.domain() Ambient space of the Root system of type ['A', 2]
-
has_descent
(i, positive=False, side='right')¶ Tests if self has a descent at position
, that is if self is on the strict negative side of the
simple reflection hyperplane.
If positive is True, tests if it is on the strict positive side instead.
EXAMPLES:
sage: W = WeylGroup(['A',3]) sage: s = W.simple_reflections() sage: [W.one().has_descent(i) for i in W.domain().index_set()] [False, False, False] sage: [s[1].has_descent(i) for i in W.domain().index_set()] [True, False, False] sage: [s[2].has_descent(i) for i in W.domain().index_set()] [False, True, False] sage: [s[3].has_descent(i) for i in W.domain().index_set()] [False, False, True] sage: [s[3].has_descent(i, True) for i in W.domain().index_set()] [True, True, False] sage: W = WeylGroup(['A',3,1]) sage: s = W.simple_reflections() sage: [W.one().has_descent(i) for i in W.domain().index_set()] [False, False, False, False] sage: [s[0].has_descent(i) for i in W.domain().index_set()] [True, False, False, False] sage: w = s[0] * s[1] sage: [w.has_descent(i) for i in W.domain().index_set()] [False, True, False, False] sage: [w.has_descent(i, side = "left") for i in W.domain().index_set()] [True, False, False, False] sage: w = s[0] * s[2] sage: [w.has_descent(i) for i in W.domain().index_set()] [True, False, True, False] sage: [w.has_descent(i, side = "left") for i in W.domain().index_set()] [True, False, True, False] sage: W = WeylGroup(['A',3]) sage: W.one().has_descent(0) True sage: W.w0.has_descent(0) False
-
has_left_descent
(i)¶ Tests if self has a left descent at position
.
EXAMPLES:
sage: W = WeylGroup(['A',3]) sage: s = W.simple_reflections() sage: [W.one().has_descent(i) for i in W.domain().index_set()] [False, False, False] sage: [s[1].has_descent(i) for i in W.domain().index_set()] [True, False, False] sage: [s[2].has_descent(i) for i in W.domain().index_set()] [False, True, False] sage: [s[3].has_descent(i) for i in W.domain().index_set()] [False, False, True] sage: [s[3].has_descent(i, True) for i in W.domain().index_set()] [True, True, False]
-
to_permutation
()¶ A first approximation of to_permutation ...
This assumes types A,B,C,D on the ambient lattice
This further assume that the basis is indexed by 0,1,... and returns a permutation of (5,4,2,3,1) (beuargl), as a tuple
-
to_permutation_string
()¶ EXAMPLES:
sage: W = WeylGroup(["A",3]) sage: s = W.simple_reflections() sage: (s[1]*s[2]*s[3]).to_permutation_string() '2341'
-
-
class
sage.combinat.root_system.weyl_group.
WeylGroup_gens
(domain, prefix)¶ Bases:
sage.misc.cachefunc.ClearCacheOnPickle
,sage.structure.unique_representation.UniqueRepresentation
,sage.groups.matrix_gps.finitely_generated.FinitelyGeneratedMatrixGroup_gap
EXAMPLES:
sage: G = WeylGroup(['B',3]) sage: TestSuite(G).run() sage: cm = CartanMatrix([[2,-5,0],[-2,2,-1],[0,-1,2]]) sage: W = WeylGroup(cm) sage: TestSuite(W).run() # long time
-
Element
¶ alias of
WeylGroupElement
-
bruhat_graph
(x, y)¶ Return the Bruhat graph as a directed graph, with an edge
if and only if
in the Bruhat order, and
.
The Bruhat graph
, defined if
in the Bruhat order, has as its vertices the Bruhat interval
, and as its edges are the pairs
such that
where
is a reflection, that is, a conjugate of a simple reflection.
REFERENCES:
Carrell, The Bruhat graph of a Coxeter group, a conjecture of Deodhar, and rational smoothness of Schubert varieties. Algebraic groups and their generalizations: classical methods (University Park, PA, 1991), 53–61, Proc. Sympos. Pure Math., 56, Part 1, Amer. Math. Soc., Providence, RI, 1994.
EXAMPLES:
sage: W = WeylGroup("A3", prefix="s") sage: s1, s2, s3 = W.simple_reflections() sage: G = W.bruhat_graph(s1*s3, s1*s2*s3*s2*s1); G Digraph on 10 vertices
Check that the graph has the correct number of edges (see trac ticket #17744):
sage: len(G.edges()) 16
-
cartan_type
()¶ Returns the CartanType associated to self.
EXAMPLES:
sage: G = WeylGroup(['F',4]) sage: G.cartan_type() ['F', 4]
-
character_table
()¶ Returns the character table as a matrix
Each row is an irreducible character. For larger tables you may preface this with a command such as gap.eval(“SizeScreen([120,40])”) in order to widen the screen.
EXAMPLES:
sage: WeylGroup(['A',3]).character_table() CT1 2 3 2 2 . 3 3 1 . . 1 . 1a 4a 2a 3a 2b X.1 1 -1 -1 1 1 X.2 3 1 -1 . -1 X.3 2 . . -1 2 X.4 3 -1 1 . -1 X.5 1 1 1 1 1
-
classical
()¶ If
self
is a Weyl group from an affine Cartan Type, this give the classical parabolic subgroup ofself
.Caveat: we assume that 0 is a special node of the Dynkin diagram
TODO: extract parabolic subgroup method
EXAMPLES:
sage: G = WeylGroup(['A',3,1]) sage: G.classical() Parabolic Subgroup of the Weyl Group of type ['A', 3, 1] (as a matrix group acting on the root space) sage: WeylGroup(['A',3]).classical() Traceback (most recent call last): ... ValueError: classical subgroup only defined for affine types
-
coxeter_matrix
()¶ Return the Coxeter matrix associated to
self
.EXAMPLES:
sage: G = WeylGroup(['A',3]) sage: G.coxeter_matrix() [1 3 2] [3 1 3] [2 3 1]
-
domain
()¶ Returns the domain of the element of
self
, that is the root lattice realization on which they act.EXAMPLES:
sage: G = WeylGroup(['F',4]) sage: G.domain() Ambient space of the Root system of type ['F', 4] sage: G = WeylGroup(['A',3,1]) sage: G.domain() Root space over the Rational Field of the Root system of type ['A', 3, 1]
-
from_morphism
(f)¶
-
index_set
()¶ Returns the index set of self.
EXAMPLES:
sage: G = WeylGroup(['F',4]) sage: G.index_set() (1, 2, 3, 4) sage: G = WeylGroup(['A',3,1]) sage: G.index_set() (0, 1, 2, 3)
-
long_element_hardcoded
()¶ Returns the long Weyl group element (hardcoded data)
Do we really want to keep it? There is a generic implementation which works in all cases. The hardcoded should have a better complexity (for large classical types), but there is a cache, so does this really matter?
EXAMPLES:
sage: types = [ ['A',5],['B',3],['C',3],['D',4],['G',2],['F',4],['E',6] ] sage: [WeylGroup(t).long_element().length() for t in types] [15, 9, 9, 12, 6, 24, 36] sage: all( WeylGroup(t).long_element() == WeylGroup(t).long_element_hardcoded() for t in types ) # long time (17s on sage.math, 2011) True
-
morphism_matrix
(f)¶
-
one
()¶ Returns the unit element of the Weyl group
- EXAMPLES::
- sage: W = WeylGroup([‘A’,3]) sage: e = W.one(); e [1 0 0 0] [0 1 0 0] [0 0 1 0] [0 0 0 1] sage: type(e) == W.element_class True
-
reflections
()¶ The reflections of W are the conjugates of the simple reflections. They are in bijection with the positive roots, for given a positive root, we may have the reflection in the hyperplane orthogonal to it. This method returns a dictionary indexed by the reflections taking values in the positive roots. This requires self to be a finite Weyl group.
EXAMPLES:
sage: W = WeylGroup("B2", prefix="s") sage: refdict = W.reflections(); refdict Finite family {s1: (1, -1), s2*s1*s2: (1, 1), s1*s2*s1: (1, 0), s2: (0, 1)} sage: [refdict[r]+r.action(refdict[r]) for r in refdict.keys()] [(0, 0), (0, 0), (0, 0), (0, 0)]
-
simple_reflection
(i)¶ Returns the
simple reflection.
EXAMPLES:
sage: G = WeylGroup(['F',4]) sage: G.simple_reflection(1) [1 0 0 0] [0 0 1 0] [0 1 0 0] [0 0 0 1] sage: W=WeylGroup(['A',2,1]) sage: W.simple_reflection(1) [ 1 0 0] [ 1 -1 1] [ 0 0 1]
-
simple_reflections
()¶ Returns the simple reflections of self, as a family.
EXAMPLES:
There are the simple reflections for the symmetric group:
sage: W=WeylGroup(['A',2]) sage: s = W.simple_reflections(); s Finite family {1: [0 1 0] [1 0 0] [0 0 1], 2: [1 0 0] [0 0 1] [0 1 0]}
As a special feature, for finite irreducible root systems, s[0] gives the reflection along the highest root:
sage: s[0] [0 0 1] [0 1 0] [1 0 0]
We now look at some further examples:
sage: W=WeylGroup(['A',2,1]) sage: W.simple_reflections() Finite family {0: [-1 1 1] [ 0 1 0] [ 0 0 1], 1: [ 1 0 0] [ 1 -1 1] [ 0 0 1], 2: [ 1 0 0] [ 0 1 0] [ 1 1 -1]} sage: W = WeylGroup(['F',4]) sage: [s1,s2,s3,s4] = W.simple_reflections() sage: w = s1*s2*s3*s4; w [ 1/2 1/2 1/2 1/2] [-1/2 1/2 1/2 -1/2] [ 1/2 1/2 -1/2 -1/2] [ 1/2 -1/2 1/2 -1/2] sage: s4^2 == W.one() True sage: type(w) == W.element_class True
-
unit
()¶ Returns the unit element of the Weyl group
- EXAMPLES::
- sage: W = WeylGroup([‘A’,3]) sage: e = W.one(); e [1 0 0 0] [0 1 0 0] [0 0 1 0] [0 0 0 1] sage: type(e) == W.element_class True
-