Skip to content

Commit 6cd4c8f

Browse files
committed
add weight structure computation on variables
1 parent ed31bdc commit 6cd4c8f

File tree

4 files changed

+116
-102
lines changed

4 files changed

+116
-102
lines changed

src/on_varieties/lie-symmetries/lie-algebras/actions.jl

Lines changed: 31 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -62,40 +62,34 @@ function act(elem::LieAlgebraElem{ScalingLieAlgebra}, f::Union{Expression, Monom
6262
return expand(dot(differentiate(f, variables(action)), -X*variables(action)))
6363
end
6464

65-
function weight_structure(a::ScalingLieAction, vars::Vector{Variable})
66-
65+
function inv_weight_space(a::AbstractLieAlgebraAction, vars::Vector{Variable})
66+
inv_vars = setdiff(vars, variables(a))
67+
isempty(inv_vars) && return nothing
68+
ws = WeightSpace(zeros(Int, rank(algebra(a))), zeros(ComplexF64, length(vars), length(inv_vars)))
69+
for (i, var) in enumerate(inv_vars)
70+
ws[vars_dict[var], i] = 1
71+
end
72+
return ws
6773
end
6874

69-
function hw_spaces(a::ScalingLieAction, vars::Vector{Variable})
75+
function weight_structure(a::ScalingLieAction, vars::Vector{Variable})
7076
@assert variables(a) vars
7177
vars_dict = Dict(zip(vars, 1:length(vars)))
72-
hw_spaces_dict = Dict{Vector{Int}, WeightSpace}()
78+
hw_struct = WeightStructure()
7379
for (i, var) in enumerate(variables(a))
7480
weight = exponents(a)[:, i]
75-
if haskey(hw_spaces_dict, weight)
76-
sp = zeros(ComplexF64, length(vars))
77-
sp[vars_dict[var]] = 1
78-
hw_spaces_dict[weight].space = hcat(hw_spaces_dict[weight].space, sp)
79-
else
80-
hw_space = WeightSpace(weight, zeros(ComplexF64, length(vars)))
81-
hw_space.space[vars_dict[var]] = 1
82-
hw_spaces_dict[weight] = hw_space
83-
end
84-
end
85-
inv_vars = setdiff(vars, variables(a))
86-
isempty(inv_vars) && return collect(values(hw_spaces_dict))
87-
inv_hw_space = WeightSpace(zeros(Int, rank(algebra(a))), zeros(ComplexF64, length(vars), length(inv_vars)))
88-
for (i, var) in enumerate(inv_vars)
89-
inv_hw_space.space[vars_dict[var], i] = 1
90-
end
91-
if haskey(hw_spaces_dict, weight(inv_hw_space))
92-
hw_spaces_dict[weight(inv_hw_space)].space = hcat(hw_spaces_dict[weight(inv_hw_space)].space, inv_hw_space.space)
93-
else
94-
hw_spaces_dict[weight(inv_hw_space)] = inv_hw_space
81+
hwv = WeightVector(weight, zeros(ComplexF64, length(vars)))
82+
hwv[vars_dict[var]] = 1
83+
push!(hw_struct, hwv)
9584
end
96-
return collect(values(hw_spaces_dict))
85+
inv_ws = inv_weight_space(a, vars)
86+
!isnothing(inv_ws) && push!(hw_struct, inv_ws)
87+
return hw_struct
9788
end
9889

90+
hw_spaces(a::ScalingLieAction, vars::Vector{Variable}) = weight_structure(a, vars)
91+
92+
9993
struct LieAlgebraAction <: AbstractLieAlgebraAction
10094
alg::LieAlgebra
10195
var_groups::Vector{Vector{Variable}}
@@ -129,38 +123,27 @@ function act(elem::LieAlgebraElem{LieAlgebra}, f::Union{Expression, Monomial}, a
129123
return expand(sum([dot(differentiate(f, vars), -X*vars) for vars in var_groups(action)]))
130124
end
131125

132-
function weight_structure(a::LieAlgebraAction, vars::Vector{Variable})
133-
134-
end
135-
136-
function hw_spaces(a::LieAlgebraAction, vars::Vector{Variable})
126+
function weight_structure(a::LieAlgebraAction, vars::Vector{Variable}; as_hw_spaces::Bool=false)
137127
@assert variables(a) vars
138128
vars_dict = Dict(zip(vars, 1:length(vars)))
139-
hw_spaces_vec = WeightSpace[]
140-
for hw_space in hw_spaces(algebra(a))
141-
hws = WeightSpace(hw_space.weight, zeros(ComplexF64, length(vars), dim(hw_space)*nvar_groups(a)))
129+
ws = WeightStructure()
130+
alg_ws = as_hw_spaces ? hw_spaces(algebra(a)) : weight_structure(algebra(a))
131+
for w_space in alg_ws
132+
new_w_space = WeightSpace(weight(w_space), zeros(ComplexF64, length(vars), dim(w_space)*nvar_groups(a)))
142133
for (i, vars_group) in enumerate(var_groups(a))
143134
for (j, var) in enumerate(vars_group)
144-
hws.space[vars_dict[var], (i-1)*dim(hw_space)+1:i*dim(hw_space)] = hw_space.space[j, :]
135+
new_w_space[vars_dict[var], (i-1)*dim(w_space)+1:i*dim(w_space)] = w_space[j, :]
145136
end
146137
end
147-
push!(hw_spaces_vec, hws)
148-
end
149-
inv_vars = setdiff(vars, variables(a))
150-
isempty(inv_vars) && return hw_spaces_vec
151-
inv_hw_space = WeightSpace(zeros(Int, rank(algebra(a))), zeros(ComplexF64, length(vars), length(inv_vars)))
152-
for (i, var) in enumerate(inv_vars)
153-
inv_hw_space.space[vars_dict[var], i] = 1
154-
end
155-
hws_dict = Dict(zip([weight(hws) for hws in hw_spaces_vec], hw_spaces_vec))
156-
if haskey(hws_dict, weight(inv_hw_space))
157-
hws_dict[weight(inv_hw_space)].space = hcat(hws_dict[weight(inv_hw_space)].space, inv_hw_space.space)
158-
else
159-
push!(hw_spaces_vec, inv_hw_space)
138+
push!(ws, new_w_space)
160139
end
161-
return hw_spaces_vec
140+
inv_ws = inv_weight_space(a, vars)
141+
!isnothing(inv_ws) && push!(ws, inv_ws)
142+
return ws
162143
end
163144

145+
hw_spaces(a::LieAlgebraAction, vars::Vector{Variable}) = weight_structure(a, vars, as_hw_spaces=true)
146+
164147

165148
struct SumLieAlgebraAction <: AbstractLieAlgebraAction
166149
alg::SumLieAlgebra

src/on_varieties/lie-symmetries/lie-reprs/representation.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
export LieAlgebraRepresentation,
2-
space,
2+
w_space,
33
isotypic_components,
44
highest_weights
55

@@ -30,11 +30,11 @@ end
3030

3131
action::LieAlgebraRepresentation) = ρ.action
3232
algebra::LieAlgebraRepresentation) = algebra.action)
33-
space::LieAlgebraRepresentation) = ρ.V
33+
w_space::LieAlgebraRepresentation) = ρ.V
3434
nisotypic::LieAlgebraRepresentation) = length.isotypic)
3535
isotypic_components::LieAlgebraRepresentation) = ρ.isotypic
3636
irreducibles::LieAlgebraRepresentation) = vcat([irreducibles(iso) for iso in ρ.isotypic]...)
37-
dim::LieAlgebraRepresentation) = dim(space(ρ))
37+
dim::LieAlgebraRepresentation) = dim(w_space(ρ))
3838
highest_weights::LieAlgebraRepresentation) = [highest_weight(ic) for ic in isotypic_components(ρ)]
3939

4040
# called by Shift+Enter
@@ -64,8 +64,8 @@ function nullspace_as_weight_vectors(
6464
tol::Real=1e-5
6565
) where {T <: Number}
6666
wvs = WeightVector[]
67-
for weight_space in weight_spaces(ws)
68-
N = space(weight_space)*nullspace(M*space(weight_space))
67+
for weight_space in ws
68+
N = matrix(weight_space)*nullspace(M*matrix(weight_space))
6969
sparsify!(N, tol)
7070
vs = M2VV(N; copy=false)
7171
for v in vs

src/on_varieties/lie-symmetries/scalings.jl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ export Grading,
33
grading,
44
scaling_symmetries
55

6-
using AbstractAlgebra: ZZ, matrix, GF, lift, hnf, snf_with_transform
6+
using AbstractAlgebra: ZZ, matrix as aa_matrix, GF, lift, hnf, snf_with_transform
77
using LinearAlgebra: diag
88

99
mutable struct Grading{Tv<:Integer,Ti<:Integer}
@@ -162,7 +162,7 @@ function _snf_scaling_symmetries(F::System)::Tuple{Vector{Int}, Vector{Matrix{In
162162
if size(K, 1) > size(K, 2)
163163
K = [K zeros(eltype(K), size(K, 1), size(K,1)-size(K,2))]
164164
end
165-
K = matrix(ZZ, K)
165+
K = aa_matrix(ZZ, K)
166166

167167
S, U, _ = snf_with_transform(K)
168168
U, S = Matrix(U), Int.(diag(Matrix(S)))
@@ -182,10 +182,10 @@ function _hnf_reduce!(
182182
)
183183
for (i, (sᵢ, Uᵢ)) in enumerate(zip(s, U))
184184
if sᵢ == 0
185-
U[i] = Matrix(hnf(matrix(ZZ, Uᵢ)))
185+
U[i] = Matrix(hnf(aa_matrix(ZZ, Uᵢ)))
186186
else
187187
try
188-
U[i] = Int.(lift.(Matrix(hnf(matrix(GF(sᵢ), Uᵢ)))))
188+
U[i] = Int.(lift.(Matrix(hnf(aa_matrix(GF(sᵢ), Uᵢ)))))
189189
catch
190190
U[i] = mod.(Uᵢ, sᵢ)
191191
end
@@ -198,12 +198,12 @@ function _hnf_reduce(grading::Grading{Tv,Ti}) where {Tv<:Integer,Ti<:Integer}
198198
U₀ = grading.free_part
199199
red_grading = Grading{Tv,Ti}()
200200
if !isnothing(U₀)
201-
red_grading.free_part = Matrix(hnf(matrix(ZZ, U₀)))
201+
red_grading.free_part = Matrix(hnf(aa_matrix(ZZ, U₀)))
202202
red_grading.nscalings = size(U₀, 1)
203203
end
204204
for (sᵢ, Uᵢ) in grading.mod_part
205205
try
206-
Uᵢ = lift.(Matrix(hnf(matrix(GF(sᵢ), Uᵢ))))
206+
Uᵢ = lift.(Matrix(hnf(aa_matrix(GF(sᵢ), Uᵢ))))
207207
catch
208208
Uᵢ = mod.(Uᵢ, sᵢ)
209209
end

src/on_varieties/lie-symmetries/weights.jl

Lines changed: 74 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,33 @@ end
2222

2323
weight(wv::WeightVector) = wv.weight
2424
vector(wv::WeightVector) = wv.vector
25+
Base.setindex!(wv::WeightVector, n::Number, i::Integer) = wv.vector[i] = n
2526

2627
mutable struct WeightSpace
2728
weight::Vector{Int}
28-
space::Matrix{ComplexF64}
29+
matrix::Matrix{ComplexF64}
2930
end
3031

3132
WeightSpace(wv::WeightVector) = WeightSpace(weight(wv), V2M(vector(wv)))
32-
WeightSpace(weight::AbstractVector, space::AbstractVector) = WeightSpace(weight, V2M(space))
33+
WeightSpace(weight::AbstractVector, v::AbstractVector) = WeightSpace(weight, V2M(v))
3334

3435
weight(ws::WeightSpace) = ws.weight
3536
weight_size(ws::WeightSpace) = length(weight(ws))
36-
space(ws::WeightSpace) = ws.space
37-
Base.size(ws::WeightSpace) = size(ws.space, 1)
38-
dim(ws::WeightSpace) = size(ws.space, 2)
37+
matrix(ws::WeightSpace) = ws.matrix
38+
Base.size(ws::WeightSpace) = size(ws.matrix, 1)
39+
dim(ws::WeightSpace) = size(ws.matrix, 2)
40+
Base.getindex(ws::WeightSpace, inds...) = ws.matrix[inds...]
41+
Base.setindex!(ws::WeightSpace, M::AbstractVecOrMat{T}, inds...) where {T <: Number} = ws.matrix[inds...] = M
42+
43+
function Base.hcat(ws1::WeightSpace, ws2::WeightSpace)
44+
if weight(ws1) != weight(ws2)
45+
throw(ArgumentError("Weights of the two spaces must be equal"))
46+
end
47+
if size(ws1) != size(ws2)
48+
throw(ArgumentError("Sizes of the two spaces must be equal"))
49+
end
50+
return WeightSpace(weight(ws1), hcat(matrix(ws1), matrix(ws2)))
51+
end
3952

4053
function Base.show(io::IO, ::MIME"text/plain", ws::WeightSpace)
4154
println(io, "WeightSpace of dimension $(dim(ws))")
@@ -48,10 +61,10 @@ end
4861

4962
function Base.iterate(ws::WeightSpace, state=1)
5063
state > dim(ws) && return nothing
51-
return (WeightVector(weight(ws), space(ws)[:, state]), state+1)
64+
return (WeightVector(weight(ws), matrix(ws)[:, state]), state+1)
5265
end
5366

54-
function intersect_spaces(A::AbstractMatrix{T}, B::AbstractMatrix{T}) where {T <: Number}
67+
function Base.:(A::AbstractMatrix{T}, B::AbstractMatrix{T}) where {T <: Number}
5568
N = nullspace(hcat(A, B))
5669
N = hcat([div_by_lowest_magnitude(N[:,i], 1e-8) for i in 1:size(N, 2)]...)
5770
sparsify!(N, 1e-8)
@@ -60,30 +73,23 @@ end
6073

6174
function Base.:(ws1::WeightSpace, ws2::WeightSpace)
6275
new_weight = vcat(weight(ws1), weight(ws2))
63-
new_space = intersect_spaces(space(ws1), space(ws2))
64-
iszero(size(new_space, 2)) && return nothing
65-
return WeightSpace(new_weight, new_space)
66-
end
67-
68-
function Base.:(ws1::Vector{WeightSpace}, ws2::Vector{WeightSpace})
69-
new_spaces = [ws1[i] ws2[j] for i in 1:length(ws1), j in 1:length(ws2)]
70-
return [ws for ws in new_spaces if !isnothing(ws)]
76+
new_matrix = (matrix(ws1), matrix(ws2))
77+
iszero(size(new_matrix, 2)) && return nothing
78+
return WeightSpace(new_weight, new_matrix)
7179
end
7280

73-
Base.:(ws::Vector{Vector{WeightSpace}}) = reduce(, ws)
74-
7581

7682
struct WeightStructure
77-
weight_spaces::Vector{WeightSpace}
78-
dict::Dict{Vector{Int}, Matrix{ComplexF64}}
83+
weights::Vector{Vector{Int}}
84+
dict::Dict{Vector{Int}, WeightSpace} # weight => space
7985
end
8086

8187
WeightStructure(
8288
weights::Vector{Vector{Int}},
8389
weight_spaces::Vector{Matrix{T}} where T <: Number
8490
) = WeightStructure(
85-
[WeightSpace(w, M) for (w, M) in zip(weights, weight_spaces)],
86-
Dict(zip(weights, weight_spaces))
91+
weights,
92+
Dict(zip(weights, [WeightSpace(w, M) for (w, M) in zip(weights, weight_spaces)]))
8793
)
8894

8995
WeightStructure(
@@ -103,20 +109,30 @@ WeightStructure(
103109
weight_vectors::Vector{Vector{T}} where T <: Number
104110
) = WeightStructure(weights, [V2M(v) for v in weight_vectors])
105111

112+
function WeightStructure(w_spaces::Vector{WeightSpace})
113+
ws = WeightStructure()
114+
for w_space in w_spaces
115+
push!(ws, w_space)
116+
end
117+
return ws
118+
end
119+
106120
weight_spaces(
107121
ws::WeightStructure;
108122
as_matrices::Bool=false
109-
) = as_matrices ? [space(wsp) for wsp in ws.weight_spaces] : ws.weight_spaces
123+
) = as_matrices ? [matrix(ws[w]) for w in weights(ws)] : [ws[w] for w in weights(ws)]
124+
110125
weight_spaces(
111126
ws::WeightStructure,
112127
inds...;
113128
as_matrices::Bool=false
114129
) = weight_spaces(ws; as_matrices=as_matrices)[inds...]
115-
weight_size(ws::WeightStructure) = weight_size(ws[1])
116-
space_dim(ws::WeightStructure) = size(ws[1])
117-
weights(ws::WeightStructure) = [weight(ws) for ws in weight_spaces(ws)]
118-
weight(ws::WeightStructure, i::Integer) = weight(weight_spaces(ws)[i])
119-
nweights(ws::WeightStructure) = length(weight_spaces(ws))
130+
131+
weights(ws::WeightStructure) = ws.weights
132+
weight_size(ws::WeightStructure) = length(first(weights(ws)))
133+
space_dim(ws::WeightStructure) = size(ws[first(weights(ws))])
134+
weight(ws::WeightStructure, i::Integer) = weights(ws)[i]
135+
nweights(ws::WeightStructure) = length(weights(ws))
120136
dims(ws::WeightStructure) = [dim(M) for M in weight_spaces(ws)]
121137

122138
function Base.show(io::IO, ws::WeightStructure)
@@ -126,30 +142,46 @@ function Base.show(io::IO, ws::WeightStructure)
126142
print(io, " max weight space dimension: ", maximum(dims(ws)))
127143
end
128144

129-
Base.getindex(ws::WeightStructure, i::Integer) = ws.weight_spaces[i]
145+
Base.length(ws::WeightStructure) = nweights(ws)
130146
Base.getindex(ws::WeightStructure, weight::Vector{Int}) = ws.dict[weight]
147+
Base.getindex(ws::WeightStructure, i::Integer) = ws[weight(ws, i)]
148+
Base.setindex!(ws::WeightStructure, ws_new::WeightSpace, weight::Vector{Int}) = ws.dict[weight] = ws_new
131149
Base.haskey(ws::WeightStructure, weight::Vector{Int}) = haskey(ws.dict, weight)
132150

133-
function Base.push!(ws::WeightStructure, wv::WeightVector)
134-
if haskey(ws, weight(wv))
135-
ws.dict[weight(wv)] = hcat(ws[weight(wv)], space(wv))
151+
function Base.iterate(ws::WeightStructure, state=1)
152+
state > nweights(ws) && return nothing
153+
return (ws[state], state+1)
154+
end
155+
156+
function Base.push!(ws::WeightStructure, w_space::WeightSpace)
157+
if haskey(ws, weight(w_space))
158+
ws[weight(w_space)] = hcat(ws[weight(w_space)], w_space)
136159
else
137-
wsp = WeightSpace(wv)
138-
push!(ws.weight_spaces, wsp)
139-
ws.dict[weight(wv)] = space(wsp)
160+
push!(weights(ws), weight(w_space))
161+
ws[weight(w_space)] = w_space
140162
end
163+
return ws
141164
end
142165

143-
function sum_weight_structure(ws::WeightStructure, d::Integer)
144-
new_weight_spaces = [zeros(ComplexF64, space_dim(ws)*d, size(M, 2)*d) for M in weight_spaces(ws)]
145-
for (M, new_M) in zip(weight_spaces(ws), new_weight_spaces)
146-
for j in 1:d
147-
new_M[(1:space_dim(ws)) .+ (j-1)*space_dim(ws), (1:size(M,2)) .+ (j-1)*size(M,2)] = M
148-
end
149-
end
150-
return WeightStructure(weights(ws), new_weight_spaces)
166+
Base.push!(ws::WeightStructure, wv::WeightVector) = push!(ws, WeightSpace(wv))
167+
168+
function Base.:(ws1::WeightStructure, ws2::WeightStructure)
169+
new_spaces = [w_space₁ w_space₂ for w_space₁ in ws1, w_space₂ in ws2]
170+
return WeightStructure([ws for ws in new_spaces if !isnothing(ws)])
151171
end
152172

173+
Base.:(ws::Vector{WeightStructure}) = reduce(, ws)
174+
175+
# function sum_weight_structure(ws::WeightStructure, d::Integer)
176+
# new_weight_spaces = [zeros(ComplexF64, space_dim(ws)*d, size(M, 2)*d) for M in weight_spaces(ws)]
177+
# for (M, new_M) in zip(weight_spaces(ws), new_weight_spaces)
178+
# for j in 1:d
179+
# new_M[(1:space_dim(ws)) .+ (j-1)*space_dim(ws), (1:size(M,2)) .+ (j-1)*size(M,2)] = M
180+
# end
181+
# end
182+
# return WeightStructure(weights(ws), new_weight_spaces)
183+
# end
184+
153185
function sym_weight_structure(ws::WeightStructure, d::Integer, mexps::Vector{<:SparseVector})
154186
d = Int(d)
155187
d == 0 && return WeightStructure([zeros(Int, weight_size(ws))], [[1;;]])
@@ -241,5 +273,4 @@ coefficients(we::WeightExpression) = we.coeffs
241273
basis(we::WeightExpression) = we.basis
242274
weight(we::WeightExpression) = we.weight
243275
expression(we::WeightExpression) = dot(coefficients(we), to_expressions(basis(we)))
244-
245276
WeightVector(we::WeightExpression) = WeightVector(weight(we), coefficients(we))

0 commit comments

Comments
 (0)