Finite Coxeter Groups - Category Framework

Skip to content
Back to top
View this page
Edit this page

# Finite Coxeter Groups

class sage.categories.finite_coxeter_groups.FiniteCoxeterGroups(base_category)

  Bases: `CategoryWithAxiom`

  The category of finite Coxeter groups.

  EXAMPLES:

  Sage

      sage: CoxeterGroups.Finite()
      Category of finite Coxeter groups
      sage: FiniteCoxeterGroups().super_categories()
      [Category of finite generalized Coxeter groups,
       Category of Coxeter groups]

      sage: G = CoxeterGroups().Finite().example()
      sage: G.cayley_graph(side = "right").plot()
      Graphics object consisting of 40 graphics primitives

  Python

      >>> from sage.all import *
      >>> CoxeterGroups.Finite()
      Category of finite Coxeter groups
      >>> FiniteCoxeterGroups().super_categories()
      [Category of finite generalized Coxeter groups,
       Category of Coxeter groups]

      >>> G = CoxeterGroups().Finite().example()
      >>> G.cayley_graph(side = "right").plot()
      Graphics object consisting of 40 graphics primitives

  Here are some further examples:

  Sage

      sage: WeylGroups().Finite().example()
      The symmetric group on {0, ..., 3}

      sage: WeylGroup(["B", 3])
      Weyl Group of type ['B', 3] (as a matrix group acting on the ambient space)

  [Python]

      >>> from sage.all import *
      >>> WeylGroups().Finite().example()
      The symmetric group on {0, ..., 3}

      >>> WeylGroup(["B", Integer(3)])
      Weyl Group of type ['B', 3] (as a matrix group acting on the ambient space)

  Those other examples will eventually be also in this category:

  Sage

      sage: SymmetricGroup(4)
      Symmetric group of order 4! as a permutation group
      sage: DihedralGroup(5)
      Dihedral group of order 10 as a permutation group

  Python

      >>> from sage.all import *
      >>> SymmetricGroup(Integer(4))
      Symmetric group of order 4! as a permutation group
      >>> DihedralGroup(Integer(5))
      Dihedral group of order 10 as a permutation group

  class ElementMethods

    Bases: `object`

    absolute_length()

      Return the absolute length of `self`.

      The absolute length is the length of the shortest expression of the element as a product of reflections. For finite Coxeter groups, the absolute length is the codimension of the 1-eigenspace of the element (Lemmas 1-3 in [Car1972a]).

      For permutations in the symmetric groups, the absolute length is the size minus the number of its disjoint cycles.

      See also

      `absolute_le()`

      EXAMPLES:

      Sage

          sage: W = WeylGroup(["A", 3])                                           # needs sage.combinat sage.groups
          sage: s = W.simple_reflections()                                        # needs sage.combinat sage.groups
          sage: (s[1]*s[2]*s[3]).absolute_length()                                # needs sage.combinat sage.groups
          3

          sage: W = SymmetricGroup(4)                                             # needs sage.groups
          sage: s = W.simple_reflections()                                        # needs sage.groups
          sage: (s[3]*s[2]*s[1]).absolute_length()                                # needs sage.combinat sage.groups
          3

      Python

          >>> from sage.all import *
          >>> W = WeylGroup(["A", Integer(3)])                                           # needs sage.combinat sage.groups
          >>> s = W.simple_reflections()                                        # needs sage.combinat sage.groups
          >>> (s[Integer(1)]*s[Integer(2)]*s[Integer(3)]).absolute_length()                                # needs sage.combinat sage.groups
          3

          >>> W = SymmetricGroup(Integer(4))                                             # needs sage.groups
          >>> s = W.simple_reflections()                                        # needs sage.groups
          >>> (s[Integer(3)]*s[Integer(2)]*s[Integer(1)]).absolute_length()                                # needs sage.combinat sage.groups
          3

    bruhat_upper_covers()

      Return all the elements that cover `self` in Bruhat order.

      EXAMPLES:

      Sage

          sage: W = WeylGroup(["A",4])
          sage: w = W.from_reduced_word([3,2])
          sage: print([v.reduced_word() for v in w.bruhat_upper_covers()])
          [[4, 3, 2], [3, 4, 2], [2, 3, 2], [3, 1, 2], [3, 2, 1]]

          sage: W = WeylGroup(["B",6])
          sage: w = W.from_reduced_word([1,2,1,4,5])
          sage: C = w.bruhat_upper_covers()
          sage: len(C)
          9
          sage: print([v.reduced_word() for v in C])
          [[6, 4, 5, 1, 2, 1], [4, 5, 6, 1, 2, 1], [3, 4, 5, 1, 2, 1], [2, 3, 4, 5, 1, 2],
          [1, 2, 3, 4, 5, 1], [4, 5, 4, 1, 2, 1], [4, 5, 3, 1, 2, 1], [4, 5, 2, 3, 1, 2],
          [4, 5, 1, 2, 3, 1]]
          sage: ww = W.from_reduced_word([5,6,5])
          sage: CC = ww.bruhat_upper_covers()
          sage: print([v.reduced_word() for v in CC])
          [[6, 5, 6, 5], [4, 5, 6, 5], [5, 6, 4, 5], [5, 6, 5, 4], [5, 6, 5, 3], [5, 6, 5, 2],
          [5, 6, 5, 1]]

      Python

          >>> from sage.all import *
          >>> W = WeylGroup(["A",Integer(4)])
          >>> w = W.from_reduced_word([Integer(3),Integer(2)])
          >>> print([v.reduced_word() for v in w.bruhat_upper_covers()])
          [[4, 3, 2], [3, 4, 2], [2, 3, 2], [3, 1, 2], [3, 2, 1]]

          >>> W = WeylGroup(["B",Integer(6)])
          >>> w = W.from_reduced_word([Integer(1),Integer(2),Integer(1),Integer(4),Integer(5)])
          >>> C = w.bruhat_upper_covers()
          >>> len(C)
          9
          >>> print([v.reduced_word() for v in C])
          [[6, 4, 5, 1, 2, 1], [4, 5, 6, 1, 2, 1], [3, 4, 5, 1, 2, 1], [2, 3, 4, 5, 1, 2],
          [1, 2, 3, 4, 5, 1], [4, 5, 4, 1, 2, 1], [4, 5, 3, 1, 2, 1], [4, 5, 2, 3, 1, 2],
          [4, 5, 1, 2, 3, 1]]
          >>> ww = W.from_reduced_word([Integer(5),Integer(6),Integer(5)])
          >>> CC = ww.bruhat_upper_covers()
          >>> print([v.reduced_word() for v in CC])
          [[6, 5, 6, 5], [4, 5, 6, 5], [5, 6, 4, 5], [5, 6, 5, 4], [5, 6, 5, 3], [5, 6, 5, 2],
          [5, 6, 5, 1]]

      Recursive algorithm: write \(w\) for `self`. If \(i\) is a non-descent of \(w\), then the covers of \(w\) are exactly \(\{ws_i, u_1s_i, u_2s_i,..., u_js_i\}\), where the \(u_k\) are those covers of \(ws_i\) that have a descent at \(i\).

    covered_reflections_subgroup()

      Return the subgroup of \(W\) generated by the conjugates by \(w\) of the simple reflections indexed by right descents of \(w\).

      This is used to compute the shard intersection order on \(W\).

      EXAMPLES:

      Sage

          sage: W = CoxeterGroup(['A',3], base_ring=ZZ)
          sage: len(W.long_element().covered_reflections_subgroup())
          24
          sage: s = W.simple_reflection(1)
          sage: Gs = s.covered_reflections_subgroup()
          sage: len(Gs)
          2
          sage: s in [u.lift() for u in Gs]
          True
          sage: len(W.one().covered_reflections_subgroup())
          1

      Python

          >>> from sage.all import *
          >>> W = CoxeterGroup(['A',Integer(3)], base_ring=ZZ)
          >>> len(W.long_element().covered_reflections_subgroup())
          24
          >>> s = W.simple_reflection(Integer(1))
          >>> Gs = s.covered_reflections_subgroup()
          >>> len(Gs)
          2
          >>> s in [u.lift() for u in Gs]
          True
          >>> len(W.one().covered_reflections_subgroup())
          1

    coxeter_knuth_graph()

      Return the Coxeter-Knuth graph of type \(A\).

      The Coxeter-Knuth graph of type \(A\) is generated by the Coxeter-Knuth relations which are given by \(a a+1 a \sim a+1 a a+1\), \(abc \sim acb\) if \(b<a<c\) and \(abc \sim bac\) if \(a<c<b\).

      EXAMPLES:

      Sage

          sage: W = WeylGroup(['A',4], prefix='s')
          sage: w = W.from_reduced_word([1,2,1,3,2])
          sage: D = w.coxeter_knuth_graph()
          sage: D.vertices(sort=True)
          [(1, 2, 1, 3, 2),
          (1, 2, 3, 1, 2),
          (2, 1, 2, 3, 2),
          (2, 1, 3, 2, 3),
          (2, 3, 1, 2, 3)]
          sage: D.edges(sort=True)
          [((1, 2, 1, 3, 2), (1, 2, 3, 1, 2), None),
          ((1, 2, 1, 3, 2), (2, 1, 2, 3, 2), None),
          ((2, 1, 2, 3, 2), (2, 1, 3, 2, 3), None),
          ((2, 1, 3, 2, 3), (2, 3, 1, 2, 3), None)]

          sage: w = W.from_reduced_word([1,3])
          sage: D = w.coxeter_knuth_graph()
          sage: D.vertices(sort=True)
          [(1, 3), (3, 1)]
          sage: D.edges(sort=False)
          []

      Python

          >>> from sage.all import *
          >>> W = WeylGroup(['A',Integer(4)], prefix='s')
          >>> w = W.from_reduced_word([Integer(1),Integer(2),Integer(1),Integer(3),Integer(2)])
          >>> D = w.coxeter_knuth_graph()
          >>> D.vertices(sort=True)
          [(1, 2, 1, 3, 2),
          (1, 2, 3, 1, 2),
          (2, 1, 2, 3, 2),
          (2, 1, 3, 2, 3),
          (2, 3, 1, 2, 3)]
          >>> D.edges(sort=True)
          [((1, 2, 1, 3, 2), (1, 2, 3, 1, 2), None),
          ((1, 2, 1, 3, 2), (2, 1, 2, 3, 2), None),
          ((2, 1, 2, 3, 2), (2, 1, 3, 2, 3), None),
          ((2, 1, 3, 2, 3), (2, 3, 1, 2, 3), None)]

          >>> w = W.from_reduced_word([Integer(1),Integer(3)])
          >>> D = w.coxeter_knuth_graph()
          >>> D.vertices(sort=True)
          [(1, 3), (3, 1)]
          >>> D.edges(sort=False)
          []

    coxeter_knuth_neighbor(w)

      Return the Coxeter-Knuth (oriented) neighbors of the reduced word \(w\) of `self`.

      INPUT:

      - `w` – reduced word of `self`

      The Coxeter-Knuth relations are given by \(a a+1 a \sim a+1 a a+1\), \(abc \sim acb\) if \(b<a<c\) and \(abc \sim bac\) if \(a<c<b\). This method returns all neighbors of `w` under the Coxeter-Knuth relations oriented from left to right.

      EXAMPLES:

      Sage

          sage: W = WeylGroup(['A',4], prefix='s')
          sage: word = [1,2,1,3,2]
          sage: w = W.from_reduced_word(word)
          sage: w.coxeter_knuth_neighbor(word)
          {(1, 2, 3, 1, 2), (2, 1, 2, 3, 2)}

          sage: word = [1,2,1,3,2,4,3]
          sage: w = W.from_reduced_word(word)
          sage: w.coxeter_knuth_neighbor(word)
          {(1, 2, 1, 3, 4, 2, 3), (1, 2, 3, 1, 2, 4, 3), (2, 1, 2, 3, 2, 4, 3)}

      Python

          >>> from sage.all import *
          >>> W = WeylGroup(['A',Integer(4)], prefix='s')
          >>> word = [Integer(1),Integer(2),Integer(1),Integer(3),Integer(2)]
          >>> w = W.from_reduced_word(word)
          >>> w.coxeter_knuth_neighbor(word)
          {(1, 2, 3, 1, 2), (2, 1, 2, 3, 2)}

          >>> word = [Integer(1),Integer(2),Integer(1),Integer(3),Integer(2),Integer(4),Integer(3)]
          >>> w = W.from_reduced_word(word)
          >>> w.coxeter_knuth_neighbor(word)
          {(1, 2, 1, 3, 4, 2, 3), (1, 2, 3, 1, 2, 4, 3), (2, 1, 2, 3, 2, 4, 3)}

    is_coxeter_element()

      Return whether this is a Coxeter element.

      This is, whether `self` has an eigenvalue \(e^{2\pi i/h}\) where \(h\) is the Coxeter number.

      See also

      `coxeter_elements()`

      EXAMPLES:

      Sage

          sage: W = CoxeterGroup(['A',2])
          sage: c = prod(W.gens())
          sage: c.is_coxeter_element()
          True
          sage: W.one().is_coxeter_element()
          False

          sage: W = WeylGroup(['G', 2])
          sage: c = prod(W.gens())
          sage: c.is_coxeter_element()
          True
          sage: W.one().is_coxeter_element()
          False

      Python

          >>> from sage.all import *
          >>> W = CoxeterGroup(['A',Integer(2)])
          >>> c = prod(W.gens())
          >>> c.is_coxeter_element()
          True
          >>> W.one().is_coxeter_element()
          False

          >>> W = WeylGroup(['G', Integer(2)])
          >>> c = prod(W.gens())
          >>> c.is_coxeter_element()
          True
          >>> W.one().is_coxeter_element()
          False

  class ParentMethods

    Bases: `object`

    Ambiguity resolution: the implementation of `some_elements` is preferable to that of `FiniteGroups`. The same holds for `__iter__`, although a breadth first search would be more natural; at least this maintains backward compatibility after Issue #13589.

    bhz_poset()

      Return the Bergeron-Hohlweg-Zabrocki partial order on the Coxeter group.

      This is a partial order on the elements of a finite Coxeter group \(W\), which is distinct from the Bruhat order, the weak order and the shard intersection order. It was defined in [BHZ2005].

      This partial order is not a lattice, as there is no unique maximal element. It can be succinctly defined as follows.

      Let \(u\) and \(v\) be two elements of the Coxeter group \(W\). Let \(S(u)\) be the support of \(u\). Then \(u \leq v\) if and only if \(v_{S(u)} = u\) (here \(v = v^I v_I\) denotes the usual parabolic decomposition with respect to the standard parabolic subgroup \(W_I\)).

      See also

      `bruhat_poset()`, `shard_poset()`, `weak_poset()`

      EXAMPLES:

      Sage

          sage: W = CoxeterGroup(['A',3], base_ring=ZZ)
          sage: P = W.bhz_poset(); P
          Finite poset containing 24 elements
          sage: P.number_of_relations()
          103
          sage: P.chain_polynomial()
          34*q^4 + 90*q^3 + 79*q^2 + 24*q + 1
          sage: len(P.maximal_elements())
          13

      Python

          >>> from sage.all import *
          >>> W = CoxeterGroup(['A',Integer(3)], base_ring=ZZ)
          >>> P = W.bhz_poset(); P
          Finite poset containing 24 elements
          >>> P.number_of_relations()
          103
          >>> P.chain_polynomial()
          34*q^4 + 90*q^3 + 79*q^2 + 24*q + 1
          >>> len(P.maximal_elements())
          13

    bruhat_poset(facade=False)

      Return the Bruhat poset of `self`.

      See also

      `bhz_poset()`, `shard_poset()`, `weak_poset()`

      EXAMPLES:

      Sage

          sage: W = WeylGroup(["A", 2])
          sage: P = W.bruhat_poset()
          sage: P
          Finite poset containing 6 elements
          sage: P.show()

      Python

          >>> from sage.all import *
          >>> W = WeylGroup(["A", Integer(2)])
          >>> P = W.bruhat_poset()
          >>> P
          Finite poset containing 6 elements
          >>> P.show()

      Here are some typical operations on this poset:

      Sage

          sage: W = WeylGroup(["A", 3])
          sage: P = W.bruhat_poset()
          sage: u = W.from_reduced_word([3,1])
          sage: v = W.from_reduced_word([3,2,1,2,3])
          sage: P(u) <= P(v)
          True
          sage: len(P.interval(P(u), P(v)))
          10
          sage: P.is_join_semilattice()
          False

      [Python]

          >>> from sage.all import *
          >>> W = WeylGroup(["A", Integer(3)])
          >>> P = W.bruhat_poset()
          >>> u = W.from_reduced_word([Integer(3),Integer(1)])
          >>> v = W.from_reduced_word([Integer(3),Integer(2),Integer(1),Integer(2),Integer(3)])
          >>> P(u) <= P(v)
          True
          >>> len(P.interval(P(u), P(v)))
          10
          >>> P.is_join_semilattice()
          False

      By default, the elements of \(P\) are aware that they belong to \(P\):

      Sage

          sage: P.an_element().parent()
          Finite poset containing 24 elements

      Python

          >>> from sage.all import *
          >>> P.an_element().parent()
          Finite poset containing 24 elements

      If instead one wants the elements to be plain elements of the Coxeter group, one can use the `facade` option:

      Sage

          sage: P = W.bruhat_poset(facade = True)
          sage: P.an_element().parent()
          Weyl Group of type ['A', 3] (as a matrix group acting on the ambient space)

      [Python]

          >>> from sage.all import *
          >>> P = W.bruhat_poset(facade = True)
          >>> P.an_element().parent()
          Weyl Group of type ['A', 3] (as a matrix group acting on the ambient space)

      See also

      `Poset()` for more on posets and facade posets.

      Todo

      - Use the symmetric group in the examples (for nicer output), and print the edges for a stronger test.

      - The constructed poset should be lazy, in order to handle large / infinite Coxeter groups.

    cambrian_lattice(c, on_roots=False)

      Return the \(c\)-Cambrian lattice on delta sequences.

      See arXiv 1503.00710 and arXiv math/0611106.

      Delta sequences are certain 2-colored minimal factorizations of \(c\) into reflections.

      INPUT:

      - `c` – a standard Coxeter element in `self` (as a tuple, or as an element of `self`)

      - `on_roots` – boolean (default: `False`); if `on_roots` is `True`, the lattice is realized on roots rather than on reflections. In order for this to work, the ElementMethod `reflection_to_root` must be available.

      EXAMPLES:

      Sage

          sage: CoxeterGroup(["A", 2]).cambrian_lattice((1,2))
          Finite lattice containing 5 elements

          sage: CoxeterGroup(["B", 2]).cambrian_lattice((1,2))
          Finite lattice containing 6 elements

          sage: CoxeterGroup(["G", 2]).cambrian_lattice((1,2))
          Finite lattice containing 8 elements

      Python

          >>> from sage.all import *
          >>> CoxeterGroup(["A", Integer(2)]).cambrian_lattice((Integer(1),Integer(2)))
          Finite lattice containing 5 elements

          >>> CoxeterGroup(["B", Integer(2)]).cambrian_lattice((Integer(1),Integer(2)))
          Finite lattice containing 6 elements

          >>> CoxeterGroup(["G", Integer(2)]).cambrian_lattice((Integer(1),Integer(2)))
          Finite lattice containing 8 elements

    codegrees()

      Return the codegrees of the Coxeter group.

      These are just the degrees minus 2.

      EXAMPLES:

      Sage

          sage: CoxeterGroup(['A', 4]).codegrees()
          (0, 1, 2, 3)
          sage: CoxeterGroup(['B', 4]).codegrees()
          (0, 2, 4, 6)
          sage: CoxeterGroup(['D', 4]).codegrees()
          (0, 2, 2, 4)
          sage: CoxeterGroup(['F', 4]).codegrees()
          (0, 4, 6, 10)
          sage: CoxeterGroup(['E', 8]).codegrees()
          (0, 6, 10, 12, 16, 18, 22, 28)
          sage: CoxeterGroup(['H', 3]).codegrees()
          (0, 4, 8)

          sage: WeylGroup([["A",3], ["A",3], ["B",2]]).codegrees()
          (0, 1, 2, 0, 1, 2, 0, 2)

      Python

          >>> from sage.all import *
          >>> CoxeterGroup(['A', Integer(4)]).codegrees()
          (0, 1, 2, 3)
          >>> CoxeterGroup(['B', Integer(4)]).codegrees()
          (0, 2, 4, 6)
          >>> CoxeterGroup(['D', Integer(4)]).codegrees()
          (0, 2, 2, 4)
          >>> CoxeterGroup(['F', Integer(4)]).codegrees()
          (0, 4, 6, 10)
          >>> CoxeterGroup(['E', Integer(8)]).codegrees()
          (0, 6, 10, 12, 16, 18, 22, 28)
          >>> CoxeterGroup(['H', Integer(3)]).codegrees()
          (0, 4, 8)

          >>> WeylGroup([["A",Integer(3)], ["A",Integer(3)], ["B",Integer(2)]]).codegrees()
          (0, 1, 2, 0, 1, 2, 0, 2)

    coxeter_complex()

      Return the Coxeter complex of `self`.

      Let \(W\) be a Coxeter group, and let \(X\) be the corresponding Tits cone, which is constructed as the \(W\) orbit of the fundamental chamber in the reflection representation. The Coxeter complex of \(W\) is the simplicial complex \((X \setminus \{0\}) / \RR_{>0}\). The face poset of this simplicial complex is given by the `coxeter_poset()`. When \(W\) is a finite group, then the Coxeter complex is homeomorphic to an \((n-1)\)-dimensional sphere, where \(n\) is the rank of \(W\).

      EXAMPLES:

      Sage

          sage: W = CoxeterGroup(['A', 3])
          sage: C = W.coxeter_complex()
          sage: C
          Simplicial complex with 14 vertices and 24 facets
          sage: C.homology()
          {0: 0, 1: 0, 2: Z}

          sage: W = WeylGroup(['B', 3])
          sage: C = W.coxeter_complex()
          sage: C
          Simplicial complex with 26 vertices and 48 facets
          sage: C.homology()
          {0: 0, 1: 0, 2: Z}

          sage: W = CoxeterGroup(['I', 7])
          sage: C = W.coxeter_complex()
          sage: C
          Simplicial complex with 14 vertices and 14 facets
          sage: C.homology()
          {0: 0, 1: Z}

          sage: W = CoxeterGroup(['H', 3])
          sage: C = W.coxeter_complex()
          sage: C
          Simplicial complex with 62 vertices and 120 facets
          sage: C.homology()
          {0: 0, 1: 0, 2: Z}

          sage: # optional - gap3
          sage: W = CoxeterGroup(['H', 3], implementation='permutation')
          sage: C = W.coxeter_complex()
          sage: C
          Simplicial complex with 62 vertices and 120 facets
          sage: C.homology()
          {0: 0, 1: 0, 2: Z}

      Python

          >>> from sage.all import *
          >>> W = CoxeterGroup(['A', Integer(3)])
          >>> C = W.coxeter_complex()
          >>> C
          Simplicial complex with 14 vertices and 24 facets
          >>> C.homology()
          {0: 0, 1: 0, 2: Z}

          >>> W = WeylGroup(['B', Integer(3)])
          >>> C = W.coxeter_complex()
          >>> C
          Simplicial complex with 26 vertices and 48 facets
          >>> C.homology()
          {0: 0, 1: 0, 2: Z}

          >>> W = CoxeterGroup(['I', Integer(7)])
          >>> C = W.coxeter_complex()
          >>> C
          Simplicial complex with 14 vertices and 14 facets
          >>> C.homology()
          {0: 0, 1: Z}

          >>> W = CoxeterGroup(['H', Integer(3)])
          >>> C = W.coxeter_complex()
          >>> C
          Simplicial complex with 62 vertices and 120 facets
          >>> C.homology()
          {0: 0, 1: 0, 2: Z}

          >>> # optional - gap3
          >>> W = CoxeterGroup(['H', Integer(3)], implementation='permutation')
          >>> C = W.coxeter_complex()
          >>> C
          Simplicial complex with 62 vertices and 120 facets
          >>> C.homology()
          {0: 0, 1: 0, 2: Z}

    coxeter_poset()

      Return the Coxeter poset of `self`.

      Let \(W\) be a Coxeter group. The Coxeter poset is defined as the set of (right) standard cosets \(gW_J\), where \(J\) is a subset of the index set \(I\) of \(W\), ordered by reverse inclusion.

      This is equal to the face poset of the `Coxeter complex`.

      EXAMPLES:

      Sage

          sage: W = CoxeterGroup(['A', 3])
          sage: P = W.coxeter_poset()
          sage: P
          Finite meet-semilattice containing 75 elements
          sage: P.rank()
          3

          sage: W = WeylGroup(['B', 3])
          sage: P = W.coxeter_poset()
          sage: P
          Finite meet-semilattice containing 147 elements
          sage: P.rank()
          3

          sage: W = CoxeterGroup(['I', 7])
          sage: P = W.coxeter_poset()
          sage: P
          Finite meet-semilattice containing 29 elements
          sage: P.rank()
          2

          sage: W = CoxeterGroup(['H', 3])
          sage: P = W.coxeter_poset()
          sage: P
          Finite meet-semilattice containing 363 elements
          sage: P.rank()
          3

          sage: # optional - gap3
          sage: W = CoxeterGroup(['H', 3], implementation='permutation')
          sage: P = W.coxeter_poset()
          sage: P
          Finite meet-semilattice containing 363 elements
          sage: P.rank()
          3

      Python

          >>> from sage.all import *
          >>> W = CoxeterGroup(['A', Integer(3)])
          >>> P = W.coxeter_poset()
          >>> P
          Finite meet-semilattice containing 75 elements
          >>> P.rank()
          3

          >>> W = WeylGroup(['B', Integer(3)])
          >>> P = W.coxeter_poset()
          >>> P
          Finite meet-semilattice containing 147 elements
          >>> P.rank()
          3

          >>> W = CoxeterGroup(['I', Integer(7)])
          >>> P = W.coxeter_poset()
          >>> P
          Finite meet-semilattice containing 29 elements
          >>> P.rank()
          2

          >>> W = CoxeterGroup(['H', Integer(3)])
          >>> P = W.coxeter_poset()
          >>> P
          Finite meet-semilattice containing 363 elements
          >>> P.rank()
          3

          >>> # optional - gap3
          >>> W = CoxeterGroup(['H', Integer(3)], implementation='permutation')
          >>> P = W.coxeter_poset()
          >>> P
          Finite meet-semilattice containing 363 elements
          >>> P.rank()
          3

    degrees()

      Return the degrees of the Coxeter group.

      The output is an increasing list of integers.

      EXAMPLES:

      Sage

          sage: CoxeterGroup(['A', 4]).degrees()
          (2, 3, 4, 5)
          sage: CoxeterGroup(['B', 4]).degrees()
          (2, 4, 6, 8)
          sage: CoxeterGroup(['D', 4]).degrees()
          (2, 4, 4, 6)
          sage: CoxeterGroup(['F', 4]).degrees()
          (2, 6, 8, 12)
          sage: CoxeterGroup(['E', 8]).degrees()
          (2, 8, 12, 14, 18, 20, 24, 30)
          sage: CoxeterGroup(['H', 3]).degrees()
          (2, 6, 10)

          sage: WeylGroup([["A",3], ["A",3], ["B",2]]).degrees()
          (2, 3, 4, 2, 3, 4, 2, 4)

      Python

          >>> from sage.all import *
          >>> CoxeterGroup(['A', Integer(4)]).degrees()
          (2, 3, 4, 5)
          >>> CoxeterGroup(['B', Integer(4)]).degrees()
          (2, 4, 6, 8)
          >>> CoxeterGroup(['D', Integer(4)]).degrees()
          (2, 4, 4, 6)
          >>> CoxeterGroup(['F', Integer(4)]).degrees()
          (2, 6, 8, 12)
          >>> CoxeterGroup(['E', Integer(8)]).degrees()
          (2, 8, 12, 14, 18, 20, 24, 30)
          >>> CoxeterGroup(['H', Integer(3)]).degrees()
          (2, 6, 10)

          >>> WeylGroup([["A",Integer(3)], ["A",Integer(3)], ["B",Integer(2)]]).degrees()
          (2, 3, 4, 2, 3, 4, 2, 4)

    inversion_sequence(word)

      Return the inversion sequence corresponding to the `word` in indices of simple generators of `self`.

      If `word` corresponds to \([w_0,w_1,...w_k]\), the output is \([w_0,w_0w_1w_0,\ldots,w_0w_1\cdots w_k \cdots w_1 w_0]\).

      INPUT:

      - `word` – a word in the indices of the simple generators of `self`

      EXAMPLES:

      Sage

          sage: CoxeterGroup(["A", 2]).inversion_sequence([1,2,1])
          [
          [-1  1]  [ 0 -1]  [ 1  0]
          [ 0  1], [-1  0], [ 1 -1]
          ]

          sage: [t.reduced_word() for t in CoxeterGroup(["A",3]).inversion_sequence([2,1,3,2,1,3])]
          [[2], [1, 2, 1], [2, 3, 2], [1, 2, 3, 2, 1], [3], [1]]

      Python

          >>> from sage.all import *
          >>> CoxeterGroup(["A", Integer(2)]).inversion_sequence([Integer(1),Integer(2),Integer(1)])
          [
          [-1  1]  [ 0 -1]  [ 1  0]
          [ 0  1], [-1  0], [ 1 -1]
          ]

          >>> [t.reduced_word() for t in CoxeterGroup(["A",Integer(3)]).inversion_sequence([Integer(2),Integer(1),Integer(3),Integer(2),Integer(1),Integer(3)])]
          [[2], [1, 2, 1], [2, 3, 2], [1, 2, 3, 2, 1], [3], [1]]

    is_real()

      Return `True` since `self` is a real reflection group.

      EXAMPLES:

      Sage

          sage: CoxeterGroup(['F',4]).is_real()
          True
          sage: CoxeterGroup(['H',4]).is_real()
          True

      Python

          >>> from sage.all import *
          >>> CoxeterGroup(['F',Integer(4)]).is_real()
          True
          >>> CoxeterGroup(['H',Integer(4)]).is_real()
          True

    long_element(index_set=None, as_word=False)

      Return the longest element of `self`, or of the parabolic subgroup corresponding to the given `index_set`.

      INPUT:

      - `index_set` – a subset (as a list or iterable) of the nodes of the Dynkin diagram; (default: all of them)

      - `as_word` – boolean (default: `False`); if `True`, then return instead a reduced decomposition of the longest element

      Should this method be called maximal_element? longest_element?

      EXAMPLES:

      Sage

          sage: D10 = FiniteCoxeterGroups().example(10)
          sage: D10.long_element()
          (1, 2, 1, 2, 1, 2, 1, 2, 1, 2)
          sage: D10.long_element([1])
          (1,)
          sage: D10.long_element([2])
          (2,)
          sage: D10.long_element([])
          ()

          sage: D7 = FiniteCoxeterGroups().example(7)
          sage: D7.long_element()
          (1, 2, 1, 2, 1, 2, 1)

      Python

          >>> from sage.all import *
          >>> D10 = FiniteCoxeterGroups().example(Integer(10))
          >>> D10.long_element()
          (1, 2, 1, 2, 1, 2, 1, 2, 1, 2)
          >>> D10.long_element([Integer(1)])
          (1,)
          >>> D10.long_element([Integer(2)])
          (2,)
          >>> D10.long_element([])
          ()

          >>> D7 = FiniteCoxeterGroups().example(Integer(7))
          >>> D7.long_element()
          (1, 2, 1, 2, 1, 2, 1)

      One can require instead a reduced word for w0:

      Sage

          sage: A3 = CoxeterGroup(['A', 3])
          sage: A3.long_element(as_word=True)
          [1, 2, 1, 3, 2, 1]

      [Python]

          >>> from sage.all import *
          >>> A3 = CoxeterGroup(['A', Integer(3)])
          >>> A3.long_element(as_word=True)
          [1, 2, 1, 3, 2, 1]

    m_cambrian_lattice(c, m=1, on_roots=False)

      Return the \(m\)-Cambrian lattice on \(m\)-delta sequences.

      See arXiv 1503.00710 and arXiv math/0611106.

      The \(m\)-delta sequences are certain \(m\)-colored minimal factorizations of \(c\) into reflections.

      INPUT:

      - `c` – a Coxeter element of `self` (as a tuple, or as an element of `self`)

      - `m` – positive integer (default: 1)

      - `on_roots` – boolean (default: `False`); if `on_roots` is `True`, the lattice is realized on roots rather than on reflections. In order for this to work, the ElementMethod `reflection_to_root` must be available.

      EXAMPLES:

      Sage

          sage: CoxeterGroup(["A",2]).m_cambrian_lattice((1,2))
          Finite lattice containing 5 elements

          sage: CoxeterGroup(["A",2]).m_cambrian_lattice((1,2),2)
          Finite lattice containing 12 elements

      Python

          >>> from sage.all import *
          >>> CoxeterGroup(["A",Integer(2)]).m_cambrian_lattice((Integer(1),Integer(2)))
          Finite lattice containing 5 elements

          >>> CoxeterGroup(["A",Integer(2)]).m_cambrian_lattice((Integer(1),Integer(2)),Integer(2))
          Finite lattice containing 12 elements

    permutahedron(point=None, base_ring=None)

      Return the permutahedron of `self`.

      This is the convex hull of the point `point` in the weight basis under the action of `self` on the underlying vector space \(V\).

      See also

      `permutahedron()`

      INPUT:

      - `point` – (optional) a point given by its coordinates in the weight basis (default: \((1, 1, 1, \ldots)\))

      - `base_ring` – (optional) the base ring of the polytope

      Note

      The result is expressed in the root basis coordinates.

      Note

      If function is too slow, switching the base ring to `RDF` will almost certainly speed things up.

      EXAMPLES:

      Sage

          sage: W = CoxeterGroup(['H',3], base_ring=RDF)
          sage: W.permutahedron()
          doctest:warning
          ...
          UserWarning: This polyhedron data is numerically complicated; cdd could not convert between the inexact V and H representation without loss of data. The resulting object might show inconsistencies.
          A 3-dimensional polyhedron in RDF^3 defined as the convex hull of 120 vertices

          sage: W = CoxeterGroup(['I',7])
          sage: W.permutahedron()
          A 2-dimensional polyhedron in AA^2 defined as the convex hull of 14 vertices
          sage: W.permutahedron(base_ring=RDF)
          A 2-dimensional polyhedron in RDF^2 defined as the convex hull of 14 vertices

          sage: W = ReflectionGroup(['A',3])                          # optional - gap3
          sage: W.permutahedron()                                     # optional - gap3
          A 3-dimensional polyhedron in QQ^3 defined as the convex hull
          of 24 vertices

          sage: W = ReflectionGroup(['A',3],['B',2])                  # optional - gap3
          sage: W.permutahedron()                                     # optional - gap3
          A 5-dimensional polyhedron in QQ^5 defined as the convex hull of 192 vertices

      Python

          >>> from sage.all import *
          >>> W = CoxeterGroup(['H',Integer(3)], base_ring=RDF)
          >>> W.permutahedron()
          doctest:warning
          ...
          UserWarning: This polyhedron data is numerically complicated; cdd could not convert between the inexact V and H representation without loss of data. The resulting object might show inconsistencies.
          A 3-dimensional polyhedron in RDF^3 defined as the convex hull of 120 vertices

          >>> W = CoxeterGroup(['I',Integer(7)])
          >>> W.permutahedron()
          A 2-dimensional polyhedron in AA^2 defined as the convex hull of 14 vertices
          >>> W.permutahedron(base_ring=RDF)
          A 2-dimensional polyhedron in RDF^2 defined as the convex hull of 14 vertices

          >>> W = ReflectionGroup(['A',Integer(3)])                          # optional - gap3
          >>> W.permutahedron()                                     # optional - gap3
          A 3-dimensional polyhedron in QQ^3 defined as the convex hull
          of 24 vertices

          >>> W = ReflectionGroup(['A',Integer(3)],['B',Integer(2)])                  # optional - gap3
          >>> W.permutahedron()                                     # optional - gap3
          A 5-dimensional polyhedron in QQ^5 defined as the convex hull of 192 vertices

    reflections_from_w0()

      Return the reflections of `self` using the inversion set of `w_0`.

      EXAMPLES:

      Sage

          sage: WeylGroup(['A',2]).reflections_from_w0()
          [
          [0 1 0]  [0 0 1]  [1 0 0]
          [1 0 0]  [0 1 0]  [0 0 1]
          [0 0 1], [1 0 0], [0 1 0]
          ]

          sage: WeylGroup(['A',3]).reflections_from_w0()
          [
          [0 1 0 0]  [0 0 1 0]  [1 0 0 0]  [0 0 0 1]  [1 0 0 0]  [1 0 0 0]
          [1 0 0 0]  [0 1 0 0]  [0 0 1 0]  [0 1 0 0]  [0 0 0 1]  [0 1 0 0]
          [0 0 1 0]  [1 0 0 0]  [0 1 0 0]  [0 0 1 0]  [0 0 1 0]  [0 0 0 1]
          [0 0 0 1], [0 0 0 1], [0 0 0 1], [1 0 0 0], [0 1 0 0], [0 0 1 0]
          ]

      Python

          >>> from sage.all import *
          >>> WeylGroup(['A',Integer(2)]).reflections_from_w0()
          [
          [0 1 0]  [0 0 1]  [1 0 0]
          [1 0 0]  [0 1 0]  [0 0 1]
          [0 0 1], [1 0 0], [0 1 0]
          ]

          >>> WeylGroup(['A',Integer(3)]).reflections_from_w0()
          [
          [0 1 0 0]  [0 0 1 0]  [1 0 0 0]  [0 0 0 1]  [1 0 0 0]  [1 0 0 0]
          [1 0 0 0]  [0 1 0 0]  [0 0 1 0]  [0 1 0 0]  [0 0 0 1]  [0 1 0 0]
          [0 0 1 0]  [1 0 0 0]  [0 1 0 0]  [0 0 1 0]  [0 0 1 0]  [0 0 0 1]
          [0 0 0 1], [0 0 0 1], [0 0 0 1], [1 0 0 0], [0 1 0 0], [0 0 1 0]
          ]

    shard_poset(side='right')

      Return the shard intersection order attached to \(W\).

      This is a lattice structure on \(W\), introduced in [Rea2009]. It contains the noncrossing partition lattice, as the induced lattice on the subset of \(c\)-sortable elements.

      The partial order is given by simultaneous inclusion of inversion sets and subgroups attached to every element.

      The precise description used here can be found in [STW2018].

      Another implementation for the symmetric groups is available as `shard_poset()`.

      See also

      `bhz_poset()`, `bruhat_poset()`, `weak_poset()`

      EXAMPLES:

      Sage

          sage: W = CoxeterGroup(['A',3], base_ring=ZZ)
          sage: SH = W.shard_poset(); SH
          Finite lattice containing 24 elements
          sage: SH.is_graded()
          True
          sage: SH.characteristic_polynomial()
          q^3 - 11*q^2 + 23*q - 13
          sage: SH.f_polynomial()
          34*q^3 + 22*q^2 + q

      Python

          >>> from sage.all import *
          >>> W = CoxeterGroup(['A',Integer(3)], base_ring=ZZ)
          >>> SH = W.shard_poset(); SH
          Finite lattice containing 24 elements
          >>> SH.is_graded()
          True
          >>> SH.characteristic_polynomial()
          q^3 - 11*q^2 + 23*q - 13
          >>> SH.f_polynomial()
          34*q^3 + 22*q^2 + q

    w0()

      Return the longest element of `self`.

      This attribute is deprecated, use `long_element()` instead.

      EXAMPLES:

      Sage

          sage: D8 = FiniteCoxeterGroups().example(8)
          sage: D8.w0
          (1, 2, 1, 2, 1, 2, 1, 2)
          sage: D3 = FiniteCoxeterGroups().example(3)
          sage: D3.w0
          (1, 2, 1)

      Python

          >>> from sage.all import *
          >>> D8 = FiniteCoxeterGroups().example(Integer(8))
          >>> D8.w0
          (1, 2, 1, 2, 1, 2, 1, 2)
          >>> D3 = FiniteCoxeterGroups().example(Integer(3))
          >>> D3.w0
          (1, 2, 1)

    weak_lattice(side='right', facade=False)

      alias of `weak_poset()`.

    weak_poset(side='right', facade=False)

      INPUT:

      - `side` – “left”, “right”, or “twosided” (default: `'right'`)

      - `facade` – boolean (default: `False`)

      Returns the left (resp. right) poset for weak order. In this poset, \(u\) is smaller than \(v\) if some reduced word of \(u\) is a right (resp. left) factor of some reduced word of \(v\).

      See also

      `bhz_poset()`, `bruhat_poset()`, `shard_poset()`

      EXAMPLES:

      Sage

          sage: W = WeylGroup(["A", 2])
          sage: P = W.weak_poset()
          sage: P
          Finite lattice containing 6 elements
          sage: P.show()

      Python

          >>> from sage.all import *
          >>> W = WeylGroup(["A", Integer(2)])
          >>> P = W.weak_poset()
          >>> P
          Finite lattice containing 6 elements
          >>> P.show()

      This poset is in fact a lattice:

      Sage

          sage: W = WeylGroup(["B", 3])
          sage: P = W.weak_poset(side = "left")
          sage: P.is_lattice()
          True

      [Python]

          >>> from sage.all import *
          >>> W = WeylGroup(["B", Integer(3)])
          >>> P = W.weak_poset(side = "left")
          >>> P.is_lattice()
          True

      so this method has an alias `weak_lattice()`:

      Sage

          sage: W.weak_lattice(side = "left") is W.weak_poset(side = "left")
          True

      Python

          >>> from sage.all import *
          >>> W.weak_lattice(side = "left") is W.weak_poset(side = "left")
          True

      As a bonus feature, one can create the left-right weak poset:

      Sage

          sage: W = WeylGroup(["A",2])
          sage: P = W.weak_poset(side = "twosided")
          sage: P.show()
          sage: len(P.hasse_diagram().edges(sort=False))
          8

      [Python]

          >>> from sage.all import *
          >>> W = WeylGroup(["A",Integer(2)])
          >>> P = W.weak_poset(side = "twosided")
          >>> P.show()
          >>> len(P.hasse_diagram().edges(sort=False))
          8

      This is the transitive closure of the union of left and right order. In this poset, \(u\) is smaller than \(v\) if some reduced word of \(u\) is a factor of some reduced word of \(v\). Note that this is not a lattice:

      Sage

          sage: P.is_lattice()
          False

      Python

          >>> from sage.all import *
          >>> P.is_lattice()
          False

      By default, the elements of \(P\) are aware of that they belong to \(P\):

      Sage

          sage: P.an_element().parent()
          Finite poset containing 6 elements

      [Python]

          >>> from sage.all import *
          >>> P.an_element().parent()
          Finite poset containing 6 elements

      If instead one wants the elements to be plain elements of the Coxeter group, one can use the `facade` option:

      Sage

          sage: P = W.weak_poset(facade = True)
          sage: P.an_element().parent()
          Weyl Group of type ['A', 2] (as a matrix group acting on the ambient space)

      Python

          >>> from sage.all import *
          >>> P = W.weak_poset(facade = True)
          >>> P.an_element().parent()
          Weyl Group of type ['A', 2] (as a matrix group acting on the ambient space)

      See also

      `Poset()` for more on posets and facade posets.

      Todo

      - Use the symmetric group in the examples (for nicer output), and print the edges for a stronger test.

      - The constructed poset should be lazy, in order to handle large / infinite Coxeter groups.

  extra_super_categories()

    EXAMPLES:

    Sage

        sage: CoxeterGroups().Finite().super_categories()
        [Category of finite generalized Coxeter groups,
         Category of Coxeter groups]

    Python

        >>> from sage.all import *
        >>> CoxeterGroups().Finite().super_categories()
        [Category of finite generalized Coxeter groups,
         Category of Coxeter groups]