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)
3Semisimple.RootSystem — Type
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 ofs_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 inpositive_roots_list).
Examples
julia> using Semisimple
julia> RootSystem(TypeA{2})
Root system of type A2, rank 2 with 3 positive rootsSemisimple.n_roots — Function
n_roots(RS::RootSystem) -> IntReturn the total number of roots (positive and negative).
Examples
julia> using Semisimple
julia> n_roots(RootSystem(TypeA{2}))
6Semisimple.n_simple_roots — Function
n_simple_roots(RS::RootSystem) -> IntReturn the number of simple roots, equal to the rank of the root system.
Examples
julia> using Semisimple
julia> n_simple_roots(RootSystem(TypeA{2}))
2Simple 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
0Listing 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 + α3Because 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)
-α1Semisimple.RootSpaceElem — Type
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 + α2Semisimple.simple_roots — Function
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
α2Semisimple.simple_root — Function
simple_root(RS::RootSystem{DT,R}, i) -> RootSpaceElemReturn the i-th simple root.
Examples
julia> using Semisimple
julia> simple_root(RootSystem(TypeA{2}), 1)
α1Semisimple.positive_roots — Function
positive_roots(RS::RootSystem{DT,R}) -> Vector{RootSpaceElem}Return all positive roots.
Examples
julia> using Semisimple
julia> length(positive_roots(RootSystem(TypeA{2})))
3Semisimple.positive_root — Function
positive_root(RS::RootSystem{DT,R}, i) -> RootSpaceElemReturn the i-th positive root.
Examples
julia> using Semisimple
julia> positive_root(RootSystem(TypeA{2}), 3)
α1 + α2Semisimple.negative_roots — Function
negative_roots(RS::RootSystem{DT,R}) -> Vector{RootSpaceElem}Return all negative roots.
Examples
julia> using Semisimple
julia> length(negative_roots(RootSystem(TypeA{2})))
3Semisimple.negative_root — Function
negative_root(RS::RootSystem{DT,R}, i) -> RootSpaceElemReturn the i-th negative root (negative of the i-th positive root).
Examples
julia> using Semisimple
julia> negative_root(RootSystem(TypeA{2}), 1)
-α1Semisimple.roots — Function
roots(RS::RootSystem) -> Vector{RootSpaceElem}Return all roots (positive followed by negative).
Examples
julia> using Semisimple
julia> length(roots(RootSystem(TypeA{2})))
6Semisimple.root — Function
root(RS::RootSystem{DT,R}, i) -> RootSpaceElemReturn 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)
-α1Semisimple.highest_root — Function
highest_root(RS::RootSystem{DT,R}) -> RootSpaceElemReturn 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 + α2Semisimple.highest_short_root — Function
highest_short_root(RS::RootSystem{DT,R}) -> RootSpaceElemReturn 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
1Semisimple.coefficients — Function
coefficients(r::RootSpaceElem) -> SVector
coefficients(w::WeightLatticeElem) -> SVectorReturn 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]
trueRoot queries
julia> is_root(RS, α1 + α2)
true
julia> is_positive_root(RS, α1 + α2)
true
julia> is_root(RS, 2 * α1)
falseSemisimple.is_root — Function
is_root(RS::RootSystem{DT,R}, v::RootSpaceElem{DT,R}) -> BoolCheck whether v is a root.
Examples
julia> using Semisimple
julia> RS = RootSystem(TypeA{2});
julia> is_root(RS, RootSpaceElem(TypeA{2}, [1, 1]))
trueSemisimple.is_positive_root — Function
is_positive_root(RS::RootSystem{DT,R}, v::RootSpaceElem{DT,R}) -> BoolCheck 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]))
falseHeight
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))
3Semisimple.height — Function
height(r::RootSpaceElem) -> IntSum of coefficients in the simple root expansion.
Examples
julia> using Semisimple
julia> height(RootSpaceElem(TypeA{2}, [1, 1]))
2Inner 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//1Coroots
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))
6Semisimple.simple_coroots — Function
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}))
trueSemisimple.positive_coroots — Function
positive_coroots(RS::RootSystem{DT,R}) -> Vector{RootSpaceElem}Return all positive coroots.
Examples
julia> using Semisimple
julia> length(positive_coroots(RootSystem(TypeB{2})))
4Coxeter 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})
4For 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)
6Semisimple.highest_coroot — Function
highest_coroot(RS::RootSystem{DT,R}) -> RootSpaceElemReturn 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 + α2Semisimple.coxeter_coefficients — Function
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
2Semisimple.dual_coxeter_coefficients — Function
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
2Semisimple.coxeter_number — Function
coxeter_number(::Type{DT}) -> Int
coxeter_number(dt::DT) -> IntReturn 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)
6Semisimple.dual_coxeter_number — Function
dual_coxeter_number(::Type{DT}) -> Int
dual_coxeter_number(dt::DT) -> IntReturn 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)
4Semisimple.degrees_fundamental_invariants — Function
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
6Examples
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
3B2
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