Weight lattice

Weights are elements of the weight lattice, expressed in the fundamental weight basis $(\omega_1, \ldots, \omega_r)$ where $\langle \alpha_i^\vee, \omega_j \rangle = \delta_{ij}$.

Creating weights

Weights are constructed with fundamental_weight or directly from a coefficient vector using WeightLatticeElem:

julia> using Semisimple

julia> ω1 = fundamental_weight(TypeA{3}, 1)
ω1

julia> ω2 = fundamental_weight(TypeA{3}, 2)
ω2

julia> ω3 = fundamental_weight(TypeA{3}, 3)
ω3

julia> ω1 + ω2
ω1 + ω2

julia> 2 * ω1
2ω1

julia> WeightLatticeElem(TypeA{3}, [3, 1, 0])
3ω1 + ω2

All fundamental weights

julia> fundamental_weights(TypeA{3})
3-element Vector{WeightLatticeElem{TypeA{3}, 3}}:
 ω1
 ω2
 ω3

Weyl vector

The Weyl vector $\rho = \omega_1 + \cdots + \omega_r$:

julia> weyl_vector(TypeA{3})
ω1 + ω2 + ω3
Semisimple.WeightLatticeElemType
WeightLatticeElem{DT,R}

An element of the weight lattice for Dynkin type DT of rank R, stored as an SVector{R,Int} of coordinates in the fundamental weight basis $(\omega_1, \ldots, \omega_r)$.

The pairing with the i-th simple coroot is simply w[i]: $\langle \alpha_i^\vee, \lambda \rangle = \lambda_i$

Constructors

WeightLatticeElem(::Type{DT}, v::AbstractVector{<:Integer})

When v has fewer entries than rank(DT), the remaining coordinates are silently filled with zeros. When v has more entries than rank(DT), a warning is emitted and only the first rank(DT) entries are used.

Length handling

The AbstractVector constructor is meant as a convenience for interactive work. For library code, tests, and reproducible computations, prefer the exact-length SVector or NTuple constructors so dimension mismatches are caught immediately. Padding can change the intended weight by implicitly adding zero coordinates, while truncation discards trailing coordinates after emitting a warning.

Examples

julia> using Semisimple

julia> WeightLatticeElem(TypeA{3}, [1, 2])   # padded with one zero
ω1 + 2ω2

julia> WeightLatticeElem(TypeA{3}, [1, 2, 3])  # exact length
ω1 + 2ω2 + 3ω3

julia> using Test

julia> @test_logs (:warn, r"truncating to first 3 entries") WeightLatticeElem(TypeA{3}, [1, 2, 3, 4])
ω1 + 2ω2 + 3ω3
source
Semisimple.fundamental_weightFunction
fundamental_weight(::Type{DT}, i) -> WeightLatticeElem{DT}

Return the i-th fundamental weight $\omega_i$.

Examples

julia> using Semisimple

julia> fundamental_weight(TypeA{3}, 1)
ω1

julia> fundamental_weight(TypeB{2}, 2)
ω2
source
Semisimple.fundamental_weightsFunction
fundamental_weights(::Type{DT}) -> Vector{WeightLatticeElem{DT}}

Return all fundamental weights.

Examples

julia> using Semisimple

julia> fundamental_weights(TypeA{2})
2-element Vector{WeightLatticeElem{TypeA{2}, 2}}:
 ω1
 ω2
source
Semisimple.weyl_vectorFunction
weyl_vector(::Type{DT}) -> WeightLatticeElem{DT}

Return the Weyl vector $\rho = \omega_1 + \omega_2 + \cdots + \omega_r = \frac{1}{2}\sum_{\alpha > 0} \alpha$.

Examples

julia> using Semisimple

julia> weyl_vector(TypeA{3})
ω1 + ω2 + ω3
source

Display

Weights are printed in the fundamental weight basis by default: ω1, 2ω1 + ω2, 0, etc.

Per-call compact format

Pass :compact => true via IOContext to switch a single show call to the concise coordinate form DT[c₁,c₂,…]:

julia> show(IOContext(stdout, :compact => true), ω1)
A3[1,0,0]

julia> show(IOContext(stdout, :compact => true), 2*ω1 - ω3)
A3[2,0,-1]

The same compact form is used by RootSpaceElem.

Global compact toggle

Call compact_display! to make the compact form the session-wide default for all WeightLatticeElem and RootSpaceElem output:

julia> compact_display!(true)
true

julia> fundamental_weights(TypeA{3})
3-element Vector{WeightLatticeElem{TypeA{3}, 3}}:
 A3[1,0,0]
 A3[0,1,0]
 A3[0,0,1]

julia> compact_display!(false)   # restore default
false
Semisimple.compact_display!Function
compact_display!(val::Bool = true)

Set the global compact-display mode for WeightLatticeElem and RootSpaceElem.

When true, every call to show on these types prints the coordinate form DT[c₁,c₂,…] (e.g. A3[1,0,0] for ω₁ in type A₃) regardless of the IOContext. When false (the default), the standard symbolic form is used (ω1, α1 + α2, etc.).

The per-call IOContext(:compact => true) override always takes precedence.

Examples

julia> using Semisimple

julia> ω1 = fundamental_weight(TypeA{3}, 1);

julia> compact_display!(true)
true

julia> ω1
A3[1,0,0]

julia> fundamental_weights(TypeA{3})
3-element Vector{WeightLatticeElem{TypeA{3}, 3}}:
 A3[1,0,0]
 A3[0,1,0]
 A3[0,0,1]

julia> compact_display!(false)
false

julia> ω1
ω1
source

Dominance

A weight is dominant when all its fundamental weight coordinates are non-negative:

julia> is_dominant(ω1)
true

julia> is_dominant(ω1 - 2 * ω2)
false

Conjugation to the dominant chamber

Every weight is Weyl-conjugate to a unique dominant weight:

julia> w = WeightLatticeElem(TypeA{3}, [-1, 2, 0]);

julia> is_dominant(w)
false

julia> conjugate_dominant_weight(w)
ω1 + ω2
Semisimple.is_dominantFunction
is_dominant(w::WeightLatticeElem) -> Bool

A weight is dominant iff all its coordinates (pairings with simple coroots) are >= 0.

Examples

julia> using Semisimple

julia> is_dominant(fundamental_weight(TypeA{2}, 1))
true

julia> is_dominant(WeightLatticeElem(TypeA{2}, [-1, 1]))
false
source
Semisimple.conjugate_dominant_weightFunction
conjugate_dominant_weight(w::WeightLatticeElem{DT,R}) -> WeightLatticeElem{DT,R}

Return the unique dominant weight in the Weyl orbit of w.

Examples

julia> using Semisimple

julia> conjugate_dominant_weight(WeightLatticeElem(TypeA{2}, [-1, 1]))
ω1

julia> conjugate_dominant_weight(fundamental_weight(TypeA{3}, 1))
ω1
source
Semisimple.conjugate_dominant_weight_with_elemFunction
conjugate_dominant_weight_with_elem(w::WeightLatticeElem{DT,R}) -> (WeightLatticeElem, Vector{Int})

Return the dominant weight and the sequence of simple reflections applied.

Examples

julia> using Semisimple

julia> conjugate_dominant_weight_with_elem(WeightLatticeElem(TypeA{2}, [-1, 1]))
(ω1, [1])
source
Semisimple.conjugate_dominant_weight_with_lengthFunction
conjugate_dominant_weight_with_length(w::WeightLatticeElem{DT,R}) -> (WeightLatticeElem, Int)

Return the dominant weight in the Weyl orbit of w together with the number of simple reflections applied (i.e. the length of the Weyl group element mapping w into the dominant chamber).

This is faster than conjugate_dominant_weight_with_elem because it only tracks a counter instead of building the full word.

Examples

julia> using Semisimple

julia> conjugate_dominant_weight_with_length(WeightLatticeElem(TypeA{2}, [-1, 1]))
(ω1, 1)

julia> conjugate_dominant_weight_with_length(fundamental_weight(TypeA{3}, 1))
(ω1, 0)
source

Reflections

Simple reflections act on weights by the formula $s_i(\lambda) = \lambda - \langle \alpha_i^\vee, \lambda \rangle \alpha_i$, which in the fundamental weight basis simplifies to $(s_i(\lambda))_j = \lambda_j - \lambda_i C_{ji}$, because $\alpha_i = \sum_j C_{ji}\omega_j$:

julia> reflect(ω1, 1)   # reflection in the first simple root
-ω1 + ω2

julia> reflect(ω1, 2)   # unchanged because the pairing is zero
ω1
Semisimple.reflectFunction
reflect(w::WeightLatticeElem{DT,R}, s::Integer) -> WeightLatticeElem{DT,R}

Reflect w by the s-th simple reflection: $s_s(\lambda) = \lambda - \langle \alpha_s^\vee, \lambda \rangle \alpha_s$

In the fundamental weight basis, $\langle \alpha_s^\vee, \lambda \rangle = \lambda_s$ and $\alpha_s = \sum_j C_{js} \omega_j$, so the new weight has coordinates: $(s_s(\lambda))_j = \lambda_j - \lambda_s C_{js}$

Examples

julia> using Semisimple

julia> reflect(WeightLatticeElem(TypeA{2}, [2, 1]), 1)
-2ω1 + 3ω2
source
reflect(w::WeightLatticeElem{DT,R}, β::RootSpaceElem{DT,R}) -> WeightLatticeElem{DT,R}

Reflect w by the root β: $s_\beta(\lambda) = \lambda - \langle \beta^\vee, \lambda \rangle \beta$ where $\langle \beta^\vee, \lambda \rangle = 2(\beta, \lambda) / (\beta, \beta)$.

The argument $\beta$ must be an actual root of the root system.

Examples

julia> using Semisimple

julia> reflect(fundamental_weight(TypeA{2}, 1), simple_root(RootSystem(TypeA{2}), 1))
-ω1 + ω2
source

Inner products

Pairing of roots and weights, $\langle \alpha^\vee, \lambda \rangle$, and the weight-space inner product:

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

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

julia> ω1 = fundamental_weight(TypeA{2}, 1);

julia> ω2 = fundamental_weight(TypeA{2}, 2);

julia> dot(α1, ω1)   # simple-coroot pairing equals 1
1//1

julia> dot(α1, ω2)   # simple-coroot pairing equals 0
0//1

julia> dot(ω1, ω1)   # invariant bilinear form
2//3

julia> dot(ω1, ω2)
1//3
LinearAlgebra.dotFunction
dot(a::RootSpaceElem{DT,R}, b::RootSpaceElem{DT,R}) -> Rational{Int}

Inner product of two root space elements using the symmetrized Cartan form.

$(α, β) = αᵀ \operatorname{diag}(d) C β$

source
dot(r::RootSpaceElem{DT,R}, w::WeightLatticeElem{DT,R}) -> Rational{Int}

Compute the inner product $(\alpha, \lambda)$ between a root $\alpha$ (in simple-root coordinates) and a weight $\lambda$ (in fundamental-weight coordinates).

Following OSCAR's convention: $(\alpha, \lambda) = \sum_i \alpha_i d_i \lambda_i$ where d is the Cartan symmetrizer.

This works because $(\alpha_i, \omega_j) = d_i \delta_{ij}$, which follows from $\langle \alpha_i^\vee, \omega_j \rangle = \delta_{ij}$ and $\alpha_i^\vee = \alpha_i / d_i$ in the bilinear-form sense.

Examples

julia> using Semisimple

julia> dot(simple_root(RootSystem(TypeA{2}), 1), fundamental_weight(TypeA{2}, 1))
1//1
source
dot(w1::WeightLatticeElem{DT,R}, w2::WeightLatticeElem{DT,R}) -> Rational{Int}

Compute the inner product $(\lambda, \mu)$ between two weights. Both are given in fundamental-weight coordinates; the implementation converts to root coordinates and applies the bilinear form there.

Examples

julia> using Semisimple

julia> dot(fundamental_weight(TypeA{2}, 1), fundamental_weight(TypeA{2}, 1))
2//3
source

Conversions

Weights and roots live in different coordinate systems. Convert between them:

julia> α1_as_weight = WeightLatticeElem(simple_root(RS, 1))
2ω1 - ω2

julia> ρ_as_root = RootSpaceElem(weyl_vector(TypeA{2}))
α1 + α2

Every weight lies in the rational span of the simple roots via $C^{-1}$. It lies in the root lattice only when those rational simple-root coordinates are integral; otherwise RootSpaceElem(w) throws an ArgumentError.