Implementing broadcasting for a nested `Vector` with a scalar

loonatick-src
Tue, 10 Jan 2023 14:52:02 +0000
General Usage

Say I have a struct one of whose members has the type

RaggedVector{T} = Vector{Vector{T}}

And if we construct two conformal instances of this type

xs = [[1, 2, 3],
      [4],
      [5, 6]]
ys = [[6, 5, 4],
      [3],
      [2, 1]]

Then the two can be broadcasted together without problems

julia> zs = xs .+ ys
3-element Vector{Vector{Int64}}:
 [7, 7, 7]
 [7]
 [7, 7]

But, when one of the operands is a scalar, the materialization of the broadcast results in <:Vector + <:Number, which does not work.

julia> zs = xs .+ 2.0
ERROR: MethodError: no method matching +(::Vector{Int64}, ::Float64)
...

So, I need to make nested vector-scalar broadcast work.

I went through the customizing broadcast section of the docs and tried to follow the functions and types in the call graph of broadcasting non-standard types like sparse arrays, and it seems that I need to create a new broadcast style that results from the combination of the two operand broadcast styles along with a dispatch on materialize, but I am struggling to figure it out completely.

Edit: I am still working on making this work using the suggestions here, and will post the final working code. It might not be “production worthy” though because most likely I will have to settle for type piracy.

8 posts - 6 participants