1515
1616Base. show(io:: IO , :: MIME"text/plain" , w:: Weight ) = print(io, " Weight: " , w. weight)
1717Base. show(io:: IO , w:: Weight ) = print(io, w. weight)
18- Base. zero(:: Type{Weight{T}} ) where T = Weight(zero(T ))
18+ Base. zero(:: Type{Weight{T}} , n ) where T = Weight(zeros(T, n ))
1919Base. zero(w:: Weight ) = Weight(zero(w. weight))
2020Base. vcat(w₁:: Weight{T} , w₂:: Weight{T} ) where T = Weight(vcat(w₁. weight, w₂. weight))
2121Base. hash(w:: Weight , h:: UInt ) = hash(w. weight, h)
2222Base.:(== )(w₁:: Weight , w₂:: Weight ) = w₁. weight == w₂. weight
2323Base.:* (n:: Number , w:: Weight ) = Weight(n* w. weight)
2424Base.:+ (w₁:: Weight{T} , w₂:: Weight{T} ) where {T} = Weight{T}(w₁. weight + w₂. weight)
25+ Base. promote_rule(:: Type{Weight{T}} , :: Type{Weight{S}} ) where {T,S} = Weight{promote_type(T, S)}
2526
2627struct WeightVector{T, W<: Weight }
2728 weight:: W
@@ -40,25 +41,26 @@ function Base.show(io::IO, wv::WeightVector)
4041 print(io, " WeightVector with weight $(weight(wv)) " )
4142end
4243
43- struct WeightSpace{F, T <: AbstractVectorSpace{F} , W<: Weight } # TODO : remove F?
44+ struct WeightSpace{T <: AbstractVectorSpace , W<: Weight }
4445 weight:: W
4546 space:: T
4647end
4748
4849WeightSpace(weight:: Vector , space:: Vector ) = WeightSpace(Weight(weight), MatrixVectorSpace(space))
49- WeightSpace{F, T,W}(wv:: WeightVector ) where {F, T,W} = WeightSpace{F, T,W}(weight(wv), T(vector(wv)))
50+ WeightSpace{T,W}(wv:: WeightVector ) where {T,W} = WeightSpace{T,W}(weight(wv), T(vector(wv)))
5051
5152Base. convert(
52- :: Type{WeightSpace{F, T, W}} ,
53+ :: Type{WeightSpace{T, W}} ,
5354 ws:: WeightSpace
54- ) where {F, T<: AbstractVectorSpace{F} , W<: Weight } = WeightSpace(
55+ ) where {T<: AbstractVectorSpace , W<: Weight } = WeightSpace(
5556 convert(W, weight(ws)),
5657 convert(T, space(ws))
5758)
5859
5960weight(ws:: WeightSpace ) = ws. weight
6061space(ws:: WeightSpace ) = ws. space
6162dim(ws:: WeightSpace ) = dim(space(ws))
63+ field_type(:: WeightSpace{T} ) where {T} = field_type(T)
6264
6365function Base. show(io:: IO , :: MIME"text/plain" , ws:: WeightSpace )
6466 println(io, " WeightSpace of dimension $(dim(ws)) " )
@@ -74,12 +76,12 @@ function Base.iterate(ws::WeightSpace, state=1)
7476 return (WeightVector(weight(ws), basis(space(ws), state)), state+ 1 )
7577end
7678
77- struct WeightStructure{F, T<: AbstractVectorSpace{F} , W<: Weight }
79+ struct WeightStructure{T<: AbstractVectorSpace , W<: Weight }
7880 weights:: Vector{W} # Ordering needed for sym_weight_structure
79- dict:: Dict{W, WeightSpace{F, T, W}} # TODO : new type for WeightSpace{F,T,W}? Do all spaces have to be of the same type?
81+ dict:: Dict{W, WeightSpace{T, W}} # TODO : new type for WeightSpace{F,T,W}? Do all spaces have to be of the same type?
8082end
8183
82- WeightStructure{F, T,W}() where {F, T,W} = WeightStructure{F, T,W}(Weight[], Dict())
84+ WeightStructure{T,W}() where {T,W} = WeightStructure{T,W}(Weight[], Dict())
8385
8486WeightStructure(
8587 weights:: Vector{<:Weight} ,
@@ -98,27 +100,31 @@ WeightStructure(
98100)
99101
100102# TODO : improve
101- function WeightStructure(w_spaces:: Vector{<:WeightSpace{F, T,W}} ) where {F, T,W}
102- ws = WeightStructure{F, T,W}()
103+ function WeightStructure(w_spaces:: Vector{<:WeightSpace{T,W}} ) where {T,W}
104+ ws = WeightStructure{T,W}()
103105 for w_space in w_spaces
104106 push!(ws, w_space)
105107 end
106108 return ws
107109end
108110
109111Base. convert(
110- :: Type{WeightStructure{F, T, W}} ,
112+ :: Type{WeightStructure{T, W}} ,
111113 ws:: WeightStructure
112- ) where {F, T<: AbstractVectorSpace{F} , W<: Weight } = WeightStructure(
114+ ) where {T<: AbstractVectorSpace , W<: Weight } = WeightStructure(
113115 convert(Vector{W}, ws. weights),
114- convert(Dict{W, WeightSpace{F, T, W}}, ws. dict)
116+ convert(Dict{W, WeightSpace{T, W}}, ws. dict)
115117)
116118
117119weights(ws:: WeightStructure ) = ws. weights
118120weights(ws:: WeightStructure , inds... ) = getindex(weights(ws), inds... )
119121nweights(ws:: WeightStructure ) = length(ws. weights)
120- weight(ws:: WeightStructure , i:: Integer ) = weights(ws)[i]
121- weight_space(ws:: WeightStructure , i:: Integer ) = ws[weight(ws, i)]
122+ weight(ws:: WeightStructure , i:: Integer ) = weights(ws)[i] # TODO : remove?
123+ weight_space(
124+ ws:: WeightStructure ,
125+ i:: Integer ;
126+ as_space:: Bool = false
127+ ) = as_space ? space(ws[weight(ws, i)]) : ws[weight(ws, i)]
122128weight_spaces(
123129 ws:: WeightStructure ;
124130 as_spaces:: Bool = false
@@ -131,12 +137,14 @@ weight_spaces(
131137dims(ws:: WeightStructure ) = [dim(space(ws[w])) for w in weights(ws)]
132138dim(ws:: WeightStructure ) = sum(dims(ws))
133139Base. length(ws:: WeightStructure ) = nweights(ws)
134- Base. getindex(ws:: WeightStructure{F,T,W} , weight:: W ) where {F,T,W<: Weight } = ws. dict[weight]
140+ Base. isempty(ws:: WeightStructure ) = isempty(weights(ws))
141+ Base. getindex(ws:: WeightStructure{T,W} , weight:: W ) where {T,W<: Weight } = ws. dict[weight]
135142Base. getindex(ws:: WeightStructure , i:: Integer ) = ws[weight(ws, i)]
136143Base. setindex!(ws:: WeightStructure , ws_new:: WeightSpace , weight:: Weight ) = ws. dict[weight] = ws_new
137144Base. haskey(ws:: WeightStructure , w:: Weight ) = haskey(ws. dict, w)
138145zero_weight(ws:: WeightStructure ) = zero(first(weights(ws)))
139- field_space(:: WeightStructure{F, T} ) where {F, T} = field_space(T)
146+ field_space(:: WeightStructure{T} ) where {T} = field_space(T)
147+ field_type(:: WeightStructure{T} ) where {T} = field_type(T)
140148
141149function Base. show(io:: IO , :: MIME"text/plain" , ws:: WeightStructure )
142150 println(io, " WeightStructure of $(dim(ws)) -dimensional vector space" )
@@ -165,9 +173,9 @@ function Base.push!(ws::WeightStructure, w_space::WeightSpace)
165173 return ws
166174end
167175
168- Base. push!(ws:: WeightStructure{F, T,W} , wv:: WeightVector ) where {F, T,W} = push!(ws, WeightSpace{F, T,W}(wv))
176+ Base. push!(ws:: WeightStructure{T,W} , wv:: WeightVector ) where {T,W} = push!(ws, WeightSpace{T,W}(wv))
169177
170- function sym(ws:: WeightStructure{F, T,W} , d:: Int ) where {F, T, W}
178+ function sym(ws:: WeightStructure{T,W} , d:: Int ) where {T, W}
171179 d == 0 && return WeightStructure([WeightSpace(zero_weight(ws), field_space(ws))])
172180 d == 1 && return ws
173181 combs = multiexponents(; degree= d, nvars= nweights(ws))
@@ -180,10 +188,31 @@ function sym(ws::WeightStructure{F,T,W}, d::Int) where {F, T, W}
180188 new_weights_dict[w] = [comb]
181189 end
182190 end
183- new_ws = WeightStructure{F, T,W}()
191+ new_ws = WeightStructure{T,W}()
184192 for (weight, combs) in new_weights_dict
185193 w_sps = [* (weight_spaces(ws, comb. nzind; as_spaces= true ), comb. nzval) for comb in combs]
186194 push!(new_ws, WeightSpace(weight, + (w_sps... )))
187195 end
188196 return new_ws
197+ end
198+
199+ function tensor(ws₁:: WeightStructure{T,W} , ws₂:: WeightStructure{T,W} ) where {T, W}
200+ combs = Base. Iterators. product(1 : nweights(ws₁), 1 : nweights(ws₂))
201+ new_weights_dict = Dict{W, Vector{typeof(first(combs))}}()
202+ for comb in combs
203+ w = weight(ws₁, comb[1 ]) + weight(ws₂, comb[2 ])
204+ val = get(new_weights_dict, w, nothing )
205+ if isnothing(val)
206+ new_weights_dict[w] = [comb]
207+ else
208+ push!(new_weights_dict[w], comb)
209+ end
210+ end
211+ new_ws = WeightStructure{T,W}()
212+ for (weight, combs) in new_weights_dict
213+ w_sps = [* ([weight_space(ws₁, comb[1 ]; as_space= true ), weight_space(ws₂, comb[2 ]; as_space= true )]; in_rref= false ) for comb in combs]
214+ total_ws = + (w_sps... ; in_rref= false )
215+ push!(new_ws, WeightSpace(weight, total_ws))
216+ end
217+ return new_ws
189218end
0 commit comments