Dynkin types and Cartan matrices

Dynkin types

Over $\mathbb{C}$, every finite-dimensional semisimple Lie algebra is classified up to isomorphism by its Dynkin type, a combinatorial datum that encodes the root system. Semisimple.jl represents types at the Julia type level — TypeA{3}, TypeB{4}, etc. — so that rank and root counts are compile-time constants, enabling zero-cost dispatch and @generated specialisation.

Simple types

The classical families TypeA{N}, TypeB{N}, TypeC{N}, TypeD{N}, and the exceptional types TypeE{6}, TypeE{7}, TypeE{8}, TypeF4, TypeG2:

julia> using Semisimple

julia> rank(TypeA{3})
3

julia> rank(TypeG2)
2

julia> n_positive_roots(TypeA{3})
6

julia> n_positive_roots(TypeE{8})
120
Semisimple.DynkinTypeType
DynkinType

Abstract supertype for finite Dynkin types (simple and semisimple).

Examples

julia> using Semisimple

julia> TypeA{2} <: DynkinType
true
source
Semisimple.SimpleDynkinTypeType
SimpleDynkinType <: DynkinType

Abstract supertype for simple (irreducible) finite Dynkin types.

Examples

julia> using Semisimple

julia> TypeG2 <: SimpleDynkinType
true
source
Semisimple.TypeAType
TypeA{N} <: SimpleDynkinType

Dynkin type $\mathrm{A}_N$: the root-system type of $\mathfrak{sl}_{N+1}(\mathbb{C})$ and groups isogenous to $\mathrm{SL}_{N+1}$. Valid for $N \ge 1$.

Examples

julia> using Semisimple

julia> rank(TypeA{3})
3
source
Semisimple.TypeBType
TypeB{N} <: SimpleDynkinType

Dynkin type $\mathrm{B}_N$: the root-system type of $\mathfrak{so}_{2N+1}(\mathbb{C})$ and groups isogenous to $\mathrm{Spin}_{2N+1}$ or $\mathrm{SO}_{2N+1}$. Valid for $N \ge 2$.

Examples

julia> using Semisimple

julia> rank(TypeB{3})
3
source
Semisimple.TypeCType
TypeC{N} <: SimpleDynkinType

Dynkin type $\mathrm{C}_N$: the root-system type of $\mathfrak{sp}_{2N}(\mathbb{C})$ and groups isogenous to $\mathrm{Sp}_{2N}$. Valid for $N \ge 2$.

Examples

julia> using Semisimple

julia> rank(TypeC{3})
3
source
Semisimple.TypeDType
TypeD{N} <: SimpleDynkinType

Dynkin type $\mathrm{D}_N$: the root-system type of $\mathfrak{so}_{2N}(\mathbb{C})$ and groups isogenous to $\mathrm{Spin}_{2N}$ or $\mathrm{SO}_{2N}$. Valid for $N \ge 3$.

Examples

julia> using Semisimple

julia> rank(TypeD{4})
4
source
Semisimple.TypeEType
TypeE{N} <: SimpleDynkinType

Exceptional Dynkin type $\mathrm{E}_N$ for $N \in \{6,7,8\}$.

Examples

julia> using Semisimple

julia> n_positive_roots(TypeE{6})
36
source
Semisimple.TypeF4Type
TypeF4 <: SimpleDynkinType

Exceptional Dynkin type $\mathrm{F}_4$.

Examples

julia> using Semisimple

julia> rank(TypeF4)
4
source
Semisimple.TypeG2Type
TypeG2 <: SimpleDynkinType

Exceptional Dynkin type $\mathrm{G}_2$.

Examples

julia> using Semisimple

julia> rank(TypeG2)
2
source
Semisimple.rankFunction
rank(::Type{DT}) where DT<:DynkinType -> Int

Return the rank (dimension of the Cartan subalgebra) of the Dynkin type DT. This is a compile-time constant.

Examples

julia> using Semisimple

julia> rank(TypeA{3})
3

julia> rank(TypeE{8})
8
source
Semisimple.n_positive_rootsFunction
n_positive_roots(::Type{DT}) -> Int

Number of positive roots for a simple Dynkin type.

Examples

julia> using Semisimple

julia> n_positive_roots(TypeA{3})
6

julia> n_positive_roots(TypeE{8})
120
source
n_positive_roots(RS::RootSystem) -> Int

Return the number of positive roots.

Examples

julia> using Semisimple

julia> n_positive_roots(RootSystem(TypeA{2}))
3
source

Dynkin diagrams

The function dynkin_diagram produces a text rendering of the Dynkin diagram following Bourbaki labelling conventions. This includes the correct arrow directions for non-simply-laced types and the branching for types D and E.

The return value is a DynkinDiagram object that pretty-prints automatically in the REPL without requiring println:

julia> dynkin_diagram(TypeA{4})
○───○───○───○
1   2   3   4

julia> dynkin_diagram(TypeG2)
○≡<≡○
1   2

For types with branching (D and E), the diagram shows the fork:

dynkin_diagram(TypeD{5})
            ○ 5
           /
○───○───○───○
1   2   3   4
dynkin_diagram(TypeE{6})
        ○ 2
        |
○───○───○───○───○
1   3   4   5   6
Semisimple.DynkinDiagramType
DynkinDiagram

A pretty-printable wrapper around the text rendering of a Dynkin diagram.

Displaying a DynkinDiagram in the REPL renders the diagram automatically without requiring println. Call string to recover the raw string.

See also: dynkin_diagram.

Examples

julia> using Semisimple

julia> occursin(Char(10), string(dynkin_diagram(TypeA{2})))
true
source
Semisimple.dynkin_diagramFunction
dynkin_diagram(::Type{DT}) -> DynkinDiagram
dynkin_diagram(dt::DynkinType) -> DynkinDiagram

Return the Dynkin diagram for the given type as a DynkinDiagram, following Bourbaki conventions. The result pretty-prints automatically in the REPL; call string to recover the raw multi-line string.

Examples

julia> using Semisimple

julia> dynkin_diagram(TypeA{4})
○───○───○───○
1   2   3   4

julia> dynkin_diagram(TypeB{3})
○───○═>═○
1   2   3

julia> dynkin_diagram(TypeG2)
○≡<≡○
1   2
source

Product types

Direct products of simple types are represented by ProductDynkinType. The Dynkin diagram shows each component separately:

julia> PT = ProductDynkinType{Tuple{TypeA{2}, TypeB{2}}};

julia> rank(PT)
4

julia> n_components(PT)
2

julia> component_ranks(PT)
(2, 2)

julia> component_offsets(PT)
(0, 2)
PT = ProductDynkinType{Tuple{TypeA{2}, TypeB{2}}}
dynkin_diagram(PT)
A2:
○───○
1   2

B2:
○═>═○
1   2
Semisimple.ProductDynkinTypeType
ProductDynkinType{Ts} <: DynkinType

Product of simple Dynkin types, representing a semisimple Lie algebra. Ts is a Tuple type of SimpleDynkinType subtypes.

Examples

julia> using Semisimple

julia> ProductDynkinType{Tuple{TypeA{3}, TypeD{5}, TypeE{6}}}()   # A3 × D5 × E6
A3 × D5 × E6
source
Semisimple.n_componentsFunction
n_components(::Type{ProductDynkinType{Ts}}) -> Int

Number of simple factors in a product type.

Examples

julia> using Semisimple

julia> n_components(ProductDynkinType{Tuple{TypeA{2}, TypeB{2}}})
2
source
Semisimple.component_typeFunction
component_type(::Type{ProductDynkinType{Ts}}, i::Integer) -> Type

Return the i-th simple Dynkin type in a product.

Examples

julia> using Semisimple

julia> PT = ProductDynkinType{Tuple{TypeA{2}, TypeB{2}}};

julia> component_type(PT, 1)
TypeA{2}

julia> component_type(PT, 2)
TypeB{2}
source
Semisimple.component_ranksFunction
component_ranks(::Type{ProductDynkinType{Ts}}) -> Tuple

Return a tuple of ranks of the components.

Examples

julia> using Semisimple

julia> component_ranks(ProductDynkinType{Tuple{TypeA{2}, TypeB{3}}})
(2, 3)
source
Semisimple.component_offsetsFunction
component_offsets(::Type{ProductDynkinType{Ts}}) -> Tuple

Return a tuple of starting index offsets for each component in the product type. The i-th component occupies indices offset[i]+1 : offset[i]+rank(component_i).

Examples

julia> using Semisimple

julia> component_offsets(ProductDynkinType{Tuple{TypeA{2}, TypeB{3}}})
(0, 2)
source

Validation

Invalid ranks are caught at construction time:

julia> TypeA{0}()
ERROR: ArgumentError: TypeA{N} requires N ≥ 1, got N=0
[...]

julia> TypeD{2}()
ERROR: ArgumentError: TypeD{N} requires N ≥ 3, got N=2
[...]

Cartan matrices

The Cartan matrix $C_{ij} = \langle \alpha_i^\vee, \alpha_j \rangle$ is computed at compile time via @generated functions, returning a StaticArrays.SMatrix. The conventions follow Bourbaki. With this convention, column $i$ of $C$ gives the simple root $\alpha_i$ in the fundamental weight basis: $\alpha_i = \sum_j C_{ji}\omega_j$.

julia> cartan_matrix(TypeA{3})
3×3 StaticArraysCore.SMatrix{3, 3, Int64, 9} with indices SOneTo(3)×SOneTo(3):
  2  -1   0
 -1   2  -1
  0  -1   2

julia> cartan_matrix(TypeG2)
2×2 StaticArraysCore.SMatrix{2, 2, Int64, 4} with indices SOneTo(2)×SOneTo(2):
  2  -3
 -1   2

julia> cartan_matrix(TypeB{2})
2×2 StaticArraysCore.SMatrix{2, 2, Int64, 4} with indices SOneTo(2)×SOneTo(2):
  2  -1
 -2   2

Symmetriser

The vector $d$ such that $\operatorname{diag}(d) \cdot C$ is symmetric. For simply-laced types (A, D, E) all entries are 1:

julia> cartan_symmetrizer(TypeA{3})
3-element StaticArraysCore.SVector{3, Int64} with indices SOneTo(3):
 1
 1
 1

julia> cartan_symmetrizer(TypeG2)
2-element StaticArraysCore.SVector{2, Int64} with indices SOneTo(2):
 1
 3

julia> cartan_symmetrizer(TypeB{2})
2-element StaticArraysCore.SVector{2, Int64} with indices SOneTo(2):
 2
 1

Bilinear form and inverse

The symmetric bilinear form $B = \operatorname{diag}(d) \cdot C$ and the rational inverse $C^{-1}$:

julia> cartan_bilinear_form(TypeA{3})
3×3 StaticArraysCore.SMatrix{3, 3, Int64, 9} with indices SOneTo(3)×SOneTo(3):
  2  -1   0
 -1   2  -1
  0  -1   2

julia> cartan_matrix_inverse(TypeA{3})
3×3 StaticArraysCore.SMatrix{3, 3, Rational{Int64}, 9} with indices SOneTo(3)×SOneTo(3):
 3//4  1//2  1//4
 1//2   1    1//2
 1//4  1//2  3//4
Semisimple.cartan_matrixFunction
cartan_matrix(::Type{ProductDynkinType{Ts}})

Block-diagonal Cartan matrix for a product of simple types.

Examples

julia> using Semisimple, StaticArrays

julia> cartan_matrix(TypeA{2}) == SMatrix{2,2}(2, -1, -1, 2)
true

julia> cartan_matrix(TypeG2) == SMatrix{2,2}(2, -1, -3, 2)
true
source
Semisimple.cartan_symmetrizerFunction
cartan_symmetrizer(::Type{DT}) -> SVector

Return the symmetrizer d such that diag(d) * C is symmetric, where C is the Cartan matrix of DT. Entries are positive integers with gcd 1.

Examples

julia> using Semisimple, StaticArrays

julia> cartan_symmetrizer(TypeB{3}) == SVector(2, 2, 1)
true

julia> cartan_symmetrizer(TypeG2) == SVector(1, 3)
true
source
Semisimple.cartan_bilinear_formFunction
cartan_bilinear_form(::Type{DT}) -> SMatrix

Return the symmetrized Cartan matrix diag(d) * C, which is a symmetric positive-definite matrix defining the inner product on the root space.

Examples

julia> using Semisimple

julia> cartan_bilinear_form(TypeB{2})
2×2 StaticArraysCore.SMatrix{2, 2, Int64, 4} with indices SOneTo(2)×SOneTo(2):
  4  -2
 -2   2
source
Semisimple.cartan_matrix_inverseFunction
cartan_matrix_inverse(::Type{DT}) -> SMatrix{R,R,Rational{Int}}

Return the inverse of the Cartan matrix over the rationals.

Examples

julia> using Semisimple

julia> cartan_matrix_inverse(TypeA{2})
2×2 StaticArraysCore.SMatrix{2, 2, Rational{Int64}, 4} with indices SOneTo(2)×SOneTo(2):
 2//3  1//3
 1//3  2//3
source
Semisimple.cartan_determinantFunction
cartan_determinant(::Type{DT}) -> Int
cartan_determinant(dt::DT) -> Int

Compute the determinant of the Cartan matrix of the Dynkin type DT.

For semisimple Lie algebras, this determinant equals the connection index, which measures the index of the root lattice in the weight lattice.

This is a compile-time constant based on hardcoded values for simple types.

Examples

julia> using Semisimple

julia> cartan_determinant(TypeA{3})
4

julia> cartan_determinant(TypeB{3})
2

julia> cartan_determinant(TypeG2)
1
source

Dimension

The dimension of the semisimple Lie algebra equals $r + 2n$ where $r$ is the rank and $n$ is the number of positive roots:

julia> dimension(TypeA{3})   # dim sl_4(C) = 15
15

julia> dimension(TypeE{8})   # dim(E_8) = 248
248

julia> dimension(ProductDynkinType{Tuple{TypeA{1}, TypeA{1}}}())   # dim(sl_2(C) + sl_2(C)) = 6
6
Semisimple.dimensionFunction
dimension(::Type{DT}) -> Int
dimension(dt::DynkinType) -> Int

Return the dimension of the semisimple Lie algebra of type DT.

For a semisimple Lie algebra of rank $r$ with $n$ positive roots, the dimension is $r + 2n$ (Cartan subalgebra plus positive and negative root spaces).

Note: for the adjoint representation dimension (same number), use degree on adjoint_representation.

Examples

julia> using Semisimple

julia> dimension(TypeA{3})  # sl_4(C) has dimension 15
15

julia> dimension(TypeE{8})  # e_8(C) has dimension 248
248

julia> dimension(ProductDynkinType{Tuple{TypeA{1}, TypeA{1}}}())  # sl_2(C) ⊕ sl_2(C)
6
source

Scaled bilinear form

The scaled bilinear form on the fundamental weight basis, used internally by Freudenthal's formula:

Semisimple.omega_bilinear_form_scaledFunction
omega_bilinear_form_scaled(::Type{DT}) -> Tuple{Int, SMatrix{R,R,Int}}

Return $(S, B_{\omega,S})$ where $B_{\omega,S} = S (C^{-1})^{\mathsf T} B C^{-1}$ is the bilinear form in the fundamental weight basis, scaled by the smallest positive integer S that makes all entries integral. This is a compile-time constant.

Examples

julia> using Semisimple

julia> first(omega_bilinear_form_scaled(TypeA{2}))
3
source

Connection index

The determinant of the Cartan matrix is the connection index, which gives the index of the root lattice $Q$ in the weight lattice $P$:

\[\det(C) = [P : Q]\]

For simply-laced types (A, D, E), the index varies by type. For multiply-laced types, the determinant encodes how the roots and weights are related:

julia> using Semisimple

julia> cartan_determinant(TypeA{3})   # A3: det = 4 = n+1
4

julia> cartan_determinant(TypeB{2})   # B2 multiply-laced
2

julia> cartan_determinant(TypeG2)
1