Finite real reflection groups#


Let \(V\) be a finite-dimensional real vector space. A reflection of \(V\) is an operator \(r \in \operatorname{GL}(V)\) that has order \(2\) and fixes pointwise a hyperplane in \(V\). In the present implementation, finite real reflection groups are tied with a root system.

Finite real reflection groups with root systems have been classified according to finite Cartan-Killing types. For more definitions and classification types of finite complex reflection groups, see Wikipedia article Complex_reflection_group.

The point of entry to work with reflection groups is ReflectionGroup() which can be used with finite Cartan-Killing types:

sage: ReflectionGroup(['A',2])                                      # optional - gap3
Irreducible real reflection group of rank 2 and type A2
sage: ReflectionGroup(['F',4])                                      # optional - gap3
Irreducible real reflection group of rank 4 and type F4
sage: ReflectionGroup(['H',3])                                      # optional - gap3
Irreducible real reflection group of rank 3 and type H3

AUTHORS:

  • Christian Stump (initial version 2011–2015)

Warning

Uses the GAP3 package Chevie which is available as an experimental package (installed by sage -i gap3) or to download by hand from Jean Michel’s website.

class sage.combinat.root_system.reflection_group_real.IrreducibleRealReflectionGroup(W_types, index_set=None, hyperplane_index_set=None, reflection_index_set=None)#

Bases: sage.combinat.root_system.reflection_group_real.RealReflectionGroup, sage.combinat.root_system.reflection_group_complex.IrreducibleComplexReflectionGroup

class Element#

Bases: sage.combinat.root_system.reflection_group_real.RealReflectionGroup.Element, sage.combinat.root_system.reflection_group_complex.IrreducibleComplexReflectionGroup.Element

class sage.combinat.root_system.reflection_group_real.RealReflectionGroup(W_types, index_set=None, hyperplane_index_set=None, reflection_index_set=None)#

Bases: sage.combinat.root_system.reflection_group_complex.ComplexReflectionGroup

A real reflection group given as a permutation group.

class Element#

Bases: sage.combinat.root_system.reflection_group_element.RealReflectionGroupElement, sage.combinat.root_system.reflection_group_complex.ComplexReflectionGroup.Element

left_coset_representatives()#

Return the left coset representatives of self.

EXAMPLES:

sage: W = ReflectionGroup(['A',2])                      # optional - gap3
sage: for w in W:                                       # optional - gap3
....:     lcr = w.left_coset_representatives()          # optional - gap3
....:     print("%s %s"%(w.reduced_word(),              # optional - gap3
....:                    [v.reduced_word() for v in lcr]))  # optional - gap3
[] [[], [2], [1], [1, 2], [2, 1], [1, 2, 1]]
[2] [[], [2], [1]]
[1] [[], [1], [2, 1]]
[1, 2] [[]]
[2, 1] [[]]
[1, 2, 1] [[], [2], [1, 2]]
right_coset_representatives()#

Return the right coset representatives of self.

EXAMPLES:

sage: W = ReflectionGroup(['A',2])                      # optional - gap3
sage: for w in W:                                       # optional - gap3
....:     rcr = w.right_coset_representatives()         # optional - gap3
....:     print("%s %s"%(w.reduced_word(),              # optional - gap3
....:                    [v.reduced_word() for v in rcr]))  # optional - gap3
[] [[], [2], [1], [2, 1], [1, 2], [1, 2, 1]]
[2] [[], [2], [1]]
[1] [[], [1], [1, 2]]
[1, 2] [[]]
[2, 1] [[]]
[1, 2, 1] [[], [2], [2, 1]]
almost_positive_roots()#

Return the almost positive roots of self.

EXAMPLES:

sage: W = ReflectionGroup(['A',3], ['B',2])                 # optional - gap3
sage: W.almost_positive_roots()                             # optional - gap3
[(-1, 0, 0, 0, 0),
 (0, -1, 0, 0, 0),
 (0, 0, -1, 0, 0),
 (0, 0, 0, -1, 0),
 (0, 0, 0, 0, -1),
 (1, 0, 0, 0, 0),
 (0, 1, 0, 0, 0),
 (0, 0, 1, 0, 0),
 (0, 0, 0, 1, 0),
 (0, 0, 0, 0, 1),
 (1, 1, 0, 0, 0),
 (0, 1, 1, 0, 0),
 (0, 0, 0, 1, 1),
 (1, 1, 1, 0, 0),
 (0, 0, 0, 2, 1)]

sage: W = ReflectionGroup(['A',3])                          # optional - gap3
sage: W.almost_positive_roots()                             # optional - gap3
[(-1, 0, 0),
 (0, -1, 0),
 (0, 0, -1),
 (1, 0, 0),
 (0, 1, 0),
 (0, 0, 1),
 (1, 1, 0),
 (0, 1, 1),
 (1, 1, 1)]
bipartite_index_set()#

Return the bipartite index set of a real reflection group.

EXAMPLES:

sage: W = ReflectionGroup(["A",5])                          # optional - gap3
sage: W.bipartite_index_set()                               # optional - gap3
[[1, 3, 5], [2, 4]]

sage: W = ReflectionGroup(["A",5],index_set=['a','b','c','d','e'])  # optional - gap3
sage: W.bipartite_index_set()                               # optional - gap3
[['a', 'c', 'e'], ['b', 'd']]
bruhat_cone(x, y, side='upper', backend='cdd')#

Return the (upper or lower) Bruhat cone associated to the interval [x,y].

To a cover relation \(v \prec w\) in strong Bruhat order you can assign a positive root \(\beta\) given by the unique reflection \(s_\beta\) such that \(s_\beta v = w\).

The upper Bruhat cone of the interval \([x,y]\) is the non-empty, polyhedral cone generated by the roots corresponding to \(x \prec a\) for all atoms \(a\) in the interval. The lower Bruhat cone of the interval \([x,y]\) is the non-empty, polyhedral cone generated by the roots corresponding to \(c \prec y\) for all coatoms \(c\) in the interval.

INPUT:

  • x - an element in the group \(W\)

  • y - an element in the group \(W\)

  • side (default: 'upper') – must be one of the following:

    • 'upper' - return the upper Bruhat cone of the interval [x, y]

    • 'lower' - return the lower Bruhat cone of the interval [x, y]

  • backend – string (default: 'cdd'); the backend to use to create the polyhedron

EXAMPLES:

sage: W = ReflectionGroup(['A',2])                          # optional - gap3
sage: x = W.from_reduced_word([1])                          # optional - gap3
sage: y = W.w0                                              # optional - gap3
sage: W.bruhat_cone(x, y)                                   # optional - gap3
A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex and 2 rays

sage: W = ReflectionGroup(['E',6])                          # optional - gap3
sage: x = W.one()                                           # optional - gap3
sage: y = W.w0                                              # optional - gap3
sage: W.bruhat_cone(x, y, side='lower')                     # optional - gap3
A 6-dimensional polyhedron in QQ^6 defined as the convex hull of 1 vertex and 6 rays

REFERENCES:

cartan_type()#

Return the Cartan type of self.

EXAMPLES:

sage: W = ReflectionGroup(['A',3])                          # optional - gap3
sage: W.cartan_type()                                       # optional - gap3
['A', 3]

sage: W = ReflectionGroup(['A',3], ['B',3])                 # optional - gap3
sage: W.cartan_type()                                       # optional - gap3
A3xB3 relabelled by {1: 3, 2: 2, 3: 1}
coxeter_diagram()#

Return the Coxeter diagram associated to self.

EXAMPLES:

sage: G = ReflectionGroup(['B',3])                          # optional - gap3
sage: sorted(G.coxeter_diagram().edges(labels=True))        # optional - gap3
[(1, 2, 4), (2, 3, 3)]
coxeter_matrix()#

Return the Coxeter matrix associated to self.

EXAMPLES:

sage: G = ReflectionGroup(['A',3])                          # optional - gap3
sage: G.coxeter_matrix()                                    # optional - gap3
[1 3 2]
[3 1 3]
[2 3 1]
fundamental_weight(i)#

Return the fundamental weight with index i.

EXAMPLES:

sage: W = ReflectionGroup(['A',3])                          # optional - gap3
sage: [ W.fundamental_weight(i) for i in W.index_set() ]    # optional - gap3
[(3/4, 1/2, 1/4), (1/2, 1, 1/2), (1/4, 1/2, 3/4)]
fundamental_weights()#

Return the fundamental weights of self in terms of the simple roots.

The fundamental weights are defined by \(s_j(\omega_i) = \omega_i - \delta_{i=j}\alpha_j\) for the simple reflection \(s_j\) with corresponding simple roots \(\alpha_j\).

In other words, the transpose Cartan matrix sends the weight basis to the root basis. Observe again that the action here is defined as a right action, see the example below.

EXAMPLES:

sage: W = ReflectionGroup(['A',3], ['B',2])                 # optional - gap3
sage: W.fundamental_weights()                               # optional - gap3
Finite family {1: (3/4, 1/2, 1/4, 0, 0), 2: (1/2, 1, 1/2, 0, 0), 3: (1/4, 1/2, 3/4, 0, 0), 4: (0, 0, 0, 1, 1/2), 5: (0, 0, 0, 1, 1)}

sage: W = ReflectionGroup(['A',3])                          # optional - gap3
sage: W.fundamental_weights()                               # optional - gap3
Finite family {1: (3/4, 1/2, 1/4), 2: (1/2, 1, 1/2), 3: (1/4, 1/2, 3/4)}

sage: W = ReflectionGroup(['A',3])                          # optional - gap3
sage: S = W.simple_reflections()                            # optional - gap3
sage: N = W.fundamental_weights()                           # optional - gap3
sage: for i in W.index_set():                               # optional - gap3
....:     for j in W.index_set():                           # optional - gap3
....:         print("{} {} {} {}".format(i, j, N[i], N[i]*S[j].to_matrix()))
1 1 (3/4, 1/2, 1/4) (-1/4, 1/2, 1/4)
1 2 (3/4, 1/2, 1/4) (3/4, 1/2, 1/4)
1 3 (3/4, 1/2, 1/4) (3/4, 1/2, 1/4)
2 1 (1/2, 1, 1/2) (1/2, 1, 1/2)
2 2 (1/2, 1, 1/2) (1/2, 0, 1/2)
2 3 (1/2, 1, 1/2) (1/2, 1, 1/2)
3 1 (1/4, 1/2, 3/4) (1/4, 1/2, 3/4)
3 2 (1/4, 1/2, 3/4) (1/4, 1/2, 3/4)
3 3 (1/4, 1/2, 3/4) (1/4, 1/2, -1/4)
iteration(algorithm='breadth', tracking_words=True)#

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

    • 'parabolic' - iterate by using parabolic subgroups

  • tracking_words (default: True) – whether or not to keep track of the reduced words and store them in _reduced_word

Note

The fastest iteration is the parabolic iteration and the depth first algorithm without tracking words is second. In particular, 'depth' is ~1.5x faster than 'breadth'.

Note

The 'parabolic' iteration does not track words and requires keeping the subgroup corresponding to \(I \setminus \{i\}\) in memory (for each \(i\) individually).

EXAMPLES:

sage: W = ReflectionGroup(["B",2])                          # optional - gap3

sage: for w in W.iteration("breadth",True):                 # optional - gap3
....:     print("%s %s"%(w, w._reduced_word))               # optional - gap3
() []
(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               # optional - gap3
()
(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)
positive_roots()#

Return the positive roots of self.

EXAMPLES:

sage: W = ReflectionGroup(['A',3], ['B',2])                 # optional - gap3
sage: W.positive_roots()                                    # optional - gap3
[(1, 0, 0, 0, 0),
 (0, 1, 0, 0, 0),
 (0, 0, 1, 0, 0),
 (0, 0, 0, 1, 0),
 (0, 0, 0, 0, 1),
 (1, 1, 0, 0, 0),
 (0, 1, 1, 0, 0),
 (0, 0, 0, 1, 1),
 (1, 1, 1, 0, 0),
 (0, 0, 0, 2, 1)]

sage: W = ReflectionGroup(['A',3])                          # optional - gap3
sage: W.positive_roots()                                    # optional - gap3
[(1, 0, 0), (0, 1, 0), (0, 0, 1), (1, 1, 0), (0, 1, 1), (1, 1, 1)]
reflection_to_positive_root(r)#

Return the positive root orthogonal to the given reflection.

EXAMPLES:

sage: W = ReflectionGroup(['A',2])  # optional - gap3
sage: for r in W.reflections():     # optional - gap3
....:     print(W.reflection_to_positive_root(r))
(1, 0)
(0, 1)
(1, 1)
right_coset_representatives(J)#

Return the right coset representatives of self for the parabolic subgroup generated by the simple reflections in J.

EXAMPLES:

sage: W = ReflectionGroup(["A",3])                          # optional - gap3
sage: for J in Subsets([1,2,3]): W.right_coset_representatives(J)   # optional - gap3
[(), (2,5)(3,9)(4,6)(8,11)(10,12), (1,4)(2,8)(3,5)(7,10)(9,11),
 (1,7)(2,4)(5,6)(8,10)(11,12), (1,2,10)(3,6,5)(4,7,8)(9,12,11),
 (1,4,6)(2,3,11)(5,8,9)(7,10,12), (1,6,4)(2,11,3)(5,9,8)(7,12,10),
 (1,7)(2,6)(3,9)(4,5)(8,12)(10,11),
 (1,10,2)(3,5,6)(4,8,7)(9,11,12), (1,2,3,12)(4,5,10,11)(6,7,8,9),
 (1,5,9,10)(2,12,8,6)(3,4,7,11), (1,6)(2,9)(3,8)(5,11)(7,12),
 (1,8)(2,7)(3,6)(4,10)(9,12), (1,10,9,5)(2,6,8,12)(3,11,7,4),
 (1,12,3,2)(4,11,10,5)(6,9,8,7), (1,3)(2,12)(4,10)(5,11)(6,8)(7,9),
 (1,5,12)(2,9,4)(3,10,8)(6,7,11), (1,8,11)(2,5,7)(3,12,4)(6,10,9),
 (1,11,8)(2,7,5)(3,4,12)(6,9,10), (1,12,5)(2,4,9)(3,8,10)(6,11,7),
 (1,3,7,9)(2,11,6,10)(4,8,5,12), (1,9,7,3)(2,10,6,11)(4,12,5,8),
 (1,11)(3,10)(4,9)(5,7)(6,12), (1,9)(2,8)(3,7)(4,11)(5,10)(6,12)]
[(), (2,5)(3,9)(4,6)(8,11)(10,12), (1,4)(2,8)(3,5)(7,10)(9,11),
 (1,2,10)(3,6,5)(4,7,8)(9,12,11), (1,4,6)(2,3,11)(5,8,9)(7,10,12),
 (1,6,4)(2,11,3)(5,9,8)(7,12,10), (1,2,3,12)(4,5,10,11)(6,7,8,9),
 (1,5,9,10)(2,12,8,6)(3,4,7,11), (1,6)(2,9)(3,8)(5,11)(7,12),
 (1,3)(2,12)(4,10)(5,11)(6,8)(7,9),
 (1,5,12)(2,9,4)(3,10,8)(6,7,11), (1,3,7,9)(2,11,6,10)(4,8,5,12)]
[(), (2,5)(3,9)(4,6)(8,11)(10,12), (1,7)(2,4)(5,6)(8,10)(11,12),
 (1,4,6)(2,3,11)(5,8,9)(7,10,12),
 (1,7)(2,6)(3,9)(4,5)(8,12)(10,11),
 (1,10,2)(3,5,6)(4,8,7)(9,11,12), (1,2,3,12)(4,5,10,11)(6,7,8,9),
 (1,10,9,5)(2,6,8,12)(3,11,7,4), (1,12,3,2)(4,11,10,5)(6,9,8,7),
 (1,8,11)(2,5,7)(3,12,4)(6,10,9), (1,12,5)(2,4,9)(3,8,10)(6,11,7),
 (1,11)(3,10)(4,9)(5,7)(6,12)]
[(), (1,4)(2,8)(3,5)(7,10)(9,11), (1,7)(2,4)(5,6)(8,10)(11,12),
 (1,2,10)(3,6,5)(4,7,8)(9,12,11), (1,6,4)(2,11,3)(5,9,8)(7,12,10),
 (1,10,2)(3,5,6)(4,8,7)(9,11,12), (1,5,9,10)(2,12,8,6)(3,4,7,11),
 (1,8)(2,7)(3,6)(4,10)(9,12), (1,12,3,2)(4,11,10,5)(6,9,8,7),
 (1,3)(2,12)(4,10)(5,11)(6,8)(7,9),
 (1,11,8)(2,7,5)(3,4,12)(6,9,10), (1,9,7,3)(2,10,6,11)(4,12,5,8)]
[(), (2,5)(3,9)(4,6)(8,11)(10,12), (1,4,6)(2,3,11)(5,8,9)(7,10,12),
 (1,2,3,12)(4,5,10,11)(6,7,8,9)]
[(), (1,4)(2,8)(3,5)(7,10)(9,11), (1,2,10)(3,6,5)(4,7,8)(9,12,11),
 (1,6,4)(2,11,3)(5,9,8)(7,12,10), (1,5,9,10)(2,12,8,6)(3,4,7,11),
 (1,3)(2,12)(4,10)(5,11)(6,8)(7,9)]
[(), (1,7)(2,4)(5,6)(8,10)(11,12), (1,10,2)(3,5,6)(4,8,7)(9,11,12),
 (1,12,3,2)(4,11,10,5)(6,9,8,7)]
[()]
root_to_reflection(root)#

Return the reflection along the given root.

EXAMPLES:

sage: W = ReflectionGroup(['A',2])                          # optional - gap3
sage: for beta in W.roots(): W.root_to_reflection(beta)     # optional - gap3
(1,4)(2,3)(5,6)
(1,3)(2,5)(4,6)
(1,5)(2,4)(3,6)
(1,4)(2,3)(5,6)
(1,3)(2,5)(4,6)
(1,5)(2,4)(3,6)
simple_root_index(i)#

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 = ReflectionGroup(['A',3])                          # optional - gap3
sage: [W.simple_root_index(i) for i in W.index_set()]       # optional - gap3
[0, 1, 2]
sage.combinat.root_system.reflection_group_real.ReflectionGroup(*args, **kwds)#

Construct a finite (complex or real) reflection group as a Sage permutation group by fetching the permutation representation of the generators from chevie’s database.

INPUT:

can be one or multiple of the following:

  • a triple \((r, p, n)\) with \(p\) divides \(r\), which denotes the group \(G(r, p, n)\)

  • an integer between \(4\) and \(37\), which denotes an exceptional irreducible complex reflection group

  • a finite Cartan-Killing type

EXAMPLES:

Finite reflection groups can be constructed from

Cartan-Killing classification types:

sage: W = ReflectionGroup(['A',3]); W                           # optional - gap3
 Irreducible real reflection group of rank 3 and type A3

sage: W = ReflectionGroup(['H',4]); W                           # optional - gap3
 Irreducible real reflection group of rank 4 and type H4

sage: W = ReflectionGroup(['I',5]); W                           # optional - gap3
 Irreducible real reflection group of rank 2 and type I2(5)

the complex infinite family \(G(r,p,n)\) with \(p\) divides \(r\):

sage: W = ReflectionGroup((1,1,4)); W                           # optional - gap3
Irreducible real reflection group of rank 3 and type A3

sage: W = ReflectionGroup((2,1,3)); W                           # optional - gap3
Irreducible real reflection group of rank 3 and type B3

Chevalley-Shepard-Todd exceptional classification types:

sage: W = ReflectionGroup(23); W                                # optional - gap3
Irreducible real reflection group of rank 3 and type H3

Cartan types and matrices:

sage: ReflectionGroup(CartanType(['A',2]))                      # optional - gap3
Irreducible real reflection group of rank 2 and type A2

sage: ReflectionGroup(CartanType((['A',2],['A',2])))            # optional - gap3
Reducible real reflection group of rank 4 and type A2 x A2

sage: C = CartanMatrix(['A',2])                                 # optional - gap3
sage: ReflectionGroup(C)                                        # optional - gap3
Irreducible real reflection group of rank 2 and type A2

multiples of the above:

sage: W = ReflectionGroup(['A',2],['B',2]); W                   # optional - gap3
Reducible real reflection group of rank 4 and type A2 x B2

sage: W = ReflectionGroup(['A',2],4); W                         # optional - gap3
Reducible complex reflection group of rank 4 and type A2 x ST4

sage: W = ReflectionGroup((4,2,2),4); W                         # optional - gap3
Reducible complex reflection group of rank 4 and type G(4,2,2) x ST4
sage.combinat.root_system.reflection_group_real.is_chevie_available()#

Test whether the GAP3 Chevie package is available.

EXAMPLES:

sage: from sage.combinat.root_system.reflection_group_real import is_chevie_available
sage: is_chevie_available() # random
False
sage: is_chevie_available() in [True, False]
True