# Implementing broadcasting for a nested \`Vector\` with a scalar

**URL:** https://discourse.julialang.org/t/implementing-broadcasting-for-a-nested-vector-with-a-scalar/92760
**Category:** General Usage
**Tags:** question, broadcasting, multiple-dispatch
**Created:** [January 10, 2023, 2:52pm UTC](https://discourse.julialang.org/t/implementing-broadcasting-for-a-nested-vector-with-a-scalar/92760 "2023-01-10T14:52:02Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![loonatick-src](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/loonatick-src/32/32248_2.png) [@loonatick-src](https://discourse.julialang.org/u/loonatick-src)
#### Post date: [January 10, 2023, 2:52pm UTC](https://discourse.julialang.org/t/implementing-broadcasting-for-a-nested-vector-with-a-scalar/92760/1 "2023-01-10T14:52:03Z")

</div>

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

```julia
RaggedVector{T} = Vector{Vector{T}}

```

And if we construct two conformal instances of this type

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

```

Then the two can be broadcasted together without problems

```julia
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
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](https://docs.julialang.org/en/v1/manual/interfaces/#man-interfaces-broadcasting) 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.

---

<div class="post-metadata">

### Author: ![br0wnelvis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/br0wnelvis/32/45751_2.png) [@br0wnelvis](https://discourse.julialang.org/u/br0wnelvis)
#### Post date: [January 10, 2023, 3:09pm UTC](https://discourse.julialang.org/t/implementing-broadcasting-for-a-nested-vector-with-a-scalar/92760/2 "2023-01-10T15:09:07Z")

</div>

You can add a line at the beginning of your file extending the operator

```julia
import Base: +
+(xs::Vector{Q}, fl::T) where Q <: Real where T <: Real = xs .+ fl

```

To extend the ` +` operator for your needs. Observe that you need to import the operator in order to extend it.

---

<div class="post-metadata">

### Author: ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)
#### Post date: [January 10, 2023, 3:26pm UTC](https://discourse.julialang.org/t/implementing-broadcasting-for-a-nested-vector-with-a-scalar/92760/3 "2023-01-10T15:26:15Z")

</div>

You could define

```julia
dotplus(x, y) = x .+ y

```

Broadcasted `dotplus` will then work with both scalars and nested vectors.

```julia
julia> dotplus.(xs, ys)
3-element Vector{Vector{Int64}}:
 [7, 7, 7]
 [7]
 [7, 7]

julia> dotplus.(xs, 2.0)
3-element Vector{Vector{Float64}}:
 [3.0, 4.0, 5.0]
 [6.0]
 [7.0, 8.0]

```

---

<div class="post-metadata">

### Author: ![fatteneder](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fatteneder/32/33991_2.png) [@fatteneder](https://discourse.julialang.org/u/fatteneder)
#### Post date: [January 10, 2023, 3:30pm UTC](https://discourse.julialang.org/t/implementing-broadcasting-for-a-nested-vector-with-a-scalar/92760/4 "2023-01-10T15:30:31Z")

</div>

Note that this is technically type piracy.

---

<div class="post-metadata">

### Author: ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)
#### Post date: [January 10, 2023, 4:56pm UTC](https://discourse.julialang.org/t/implementing-broadcasting-for-a-nested-vector-with-a-scalar/92760/5 "2023-01-10T16:56:48Z")

</div>

I just realised: these days can also do `(.+).(xs, 2.0)` without defining `dotplus`.

---

<div class="post-metadata">

### Author: ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)
#### Post date: [January 10, 2023, 9:27pm UTC](https://discourse.julialang.org/t/implementing-broadcasting-for-a-nested-vector-with-a-scalar/92760/6 "2023-01-10T21:27:11Z")

</div>

the previous solutions are valid if T\<:Real (In practice, with only two levels of nesting.)  
In the more general case where T=Any something like this might work

```julia
pnest!(xs::Int,n)=xs+n
pnest!(xs::Vector{Int},n)=xs.+n
pnest!(xs,n)=[xs[i]=pnest!(xsi,n) for (i,xsi) in enumerate(xs)]

```

the not mutating version

```julia
julia> xs
3-element Vector{Vector{Any}}:
 [1, 2, 3]
 [4]
 [5, Any[6, [7, 8]]]

julia> 

       pnest(xs::Int,n)=xs+n
       pnest(xs::Vector{Int},n)=xs.+n
       pnest(xs,n)=[pnest(xsi,n) for xsi in xs]
pnest (generic function with 3 methods)

julia> 

julia> 

julia> pnest(xs,-11)
3-element Vector{Vector}:
 [-10, -9, -8]
 [-7]
 Any[-6, Any[-5, [-4, -3]]]

julia> pnest(xs,-11)
3-element Vector{Vector}:
 [-10, -9, -8]
 [-7]
 Any[-6, Any[-5, [-4, -3]]]

```

---

<div class="post-metadata">

### Author: ![loonatick-src](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/loonatick-src/32/32248_2.png) [@loonatick-src](https://discourse.julialang.org/u/loonatick-src)
#### Post date: [January 11, 2023, 2:56am UTC](https://discourse.julialang.org/t/implementing-broadcasting-for-a-nested-vector-with-a-scalar/92760/7 "2023-01-11T02:56:29Z")

</div>

Thank you, this works the intended way, but I want to avoid type piracy as @fatteneder pointed out.

---

<div class="post-metadata">

### Author: ![torrance](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/torrance/32/38990_2.png) [@torrance](https://discourse.julialang.org/u/torrance)
#### Post date: [January 11, 2023, 6:36am UTC](https://discourse.julialang.org/t/implementing-broadcasting-for-a-nested-vector-with-a-scalar/92760/8 "2023-01-11T06:36:50Z")

</div>

The solution by @Per is best here, but in my own code I often use the equivalent:

```julia
broadcast(.+, xs, 2) == (.+).(xs, 2)

```

Sometimes this is preferable as you can more easily pass in an anonymous function if you’re doing anything a little more involved than just addition, and also in my own code those extra `.` start to get a little too much for my liking. YYMV, of course.
