Finite complex reflection groups


Let \(V\) be a finite-dimensional complex vector space. A reflection of \(V\) is an operator \(r \in \operatorname{GL}(V)\) that has finite order and fixes pointwise a hyperplane in \(V\).

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

or with Shephard-Todd types:

sage: ReflectionGroup((1,1,3))                                      # optional - gap3
Irreducible real reflection group of rank 2 and type A2
sage: ReflectionGroup((2,1,3))                                      # optional - gap3
Irreducible real reflection group of rank 3 and type B3
sage: ReflectionGroup((3,1,3))                                      # optional - gap3
Irreducible complex reflection group of rank 3 and type G(3,1,3)
sage: ReflectionGroup((4,2,3))                                      # optional - gap3
Irreducible complex reflection group of rank 3 and type G(4,2,3)
sage: ReflectionGroup(4)                                            # optional - gap3
Irreducible complex reflection group of rank 2 and type ST4
sage: ReflectionGroup(31)                                           # optional - gap3
Irreducible complex reflection group of rank 4 and type ST31

Also reducible types are allowed using concatenation:

sage: ReflectionGroup(['A',3],(4,2,3))                              # optional - gap3
Reducible complex reflection group of rank 6 and type A3 x G(4,2,3)

Some special cases also occur, among them are:

sage: W = ReflectionGroup((2,2,2)); W                               # optional - gap3
Reducible real reflection group of rank 2 and type A1 x A1
sage: W = ReflectionGroup((2,2,3)); W                               # optional - gap3
Irreducible real reflection group of rank 3 and type A3

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.

A guided tour

We start with the example type \(B_2\):

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

Most importantly, observe that the group elements are usually represented by permutations of the roots:

sage: for w in W: print(w)                                          # optional - gap3
()
(1,3)(2,6)(5,7)
(1,5)(2,4)(6,8)
(1,7,5,3)(2,4,6,8)
(1,3,5,7)(2,8,6,4)
(2,8)(3,7)(4,6)
(1,7)(3,5)(4,8)
(1,5)(2,6)(3,7)(4,8)

This has the drawback that one can hardly see anything. Usually, one would look at elements with either of the following methods:

sage: for w in W: w.reduced_word()                                  # optional - gap3
[]
[2]
[1]
[1, 2]
[2, 1]
[2, 1, 2]
[1, 2, 1]
[1, 2, 1, 2]

sage: for w in W: w.reduced_word_in_reflections()                   # optional - gap3
[]
[2]
[1]
[1, 2]
[1, 4]
[3]
[4]
[1, 3]

sage: for w in W: w.reduced_word(); w.to_matrix(); print("")        # optional - gap3
[]
[1 0]
[0 1]

[2]
[ 1  1]
[ 0 -1]

[1]
[-1  0]
[ 2  1]

[1, 2]
[-1 -1]
[ 2  1]

[2, 1]
[ 1  1]
[-2 -1]

[2, 1, 2]
[ 1  0]
[-2 -1]

[1, 2, 1]
[-1 -1]
[ 0  1]

[1, 2, 1, 2]
[-1  0]
[ 0 -1]

The standard references for actions of complex reflection groups have the matrices acting on the right, so:

sage: W.simple_reflection(1).to_matrix()                            # optional - gap3
[-1  0]
[ 2  1]

sends the simple root \(\alpha_0\), or (1,0) in vector notation, to its negative, while sending \(\alpha_1\) to \(2\alpha_0+\alpha_1\).

Todo

  • properly provide root systems for real reflection groups

  • element class should be unique to be able to work with large groups without creating elements multiple times

  • is_shephard_group, is_generalized_coxeter_group

  • exponents and coexponents

  • coinvariant ring:

    • fake degrees from Torsten Hoge
    • operation of linear characters on all characters
    • harmonic polynomials
  • linear forms for hyperplanes

  • field of definition

  • intersection lattice and characteristic polynomial:

    X = [ alpha(t) for t in W.distinguished_reflections() ]
    X = Matrix(CF,X).transpose()
    Y = Matroid(X)
    
  • linear characters

  • permutation pi on irreducibles

  • hyperplane orbits (76.13 in Gap Manual)

  • improve invariant_form with a code similar to the one in reflection_group_real.py

  • add a method reflection_to_root or distinguished_reflection_to_positive_root

  • diagrams in ASCII-art (76.15)

  • standard (BMR) presentations

  • character table directly from Chevie

  • GenericOrder (76.20), TorusOrder (76.21)

  • correct fundamental invariants for \(G_34\), check the others

  • copy hardcoded data (degrees, invariants, braid relations…) into sage

  • add other hardcoded data from the tables in chevie (location is SAGEDIR/local/gap3/gap-jm5-2015-02-01/gap3/pkg/chevie/tbl): basic derivations, discriminant, …

  • transfer code for reduced_word_in_reflections into Gap4 or Sage

  • list of reduced words for an element

  • list of reduced words in reflections for an element

  • Hurwitz action?

  • is_crystallographic() should be hardcoded

AUTHORS:

  • Christian Stump (2015): initial version
sage.combinat.root_system.reflection_group_complex.ComplexReflectionGroup

A complex reflection group given as a permutation group.

class sage.combinat.root_system.reflection_group_complex.IrreducibleComplexReflectionGroup(W_types, index_set=None, hyperplane_index_set=None, reflection_index_set=None)

Bases: sage.combinat.root_system.reflection_group_complex.ComplexReflectionGroup

class Element

Bases: sage.combinat.root_system.reflection_group_complex.ComplexReflectionGroup.Element

is_coxeter_element(which_primitive=1, is_class_representative=False)

Return True if self is a Coxeter element.

This is, whether self has an eigenvalue that is a primitive \(h\)-th root of unity.

INPUT:

  • which_primitive – (default:1) for which power of the first primitive h-th root of unity to look as a reflection eigenvalue for a regular element
  • is_class_representative – boolean (default True) whether to compute instead on the conjugacy class representative

See also

coxeter_element() coxeter_elements()

EXAMPLES:

sage: W = ReflectionGroup((1,1,3))                      # optional - gap3
sage: for w in W:                                       # optional - gap3
....:     print('%s %s'%(w.reduced_word(), w.is_coxeter_element())) # optional - gap3
[] False
[2] False
[1] False
[1, 2] True
[2, 1] True
[1, 2, 1] False
is_h_regular(is_class_representative=False)

Return whether self is regular.

This is if self has an eigenvector with eigenvalue \(h\) and which does not lie in any reflection hyperplane. Here, \(h\) denotes the Coxeter number.

EXAMPLES:

sage: W = ReflectionGroup((1,1,3))                      # optional - gap3
sage: for w in W:                                       # optional - gap3
....:     print('%s %s'%(w.reduced_word(), w.is_h_regular()))   # optional - gap3
[] False
[2] False
[1] False
[1, 2] True
[2, 1] True
[1, 2, 1] False
is_regular(h, is_class_representative=False)

Return whether self is regular.

This is, if self has an eigenvector with eigenvalue of order h and which does not lie in any reflection hyperplane.

INPUT:

  • h – the order of the eigenvalue
  • is_class_representative – boolean (default True) whether to compute instead on the conjugacy class representative

EXAMPLES:

sage: W = ReflectionGroup((1,1,3))                      # optional - gap3
sage: h = W.coxeter_number()                            # optional - gap3
sage: for w in W:                                       # optional - gap3
....:     print("{} {}".format(w.reduced_word(), w.is_regular(h)))
[] False
[2] False
[1] False
[1, 2] True
[2, 1] True
[1, 2, 1] False

sage: W = ReflectionGroup(23); h = W.coxeter_number()   # optional - gap3
sage: for w in W:                                       # optional - gap3
....:     if w.is_regular(h):                           # optional - gap3
....:         w.reduced_word()                          # optional - gap3
[1, 2, 3]
[2, 1, 3]
[1, 3, 2]
[3, 2, 1]
[2, 1, 2, 3, 2]
[2, 3, 2, 1, 2]
[1, 2, 1, 2, 3, 2, 1]
[1, 2, 3, 2, 1, 2, 1]
[1, 2, 1, 2, 3, 2, 1, 2, 3]
[2, 1, 2, 1, 3, 2, 1, 2, 3]
[2, 1, 2, 3, 2, 1, 2, 1, 3]
[1, 2, 3, 2, 1, 2, 1, 3, 2]
[3, 2, 1, 2, 1, 3, 2, 1, 2]
[1, 2, 1, 2, 1, 3, 2, 1, 2]
[2, 3, 2, 1, 2, 1, 3, 2, 1]
[2, 1, 2, 1, 3, 2, 1, 2, 1]
[2, 3, 2, 1, 2, 1, 3, 2, 1, 2, 3]
[1, 3, 2, 1, 2, 1, 3, 2, 1, 2, 3]
[1, 2, 1, 2, 1, 3, 2, 1, 2, 1, 3]
[1, 2, 1, 2, 3, 2, 1, 2, 1, 3, 2]
[1, 2, 3, 2, 1, 2, 1, 3, 2, 1, 2]
[2, 1, 2, 3, 2, 1, 2, 1, 3, 2, 1]
[2, 1, 2, 3, 2, 1, 2, 1, 3, 2, 1, 2, 3]
[1, 2, 1, 3, 2, 1, 2, 1, 3, 2, 1, 2, 3]

Check that trac ticket #25478 is fixed:

sage: W = ReflectionGroup(["A",5])                      # optional - gap3
sage: w = W.from_reduced_word([1,2,3,5])                # optional - gap3
sage: w.is_regular(4)                                   # optional - gap3
False
sage: W = ReflectionGroup(["A",3])                      # optional - gap3
sage: len([w for w in W if w.is_regular(w.order())])    # optional - gap3
18
sage.combinat.root_system.reflection_group_complex.multi_partitions(n, S, i=None)

Return all vectors as lists of the same length as S whose standard inner product with S equals n.

EXAMPLES:

sage: from sage.combinat.root_system.reflection_group_complex import multi_partitions
sage: multi_partitions(10, [2,3,3,4])
[[5, 0, 0, 0],
 [3, 0, 0, 1],
 [2, 2, 0, 0],
 [2, 1, 1, 0],
 [2, 0, 2, 0],
 [1, 0, 0, 2],
 [0, 2, 0, 1],
 [0, 1, 1, 1],
 [0, 0, 2, 1]]
sage.combinat.root_system.reflection_group_complex.power(f, k)

Return \(f^k\) and caching all intermediate results.

Speeds the computation if one has to compute \(f^k\)‘s for many values of \(k\).

EXAMPLES:

sage: P.<x,y,z> = PolynomialRing(QQ)
sage: f = -2*x^2 + 2*x*y - 2*y^2 + 2*y*z - 2*z^2
sage: all( f^k == power(f,k) for k in range(20) )
True