Skip to content

Commit 86795ff

Browse files
committed
add weight structure decomposition
1 parent d1ec331 commit 86795ff

File tree

13 files changed

+289
-93
lines changed

13 files changed

+289
-93
lines changed

src/DecomposingRepresentations.jl

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export @polyvar, Variable, Monomial, Polynomial, Commutative, CreationOrder, Gra
1010

1111
using Combinatorics: partitions, multiset_permutations, combinations, with_replacement_combinations
1212

13-
using Base.Iterators: product
13+
using Base.Iterators: product, flatten
1414

1515
include("utils/basic.jl")
1616
include("utils/Gauss-Jordan.jl")
@@ -19,9 +19,13 @@ include("types.jl")
1919
include("vector-spaces/basic.jl")
2020
include("vector-spaces/composite.jl")
2121

22-
include("lie-groups/lie-algebras/weights.jl")
22+
include("lie-groups/lie-algebras/weights/weight.jl")
23+
include("lie-groups/lie-algebras/weights/weight-vector.jl")
24+
include("lie-groups/lie-algebras/weights/weight-space.jl")
25+
include("lie-groups/lie-algebras/weights/weight-struct.jl")
2326
include("lie-groups/lie-algebras/algebras.jl")
2427
include("lie-groups/lie-algebras/elements.jl")
28+
include("lie-groups/lie-algebras/weights/decompose-weights.jl")
2529

2630
include("lie-groups/lie-groups/groups.jl")
2731
include("lie-groups/lie-groups/elements.jl")

src/decompositions/irred-decomp.jl

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
export irreducibles, irreducibles_old
2+
13
function ws_nullspace(
24
X::AbstractLieAlgebraElem,
35
a::AbstractGroupAction{Lie},
@@ -14,7 +16,7 @@ function ws_nullspace(
1416
isempty(Cs) && return nothing
1517
return WeightSpace(
1618
weight(ws),
17-
VectorSpace(field_type(ws), [sum(sparsify!(div_by_lowest_magnitude(c, tol), tol) .* B) for c in Cs]; in_rref=false)
19+
VectorSpace(field_type(ws), [sum(c .* B) for c in Cs]; in_rref=false)
1820
)
1921
end
2022

@@ -58,16 +60,54 @@ end
5860

5961
function irreducibles(
6062
ρ::GroupRepresentation{A, S}
63+
) where {T, F, A<:AbstractGroupAction{Lie}, S<:SymmetricPower{T, F, <:HighestWeightModule}}
64+
V = space(ρ)
65+
Vb = base_space(V)
66+
power(V) == 1 && return [IrreducibleRepresentation(action(ρ), Vb)]
67+
ws = weight_structure(Vb)
68+
sym_ws = sym_weight_struct(highest_weight(Vb), algebra(action(ρ)), power(V), ws)
69+
println("new nweights: ", nweights(sym_ws))
70+
println("new sum of dims: ", sum([dim(space(sym_ws[w])) for w in weights(sym_ws)]))
71+
Xs = positive_root_elements(algebra(action(ρ)))
72+
hw_vectors = common_nullspace_as_weight_vectors(Xs, action(ρ), sym_ws)
73+
return [IrreducibleRepresentation(action(ρ), hwv) for hwv in hw_vectors]
74+
end
75+
76+
function irreducibles_old(
77+
ρ::GroupRepresentation{A, S}
6178
) where {T, F, A<:AbstractGroupAction{Lie}, S<:SymmetricPower{T, F, <:HighestWeightModule}}
6279
V = space(ρ)
6380
power(V) == 1 && return [IrreducibleRepresentation(action(ρ), base_space(V))]
6481
ws = weight_structure(base_space(V))
6582
sym_ws = sym(ws, power(V))
83+
println("old nweights: ", nweights(sym_ws))
84+
println("old sum of dims: ", sum([dim(space(sym_ws[w])) for w in weights(sym_ws)]))
6685
Xs = positive_root_elements(algebra(action(ρ)))
6786
hw_vectors = common_nullspace_as_weight_vectors(Xs, action(ρ), sym_ws)
6887
return [IrreducibleRepresentation(action(ρ), hwv) for hwv in hw_vectors]
6988
end
7089

90+
function irreducibles_old(
91+
ρ::GroupRepresentation{A, T}
92+
) where {A<:AbstractGroupAction{Lie}, T<:SymmetricPower}
93+
V = space(ρ)
94+
ρ_base = GroupRepresentation(action(ρ), base_space(V))
95+
irreds_base = irreducibles(ρ_base)
96+
if length(irreds_base) == 1
97+
V = SymmetricPower(space(first(irreds_base)), power(V))
98+
ρᵢ = GroupRepresentation(action(ρ), V)
99+
return irreducibles_old(ρᵢ)
100+
end
101+
mexps = multiexponents(degree=power(V), nvars=length(irreds_base))
102+
irreds = IrreducibleRepresentation{A}[]
103+
for mexp in mexps
104+
Vᵢ = TensorProduct([SymmetricPower(space(irreds_base[idx]), val) for (val, idx) in zip(mexp.nzval, mexp.nzind)])
105+
ρᵢ = GroupRepresentation(action(ρ), Vᵢ)
106+
append!(irreds, irreducibles(ρᵢ))
107+
end
108+
return irreds
109+
end
110+
71111
function irreducibles(
72112
ρ::GroupRepresentation{A, T}
73113
) where {A<:AbstractGroupAction{Lie}, T<:SymmetricPower}

src/decompositions/isotypic-decomp.jl

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
export isotypic_dict
2+
13
function isotypic_components(
24
irreds::Vector{T}
35
) where {T<:IrreducibleRepresentation}
@@ -19,4 +21,8 @@ function isotypic_components(
1921
) where {A<:AbstractGroupAction{Lie}}
2022
irreds = irreducibles(ρ)
2123
return isotypic_components(irreds)
22-
end
24+
end
25+
26+
isotypic_dict(
27+
iso::Vector{T}
28+
) where T<:IsotypicComponent = Dict{Weight, T}(zip([highest_weight(ic) for ic in iso], iso))
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
export sym_weight_dict
2+
3+
# TODO: works only for so(3)
4+
function (hw₁::Weight, hw₂::Weight, ::LieAlgebra)
5+
@assert length(hw₁) == length(hw₂) == 1
6+
m, n = hw₁[1], hw₂[1]
7+
m, n = m > n ? (m, n) : (n, m)
8+
return [Weight([m+n-j]) for j in 0:2*n]
9+
end
10+
11+
(hw₁::Weight, hw₂::Weight, ::ScalingLieAlgebra) = [hw₁ + hw₂]
12+
13+
14+
function split_weight(w::T, A::SumLieAlgebra) where T<:Weight
15+
inds = cumsum([rank(alg) for alg in algebras(A)])
16+
st_ind = 1
17+
ws = T[]
18+
for end_ind in inds
19+
push!(ws, Weight(w[st_ind:end_ind]))
20+
st_ind = end_ind + 1
21+
end
22+
return ws
23+
end
24+
25+
function (hw₁::Weight, hw₂::Weight, A::SumLieAlgebra)
26+
ws₁ = split_weight(hw₁, A)
27+
ws₂ = split_weight(hw₂, A)
28+
sep_ws = [(w₁, w₂, alg) for (w₁, w₂, alg) in zip(ws₁, ws₂, algebras(A))]
29+
all_ws = product(sep_ws...)
30+
return [vcat(collect(ws)...) for ws in all_ws][:]
31+
end
32+
33+
# TODO: works only for so(3)
34+
hw2all(hw::Weight, ::LieAlgebra) = [Weight([j]) for j in -hw[1]:hw[1]]
35+
hw2all(hw::Weight, ::ScalingLieAlgebra) = [hw]
36+
37+
function hw2all(hw::Weight, A::SumLieAlgebra)
38+
ws = split_weight(hw, A)
39+
all_ws = [hw2all(w, alg) for (w, alg) in zip(ws, algebras(A))]
40+
all_ws = product(all_ws...)
41+
return [vcat(collect(ws)...) for ws in all_ws][:]
42+
end
43+
44+
function sym_weight_dict(hw::T, A::AbstractLieAlgebra, p::Int) where T<:Weight
45+
ws = hw2all(hw, A)
46+
combs = multiexponents(; degree=p, nvars=length(ws))
47+
ws_dict = Dict{T, Int}()
48+
for comb in combs
49+
w = sum([val*ws[ind] for (ind, val) in zip(comb.nzind, comb.nzval)])
50+
ws_dict[w] = get(ws_dict, w, 0) + 1
51+
end
52+
return p*hw, ws_dict
53+
end
54+
55+
# # TODO: works only for so(3)
56+
# child_weights(hw::T, ::LieAlgebra) where T<:Weight = iszero(hw[1]) ? T[] : [Weight([hw[1]-1])]
57+
# child_weights(::T, ::ScalingLieAlgebra) where T<:Weight = T[]
58+
# function child_weights(hw::Weight, A::SumLieAlgebra)
59+
# ws = split_weight(hw, A)
60+
# all_child_ws = [child_weights(w, alg) for (w, alg) in zip(ws, algebras(A))]
61+
# full_child_ws = [[copy(ws) for _ in child_ws] for child_ws in all_child_ws]
62+
# for (i, child_ws) in enumerate(all_child_ws)
63+
# for (j, w) in enumerate(child_ws)
64+
# full_child_ws[i][j][i] = w
65+
# end
66+
# end
67+
# return [vcat(ch_ws...) for ch_ws in flatten(full_child_ws)]
68+
# end
69+
70+
function some_highest_weight(
71+
ws_dict::Dict{W, Int},
72+
A::AbstractLieAlgebra
73+
) where W<:Weight
74+
w = first(keys(ws_dict))
75+
while true
76+
exists = false
77+
for α in positive_roots(A)
78+
if haskey(ws_dict, w + α)
79+
w = w + α
80+
exists = true
81+
break
82+
end
83+
end
84+
!exists && return w
85+
end
86+
end
87+
88+
function sym!(
89+
hw::W,
90+
A::AbstractLieAlgebra,
91+
ws_dict::Dict{W, Int},
92+
decomp_hws::Union{Set{W}, Vector{W}}
93+
) where W<:Weight
94+
if ws_dict[hw] != 0
95+
orbit_ws = hw2all(hw, A)
96+
while ws_dict[hw] > 0
97+
push!(decomp_hws, hw)
98+
[ws_dict[w] -= 1 for w in orbit_ws]
99+
end
100+
for w in collect(keys(ws_dict))
101+
ws_dict[w] == 0 && delete!(ws_dict, w)
102+
end
103+
end
104+
isempty(ws_dict) && return decomp_hws
105+
shw = some_highest_weight(ws_dict, A)
106+
sym!(shw, A, ws_dict, decomp_hws)
107+
end
108+
109+
function sym(hw::T, A::AbstractLieAlgebra, p::Int; with_muls::Bool=false) where T<:Weight
110+
sym_hw, ws_dict = sym_weight_dict(hw, A, p)
111+
decomp_hws = with_muls ? T[] : Set{T}()
112+
sym!(sym_hw, A, ws_dict, decomp_hws)
113+
return collect(decomp_hws)
114+
end
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
export WeightSpace,
2+
space
3+
4+
struct WeightSpace{T <: AbstractVectorSpace, W<:Weight}
5+
weight::W
6+
space::T
7+
end
8+
9+
WeightSpace(weight::Vector, space::Vector) = WeightSpace(Weight(weight), MatrixVectorSpace(space))
10+
WeightSpace{T,W}(wv::WeightVector) where {T,W} = WeightSpace{T,W}(weight(wv), T(vector(wv)))
11+
12+
Base.convert(
13+
::Type{WeightSpace{T, W}},
14+
ws::WeightSpace
15+
) where {T<:AbstractVectorSpace, W<:Weight} = WeightSpace(
16+
convert(W, weight(ws)),
17+
convert(T, space(ws))
18+
)
19+
20+
weight(ws::WeightSpace) = ws.weight
21+
space(ws::WeightSpace) = ws.space
22+
dim(ws::WeightSpace) = dim(space(ws))
23+
field_type(::WeightSpace{T}) where {T} = field_type(T)
24+
25+
function Base.show(io::IO, ::MIME"text/plain", ws::WeightSpace)
26+
println(io, "WeightSpace of dimension $(dim(ws))")
27+
print(io, " weight: $(weight(ws))")
28+
end
29+
30+
function Base.show(io::IO, ws::WeightSpace)
31+
print(io, "WeightSpace of dimension $(dim(ws))")
32+
end
33+
34+
function Base.iterate(ws::WeightSpace, state=1)
35+
state > dim(ws) && return nothing
36+
return (WeightVector(weight(ws), basis(space(ws), state)), state+1)
37+
end

src/lie-groups/lie-algebras/weights.jl renamed to src/lie-groups/lie-algebras/weights/weight-struct.jl

Lines changed: 27 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,86 +1,7 @@
1-
export Weight,
2-
WeightVector,
3-
weight,
4-
vector,
5-
WeightSpace,
6-
space,
7-
WeightStructure,
1+
export WeightStructure,
82
weight_space,
93
sym
104

11-
12-
struct Weight{T}
13-
weight::Vector{T}
14-
end
15-
16-
Base.show(io::IO, ::MIME"text/plain", w::Weight) = print(io, "Weight: ", w.weight)
17-
Base.show(io::IO, w::Weight) = print(io, w.weight)
18-
Base.zero(::Type{Weight{T}}, n) where T = Weight(zeros(T, n))
19-
Base.zero(w::Weight) = Weight(zero(w.weight))
20-
Base.vcat(w₁::Weight{T}, w₂::Weight{T}) where T = Weight(vcat(w₁.weight, w₂.weight))
21-
Base.vcat(ws::Weight{T}...) where T = Weight(vcat([w.weight for w in ws]...))
22-
Base.hash(w::Weight, h::UInt) = hash(w.weight, h)
23-
Base.:(==)(w₁::Weight, w₂::Weight) = w₁.weight == w₂.weight
24-
Base.:*(n::Number, w::Weight) = Weight(n*w.weight)
25-
Base.:+(w₁::Weight{T}, w₂::Weight{T}) where {T} = Weight{T}(w₁.weight + w₂.weight)
26-
Base.promote_rule(::Type{Weight{T}}, ::Type{Weight{S}}) where {T,S} = Weight{promote_type(T, S)}
27-
Base.getindex(w::Weight, i::Integer) = w.weight[i]
28-
Base.getindex(w::Weight, inds...) = getindex(w.weight, inds...)
29-
Base.length(w::Weight) = length(w.weight)
30-
Base.eachindex(w::Weight) = eachindex(w.weight)
31-
32-
struct WeightVector{T, W<:Weight}
33-
weight::W
34-
vector::T
35-
end
36-
37-
weight(wv::WeightVector) = wv.weight
38-
vector(wv::WeightVector) = wv.vector
39-
40-
function Base.show(io::IO, ::MIME"text/plain", wv::WeightVector)
41-
println(io, "WeightVector with weight $(weight(wv))")
42-
print(io, " vector: $(repr(vector(wv)))")
43-
end
44-
45-
function Base.show(io::IO, wv::WeightVector)
46-
print(io, "WeightVector with weight $(weight(wv))")
47-
end
48-
49-
struct WeightSpace{T <: AbstractVectorSpace, W<:Weight}
50-
weight::W
51-
space::T
52-
end
53-
54-
WeightSpace(weight::Vector, space::Vector) = WeightSpace(Weight(weight), MatrixVectorSpace(space))
55-
WeightSpace{T,W}(wv::WeightVector) where {T,W} = WeightSpace{T,W}(weight(wv), T(vector(wv)))
56-
57-
Base.convert(
58-
::Type{WeightSpace{T, W}},
59-
ws::WeightSpace
60-
) where {T<:AbstractVectorSpace, W<:Weight} = WeightSpace(
61-
convert(W, weight(ws)),
62-
convert(T, space(ws))
63-
)
64-
65-
weight(ws::WeightSpace) = ws.weight
66-
space(ws::WeightSpace) = ws.space
67-
dim(ws::WeightSpace) = dim(space(ws))
68-
field_type(::WeightSpace{T}) where {T} = field_type(T)
69-
70-
function Base.show(io::IO, ::MIME"text/plain", ws::WeightSpace)
71-
println(io, "WeightSpace of dimension $(dim(ws))")
72-
print(io, " weight: $(weight(ws))")
73-
end
74-
75-
function Base.show(io::IO, ws::WeightSpace)
76-
print(io, "WeightSpace of dimension $(dim(ws))")
77-
end
78-
79-
function Base.iterate(ws::WeightSpace, state=1)
80-
state > dim(ws) && return nothing
81-
return (WeightVector(weight(ws), basis(space(ws), state)), state+1)
82-
end
83-
845
struct WeightStructure{T<:AbstractVectorSpace, W<:Weight}
856
weights::Vector{W} # Ordering needed for sym_weight_structure
867
dict::Dict{W, WeightSpace{T, W}} # TODO: new type for WeightSpace{F,T,W}? Do all spaces have to be of the same type?
@@ -180,6 +101,32 @@ end
180101

181102
Base.push!(ws::WeightStructure{T,W}, wv::WeightVector) where {T,W} = push!(ws, WeightSpace{T,W}(wv))
182103

104+
function sym_weights_dict(ws::Vector{W}, p::Int) where W<:Weight
105+
combs = multiexponents(; degree=p, nvars=length(ws))
106+
ws_dict = Dict{W, Vector{typeof(first(combs))}}()
107+
for comb in combs
108+
w = sum([val*ws[ind] for (val, ind) in zip(comb.nzval, comb.nzind)])
109+
if haskey(ws_dict, w)
110+
push!(ws_dict[w], comb)
111+
else
112+
ws_dict[w] = [comb]
113+
end
114+
end
115+
return ws_dict
116+
end
117+
118+
function sym_weight_struct(hw::W, A::AbstractLieAlgebra, p::Int, ws::WeightStructure{T,W}) where {T, W<:Weight}
119+
dir_sum_hws = sym(hw, A, p)
120+
ws_dict = sym_weights_dict(weights(ws), p)
121+
new_ws = WeightStructure{T,W}()
122+
for hw in dir_sum_hws
123+
combs = ws_dict[hw]
124+
w_sps = [*(weight_spaces(ws, comb.nzind; as_spaces=true), comb.nzval; in_rref=false) for comb in combs]
125+
push!(new_ws, WeightSpace(hw, +(w_sps...; in_rref=false)))
126+
end
127+
return new_ws
128+
end
129+
183130
function sym(ws::WeightStructure{T,W}, d::Int) where {T, W}
184131
d == 0 && return WeightStructure([WeightSpace(zero_weight(ws), field_space(ws))])
185132
d == 1 && return ws

0 commit comments

Comments
 (0)