Finite real reflection groups


Let V be a finite-dimensional real vector space. A reflection of V is an operator rGL(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']]
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 sj(ωi)=ωiδi=jαj for the simple reflection sj with corresponding simple roots α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{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 αi.

This is the position of α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