Root systems

A root system is determined by its Dynkin type. Semisimple.jl caches one immutable RootSystem singleton per type, so constructing the same type twice returns the same object.

Creating a root system

julia> using Semisimple

julia> RS = RootSystem(TypeA{3})
Root system of type A3, rank 3 with 6 positive roots

julia> n_roots(RS)
12

julia> n_simple_roots(RS)
3
Semisimple.RootSystemType
RootSystem{DT,R,N}

A root system for the Dynkin type DT of rank R with N positive roots. For small ranks the data is emitted directly by a @generated constructor; for larger ranks it is built once at runtime and cached per Dynkin type.

Fields:

  • positive_roots_list: NTuple{N, SVector{R,Int}} of positive roots, ordered by non-decreasing height (pos_roots[N] is the highest root).
  • positive_coroots_list: NTuple{N, SVector{R,Int}} of positive coroots, in the same order as the roots.
  • refl: SMatrix{R,N,UInt} reflection table — refl[s, i] = index of s_s(α_i) among positive roots, or 0 if the result is negative.
  • highest_coroot_idx: the index of the positive coroot with greatest height (= index of the highest short root in positive_roots_list).

Examples

julia> using Semisimple

julia> RootSystem(TypeA{2})
Root system of type A2, rank 2 with 3 positive roots
source
Semisimple.n_rootsFunction
n_roots(RS::RootSystem) -> Int

Return the total number of roots (positive and negative).

Examples

julia> using Semisimple

julia> n_roots(RootSystem(TypeA{2}))
6
source
Semisimple.n_simple_rootsFunction
n_simple_roots(RS::RootSystem) -> Int

Return the number of simple roots, equal to the rank of the root system.

Examples

julia> using Semisimple

julia> n_simple_roots(RootSystem(TypeA{2}))
2
source

Simple and positive roots

Roots are stored in the simple root basis as RootSpaceElem values. Use coefficients to extract the underlying coordinate vector:

julia> α1 = simple_root(RS, 1)
α1

julia> α2 = simple_root(RS, 2)
α2

julia> α1 + α2
α1 + α2

julia> 2 * α1
2α1

julia> coefficients(α1)
3-element StaticArraysCore.SVector{3, Int64} with indices SOneTo(3):
 1
 0
 0

Listing roots

Positive roots are returned in non-decreasing order of height: indices 1 through rank are the simple roots (height 1), and the last element is always the highest root.

julia> length(positive_roots(RS))
6

julia> positive_root(RS, 3)
α3

julia> positive_root(RS, 4)
α1 + α2

julia> highest_root(RS)
α1 + α2 + α3

Because the ordering is canonical, highest_root simply returns the last positive root — no search is performed.

Negative roots are the negations of positive roots:

julia> negative_root(RS, 1)
-α1
Semisimple.RootSpaceElemType
RootSpaceElem{DT,R}

An element of the root space for Dynkin type DT of rank R, stored as an SVector{R,Int} of coordinates in the simple root basis.

Examples

julia> using Semisimple

julia> RootSpaceElem(TypeA{2}, [1, 1])
α1 + α2
source
Semisimple.simple_rootsFunction
simple_roots(RS::RootSystem{DT,R}) -> Vector{RootSpaceElem}

Return all simple roots.

Examples

julia> using Semisimple

julia> simple_roots(RootSystem(TypeA{2}))
2-element Vector{RootSpaceElem{TypeA{2}, 2}}:
 α1
 α2
source
Semisimple.simple_rootFunction
simple_root(RS::RootSystem{DT,R}, i) -> RootSpaceElem

Return the i-th simple root.

Examples

julia> using Semisimple

julia> simple_root(RootSystem(TypeA{2}), 1)
α1
source
Semisimple.positive_rootsFunction
positive_roots(RS::RootSystem{DT,R}) -> Vector{RootSpaceElem}

Return all positive roots.

Examples

julia> using Semisimple

julia> length(positive_roots(RootSystem(TypeA{2})))
3
source
Semisimple.positive_rootFunction
positive_root(RS::RootSystem{DT,R}, i) -> RootSpaceElem

Return the i-th positive root.

Examples

julia> using Semisimple

julia> positive_root(RootSystem(TypeA{2}), 3)
α1 + α2
source
Semisimple.negative_rootsFunction
negative_roots(RS::RootSystem{DT,R}) -> Vector{RootSpaceElem}

Return all negative roots.

Examples

julia> using Semisimple

julia> length(negative_roots(RootSystem(TypeA{2})))
3
source
Semisimple.negative_rootFunction
negative_root(RS::RootSystem{DT,R}, i) -> RootSpaceElem

Return the i-th negative root (negative of the i-th positive root).

Examples

julia> using Semisimple

julia> negative_root(RootSystem(TypeA{2}), 1)
-α1
source
Semisimple.rootsFunction
roots(RS::RootSystem) -> Vector{RootSpaceElem}

Return all roots (positive followed by negative).

Examples

julia> using Semisimple

julia> length(roots(RootSystem(TypeA{2})))
6
source
Semisimple.rootFunction
root(RS::RootSystem{DT,R}, i) -> RootSpaceElem

Return the i-th root. Indices 1..npos are positive roots, npos+1..2*n_pos are negative roots.

Examples

julia> using Semisimple

julia> root(RootSystem(TypeA{2}), 4)
-α1
source
Semisimple.highest_rootFunction
highest_root(RS::RootSystem{DT,R}) -> RootSpaceElem

Return the highest root. Positive roots are ordered by non-decreasing height, so the highest root is always the last positive root.

Examples

julia> using Semisimple

julia> highest_root(RootSystem(TypeA{2}))
α1 + α2
source
Semisimple.highest_short_rootFunction
highest_short_root(RS::RootSystem{DT,R}) -> RootSpaceElem

Return the highest short root: the positive root of minimal length that has greatest height among all short positive roots.

For simply-laced types (A, D, E), every root has the same length, so this coincides with highest_root.

The index equals RS.highest_coroot_idx, precomputed at compile time.

Examples

julia> using Semisimple

julia> RS = RootSystem(TypeB{2});

julia> coefficients(highest_short_root(RS))
2-element StaticArraysCore.SVector{2, Int64} with indices SOneTo(2):
 1
 1

julia> RS_G2 = RootSystem(TypeG2);

julia> coefficients(highest_short_root(RS_G2))
2-element StaticArraysCore.SVector{2, Int64} with indices SOneTo(2):
 2
 1
source
Semisimple.coefficientsFunction
coefficients(r::RootSpaceElem) -> SVector
coefficients(w::WeightLatticeElem) -> SVector

Return the coordinate vector of a root space element (in the simple root basis) or of a weight lattice element (in the fundamental weight basis).

Examples

julia> using Semisimple

julia> coefficients(RootSpaceElem(TypeA{2}, [1, 1])) == [1, 1]
true
source

Root queries

julia> is_root(RS, α1 + α2)
true

julia> is_positive_root(RS, α1 + α2)
true

julia> is_root(RS, 2 * α1)
false
Semisimple.is_rootFunction
is_root(RS::RootSystem{DT,R}, v::RootSpaceElem{DT,R}) -> Bool

Check whether v is a root.

Examples

julia> using Semisimple

julia> RS = RootSystem(TypeA{2});

julia> is_root(RS, RootSpaceElem(TypeA{2}, [1, 1]))
true
source
Semisimple.is_positive_rootFunction
is_positive_root(RS::RootSystem{DT,R}, v::RootSpaceElem{DT,R}) -> Bool

Check whether v is a positive root.

Examples

julia> using Semisimple

julia> RS = RootSystem(TypeA{2});

julia> is_positive_root(RS, RootSpaceElem(TypeA{2}, [-1, 0]))
false
source

Height

The height of a root is the sum of its simple root coefficients:

julia> height(α1)
1

julia> height(α1 + α2)
2

julia> height(highest_root(RS))
3
Semisimple.heightFunction
height(r::RootSpaceElem) -> Int

Sum of coefficients in the simple root expansion.

Examples

julia> using Semisimple

julia> height(RootSpaceElem(TypeA{2}, [1, 1]))
2
source

Inner product

The inner product on the root space uses the symmetrised Cartan form $(\alpha, \beta) = \alpha^T \operatorname{diag}(d) \, C \, \beta$:

julia> dot(α1, α1)
2//1

julia> dot(α1, α2)
-1//1

Coroots

For simply-laced types (A, D, E), coroots coincide with roots. For non-simply-laced types the coroots are rescaled by the symmetriser entries:

julia> sc = simple_coroots(RS);

julia> sc[1]
α1

julia> length(positive_coroots(RS))
6
Semisimple.simple_corootsFunction
simple_coroots(RS::RootSystem{DT,R}) -> Vector{RootSpaceElem}

Return the simple coroots.

Examples

julia> using Semisimple

julia> simple_coroots(RootSystem(TypeA{2})) == simple_roots(RootSystem(TypeA{2}))
true
source
Semisimple.positive_corootsFunction
positive_coroots(RS::RootSystem{DT,R}) -> Vector{RootSpaceElem}

Return all positive coroots.

Examples

julia> using Semisimple

julia> length(positive_coroots(RootSystem(TypeB{2})))
4
source

Coxeter invariants

The highest root is a fundamental invariant of the root system. When expressed in the simple root basis as $\theta = \sum_i m_i \alpha_i$, the coefficients $m_i$ are the Coxeter labels or marks (returned by coxeter_coefficients). Because positive roots are sorted by height, highest_root(RS) is simply positive_root(RS, N) where N is the number of positive roots — no search needed.

The highest short root $\theta_s$ is the short root of greatest height. For simply-laced types (A, D, E) it coincides with $\theta$. Its index in the positive root list is precomputed at compile time and stored in RS.highest_coroot_idx.

The highest coroot (or dominant coroot) $\theta^\vee$ is the positive coroot of greatest height. It equals the coroot of the highest short root, and is stored at the same precomputed index RS.highest_coroot_idx.

The Coxeter number $h = 1 + \sum_i m_i$ is the order of a Coxeter element in the Weyl group.

For the dual root system (Langlands dual, swapping B↔C), the corresponding invariants are the dual Coxeter labels and dual Coxeter number $h^\vee$.

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

julia> coxeter_number(TypeA{3})
4

julia> cartan_determinant(TypeA{3})
4

For multiply-laced types like $\mathrm{G}_2$:

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

julia> coxeter_number(TypeG2)
6
Semisimple.highest_corootFunction
highest_coroot(RS::RootSystem{DT,R}) -> RootSpaceElem

Return the highest coroot $\theta^\vee$: the positive coroot of greatest height. This is the coroot of the highest short root.

The index is precomputed at compile time and stored in RS.highest_coroot_idx.

Examples

julia> using Semisimple

julia> highest_coroot(RootSystem(TypeA{2}))
α1 + α2
source
Semisimple.coxeter_coefficientsFunction
coxeter_coefficients(::Type{DT}) -> SVector{R,Int}
coxeter_coefficients(dt::DT) -> SVector{R,Int}

Return the Coxeter labels (also called marks): the coefficients of the highest root in the simple root basis: $\theta = \sum_i m_i \alpha_i$

These are not the Weyl group exponents; the degrees of fundamental invariants are returned by degrees_fundamental_invariants, and the exponents are those degrees minus 1.

Examples

julia> using Semisimple

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

julia> coxeter_coefficients(TypeB{2})
2-element StaticArraysCore.SVector{2, Int64} with indices SOneTo(2):
 1
 2
source
Semisimple.dual_coxeter_coefficientsFunction
dual_coxeter_coefficients(::Type{DT}) -> SVector{R,Int}
dual_coxeter_coefficients(dt::DT) -> SVector{R,Int}

Return the dual Coxeter coefficients: the coefficients of simple roots in the highest short root of the dual root system (Langlands dual). The dual Coxeter number is $h^\vee = 1 + \sum_i n_i^\vee$.

For simply-laced types (A, D, E) all roots have the same length, so these equal the Coxeter coefficients. For B, C, F4, and G2 they differ.

Examples

julia> using Semisimple

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

julia> dual_coxeter_coefficients(TypeG2)
2-element StaticArraysCore.SVector{2, Int64} with indices SOneTo(2):
 1
 2
source
Semisimple.coxeter_numberFunction
coxeter_number(::Type{DT}) -> Int
coxeter_number(dt::DT) -> Int

Return the Coxeter number $h$ of the Dynkin type, defined as $h = 1 + \sum_i m_i$ where $m_i$ are the Coxeter coefficients (coefficients of the highest root).

The Coxeter number is the order of a Coxeter element (product of all simple reflections) in the Weyl group.

Examples

julia> using Semisimple

julia> coxeter_number(TypeA{1})
2

julia> coxeter_number(TypeA{3})
4

julia> coxeter_number(TypeG2)
6
source
Semisimple.dual_coxeter_numberFunction
dual_coxeter_number(::Type{DT}) -> Int
dual_coxeter_number(dt::DT) -> Int

Return the dual Coxeter number $h^\vee$ of the Dynkin type, which is the Coxeter number of the Langlands dual root system.

Examples

julia> using Semisimple

julia> dual_coxeter_number(TypeA{1})
2

julia> dual_coxeter_number(TypeA{3})
4

julia> dual_coxeter_number(TypeB{2})
3

julia> dual_coxeter_number(TypeG2)
4
source
Semisimple.degrees_fundamental_invariantsFunction
degrees_fundamental_invariants(::Type{DT}) -> SVector{R,Int}
degrees_fundamental_invariants(dt::DT) -> SVector{R,Int}

Return the degrees of the fundamental invariants of the Weyl group action on the polynomial ring.

Examples

julia> using Semisimple

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

julia> degrees_fundamental_invariants(TypeB{3})
3-element StaticArraysCore.SVector{3, Int64} with indices SOneTo(3):
 2
 4
 6

julia> degrees_fundamental_invariants(TypeD{4})
4-element StaticArraysCore.SVector{4, Int64} with indices SOneTo(4):
 2
 4
 6
 4

julia> degrees_fundamental_invariants(TypeG2)
2-element StaticArraysCore.SVector{2, Int64} with indices SOneTo(2):
 2
 6
source

Examples

A2

julia> RS2 = RootSystem(TypeA{2})
Root system of type A2, rank 2 with 3 positive roots

julia> [positive_root(RS2, i) for i in 1:3]
3-element Vector{RootSpaceElem{TypeA{2}, 2}}:
 α1
 α2
 α1 + α2

julia> highest_root(RS2)
α1 + α2

julia> highest_short_root(RS2)
α1 + α2

julia> coefficients(highest_coroot(RS2))
2-element StaticArraysCore.SVector{2, Int64} with indices SOneTo(2):
 1
 1

$\mathrm{A}_2$ is simply-laced, so the highest root, highest short root, and highest coroot all coincide.

G2

The exceptional type $\mathrm{G}_2$ has short roots of squared length $2$ and long roots of squared length $6$. The highest short root and the highest long root are distinct:

julia> RS_G2 = RootSystem(TypeG2);

julia> n_positive_roots(TypeG2)
6

julia> highest_root(RS_G2)
3α1 + 2α2

julia> highest_short_root(RS_G2)
2α1 + α2

julia> coefficients(highest_coroot(RS_G2))
2-element StaticArraysCore.SVector{2, Int64} with indices SOneTo(2):
 2
 3

B2

julia> RS_B2 = RootSystem(TypeB{2});

julia> highest_root(RS_B2)
α1 + 2α2

julia> highest_short_root(RS_B2)
α1 + α2

julia> coefficients(highest_coroot(RS_B2))
2-element StaticArraysCore.SVector{2, Int64} with indices SOneTo(2):
 2
 1