Affine Root System Basics¶
Among infinite-dimensional Lie algebras, Kac-Moody Lie algebras are generalizations of finite-dimensional simple Lie algebras. They include finite-dimensional simple Lie algebras as special cases but are usually infinite-dimensional. Many concepts and results from the representation theory of finite-dimensional Lie groups and Lie algebras extend to Kac-Moody Lie algebras. This includes the root system, Weyl group, weight lattice, the parametrization of important representations (the integrable highest weight ones) by dominant weights and the Weyl character formula for these representations.
Among Kac-Moody Lie algebras, affine Lie algebras are an important infinite-dimensional class, and their infinite-dimensional integrable highest-weight representations are an important class among their representations. In this section many of the concepts are applicable to general Kac-Moody Lie algebras. However the code that we will discuss is mainly for the affine case. This is sufficiently different from the general case (and important) to merit special attention.
In this section we will review some of the Kac-Moody theory, taking [Kac] as our primary reference. We also recommend [KMPS]. This two volume set contains tables (in Volume 2) of quantities such as string functions and modular characteristics that you can now compute in Sage. Volume 1 contains an introduction to affine Lie algebras and their representations, including a valuable discussion of how they arise in string theory.
In this section and the next, we will also explain what facilities there are in Sage for computing with these. We will often restrict ourselves to the case of affine Lie algebras.
Cartan Matrix¶
See [Kac] Chapter 1 for this topic.
The basic data defining a Kac-Moody Lie algebra is a
(generalized) Cartan matrix. This is a square matrix
Given a generalized Cartan matrix there is a vector space
(These conditions do not quite characterize
The significance of the diagonalizability assumption
is that
The transpose of
In Sage, we may recover the Cartan matrix as follows:
sage: RootSystem(['B',2]).cartan_matrix()
[ 2 -1]
[-2 2]
sage: RootSystem(['B',2,1]).cartan_matrix()
[ 2 0 -1]
[ 0 2 -1]
[-2 -2 2]
>>> from sage.all import *
>>> RootSystem(['B',Integer(2)]).cartan_matrix()
[ 2 -1]
[-2 2]
>>> RootSystem(['B',Integer(2),Integer(1)]).cartan_matrix()
[ 2 0 -1]
[ 0 2 -1]
[-2 -2 2]
RootSystem(['B',2]).cartan_matrix() RootSystem(['B',2,1]).cartan_matrix()
If
Untwisted Affine Kac-Moody Lie Algebras¶
One realization of affine Lie algebras, described in Chapter 7
of [Kac] begins with a finite-dimensional simple Lie algebra
['X',l]
in Sage).
Tensoring with the Laurent polynomial ring gives the loop Lie algebra
After that, it is convenient to adjoin another basis element,
which acts on
The resulting Lie algebra ['X',l,1]
or "Xl~"
in Sage. The Dynkin diagram of this Cartan type is the
extended Dynkin-diagram of
sage: CartanType("E6~").dynkin_diagram()
O 0
|
|
O 2
|
|
O---O---O---O---O
1 3 4 5 6
E6~
>>> from sage.all import *
>>> CartanType("E6~").dynkin_diagram()
O 0
|
|
O 2
|
|
O---O---O---O---O
1 3 4 5 6
E6~
CartanType("E6~").dynkin_diagram()
From the Dynkin diagram, we can read off generators and relations
for the affine Weyl group, which is a Coxeter group with generators
The index set for the finite-dimensional Lie algebra
The subset of
sage: RootSystem("A2~").weight_lattice()
Weight lattice of the Root system of type ['A', 2, 1]
sage: RootSystem("A2~").weight_lattice(extended=True)
Extended weight lattice of the Root system of type ['A', 2, 1]
>>> from sage.all import *
>>> RootSystem("A2~").weight_lattice()
Weight lattice of the Root system of type ['A', 2, 1]
>>> RootSystem("A2~").weight_lattice(extended=True)
Extended weight lattice of the Root system of type ['A', 2, 1]
RootSystem("A2~").weight_lattice() RootSystem("A2~").weight_lattice(extended=True)
Referring to the extended lattice, the term lattice is a slight misnomer
because
The Weyl vector
Usually there is an advantage to working with
There are exceptions to this rule of preferring the extended
weight lattice. In particular, we can construct non-trivial
irreducible finite-dimensional representations of
Twisted Types¶
There are also twisted types with Cartan type ['X',l,m]
where ['E',6,2]
(or ['F',4,1]
(or
Referring to the above Dynkin diagram for ['E',6,1]
, if
we collapse the nodes 1 and 6 together, and the nodes 3 and 5,
we obtain the Dynkin diagram for ['E',6,2]
:
sage: CartanType(['E',6,2]).dynkin_diagram()
O---O---O=<=O---O
0 1 2 3 4
F4~*
>>> from sage.all import *
>>> CartanType(['E',Integer(6),Integer(2)]).dynkin_diagram()
O---O---O=<=O---O
0 1 2 3 4
F4~*
CartanType(['E',6,2]).dynkin_diagram()
We must explain why Sage calls this Cartan type F4~*
.
The Cartan type ['F',4,1]
is obtained by adding one
Dynkin node to the Cartan type “F4”:
sage: CartanType(['F',4,1]).dynkin_diagram()
O---O---O=>=O---O
0 1 2 3 4
F4~
>>> from sage.all import *
>>> CartanType(['F',Integer(4),Integer(1)]).dynkin_diagram()
O---O---O=>=O---O
0 1 2 3 4
F4~
CartanType(['F',4,1]).dynkin_diagram()
The Cartan types ['E',6,2]
and ['F',4,1]
(abbreviated F4~
)
are dual in the sense that long roots of one correspond to short roots
of the other. (Thus ['E',6,2]
, they are long roots of ['F',4,1]
.)
More generally, every twisted affine type is dual to a unique untwisted
type, and the Macdonald convention is to refer to the Cartan type as
the dual of the corresponding untwisted type:
sage: CartanType(['F',4,1]).dual() == CartanType(['E',6,2])
True
>>> from sage.all import *
>>> CartanType(['F',Integer(4),Integer(1)]).dual() == CartanType(['E',Integer(6),Integer(2)])
True
CartanType(['F',4,1]).dual() == CartanType(['E',6,2])
Roots and Weights¶
A Kac-Moody Lie algebra
where
If
where
As a special case,
The roots are the nonzero weights in the adjoint representation of
The roots may be divided into those in the adjoint
representation of
Returning to the general module
If
A weight
for all simple coroots
A weight has a level which can be defined as its inner product
with the canonical central element
sage: L = RootSystem(['E',6,1]).weight_lattice(extended=True)
sage: Lambda = L.fundamental_weights()
sage: [Lambda[i].level() for i in L.index_set()]
[1, 1, 2, 2, 3, 2, 1]
>>> from sage.all import *
>>> L = RootSystem(['E',Integer(6),Integer(1)]).weight_lattice(extended=True)
>>> Lambda = L.fundamental_weights()
>>> [Lambda[i].level() for i in L.index_set()]
[1, 1, 2, 2, 3, 2, 1]
L = RootSystem(['E',6,1]).weight_lattice(extended=True) Lambda = L.fundamental_weights() [Lambda[i].level() for i in L.index_set()]
Affine Root System and Weyl Group¶
We now specialize to affine Kac-Moody Lie algebras and their root systems. The basic reference for the affine root system and Weyl group is [Kac] Chapter 6.
In the untwisted affine case, the root system
The multiplicity
In most cases we recommend creating the weight lattice with the
option extended=True
:
sage: WL = RootSystem(['A',2,1]).weight_lattice(extended=True); WL
Extended weight lattice of the Root system of type ['A', 2, 1]
sage: WL.positive_roots()
Disjoint union of Family (Positive real roots of type ['A', 2, 1], Positive imaginary roots of type ['A', 2, 1])
sage: WL.simple_roots()
Finite family {0: 2*Lambda[0] - Lambda[1] - Lambda[2] + delta, 1: -Lambda[0] + 2*Lambda[1] - Lambda[2], 2: -Lambda[0] - Lambda[1] + 2*Lambda[2]}
sage: WL.weyl_group()
Weyl Group of type ['A', 2, 1] (as a matrix group acting on the extended weight lattice)
sage: WL.basic_imaginary_roots()[0]
delta
>>> from sage.all import *
>>> WL = RootSystem(['A',Integer(2),Integer(1)]).weight_lattice(extended=True); WL
Extended weight lattice of the Root system of type ['A', 2, 1]
>>> WL.positive_roots()
Disjoint union of Family (Positive real roots of type ['A', 2, 1], Positive imaginary roots of type ['A', 2, 1])
>>> WL.simple_roots()
Finite family {0: 2*Lambda[0] - Lambda[1] - Lambda[2] + delta, 1: -Lambda[0] + 2*Lambda[1] - Lambda[2], 2: -Lambda[0] - Lambda[1] + 2*Lambda[2]}
>>> WL.weyl_group()
Weyl Group of type ['A', 2, 1] (as a matrix group acting on the extended weight lattice)
>>> WL.basic_imaginary_roots()[Integer(0)]
delta
WL = RootSystem(['A',2,1]).weight_lattice(extended=True); WL WL.positive_roots() WL.simple_roots() WL.weyl_group() WL.basic_imaginary_roots()[0]
Be aware that for the exceptional groups, the ordering of the indices
are different from those in [Kac]. This is because Sage uses the Bourbaki
ordering of the roots, and Kac does not. Thus in Bourbaki (and in Sage)
the
sage: CartanType(['G',2,1]).dynkin_diagram()
3
O=<=O---O
1 2 0
G2~
>>> from sage.all import *
>>> CartanType(['G',Integer(2),Integer(1)]).dynkin_diagram()
3
O=<=O---O
1 2 0
G2~
CartanType(['G',2,1]).dynkin_diagram()
By contrast in Kac,
Labels and Coxeter Number¶
Certain constants
sage: CartanType(['B',5,1]).a()
Finite family {0: 1, 1: 1, 2: 2, 3: 2, 4: 2, 5: 2}
>>> from sage.all import *
>>> CartanType(['B',Integer(5),Integer(1)]).a()
Finite family {0: 1, 1: 1, 2: 2, 3: 2, 4: 2, 5: 2}
CartanType(['B',5,1]).a()
The column vector
sage: RS = RootSystem(['E',6,2]); RS
Root system of type ['F', 4, 1]^*
sage: A = RS.cartan_matrix(); A
[ 2 -1 0 0 0]
[-1 2 -1 0 0]
[ 0 -1 2 -2 0]
[ 0 0 -1 2 -1]
[ 0 0 0 -1 2]
sage: ann = Matrix([[v] for v in RS.cartan_type().a()]); ann
[1]
[2]
[3]
[2]
[1]
sage: A*ann
[0]
[0]
[0]
[0]
[0]
>>> from sage.all import *
>>> RS = RootSystem(['E',Integer(6),Integer(2)]); RS
Root system of type ['F', 4, 1]^*
>>> A = RS.cartan_matrix(); A
[ 2 -1 0 0 0]
[-1 2 -1 0 0]
[ 0 -1 2 -2 0]
[ 0 0 -1 2 -1]
[ 0 0 0 -1 2]
>>> ann = Matrix([[v] for v in RS.cartan_type().a()]); ann
[1]
[2]
[3]
[2]
[1]
>>> A*ann
[0]
[0]
[0]
[0]
[0]
RS = RootSystem(['E',6,2]); RS A = RS.cartan_matrix(); A ann = Matrix([[v] for v in RS.cartan_type().a()]); ann A*ann
The nullroot
sage: WL = RootSystem('C3~').weight_lattice(extended=True); WL
Extended weight lattice of the Root system of type ['C', 3, 1]
sage: sum(WL.cartan_type().a()[i]*WL.simple_root(i) for i in WL.cartan_type().index_set())
delta
>>> from sage.all import *
>>> WL = RootSystem('C3~').weight_lattice(extended=True); WL
Extended weight lattice of the Root system of type ['C', 3, 1]
>>> sum(WL.cartan_type().a()[i]*WL.simple_root(i) for i in WL.cartan_type().index_set())
delta
WL = RootSystem('C3~').weight_lattice(extended=True); WL sum(WL.cartan_type().a()[i]*WL.simple_root(i) for i in WL.cartan_type().index_set())
The number
sage: sum(CartanType(['F',4,1]).a()) # Coxeter number
12
sage: sum(CartanType(['F',4,1]).dual().a()) # Dual Coxeter number
9
>>> from sage.all import *
>>> sum(CartanType(['F',Integer(4),Integer(1)]).a()) # Coxeter number
12
>>> sum(CartanType(['F',Integer(4),Integer(1)]).dual().a()) # Dual Coxeter number
9
sum(CartanType(['F',4,1]).a()) # Coxeter number sum(CartanType(['F',4,1]).dual().a()) # Dual Coxeter number
The Weyl Group¶
The ambient space of the root system comes with an
(indefinite) inner product. The real roots have
nonzero length but the imaginary roots are isotropic.
If
Illustrating how to use Sage to compute the action of
sage: L = RootSystem("A2~").weight_lattice(extended=True)
sage: Lambda = L.fundamental_weights()
sage: delta = L.null_root()
sage: W = L.weyl_group(prefix="s")
sage: s0,s1,s2 = W.simple_reflections()
sage: [(s0*s1*s2*s1).action(x) - x for x in Lambda]
[-2*Lambda[0] + Lambda[1] + Lambda[2] - delta,
-2*Lambda[0] + Lambda[1] + Lambda[2] - 2*delta,
-2*Lambda[0] + Lambda[1] + Lambda[2] - 2*delta]
sage: [s0.action(x) for x in Lambda]
[-Lambda[0] + Lambda[1] + Lambda[2] - delta, Lambda[1], Lambda[2]]
sage: s0.action(delta)
delta
>>> from sage.all import *
>>> L = RootSystem("A2~").weight_lattice(extended=True)
>>> Lambda = L.fundamental_weights()
>>> delta = L.null_root()
>>> W = L.weyl_group(prefix="s")
>>> s0,s1,s2 = W.simple_reflections()
>>> [(s0*s1*s2*s1).action(x) - x for x in Lambda]
[-2*Lambda[0] + Lambda[1] + Lambda[2] - delta,
-2*Lambda[0] + Lambda[1] + Lambda[2] - 2*delta,
-2*Lambda[0] + Lambda[1] + Lambda[2] - 2*delta]
>>> [s0.action(x) for x in Lambda]
[-Lambda[0] + Lambda[1] + Lambda[2] - delta, Lambda[1], Lambda[2]]
>>> s0.action(delta)
delta
L = RootSystem("A2~").weight_lattice(extended=True) Lambda = L.fundamental_weights() delta = L.null_root() W = L.weyl_group(prefix="s") s0,s1,s2 = W.simple_reflections() [(s0*s1*s2*s1).action(x) - x for x in Lambda] [s0.action(x) for x in Lambda] s0.action(delta)
The extended affine Weyl Group¶
The subgroup
Geometrically,
sage: E = ExtendedAffineWeylGroup(["A",2,1]); E
Extended affine Weyl group of type ['A', 2, 1]
>>> from sage.all import *
>>> E = ExtendedAffineWeylGroup(["A",Integer(2),Integer(1)]); E
Extended affine Weyl group of type ['A', 2, 1]
E = ExtendedAffineWeylGroup(["A",2,1]); E
See the documentation in
extended_affine_weyl_group
if you need this.