Root systems#


See Root Systems for an overview.

class sage.combinat.root_system.root_system.RootSystem(cartan_type, as_dual_of=None)#

Bases: UniqueRepresentation, SageObject

A class for root systems.

EXAMPLES:

We construct the root system for type \(B_3\):

sage: R = RootSystem(['B',3]); R
Root system of type ['B', 3]

R models the root system abstractly. It comes equipped with various realizations of the root and weight lattices, where all computations take place. Let us play first with the root lattice:

sage: space = R.root_lattice(); space
Root lattice of the Root system of type ['B', 3]

This is the free \(\ZZ\)-module \(\bigoplus_i \ZZ.\alpha_i\) spanned by the simple roots:

sage: space.base_ring()
Integer Ring
sage: list(space.basis())
[alpha[1], alpha[2], alpha[3]]

Let us do some computations with the simple roots:

sage: alpha = space.simple_roots()
sage: alpha[1] + alpha[2]
alpha[1] + alpha[2]

There is a canonical pairing between the root lattice and the coroot lattice:

sage: R.coroot_lattice()
Coroot lattice of the Root system of type ['B', 3]

We construct the simple coroots, and do some computations (see comments about duality below for some caveat):

sage: alphacheck = space.simple_coroots()
sage: list(alphacheck)
[alphacheck[1], alphacheck[2], alphacheck[3]]

We can carry over the same computations in any of the other realizations of the root lattice, like the root space \(\bigoplus_i \QQ.\alpha_i\), the weight lattice \(\bigoplus_i \ZZ.\Lambda_i\), the weight space \(\bigoplus_i \QQ.\Lambda_i\). For example:

sage: space = R.weight_space(); space
Weight space over the Rational Field of the Root system of type ['B', 3]
sage: space.base_ring()
Rational Field
sage: list(space.basis())
[Lambda[1], Lambda[2], Lambda[3]]
sage: alpha = space.simple_roots()                                              # needs sage.graphs
sage: alpha[1] + alpha[2]                                                       # needs sage.graphs
Lambda[1] + Lambda[2] - 2*Lambda[3]

The fundamental weights are the dual basis of the coroots:

sage: Lambda = space.fundamental_weights()
sage: Lambda[1]
Lambda[1]
sage: alphacheck = space.simple_coroots()                                       # needs sage.graphs
sage: list(alphacheck)                                                          # needs sage.graphs
[alphacheck[1], alphacheck[2], alphacheck[3]]
sage: [Lambda[i].scalar(alphacheck[1]) for i in space.index_set()]
[1, 0, 0]
sage: [Lambda[i].scalar(alphacheck[2]) for i in space.index_set()]
[0, 1, 0]
sage: [Lambda[i].scalar(alphacheck[3]) for i in space.index_set()]
[0, 0, 1]

Let us use the simple reflections. In the weight space, they work as in the number game: firing the node \(i\) on an element \(x\) adds \(c\) times the simple root \(\alpha_i\), where \(c\) is the coefficient of \(i\) in \(x\):

sage: # needs sage.graphs
sage: Lambda[1].simple_reflection(1)
-Lambda[1] + Lambda[2]
sage: Lambda[2].simple_reflection(1)
Lambda[2]
sage: Lambda[3].simple_reflection(1)
Lambda[3]
sage: (-2*Lambda[1] + Lambda[2] + Lambda[3]).simple_reflection(1)
2*Lambda[1] - Lambda[2] + Lambda[3]

It can be convenient to manipulate the simple reflections themselves:

sage: # needs sage.graphs
sage: s = space.simple_reflections()
sage: s[1](Lambda[1])
-Lambda[1] + Lambda[2]
sage: s[1](Lambda[2])
Lambda[2]
sage: s[1](Lambda[3])
Lambda[3]

Ambient spaces

The root system may also come equipped with an ambient space. This is a \(\QQ\)-module, endowed with its canonical Euclidean scalar product, which admits simultaneous embeddings of the (extended) weight and the (extended) coweight lattice, and therefore the root and the coroot lattice. This is implemented on a type by type basis for the finite crystallographic root systems following Bourbaki’s conventions and is extended to the affine cases. Coefficients permitting, this is also available as an ambient lattice.

See also

ambient_space() and ambient_lattice() for details

In finite type \(A\), we recover the natural representation of the symmetric group as group of permutation matrices:

sage: RootSystem(["A",2]).ambient_space().weyl_group().simple_reflections()     # needs sage.libs.gap sage.libs.pari
Finite family {1: [0 1 0]
                  [1 0 0]
                  [0 0 1],
               2: [1 0 0]
                  [0 0 1]
                  [0 1 0]}

In type \(B\), \(C\), and \(D\), we recover the natural representation of the Weyl group as groups of signed permutation matrices:

sage: RootSystem(["B",3]).ambient_space().weyl_group().simple_reflections()     # needs sage.libs.gap sage.libs.pari
Finite family {1: [0 1 0]
                  [1 0 0]
                  [0 0 1],
               2: [1 0 0]
                  [0 0 1]
                  [0 1 0],
               3: [ 1  0  0]
                  [ 0  1  0]
                  [ 0  0 -1]}

In (untwisted) affine types \(A\), …, \(D\), one can recover from the ambient space the affine permutation representation, in window notation. Let us consider the ambient space for affine type \(A\):

sage: L = RootSystem(["A",2,1]).ambient_space(); L
Ambient space of the Root system of type ['A', 2, 1]

Define the “identity” by an appropriate vector at level \(-3\):

sage: e = L.basis(); Lambda = L.fundamental_weights()                           # needs sage.graphs
sage: id = e[0] + 2*e[1] + 3*e[2]  - 3*Lambda[0]                                # needs sage.graphs

The corresponding permutation is obtained by projecting it onto the classical ambient space:

sage: L.classical()
Ambient space of the Root system of type ['A', 2]
sage: L.classical()(id)                                                         # needs sage.graphs
(1, 2, 3)

Here is the orbit of the identity under the action of the finite group:

sage: # needs sage.graphs sage.libs.gap sage.libs.pari
sage: W = L.weyl_group()
sage: S3 = [ w.action(id) for w in W.classical() ]
sage: [L.classical()(x) for x in S3]
[(1, 2, 3), (3, 1, 2), (2, 3, 1), (2, 1, 3), (1, 3, 2), (3, 2, 1)]

And the action of \(s_0\) on these yields:

sage: # needs sage.graphs sage.libs.gap sage.libs.pari
sage: s = W.simple_reflections()
sage: [L.classical()(s[0].action(x)) for x in S3]
[(0, 2, 4), (-1, 1, 6), (-2, 3, 5), (0, 1, 5), (-1, 3, 4), (-2, 2, 6)]

We can also plot various components of the ambient spaces:

sage: L = RootSystem(['A',2]).ambient_space()
sage: L.plot()                                                                  # needs sage.plot sage.symbolic
Graphics object consisting of 13 graphics primitives

For more on plotting, see Tutorial: visualizing root systems.

Dual root systems

The root system is aware of its dual root system:

sage: R.dual
Dual of root system of type ['B', 3]

R.dual is really the root system of type \(C_3\):

sage: R.dual.cartan_type()
['C', 3]

And the coroot lattice that we have been manipulating before is really implemented as the root lattice of the dual root system:

sage: R.dual.root_lattice()
Coroot lattice of the Root system of type ['B', 3]

In particular, the coroots for the root lattice are in fact the roots of the coroot lattice:

sage: list(R.root_lattice().simple_coroots())
[alphacheck[1], alphacheck[2], alphacheck[3]]
sage: list(R.coroot_lattice().simple_roots())
[alphacheck[1], alphacheck[2], alphacheck[3]]
sage: list(R.dual.root_lattice().simple_roots())
[alphacheck[1], alphacheck[2], alphacheck[3]]

The coweight lattice and space are defined similarly. Note that, to limit confusion, all the output have been tweaked appropriately.

See also

ambient_lattice()#

Return the ambient lattice for this root_system.

This is the ambient space, over \(\ZZ\).

EXAMPLES:

sage: RootSystem(['A',4]).ambient_lattice()
Ambient lattice of the Root system of type ['A', 4]
sage: RootSystem(['A',4,1]).ambient_lattice()
Ambient lattice of the Root system of type ['A', 4, 1]

Except in type A, only an ambient space can be realized:

sage: RootSystem(['B',4]).ambient_lattice()
sage: RootSystem(['C',4]).ambient_lattice()
sage: RootSystem(['D',4]).ambient_lattice()
sage: RootSystem(['E',6]).ambient_lattice()
sage: RootSystem(['F',4]).ambient_lattice()
sage: RootSystem(['G',2]).ambient_lattice()
ambient_space(base_ring=Rational Field)#

Return the usual ambient space for this root_system.

INPUT:

  • base_ring – a base ring (default: \(\QQ\))

This is a base_ring-module, endowed with its canonical Euclidean scalar product, which admits simultaneous embeddings into the weight and the coweight lattice, and therefore the root and the coroot lattice, and preserves scalar products between elements of the coroot lattice and elements of the root or weight lattice (and dually).

There is no mechanical way to define the ambient space just from the Cartan matrix. Instead it is constructed from hard coded type by type data, according to the usual Bourbaki conventions. Such data is provided for all the finite (crystallographic) types. From this data, ambient spaces can be built as well for dual types, reducible types and affine types. When no data is available, or if the base ring is not large enough, None is returned.

Warning

for affine types

See also

EXAMPLES:

sage: RootSystem(['A',4]).ambient_space()
Ambient space of the Root system of type ['A', 4]
sage: RootSystem(['B',4]).ambient_space()
Ambient space of the Root system of type ['B', 4]
sage: RootSystem(['C',4]).ambient_space()
Ambient space of the Root system of type ['C', 4]
sage: RootSystem(['D',4]).ambient_space()
Ambient space of the Root system of type ['D', 4]
sage: RootSystem(['E',6]).ambient_space()
Ambient space of the Root system of type ['E', 6]
sage: RootSystem(['F',4]).ambient_space()
Ambient space of the Root system of type ['F', 4]
sage: RootSystem(['G',2]).ambient_space()
Ambient space of the Root system of type ['G', 2]

An alternative base ring can be provided as an option:

sage: e = RootSystem(['B',3]).ambient_space(RR)
sage: TestSuite(e).run()                                                    # needs sage.graphs

It should contain the smallest ring over which the ambient space can be defined (\(\ZZ\) in type \(A\) or \(\QQ\) otherwise). Otherwise None is returned:

sage: RootSystem(['B',2]).ambient_space(ZZ)

The base ring should also be totally ordered. In practice, only \(\ZZ\) and \(\QQ\) are really supported at this point, but you are welcome to experiment:

sage: e = RootSystem(['G',2]).ambient_space(RR)
sage: TestSuite(e).run()                                                    # needs sage.graphs
Failure in _test_root_lattice_realization:
Traceback (most recent call last):
...
AssertionError: 2.00000000000000 != 2.00000000000000
------------------------------------------------------------
The following tests failed: _test_root_lattice_realization
cartan_matrix()#

EXAMPLES:

sage: RootSystem(['A',3]).cartan_matrix()                                   # needs sage.graphs
[ 2 -1  0]
[-1  2 -1]
[ 0 -1  2]
cartan_type()#

Return the Cartan type of the root system.

EXAMPLES:

sage: R = RootSystem(['A',3])
sage: R.cartan_type()
['A', 3]
coambient_space(base_ring=Rational Field)#

Return the coambient space for this root system.

This is the ambient space of the dual root system.

See also

EXAMPLES:

sage: L = RootSystem(["B",2]).ambient_space(); L
Ambient space of the Root system of type ['B', 2]
sage: coL = RootSystem(["B",2]).coambient_space(); coL
Coambient space of the Root system of type ['B', 2]

The roots and coroots are interchanged:

sage: coL.simple_roots()
Finite family {1: (1, -1), 2: (0, 2)}
sage: L.simple_coroots()
Finite family {1: (1, -1), 2: (0, 2)}

sage: coL.simple_coroots()
Finite family {1: (1, -1), 2: (0, 1)}
sage: L.simple_roots()
Finite family {1: (1, -1), 2: (0, 1)}
coroot_lattice()#

Return the coroot lattice associated to self.

EXAMPLES:

sage: RootSystem(['A',3]).coroot_lattice()
Coroot lattice of the Root system of type ['A', 3]
coroot_space(base_ring=Rational Field)#

Return the coroot space associated to self.

EXAMPLES:

sage: RootSystem(['A',3]).coroot_space()
Coroot space over the Rational Field of the Root system of type ['A', 3]
coweight_lattice(extended=False)#

Return the coweight lattice associated to self.

This is the weight lattice of the dual root system.

EXAMPLES:

sage: RootSystem(['A',3]).coweight_lattice()
Coweight lattice of the Root system of type ['A', 3]

sage: RootSystem(['A',3,1]).coweight_lattice(extended=True)
Extended coweight lattice of the Root system of type ['A', 3, 1]
coweight_space(base_ring=Rational Field, extended=False)#

Return the coweight space associated to self.

This is the weight space of the dual root system.

EXAMPLES:

sage: RootSystem(['A',3]).coweight_space()
Coweight space over the Rational Field of the Root system of type ['A', 3]

sage: RootSystem(['A',3,1]).coweight_space(extended=True)
Extended coweight space over the Rational Field
 of the Root system of type ['A', 3, 1]
dynkin_diagram()#

Return the Dynkin diagram of the root system.

EXAMPLES:

sage: R = RootSystem(['A',3])
sage: R.dynkin_diagram()                                                    # needs sage.graphs
O---O---O
1   2   3
A3
index_set()#

EXAMPLES:

sage: RootSystem(['A',3]).index_set()
(1, 2, 3)
is_finite()#

Return True if self is a finite root system.

EXAMPLES:

sage: RootSystem(["A",3]).is_finite()
True
sage: RootSystem(["A",3,1]).is_finite()
False
is_irreducible()#

Return True if self is an irreducible root system.

EXAMPLES:

sage: RootSystem(['A', 3]).is_irreducible()
True
sage: RootSystem("A2xB2").is_irreducible()
False
root_lattice()#

Return the root lattice associated to self.

EXAMPLES:

sage: RootSystem(['A',3]).root_lattice()
Root lattice of the Root system of type ['A', 3]
root_poset(restricted=False, facade=False)#

Return the (restricted) root poset associated to self.

The elements are given by the positive roots (resp. non-simple, positive roots), and \(\alpha \leq \beta\) iff \(\beta - \alpha\) is a non-negative linear combination of simple roots.

INPUT:

  • restricted – (default:False) if True, only non-simple roots are considered.

  • facade – (default:False) passes facade option to the poset generator.

EXAMPLES:

sage: Phi = RootSystem(['A',2]).root_poset(); Phi                           # needs sage.graphs
Finite poset containing 3 elements
sage: sorted(Phi.cover_relations(), key=str)                                # needs sage.graphs
[[alpha[1], alpha[1] + alpha[2]], [alpha[2], alpha[1] + alpha[2]]]

sage: Phi = RootSystem(['A',3]).root_poset(restricted=True); Phi            # needs sage.graphs
Finite poset containing 3 elements
sage: sorted(Phi.cover_relations(), key=str)                                # needs sage.graphs
[[alpha[1] + alpha[2], alpha[1] + alpha[2] + alpha[3]],
 [alpha[2] + alpha[3], alpha[1] + alpha[2] + alpha[3]]]

sage: Phi = RootSystem(['B',2]).root_poset(); Phi                           # needs sage.graphs
Finite poset containing 4 elements
sage: Phi.cover_relations()                                                 # needs sage.graphs
[[alpha[2], alpha[1] + alpha[2]], [alpha[1], alpha[1] + alpha[2]],
 [alpha[1] + alpha[2], alpha[1] + 2*alpha[2]]]
root_space(base_ring=Rational Field)#

Return the root space associated to self.

EXAMPLES:

sage: RootSystem(['A',3]).root_space()
Root space over the Rational Field of the Root system of type ['A', 3]
weight_lattice(extended=False)#

Return the weight lattice associated to self.

EXAMPLES:

sage: RootSystem(['A',3]).weight_lattice()
Weight lattice of the Root system of type ['A', 3]

sage: RootSystem(['A',3,1]).weight_space(extended=True)
Extended weight space over the Rational Field
 of the Root system of type ['A', 3, 1]
weight_space(base_ring=Rational Field, extended=False)#

Returns the weight space associated to self.

EXAMPLES:

sage: RootSystem(['A',3]).weight_space()
Weight space over the Rational Field of the Root system of type ['A', 3]

sage: RootSystem(['A',3,1]).weight_space(extended=True)
Extended weight space over the Rational Field
 of the Root system of type ['A', 3, 1]
sage.combinat.root_system.root_system.WeylDim(ct, coeffs)#

The Weyl Dimension Formula.

INPUT:

  • ct – a Cartan type

  • coeffs – a list of nonnegative integers

The length of the list must equal the rank type[1]. A dominant weight hwv is constructed by summing the fundamental weights with coefficients from this list. The dimension of the irreducible representation of the semisimple complex Lie algebra with highest weight vector hwv is returned.

EXAMPLES:

For \(SO(7)\), the Cartan type is \(B_3\), so:

sage: WeylDim(['B',3],[1,0,0])  # standard representation of SO(7)
7
sage: WeylDim(['B',3],[0,1,0])  # exterior square
21
sage: WeylDim(['B',3],[0,0,1])  # spin representation of spin(7)
8
sage: WeylDim(['B',3],[1,0,1])  # sum of the first and third fundamental weights
48
sage: [WeylDim(['F',4],x) for x in ([1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1])]
[52, 1274, 273, 26]
sage: [WeylDim(['E', 6], x)
....:  for x in ([0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1],
....:            [0, 0, 0, 0, 0, 2], [0, 0, 0, 0, 1, 0], [0, 0, 1, 0, 0, 0],
....:            [1, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 1], [2, 0, 0, 0, 0, 0])]
[1, 78, 27, 351, 351, 351, 27, 650, 351]