I have a custom type
struct State{T} <: AbstractArray{T,1}
fields::Dict{Symbol, UnitRange{Int64}}
arr::Array{T}
end
Base.size(S::State) = size(S.arr)
Base.IndexStyle(::Type{<:State}) = IndexLinear()
Base.getindex(S::State{T}, inds::Vararg{Int,1}) where {T} = S.arr[inds...]
Base.getindex(S::State{T}, ind::Symbol) where {T} = S.arr[S.fields[ind]]
Base.setindex!(S::State{T}, val, inds::Vararg{Int,1}) where {T} = (S.arr[inds...] = val)
that allows indexing with symbols, e.g.
julia> state0 = State(Dict([(:r, 1:3), (:v, 4:6)]), [10; 11; 12; 13; 14; 15])
6-element Constants.State{Int64}:
10
11
12
13
14
15
julia> state0[:r]
3-element Array{Int64,1}:
10
11
12
I plan on using this with DifferentialEquations.jl, but I’m currently having trouble getting broadcasting to work. For example, I cannot do
julia> dstate = deepcopy(state0)
6-element Constants.State{Int64}:
10
11
12
13
14
15
julia> dstate[:r] .= 5.0
ERROR: ArgumentError: invalid index: r
I found Broadcast for custom type - #3 by fengyang.wang which suggested I do
Base.Broadcast._containertype(::Type{<:State}) = State
Base.Broadcast.promote_containertype(::Type{State}, _) = State
Base.Broadcast.promote_containertype(_, ::Type{State}) = State
Base.Broadcast.promote_containertype(::Type{State}, ::Type{State}) = State
but I’m having trouble implementing the last step, to write a Base.Broadcast.broadcast_c(f, ::Type{State}, _...) = ...
that makes use of my symbol indexing. It looks like implementing custom broadcasting will be improved in 0.7, but I’m stuck with 0.6 for now.