Weyl Groups¶
AUTHORS:
Daniel Bump (2008): initial version
Mike Hansen (2008): initial version
Anne Schilling (2008): initial version
Nicolas Thiéry (2008): initial version
Volker Braun (2013): LibGAP-based matrix groups
EXAMPLES:
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) # needs sage.plot
>>> from sage.all import *
>>> w = WeylGroup(['A',Integer(3)])
>>> d = w.cayley_graph(); d
Digraph on 24 vertices
>>> d.show3d(color_by_label=True, edge_size=RealNumber('0.01'), vertex_size=RealNumber('0.03')) # needs sage.plot
w = WeylGroup(['A',3]) d = w.cayley_graph(); d d.show3d(color_by_label=True, edge_size=0.01, vertex_size=0.03) # needs sage.plot
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), needs sage.plot
>>> from sage.all import *
>>> w = WeylGroup(['D',Integer(4)])
>>> d = w.cayley_graph(); d
Digraph on 192 vertices
>>> d.show3d(color_by_label=True, edge_size=RealNumber('0.01'), vertex_size=RealNumber('0.03')) # long time (less than one minute), needs sage.plot
w = WeylGroup(['D',4]) d = w.cayley_graph(); d d.show3d(color_by_label=True, edge_size=0.01, vertex_size=0.03) # long time (less than one minute), needs sage.plot
Todo
More examples on Weyl Groups should be added here.
- class sage.combinat.root_system.weyl_group.ClassicalWeylSubgroup(domain, prefix)[source]¶
Bases:
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 irreducible Weyl groups sage: G.cardinality() 24 sage: G.index_set() (1, 2, 3) sage: TestSuite(G).run()
>>> from sage.all import * >>> G = WeylGroup(["A",Integer(3),Integer(1)]).classical() >>> G Parabolic Subgroup of the Weyl Group of type ['A', 3, 1] (as a matrix group acting on the root space) >>> G.category() Category of finite irreducible Weyl groups >>> G.cardinality() 24 >>> G.index_set() (1, 2, 3) >>> TestSuite(G).run()
G = WeylGroup(["A",3,1]).classical() G G.category() G.cardinality() G.index_set() TestSuite(G).run()
Todo
implement:
Parabolic subrootsystems
Parabolic subgroups with a set of nodes as argument
- cartan_type()[source]¶
EXAMPLES:
sage: WeylGroup(['A',3,1]).classical().cartan_type() ['A', 3] sage: WeylGroup(['A',3,1]).classical().index_set() (1, 2, 3)
>>> from sage.all import * >>> WeylGroup(['A',Integer(3),Integer(1)]).classical().cartan_type() ['A', 3] >>> WeylGroup(['A',Integer(3),Integer(1)]).classical().index_set() (1, 2, 3)
WeylGroup(['A',3,1]).classical().cartan_type() WeylGroup(['A',3,1]).classical().index_set()
Note: won’t be needed, once the lattice will be a parabolic sub root system
- simple_reflections()[source]¶
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]}
>>> from sage.all import * >>> WeylGroup(['A',Integer(2),Integer(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]}
WeylGroup(['A',2,1]).classical().simple_reflections()
Note: won’t be needed, once the lattice will be a parabolic sub root system
- weyl_group(prefix='hereditary')[source]¶
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)
>>> from sage.all import * >>> WeylGroup(['A',Integer(4),Integer(1)]).classical().weyl_group() Weyl Group of type ['A', 4, 1] (as a matrix group acting on the root space) >>> WeylGroup(['C',Integer(4),Integer(1)]).classical().weyl_group() Weyl Group of type ['C', 4, 1] (as a matrix group acting on the root space) >>> WeylGroup(['E',Integer(8),Integer(1)]).classical().weyl_group() Weyl Group of type ['E', 8, 1] (as a matrix group acting on the root space)
WeylGroup(['A',4,1]).classical().weyl_group() WeylGroup(['C',4,1]).classical().weyl_group() WeylGroup(['E',8,1]).classical().weyl_group()
- sage.combinat.root_system.weyl_group.WeylGroup(x, prefix=None, implementation='matrix')[source]¶
Return 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 reflectionsimplementation
– one of the following:'matrix'
– as matrices acting on a root system'permutation'
– as a permutation group acting on the roots
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()
>>> from sage.all import * >>> G = WeylGroup(['F',Integer(4)]) >>> L = G.domain()
G = WeylGroup(['F',4]) L = G.domain()
or alternatively and equivalently:
sage: L = RootSystem(['F',4]).ambient_space() sage: G = L.weyl_group() sage: W = WeylGroup(L)
>>> from sage.all import * >>> L = RootSystem(['F',Integer(4)]).ambient_space() >>> G = L.weyl_group() >>> W = WeylGroup(L)
L = RootSystem(['F',4]).ambient_space() G = L.weyl_group() 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
>>> from sage.all import * >>> G = WeylGroup(['F',Integer(4)]) >>> G.order() 1152 >>> [s1,s2,s3,s4] = G.simple_reflections() >>> 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] >>> type(w) == G.element_class True >>> w.order() 12 >>> w.length() # length function on Weyl group 4
G = WeylGroup(['F',4]) G.order() [s1,s2,s3,s4] = G.simple_reflections() w = s1*s2*s3*s4; w type(w) == G.element_class w.order() w.length() # length function on Weyl group
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]
>>> from sage.all import * >>> W=WeylGroup("C3",prefix='s') >>> [s1,s2,s3]=W.simple_reflections() # lets Sage parse its own output >>> s2*s1*s2*s3 s1*s2*s3*s1 >>> s2*s1*s2*s3 == s1*s2*s3*s1 True >>> (s2*s3)**Integer(2)==(s3*s2)**Integer(2) True >>> (s1*s2*s3*s1).matrix() [ 0 0 -1] [ 0 1 0] [ 1 0 0]
W=WeylGroup("C3",prefix='s') [s1,s2,s3]=W.simple_reflections() # lets Sage parse its own output s2*s1*s2*s3 s2*s1*s2*s3 == s1*s2*s3*s1 (s2*s3)^2==(s3*s2)^2 (s1*s2*s3*s1).matrix()
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)
>>> from sage.all import * >>> L = G.domain() >>> 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)} >>> rho = sum(fw); rho (11/2, 5/2, 3/2, 1/2) >>> w.action(rho) # action of G on weight lattice (5, -1, 3, 2)
L = G.domain() fw = L.fundamental_weights(); fw rho = sum(fw); rho w.action(rho) # action of G on weight lattice
>>> from sage.all import * >>> L = G.domain() >>> 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)} >>> rho = sum(fw); rho (11/2, 5/2, 3/2, 1/2) >>> w.action(rho) # action of G on weight lattice (5, -1, 3, 2)
L = G.domain() fw = L.fundamental_weights(); fw rho = sum(fw); rho w.action(rho) # action of G on weight lattice
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]
>>> from sage.all import * >>> cm = CartanMatrix([[Integer(2),-Integer(5),Integer(0)],[-Integer(2),Integer(2),-Integer(1)],[Integer(0),-Integer(1),Integer(2)]]) >>> W = WeylGroup(cm) >>> 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] ) >>> s0,s1,s2 = W.gens() >>> s1*s2*s1 [ 1 0 0] [ 2 0 -1] [ 2 -1 0] >>> s2*s1*s2 [ 1 0 0] [ 2 0 -1] [ 2 -1 0] >>> s0*s1*s0*s2*s0 [ 9 0 -5] [ 2 0 -1] [ 0 1 -1]
cm = CartanMatrix([[2,-5,0],[-2,2,-1],[0,-1,2]]) W = WeylGroup(cm) W.gens() s0,s1,s2 = W.gens() s1*s2*s1 s2*s1*s2 s0*s1*s0*s2*s0
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
>>> from sage.all import * >>> W = WeylGroup(cm, prefix='s') >>> s0,s1,s2 = W.gens() >>> s0*s2*s1 s2*s0*s1 >>> (s1*s2)**Integer(3) 1 >>> (s0*s1)**Integer(5) s0*s1*s0*s1*s0*s1*s0*s1*s0*s1 >>> s0*s1*s2*s1*s2 s2*s0*s1 >>> s0*s1*s2*s0*s2 s0*s1*s0
W = WeylGroup(cm, prefix='s') s0,s1,s2 = W.gens() s0*s2*s1 (s1*s2)^3 (s0*s1)^5 s0*s1*s2*s1*s2 s0*s1*s2*s0*s2
- class sage.combinat.root_system.weyl_group.WeylGroupElement(parent, g, check=False)[source]¶
Bases:
MatrixGroupElement_gap
Class for a Weyl Group elements
- action(v)[source]¶
Return 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]
>>> from sage.all import * >>> W = WeylGroup(['A',Integer(2)]) >>> s = W.simple_reflections() >>> v = W.domain()([Integer(1),Integer(0),Integer(0)]) >>> s[Integer(1)].action(v) (0, 1, 0) >>> W = WeylGroup(RootSystem(['A',Integer(2)]).root_lattice()) >>> s = W.simple_reflections() >>> alpha = W.domain().simple_roots() >>> s[Integer(1)].action(alpha[Integer(1)]) -alpha[1] >>> W=WeylGroup(['A',Integer(2),Integer(1)]) >>> alpha = W.domain().simple_roots() >>> s = W.simple_reflections() >>> s[Integer(1)].action(alpha[Integer(1)]) -alpha[1] >>> s[Integer(1)].action(alpha[Integer(0)]) alpha[0] + alpha[1]
W = WeylGroup(['A',2]) s = W.simple_reflections() v = W.domain()([1,0,0]) s[1].action(v) W = WeylGroup(RootSystem(['A',2]).root_lattice()) s = W.simple_reflections() alpha = W.domain().simple_roots() s[1].action(alpha[1]) W=WeylGroup(['A',2,1]) alpha = W.domain().simple_roots() s = W.simple_reflections() s[1].action(alpha[1]) s[1].action(alpha[0])
- domain()[source]¶
Return 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]
>>> from sage.all import * >>> W = WeylGroup(['A',Integer(2)]) >>> s1 = W.simple_reflection(Integer(1)) >>> s1.domain() Ambient space of the Root system of type ['A', 2]
W = WeylGroup(['A',2]) s1 = W.simple_reflection(1) s1.domain()
- has_descent(i, positive=False, side='right')[source]¶
Test if
self
has a descent at positioni
.An element \(w\) has a descent in position \(i\) if \(w\) is on the strict negative side of the \(i\)-th simple reflection hyperplane.
If
positive
isTrue
, 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
>>> from sage.all import * >>> W = WeylGroup(['A',Integer(3)]) >>> s = W.simple_reflections() >>> [W.one().has_descent(i) for i in W.domain().index_set()] [False, False, False] >>> [s[Integer(1)].has_descent(i) for i in W.domain().index_set()] [True, False, False] >>> [s[Integer(2)].has_descent(i) for i in W.domain().index_set()] [False, True, False] >>> [s[Integer(3)].has_descent(i) for i in W.domain().index_set()] [False, False, True] >>> [s[Integer(3)].has_descent(i, True) for i in W.domain().index_set()] [True, True, False] >>> W = WeylGroup(['A',Integer(3),Integer(1)]) >>> s = W.simple_reflections() >>> [W.one().has_descent(i) for i in W.domain().index_set()] [False, False, False, False] >>> [s[Integer(0)].has_descent(i) for i in W.domain().index_set()] [True, False, False, False] >>> w = s[Integer(0)] * s[Integer(1)] >>> [w.has_descent(i) for i in W.domain().index_set()] [False, True, False, False] >>> [w.has_descent(i, side = "left") for i in W.domain().index_set()] [True, False, False, False] >>> w = s[Integer(0)] * s[Integer(2)] >>> [w.has_descent(i) for i in W.domain().index_set()] [True, False, True, False] >>> [w.has_descent(i, side = "left") for i in W.domain().index_set()] [True, False, True, False] >>> W = WeylGroup(['A',Integer(3)]) >>> W.one().has_descent(Integer(0)) True >>> W.w0.has_descent(Integer(0)) False
W = WeylGroup(['A',3]) s = W.simple_reflections() [W.one().has_descent(i) for i in W.domain().index_set()] [s[1].has_descent(i) for i in W.domain().index_set()] [s[2].has_descent(i) for i in W.domain().index_set()] [s[3].has_descent(i) for i in W.domain().index_set()] [s[3].has_descent(i, True) for i in W.domain().index_set()] W = WeylGroup(['A',3,1]) s = W.simple_reflections() [W.one().has_descent(i) for i in W.domain().index_set()] [s[0].has_descent(i) for i in W.domain().index_set()] w = s[0] * s[1] [w.has_descent(i) for i in W.domain().index_set()] [w.has_descent(i, side = "left") for i in W.domain().index_set()] w = s[0] * s[2] [w.has_descent(i) for i in W.domain().index_set()] [w.has_descent(i, side = "left") for i in W.domain().index_set()] W = WeylGroup(['A',3]) W.one().has_descent(0) W.w0.has_descent(0)
- has_left_descent(i)[source]¶
Test if
self
has a left descent at positioni
.EXAMPLES:
sage: W = WeylGroup(['A',3]) sage: s = W.simple_reflections() sage: [W.one().has_left_descent(i) for i in W.domain().index_set()] [False, False, False] sage: [s[1].has_left_descent(i) for i in W.domain().index_set()] [True, False, False] sage: [s[2].has_left_descent(i) for i in W.domain().index_set()] [False, True, False] sage: [s[3].has_left_descent(i) for i in W.domain().index_set()] [False, False, True] sage: [(s[3]*s[2]).has_left_descent(i) for i in W.domain().index_set()] [False, False, True]
>>> from sage.all import * >>> W = WeylGroup(['A',Integer(3)]) >>> s = W.simple_reflections() >>> [W.one().has_left_descent(i) for i in W.domain().index_set()] [False, False, False] >>> [s[Integer(1)].has_left_descent(i) for i in W.domain().index_set()] [True, False, False] >>> [s[Integer(2)].has_left_descent(i) for i in W.domain().index_set()] [False, True, False] >>> [s[Integer(3)].has_left_descent(i) for i in W.domain().index_set()] [False, False, True] >>> [(s[Integer(3)]*s[Integer(2)]).has_left_descent(i) for i in W.domain().index_set()] [False, False, True]
W = WeylGroup(['A',3]) s = W.simple_reflections() [W.one().has_left_descent(i) for i in W.domain().index_set()] [s[1].has_left_descent(i) for i in W.domain().index_set()] [s[2].has_left_descent(i) for i in W.domain().index_set()] [s[3].has_left_descent(i) for i in W.domain().index_set()] [(s[3]*s[2]).has_left_descent(i) for i in W.domain().index_set()]
- has_right_descent(i)[source]¶
Test if
self
has a right descent at positioni
.EXAMPLES:
sage: W = WeylGroup(['A',3]) sage: s = W.simple_reflections() sage: [W.one().has_right_descent(i) for i in W.domain().index_set()] [False, False, False] sage: [s[1].has_right_descent(i) for i in W.domain().index_set()] [True, False, False] sage: [s[2].has_right_descent(i) for i in W.domain().index_set()] [False, True, False] sage: [s[3].has_right_descent(i) for i in W.domain().index_set()] [False, False, True] sage: [(s[3]*s[2]).has_right_descent(i) for i in W.domain().index_set()] [False, True, False]
>>> from sage.all import * >>> W = WeylGroup(['A',Integer(3)]) >>> s = W.simple_reflections() >>> [W.one().has_right_descent(i) for i in W.domain().index_set()] [False, False, False] >>> [s[Integer(1)].has_right_descent(i) for i in W.domain().index_set()] [True, False, False] >>> [s[Integer(2)].has_right_descent(i) for i in W.domain().index_set()] [False, True, False] >>> [s[Integer(3)].has_right_descent(i) for i in W.domain().index_set()] [False, False, True] >>> [(s[Integer(3)]*s[Integer(2)]).has_right_descent(i) for i in W.domain().index_set()] [False, True, False]
W = WeylGroup(['A',3]) s = W.simple_reflections() [W.one().has_right_descent(i) for i in W.domain().index_set()] [s[1].has_right_descent(i) for i in W.domain().index_set()] [s[2].has_right_descent(i) for i in W.domain().index_set()] [s[3].has_right_descent(i) for i in W.domain().index_set()] [(s[3]*s[2]).has_right_descent(i) for i in W.domain().index_set()]
- to_matrix()[source]¶
Return
self
as a matrix.EXAMPLES:
sage: G = WeylGroup(['A',2]) sage: s1 = G.simple_reflection(1) sage: s1.to_matrix() == s1.matrix() True
>>> from sage.all import * >>> G = WeylGroup(['A',Integer(2)]) >>> s1 = G.simple_reflection(Integer(1)) >>> s1.to_matrix() == s1.matrix() True
G = WeylGroup(['A',2]) s1 = G.simple_reflection(1) s1.to_matrix() == s1.matrix()
- to_permutation()[source]¶
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()[source]¶
EXAMPLES:
sage: W = WeylGroup(["A",3]) sage: s = W.simple_reflections() sage: (s[1]*s[2]*s[3]).to_permutation_string() '2341'
>>> from sage.all import * >>> W = WeylGroup(["A",Integer(3)]) >>> s = W.simple_reflections() >>> (s[Integer(1)]*s[Integer(2)]*s[Integer(3)]).to_permutation_string() '2341'
W = WeylGroup(["A",3]) s = W.simple_reflections() (s[1]*s[2]*s[3]).to_permutation_string()
- class sage.combinat.root_system.weyl_group.WeylGroup_gens(domain, prefix)[source]¶
Bases:
UniqueRepresentation
,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
>>> from sage.all import * >>> G = WeylGroup(['B',Integer(3)]) >>> TestSuite(G).run() >>> cm = CartanMatrix([[Integer(2),-Integer(5),Integer(0)],[-Integer(2),Integer(2),-Integer(1)],[Integer(0),-Integer(1),Integer(2)]]) >>> W = WeylGroup(cm) >>> TestSuite(W).run() # long time
G = WeylGroup(['B',3]) TestSuite(G).run() cm = CartanMatrix([[2,-5,0],[-2,2,-1],[0,-1,2]]) W = WeylGroup(cm) TestSuite(W).run() # long time
- Element[source]¶
alias of
WeylGroupElement
- cartan_type()[source]¶
Return the
CartanType
associated toself
.EXAMPLES:
sage: G = WeylGroup(['F',4]) sage: G.cartan_type() ['F', 4]
>>> from sage.all import * >>> G = WeylGroup(['F',Integer(4)]) >>> G.cartan_type() ['F', 4]
G = WeylGroup(['F',4]) G.cartan_type()
- character_table()[source]¶
Return 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
>>> from sage.all import * >>> WeylGroup(['A',Integer(3)]).character_table() CT1 <BLANKLINE> 2 3 2 2 . 3 3 1 . . 1 . <BLANKLINE> 1a 4a 2a 3a 2b <BLANKLINE> 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
WeylGroup(['A',3]).character_table()
- classical()[source]¶
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
>>> from sage.all import * >>> G = WeylGroup(['A',Integer(3),Integer(1)]) >>> G.classical() Parabolic Subgroup of the Weyl Group of type ['A', 3, 1] (as a matrix group acting on the root space) >>> WeylGroup(['A',Integer(3)]).classical() Traceback (most recent call last): ... ValueError: classical subgroup only defined for affine types
G = WeylGroup(['A',3,1]) G.classical() WeylGroup(['A',3]).classical()
- domain()[source]¶
Return 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 sage.all import * >>> G = WeylGroup(['F',Integer(4)]) >>> G.domain() Ambient space of the Root system of type ['F', 4] >>> G = WeylGroup(['A',Integer(3),Integer(1)]) >>> G.domain() Root space over the Rational Field of the Root system of type ['A', 3, 1]
G = WeylGroup(['F',4]) G.domain() G = WeylGroup(['A',3,1]) G.domain()
- index_set()[source]¶
Return 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)
>>> from sage.all import * >>> G = WeylGroup(['F',Integer(4)]) >>> G.index_set() (1, 2, 3, 4) >>> G = WeylGroup(['A',Integer(3),Integer(1)]) >>> G.index_set() (0, 1, 2, 3)
G = WeylGroup(['F',4]) G.index_set() G = WeylGroup(['A',3,1]) G.index_set()
- long_element_hardcoded()[source]¶
Return 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
>>> from sage.all import * >>> types = [ ['A',Integer(5)],['B',Integer(3)],['C',Integer(3)],['D',Integer(4)],['G',Integer(2)],['F',Integer(4)],['E',Integer(6)] ] >>> [WeylGroup(t).long_element().length() for t in types] [15, 9, 9, 12, 6, 24, 36] >>> all(WeylGroup(t).long_element() == WeylGroup(t).long_element_hardcoded() for t in types) # long time (17s on sage.math, 2011) True
types = [ ['A',5],['B',3],['C',3],['D',4],['G',2],['F',4],['E',6] ] [WeylGroup(t).long_element().length() for t in types] all(WeylGroup(t).long_element() == WeylGroup(t).long_element_hardcoded() for t in types) # long time (17s on sage.math, 2011)
- one()[source]¶
Return 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
>>> from sage.all import * >>> W = WeylGroup(['A',Integer(3)]) >>> e = W.one(); e [1 0 0 0] [0 1 0 0] [0 0 1 0] [0 0 0 1] >>> type(e) == W.element_class True
W = WeylGroup(['A',3]) e = W.one(); e type(e) == W.element_class
- reflections()[source]¶
Return the reflections of
self
.The reflections of a Coxeter group \(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 family indexed by the positive roots taking values in the reflections. This requires
self
to be a finite Weyl group.Note
Prior to Issue #20027, the reflections were the keys of the family and the values were the positive roots.
EXAMPLES:
sage: W = WeylGroup("B2", prefix='s') sage: refdict = W.reflections(); refdict Finite family {(1, -1): s1, (0, 1): s2, (1, 1): s2*s1*s2, (1, 0): s1*s2*s1} sage: [r+refdict[r].action(r) for r in refdict.keys()] [(0, 0), (0, 0), (0, 0), (0, 0)] sage: W = WeylGroup(['A',2,1], prefix='s') sage: W.reflections() Lazy family (real root to reflection(i))_{i in Positive real roots of type ['A', 2, 1]}
>>> from sage.all import * >>> W = WeylGroup("B2", prefix='s') >>> refdict = W.reflections(); refdict Finite family {(1, -1): s1, (0, 1): s2, (1, 1): s2*s1*s2, (1, 0): s1*s2*s1} >>> [r+refdict[r].action(r) for r in refdict.keys()] [(0, 0), (0, 0), (0, 0), (0, 0)] >>> W = WeylGroup(['A',Integer(2),Integer(1)], prefix='s') >>> W.reflections() Lazy family (real root to reflection(i))_{i in Positive real roots of type ['A', 2, 1]}
W = WeylGroup("B2", prefix='s') refdict = W.reflections(); refdict [r+refdict[r].action(r) for r in refdict.keys()] W = WeylGroup(['A',2,1], prefix='s') W.reflections()
- simple_reflection(i)[source]¶
Return the \(i\)-th 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]
>>> from sage.all import * >>> G = WeylGroup(['F',Integer(4)]) >>> G.simple_reflection(Integer(1)) [1 0 0 0] [0 0 1 0] [0 1 0 0] [0 0 0 1] >>> W=WeylGroup(['A',Integer(2),Integer(1)]) >>> W.simple_reflection(Integer(1)) [ 1 0 0] [ 1 -1 1] [ 0 0 1]
G = WeylGroup(['F',4]) G.simple_reflection(1) W=WeylGroup(['A',2,1]) W.simple_reflection(1)
- simple_reflections()[source]¶
Return 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]}
>>> from sage.all import * >>> W=WeylGroup(['A',Integer(2)]) >>> 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]}
W=WeylGroup(['A',2]) s = W.simple_reflections(); s
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]
>>> from sage.all import * >>> s[Integer(0)] [0 0 1] [0 1 0] [1 0 0]
s[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
>>> from sage.all import * >>> W=WeylGroup(['A',Integer(2),Integer(1)]) >>> 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]} >>> W = WeylGroup(['F',Integer(4)]) >>> [s1,s2,s3,s4] = W.simple_reflections() >>> 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] >>> s4**Integer(2) == W.one() True >>> type(w) == W.element_class True
W=WeylGroup(['A',2,1]) W.simple_reflections() W = WeylGroup(['F',4]) [s1,s2,s3,s4] = W.simple_reflections() w = s1*s2*s3*s4; w s4^2 == W.one() type(w) == W.element_class
- unit()[source]¶
Return 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
>>> from sage.all import * >>> W = WeylGroup(['A',Integer(3)]) >>> e = W.one(); e [1 0 0 0] [0 1 0 0] [0 0 1 0] [0 0 0 1] >>> type(e) == W.element_class True
W = WeylGroup(['A',3]) e = W.one(); e type(e) == W.element_class
- class sage.combinat.root_system.weyl_group.WeylGroup_permutation(cartan_type, prefix)[source]¶
Bases:
UniqueRepresentation
,PermutationGroup_generic
A Weyl group given as a permutation group.
- cartan_type()[source]¶
Return the Cartan type of
self
.EXAMPLES:
sage: W = WeylGroup(['A',4], implementation='permutation') sage: W.cartan_type() ['A', 4]
>>> from sage.all import * >>> W = WeylGroup(['A',Integer(4)], implementation='permutation') >>> W.cartan_type() ['A', 4]
W = WeylGroup(['A',4], implementation='permutation') W.cartan_type()
- distinguished_reflections()[source]¶
Return the reflections of
self
.EXAMPLES:
sage: W = WeylGroup(['B',2], implementation='permutation') sage: W.distinguished_reflections() Finite family {1: (1,5)(2,4)(6,8), 2: (1,3)(2,6)(5,7), 3: (2,8)(3,7)(4,6), 4: (1,7)(3,5)(4,8)}
>>> from sage.all import * >>> W = WeylGroup(['B',Integer(2)], implementation='permutation') >>> W.distinguished_reflections() Finite family {1: (1,5)(2,4)(6,8), 2: (1,3)(2,6)(5,7), 3: (2,8)(3,7)(4,6), 4: (1,7)(3,5)(4,8)}
W = WeylGroup(['B',2], implementation='permutation') W.distinguished_reflections()
- independent_roots()[source]¶
Return the simple roots of
self
.EXAMPLES:
sage: W = WeylGroup(['A',4], implementation='permutation') sage: W.simple_roots() Finite family {1: (1, 0, 0, 0), 2: (0, 1, 0, 0), 3: (0, 0, 1, 0), 4: (0, 0, 0, 1)}
>>> from sage.all import * >>> W = WeylGroup(['A',Integer(4)], implementation='permutation') >>> W.simple_roots() Finite family {1: (1, 0, 0, 0), 2: (0, 1, 0, 0), 3: (0, 0, 1, 0), 4: (0, 0, 0, 1)}
W = WeylGroup(['A',4], implementation='permutation') W.simple_roots()
- index_set()[source]¶
Return the index set of
self
.EXAMPLES:
sage: W = WeylGroup(['A',4], implementation='permutation') sage: W.index_set() (1, 2, 3, 4)
>>> from sage.all import * >>> W = WeylGroup(['A',Integer(4)], implementation='permutation') >>> W.index_set() (1, 2, 3, 4)
W = WeylGroup(['A',4], implementation='permutation') W.index_set()
- iteration(algorithm='breadth', tracking_words=True)[source]¶
Return an iterator going through all elements in
self
.INPUT:
algorithm
– (default:'breadth'
) must be one of the following:'breadth'
– iterate over in a linear extension of the weak order'depth'
– iterate by a depth-first-search
tracking_words
– boolean (default:True
); whether or not to keep track of the reduced words and store them in_reduced_word
Note
The fastest iteration is the depth first algorithm without tracking words. In particular,
'depth'
is ~1.5x faster.EXAMPLES:
sage: W = WeylGroup(["B",2], implementation='permutation') sage: for w in W.iteration("breadth",True): ....: print("%s %s"%(w, w._reduced_word)) () [] (1,3)(2,6)(5,7) [1] (1,5)(2,4)(6,8) [0] (1,7,5,3)(2,4,6,8) [0, 1] (1,3,5,7)(2,8,6,4) [1, 0] (2,8)(3,7)(4,6) [1, 0, 1] (1,7)(3,5)(4,8) [0, 1, 0] (1,5)(2,6)(3,7)(4,8) [0, 1, 0, 1] sage: for w in W.iteration("depth", False): w () (1,3)(2,6)(5,7) (1,5)(2,4)(6,8) (1,3,5,7)(2,8,6,4) (1,7)(3,5)(4,8) (1,7,5,3)(2,4,6,8) (2,8)(3,7)(4,6) (1,5)(2,6)(3,7)(4,8)
>>> from sage.all import * >>> W = WeylGroup(["B",Integer(2)], implementation='permutation') >>> for w in W.iteration("breadth",True): ... print("%s %s"%(w, w._reduced_word)) () [] (1,3)(2,6)(5,7) [1] (1,5)(2,4)(6,8) [0] (1,7,5,3)(2,4,6,8) [0, 1] (1,3,5,7)(2,8,6,4) [1, 0] (2,8)(3,7)(4,6) [1, 0, 1] (1,7)(3,5)(4,8) [0, 1, 0] (1,5)(2,6)(3,7)(4,8) [0, 1, 0, 1] >>> for w in W.iteration("depth", False): w () (1,3)(2,6)(5,7) (1,5)(2,4)(6,8) (1,3,5,7)(2,8,6,4) (1,7)(3,5)(4,8) (1,7,5,3)(2,4,6,8) (2,8)(3,7)(4,6) (1,5)(2,6)(3,7)(4,8)
W = WeylGroup(["B",2], implementation='permutation') for w in W.iteration("breadth",True): print("%s %s"%(w, w._reduced_word)) for w in W.iteration("depth", False): w
- number_of_reflections()[source]¶
Return the number of reflections in
self
.EXAMPLES:
sage: W = WeylGroup(['D',4], implementation='permutation') sage: W.number_of_reflections() 12
>>> from sage.all import * >>> W = WeylGroup(['D',Integer(4)], implementation='permutation') >>> W.number_of_reflections() 12
W = WeylGroup(['D',4], implementation='permutation') W.number_of_reflections()
- positive_roots()[source]¶
Return the positive roots of
self
.EXAMPLES:
sage: W = WeylGroup(['C',3], implementation='permutation') sage: W.positive_roots() ((1, 0, 0), (0, 1, 0), (0, 0, 1), (1, 1, 0), (0, 1, 1), (0, 2, 1), (1, 1, 1), (2, 2, 1), (1, 2, 1))
>>> from sage.all import * >>> W = WeylGroup(['C',Integer(3)], implementation='permutation') >>> W.positive_roots() ((1, 0, 0), (0, 1, 0), (0, 0, 1), (1, 1, 0), (0, 1, 1), (0, 2, 1), (1, 1, 1), (2, 2, 1), (1, 2, 1))
W = WeylGroup(['C',3], implementation='permutation') W.positive_roots()
- rank()[source]¶
Return the rank of
self
.EXAMPLES:
sage: W = WeylGroup(['A',4], implementation='permutation') sage: W.rank() 4
>>> from sage.all import * >>> W = WeylGroup(['A',Integer(4)], implementation='permutation') >>> W.rank() 4
W = WeylGroup(['A',4], implementation='permutation') W.rank()
- reflection_index_set()[source]¶
Return the index set of reflections of
self
.EXAMPLES:
sage: W = WeylGroup(['A',3], implementation='permutation') sage: W.reflection_index_set() (1, 2, 3, 4, 5, 6)
>>> from sage.all import * >>> W = WeylGroup(['A',Integer(3)], implementation='permutation') >>> W.reflection_index_set() (1, 2, 3, 4, 5, 6)
W = WeylGroup(['A',3], implementation='permutation') W.reflection_index_set()
- reflections()[source]¶
Return the reflections of
self
.EXAMPLES:
sage: W = WeylGroup(['B',2], implementation='permutation') sage: W.distinguished_reflections() Finite family {1: (1,5)(2,4)(6,8), 2: (1,3)(2,6)(5,7), 3: (2,8)(3,7)(4,6), 4: (1,7)(3,5)(4,8)}
>>> from sage.all import * >>> W = WeylGroup(['B',Integer(2)], implementation='permutation') >>> W.distinguished_reflections() Finite family {1: (1,5)(2,4)(6,8), 2: (1,3)(2,6)(5,7), 3: (2,8)(3,7)(4,6), 4: (1,7)(3,5)(4,8)}
W = WeylGroup(['B',2], implementation='permutation') W.distinguished_reflections()
- roots()[source]¶
Return the roots of
self
.EXAMPLES:
sage: W = WeylGroup(['G',2], implementation='permutation') sage: W.roots() ((1, 0), (0, 1), (1, 1), (3, 1), (2, 1), (3, 2), (-1, 0), (0, -1), (-1, -1), (-3, -1), (-2, -1), (-3, -2))
>>> from sage.all import * >>> W = WeylGroup(['G',Integer(2)], implementation='permutation') >>> W.roots() ((1, 0), (0, 1), (1, 1), (3, 1), (2, 1), (3, 2), (-1, 0), (0, -1), (-1, -1), (-3, -1), (-2, -1), (-3, -2))
W = WeylGroup(['G',2], implementation='permutation') W.roots()
- simple_reflection(i)[source]¶
Return the
i
-th simple reflection ofself
.EXAMPLES:
sage: W = WeylGroup(['A',4], implementation='permutation') sage: W.simple_reflection(1) (1,11)(2,5)(6,8)(9,10)(12,15)(16,18)(19,20) sage: W.simple_reflections() Finite family {1: (1,11)(2,5)(6,8)(9,10)(12,15)(16,18)(19,20), 2: (1,5)(2,12)(3,6)(7,9)(11,15)(13,16)(17,19), 3: (2,6)(3,13)(4,7)(5,8)(12,16)(14,17)(15,18), 4: (3,7)(4,14)(6,9)(8,10)(13,17)(16,19)(18,20)}
>>> from sage.all import * >>> W = WeylGroup(['A',Integer(4)], implementation='permutation') >>> W.simple_reflection(Integer(1)) (1,11)(2,5)(6,8)(9,10)(12,15)(16,18)(19,20) >>> W.simple_reflections() Finite family {1: (1,11)(2,5)(6,8)(9,10)(12,15)(16,18)(19,20), 2: (1,5)(2,12)(3,6)(7,9)(11,15)(13,16)(17,19), 3: (2,6)(3,13)(4,7)(5,8)(12,16)(14,17)(15,18), 4: (3,7)(4,14)(6,9)(8,10)(13,17)(16,19)(18,20)}
W = WeylGroup(['A',4], implementation='permutation') W.simple_reflection(1) W.simple_reflections()
- simple_root_index(i)[source]¶
Return the index of the simple root \(\alpha_i\).
This is the position of \(\alpha_i\) in the list of simple roots.
EXAMPLES:
sage: W = WeylGroup(['A',3], implementation='permutation') sage: [W.simple_root_index(i) for i in W.index_set()] [0, 1, 2]
>>> from sage.all import * >>> W = WeylGroup(['A',Integer(3)], implementation='permutation') >>> [W.simple_root_index(i) for i in W.index_set()] [0, 1, 2]
W = WeylGroup(['A',3], implementation='permutation') [W.simple_root_index(i) for i in W.index_set()]
- simple_roots()[source]¶
Return the simple roots of
self
.EXAMPLES:
sage: W = WeylGroup(['A',4], implementation='permutation') sage: W.simple_roots() Finite family {1: (1, 0, 0, 0), 2: (0, 1, 0, 0), 3: (0, 0, 1, 0), 4: (0, 0, 0, 1)}
>>> from sage.all import * >>> W = WeylGroup(['A',Integer(4)], implementation='permutation') >>> W.simple_roots() Finite family {1: (1, 0, 0, 0), 2: (0, 1, 0, 0), 3: (0, 0, 1, 0), 4: (0, 0, 0, 1)}
W = WeylGroup(['A',4], implementation='permutation') W.simple_roots()