# Writing \`broadcast\_c\` for struct with custom indexing

**URL:** https://discourse.julialang.org/t/writing-broadcast-c-for-struct-with-custom-indexing/9071
**Category:** General Usage
**Created:** [February 14, 2018, 10:23pm UTC](https://discourse.julialang.org/t/writing-broadcast-c-for-struct-with-custom-indexing/9071 "2018-02-14T22:23:53Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![EP-Guy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ep-guy/32/3442_2.png) [@EP-Guy](https://discourse.julialang.org/u/EP-Guy)
#### Post date: [February 14, 2018, 10:23pm UTC](https://discourse.julialang.org/t/writing-broadcast-c-for-struct-with-custom-indexing/9071/1 "2018-02-14T22:23:53Z")

</div>

I have a custom type

```julia
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
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
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](https://discourse.julialang.org/t/broadcast-for-custom-type/3497/3) which suggested I do

```julia
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.

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [February 14, 2018, 10:30pm UTC](https://discourse.julialang.org/t/writing-broadcast-c-for-struct-with-custom-indexing/9071/2 "2018-02-14T22:30:29Z")

</div>

I think the nicer way to handle this is to make broadcast just apply to the `arr` fields. I would make the `fields` be an `OrderedDict` so you have a canonical numbers for the array and then let broadcast run down the array directly, by passing the slow dictionary access.

BTW,

```julia
arr::Array{T}

```

that’s not type-stable since arrays need the dimension.

One thing to note too is that we have some proof-of-concept implementations of arrays with naming schemes here:

[https://github.com/JuliaDiffEq/LabelledArrays.jl](https://github.com/JuliaDiffEq/LabelledArrays.jl)

On v0.7 we want to make that compile away the cost of named access via either `a.b` overloads or `a[:b]` literals, but for now it does have a small cost.

But even on v0.6 the StaticArray version should be fast.

---

<div class="post-metadata">

### Author: ![EP-Guy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ep-guy/32/3442_2.png) [@EP-Guy](https://discourse.julialang.org/u/EP-Guy)
#### Post date: [February 14, 2018, 11:16pm UTC](https://discourse.julialang.org/t/writing-broadcast-c-for-struct-with-custom-indexing/9071/3 "2018-02-14T23:16:54Z")

</div>

I’m looking at LabelledArrays.jl, except I’m getting an error running the example code for constructing LMArrays and LArrays (also, I think the single line constructor macro names are wrong in the README).

Copy pasting

```julia
names = @SArray [:a,:b,:c]
values = @MArray [1,2,3]

```

gives

```julia
julia> A = LMArray(names,values)
3-element LArray{Tuple{3},Int64,1,3}:
Error showing value of type LArray{Tuple{3},Int64,1,3}:
ERROR: ArgumentError: invalid index: (1, 1)

```

Additionally, would this allow indexing by multiple names at once? e.g. `A[:a,:b]`? I often need access to several elements at once for easy vector math (`:r -> :rx, :ry, :rz`).

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [February 15, 2018, 12:31am UTC](https://discourse.julialang.org/t/writing-broadcast-c-for-struct-with-custom-indexing/9071/4 "2018-02-15T00:31:30Z")

</div>

That error is just in the display. It’s being made correctly but it’s not printing correctly. That’s fine though: the library is not released and still being worked on so think of it as a preview.

> [@EP-Guy](#):
>
> Additionally, would this allow indexing by multiple names at once? e.g. A[:a,:b]? I often need access to several elements at once for easy vector math (:r -\> :rx, :ry, :rz).

It doesn’t handle this. That’s a good idea though.

---

<div class="post-metadata">

### Author: ![EP-Guy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ep-guy/32/3442_2.png) [@EP-Guy](https://discourse.julialang.org/u/EP-Guy)
#### Post date: [February 15, 2018, 5:44am UTC](https://discourse.julialang.org/t/writing-broadcast-c-for-struct-with-custom-indexing/9071/5 "2018-02-15T05:44:35Z")

</div>

Do I have to do anything special to use LMArray in an in-place function to integrate? Trying to solve an ODEProblem this gives a ‘no method matching’ error that looks related to uType.

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [February 16, 2018, 9:45pm UTC](https://discourse.julialang.org/t/writing-broadcast-c-for-struct-with-custom-indexing/9071/6 "2018-02-16T21:45:59Z")

</div>

Looks like this library still needs work. Now that I know that someone is interested I’ll move it up the priority list. Ping me every once in awhile here or in the chat to force me to do it 😛

---

<div class="post-metadata">

### Author: ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)
#### Post date: [December 12, 2018, 11:46am UTC](https://discourse.julialang.org/t/writing-broadcast-c-for-struct-with-custom-indexing/9071/7 "2018-12-12T11:46:50Z")

</div>

The friendliest of pings: 🏓

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [December 12, 2018, 3:36pm UTC](https://discourse.julialang.org/t/writing-broadcast-c-for-struct-with-custom-indexing/9071/8 "2018-12-12T15:36:31Z")

</div>

LabelledArrays works and is registered now.

Julia changed its broadcasting implementation. You can now read about it here. [Interfaces · The Julia Language](https://docs.julialang.org/en/v1/manual/interfaces/index.html#man-interfaces-broadcasting-1)
