Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions benchmark/bench.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ using Semisimple
using StaticArrays
using Dates

import Semisimple: borel_weil_bott
import Semisimple: _borel_weil_bott

# ─── CLI ────────────────────────────────────────────────────────────────────

Expand Down Expand Up @@ -456,7 +456,7 @@ function bench_bwb_box(::Type{DT}, bound) where {DT}
count = 0
for coords in Iterators.product(ntuple(_ -> (-bound):bound, R)...)
λ = WeightLatticeElem(DT, SVector{R,Int}(coords))
borel_weil_bott(λ)
_borel_weil_bott(λ)
count += 1
end
return count
Expand Down Expand Up @@ -484,7 +484,7 @@ end

function bench_bwb_deep(::Type{DT}, weights) where {DT}
for w in weights
borel_weil_bott(w)
_borel_weil_bott(w)
end
end

Expand Down
18 changes: 10 additions & 8 deletions docs/src/weyl.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,28 +198,30 @@ Compute the cohomological degree and resulting representation for
a weight on a flag variety:

```jldoctest weyl
julia> import Semisimple: borel_weil_bott
julia> import Semisimple: _borel_weil_bott

julia> borel_weil_bott(ω1) # dominant weight → degree 0
julia> _borel_weil_bott(ω1) # dominant weight → degree 0
(0, ω1)

julia> borel_weil_bott(WeightLatticeElem(TypeA{3}, [-3, 2, 1]))
julia> _borel_weil_bott(WeightLatticeElem(TypeA{3}, [-3, 2, 1]))
(1, ω1 + ω3)
```

Singular weights give zero cohomology, and `borel_weil_bott` returns `nothing`:
Singular weights give zero cohomology, and `_borel_weil_bott` returns `nothing`:

```jldoctest weyl
julia> borel_weil_bott(-weyl_vector(TypeA{3})) === nothing
julia> _borel_weil_bott(-weyl_vector(TypeA{3})) === nothing
true
```

!!! note
`borel_weil_bott` is not exported. It is rather a feature for `PartialFlagVarieties.jl`.
Use `import Semisimple: borel_weil_bott` to access it.
`_borel_weil_bott` is internal: the leading underscore marks it as neither
exported nor covered by semantic versioning. It is rather a feature for
`PartialFlagVarieties.jl`, which builds it out of the exported
`conjugate_dominant_weight_with_length`.

```@docs
Semisimple.borel_weil_bott
Semisimple._borel_weil_bott
```

### Singular weights
Expand Down
32 changes: 17 additions & 15 deletions src/WeylGroup.jl
Original file line number Diff line number Diff line change
Expand Up @@ -944,7 +944,7 @@ Passing `nodes` restricts the question to the root subsystem spanned by
``S`` = `nodes`, as in [`conjugate_dominant_weight`](@ref): the result is then
whether ``⟨α^\\vee, w⟩ = 0`` for some positive root ``α`` of that subsystem.
This is the vanishing criterion of the relative
[`borel_weil_bott`](@ref).
[`_borel_weil_bott`](@ref).

# Examples
```jldoctest
Expand Down Expand Up @@ -978,15 +978,17 @@ end
# ─── Borel–Weil–Bott ────────────────────────────────────────────────────────

"""
borel_weil_bott(λ::WeightLatticeElem{DT,R}, nodes=nothing) -> Union{Nothing, Tuple{Int, WeightLatticeElem{DT,R}}}
_borel_weil_bott(λ::WeightLatticeElem{DT,R}, nodes=nothing) -> Union{Nothing, Tuple{Int, WeightLatticeElem{DT,R}}}

Apply the Borel–Weil–Bott theorem to the weight `λ`.

!!! note "Package placement"
This function is a preview implementation that properly belongs to
`PartialFlagVarieties.jl`, an upcoming companion package. It is included here
for convenience but is **not part of the public API of `Semisimple.jl`** and is not
exported. Access it via `import Semisimple: borel_weil_bott`.
!!! note "Internal"
The leading underscore marks this as internal: it is not exported, not part
of the public API of `Semisimple.jl`, and not covered by semantic
versioning. The theorem properly belongs to `PartialFlagVarieties.jl`, which
builds it out of the exported
[`conjugate_dominant_weight_with_length`](@ref); this implementation is kept
here only to exercise the restricted fold from the tests.

Compute `μ = λ + ρ` and find the unique Weyl group element `w` such that
`w(μ)` is dominant. If `μ` is singular (lies on a Weyl chamber wall),
Expand All @@ -1009,32 +1011,32 @@ therefore ``\\mathrm{W}_S``-invariant.

# Examples
```jldoctest
julia> using Semisimple; import Semisimple: borel_weil_bott
julia> using Semisimple; import Semisimple: _borel_weil_bott

julia> borel_weil_bott(fundamental_weight(TypeA{2}, 1))
julia> _borel_weil_bott(fundamental_weight(TypeA{2}, 1))
(0, ω1)

julia> borel_weil_bott(WeightLatticeElem(TypeA{2}, [-2, 1]))
julia> _borel_weil_bott(WeightLatticeElem(TypeA{2}, [-2, 1]))
(1, 0)

julia> borel_weil_bott(-weyl_vector(TypeA{2})) === nothing
julia> _borel_weil_bott(-weyl_vector(TypeA{2})) === nothing
true
```

The same weight, but reflecting only in the second node: it is already dominant
there, so it stays put in degree zero.

```jldoctest
julia> using Semisimple; import Semisimple: borel_weil_bott
julia> using Semisimple; import Semisimple: _borel_weil_bott

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

julia> borel_weil_bott(-weyl_vector(TypeA{2}), (2,)) === nothing # singular for s2 too
julia> _borel_weil_bott(-weyl_vector(TypeA{2}), (2,)) === nothing # singular for s2 too
true
```
"""
function borel_weil_bott(λ::WeightLatticeElem{DT,R}, nodes=nothing) where {DT,R}
function _borel_weil_bott(λ::WeightLatticeElem{DT,R}, nodes=nothing) where {DT,R}
ρ = weyl_vector(DT)
μ = λ + ρ

Expand Down
48 changes: 24 additions & 24 deletions test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using Test
using Semisimple
using Aqua
import Semisimple: borel_weil_bott # no longer publicly exported; tested here via explicit import
import Semisimple: _borel_weil_bott # no longer publicly exported; tested here via explicit import
using StaticArrays
using LinearAlgebra: det

Expand Down Expand Up @@ -1019,58 +1019,58 @@ end
ρ = weyl_vector(TypeA{2})

# ω1 is dominant: H⁰ = V(ω1), dim = 3
result = borel_weil_bott(ω1)
result = _borel_weil_bott(ω1)
@test result !== nothing
d, μ = result
@test d == 0
@test μ == ω1

# ω2 is dominant: H⁰ = V(ω2), dim = 3
result = borel_weil_bott(ω2)
result = _borel_weil_bott(ω2)
@test result !== nothing
d, μ = result
@test d == 0
@test μ == ω2

# λ = -ρ: λ + ρ = 0, singular → nothing
@test borel_weil_bott(-ρ) === nothing
@test _borel_weil_bott(-ρ) === nothing

# λ = [-2, 1]: λ+ρ = [-1, 2], s1 gives [1, 1], d=1, μ = [0, 0]
λ = WeightLatticeElem(TypeA{2}, [-2, 1])
result = borel_weil_bott(λ)
result = _borel_weil_bott(λ)
@test result !== nothing
d, μ = result
@test d == 1
@test μ == WeightLatticeElem(TypeA{2}, [0, 0]) # trivial rep

# λ = [-3, 3]: λ+ρ = [-2, 4], s1 gives [2, 2], d=1, μ = [1, 1]
λ = WeightLatticeElem(TypeA{2}, [-3, 3])
result = borel_weil_bott(λ)
result = _borel_weil_bott(λ)
@test result !== nothing
d, μ = result
@test d == 1
@test μ == WeightLatticeElem(TypeA{2}, [1, 1]) # adjoint rep

# λ = [-3, 1]: λ+ρ = [-2, 2], conjugates to singular weight [2, 0]
@test borel_weil_bott(WeightLatticeElem(TypeA{2}, [-3, 1])) === nothing
@test _borel_weil_bott(WeightLatticeElem(TypeA{2}, [-3, 1])) === nothing
end

# ── A1 ──────────────────────────────────────────────────────────────
@testset "A1" begin
# nomega1 dominant: degree 0, result is nomega1
for n in 0:5
result = borel_weil_bott(WeightLatticeElem(TypeA{1}, [n]))
result = _borel_weil_bott(WeightLatticeElem(TypeA{1}, [n]))
@test result !== nothing
d, μ = result
@test d == 0
@test μ == WeightLatticeElem(TypeA{1}, [n])
end

# λ = -1: λ+ρ = 0, singular
@test borel_weil_bott(WeightLatticeElem(TypeA{1}, [-1])) === nothing
@test _borel_weil_bott(WeightLatticeElem(TypeA{1}, [-1])) === nothing

# λ = -3: λ+ρ = -2, s1 → 2, dominant, d=1, μ = 2-1 = 1
result = borel_weil_bott(WeightLatticeElem(TypeA{1}, [-3]))
result = _borel_weil_bott(WeightLatticeElem(TypeA{1}, [-3]))
@test result !== nothing
d, μ = result
@test d == 1
Expand All @@ -1081,7 +1081,7 @@ end
@testset "B2" begin
# Dominant weight: degree 0
ω1 = fundamental_weight(TypeB{2}, 1)
result = borel_weil_bott(ω1)
result = _borel_weil_bott(ω1)
@test result !== nothing
d, μ = result
@test d == 0
Expand All @@ -1094,7 +1094,7 @@ end
R = rank(DT)
for i in 1:R
ωi = fundamental_weight(DT, i)
result = borel_weil_bott(ωi)
result = _borel_weil_bott(ωi)
@test result !== nothing
d, μ = result
@test d == 0
Expand All @@ -1106,7 +1106,7 @@ end
@testset "E8" begin
λ = WeightLatticeElem(TypeE{8}, [-5, 3, -2, -3, 5, -8, 2, 1])
# λ+ρ conjugates to a singular weight, so all cohomology vanishes
@test borel_weil_bott(λ) === nothing
@test _borel_weil_bott(λ) === nothing
end
end

Expand Down Expand Up @@ -1165,7 +1165,7 @@ end
@test conjugate_dominant_weight(λ, 1:R) == conjugate_dominant_weight(λ)
@test conjugate_dominant_weight_with_length(λ, Tuple(1:R)) ==
conjugate_dominant_weight_with_length(λ)
@test borel_weil_bott(λ, 1:R) == borel_weil_bott(λ)
@test _borel_weil_bott(λ, 1:R) == _borel_weil_bott(λ)
end
end

Expand All @@ -1188,7 +1188,7 @@ end
@test_throws ArgumentError conjugate_dominant_weight(λ, nodes)
@test_throws ArgumentError conjugate_dominant_weight_with_length(λ, nodes)
@test_throws ArgumentError conjugate_dominant_weight_with_elem(λ, nodes)
@test_throws ArgumentError borel_weil_bott(λ, nodes)
@test_throws ArgumentError _borel_weil_bott(λ, nodes)
@test_throws ArgumentError is_singular(λ, nodes)
end

Expand All @@ -1212,13 +1212,13 @@ end

for seed in 1:8
λ = WeightLatticeElem(DT, Int[((seed * i) % 7) - 3 for i in 1:R])
result = borel_weil_bott(λ, S)
result = _borel_weil_bott(λ, S)

sub_λ =
WeightLatticeElem(
LT, Int[coefficients(λ)[ord[k]] + coefficients(ρ)[ord[k]] for k in 1:rank(LT)]
) - ρ_S
sub_result = borel_weil_bott(sub_λ)
sub_result = _borel_weil_bott(sub_λ)

@test (result === nothing) == (sub_result === nothing)
result === nothing && continue
Expand All @@ -1231,7 +1231,7 @@ end
end
end

# is_singular is the vanishing criterion, so it must agree with borel_weil_bott
# is_singular is the vanishing criterion, so it must agree with _borel_weil_bott
# on exactly when nothing survives.
@testset "is_singular restricted: $DT / $S" for (DT, S) in
[(TypeA{3}, (1, 3)), (TypeB{3}, (2, 3)),
Expand All @@ -1250,7 +1250,7 @@ end
# Ground truth: pair λ + ρ against every positive root of the subsystem.
expected = any(iszero(dot(α, λ + ρ)) for α in sub_positive)
@test is_singular(λ + ρ, S) == expected
@test (borel_weil_bott(λ, S) === nothing) == expected
@test (_borel_weil_bott(λ, S) === nothing) == expected

# Singular for the subsystem implies singular for the whole system, since
# the offending root is a root of both.
Expand All @@ -1264,16 +1264,16 @@ end

# A weight that is regular for the whole group but singular for a subsystem,
# and one that is singular for the whole group but regular for a subsystem.
@test borel_weil_bott(WeightLatticeElem(TypeA{2}, [-2, 1])) ==
@test _borel_weil_bott(WeightLatticeElem(TypeA{2}, [-2, 1])) ==
(1, WeightLatticeElem(TypeA{2}))
@test borel_weil_bott(WeightLatticeElem(TypeA{2}, [-2, 1]), (2,)) ==
@test _borel_weil_bott(WeightLatticeElem(TypeA{2}, [-2, 1]), (2,)) ==
(0, WeightLatticeElem(TypeA{2}, [-2, 1]))
@test borel_weil_bott(WeightLatticeElem(TypeA{2}, [0, -1])) === nothing
@test borel_weil_bott(WeightLatticeElem(TypeA{2}, [0, -1]), (1,)) ==
@test _borel_weil_bott(WeightLatticeElem(TypeA{2}, [0, -1])) === nothing
@test _borel_weil_bott(WeightLatticeElem(TypeA{2}, [0, -1]), (1,)) ==
(0, WeightLatticeElem(TypeA{2}, [0, -1]))

# No nodes to reflect in: nothing can be singular and nothing moves.
@test borel_weil_bott(WeightLatticeElem(TypeA{2}, [-5, -5]), ()) ==
@test _borel_weil_bott(WeightLatticeElem(TypeA{2}, [-5, -5]), ()) ==
(0, WeightLatticeElem(TypeA{2}, [-5, -5]))
end

Expand Down
Loading