# Broadcasting with vectors of static vectors

**URL:** https://discourse.julialang.org/t/broadcasting-with-vectors-of-static-vectors/12693
**Category:** General Usage
**Tags:** broadcast
**Created:** [July 27, 2018, 9:47pm UTC](https://discourse.julialang.org/t/broadcasting-with-vectors-of-static-vectors/12693 "2018-07-27T21:47:12Z")
**Posts on this page:** 12
**Page:** 1

<div class="post-metadata">

### Author: ![tomlee](https://avatars.discourse-cdn.com/v4/letter/t/f08c70/32.png) [@tomlee](https://discourse.julialang.org/u/tomlee)
#### Post date: [July 27, 2018, 9:47pm UTC](https://discourse.julialang.org/t/broadcasting-with-vectors-of-static-vectors/12693/1 "2018-07-27T21:47:12Z")

</div>

Any advice on how to broadcast vectors of `SVector`s in Julia 0.7?

eg:

```julia
julia> using StaticArrays

julia> const Vec = SVector{3, Float64}
SArray{Tuple{3},Float64,1,3}

julia> a=[Vec(i,i,i) for i in 1:5]
5-element Array{SArray{Tuple{3},Float64,1,3},1}:
 [1.0, 1.0, 1.0]
 [2.0, 2.0, 2.0]
 [3.0, 3.0, 3.0]
 [4.0, 4.0, 4.0]
 [5.0, 5.0, 5.0]

julia> a .+ Vec(2,2,2)
ERROR: DimensionMismatch("arrays could not be broadcast to a common size")
Stacktrace:
 [1] _bcs1 at ./broadcast.jl:444 [inlined]
 [2] _bcs at ./broadcast.jl:438 [inlined]
 [3] broadcast_shape at ./broadcast.jl:432 [inlined]
 [4] combine_axes at ./broadcast.jl:427 [inlined]
 [5] instantiate at ./broadcast.jl:266 [inlined]
 [6] materialize(::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1},Nothing,typeof(+),Tuple{Array{SArray{Tuple{3},Float64,1,3},1},SArray{Tuple{3},Float64,1,3}}}) at ./broadcast.jl:729
 [7] top-level scope at none:0

```

Or is this just some crazy dream?

---

<div class="post-metadata">

### Author: ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)
#### Post date: [July 27, 2018, 9:59pm UTC](https://discourse.julialang.org/t/broadcasting-with-vectors-of-static-vectors/12693/2 "2018-07-27T21:59:02Z")

</div>

Broadcasting works only on the outermost shape of each and every argument. As you’ve written it, you’re attempting to broadcast a 5-element vector and a 3-element vector.

Now, what you want is for the 3-element vector to behave like a “scalar” — that is, broadcast should repeat it for each element of the 5-element vector. To do that, you can “protect” it inside a 1-element container like a tuple:

```julia
julia> a .+ (Vec(2,2,2),)
5-element Array{SArray{Tuple{3},Float64,1,3},1}:
 [3.0, 3.0, 3.0]
 [4.0, 4.0, 4.0]
 [5.0, 5.0, 5.0]
 [6.0, 6.0, 6.0]
 [7.0, 7.0, 7.0]

```

Note that this doesn’t really have anything to do with StaticArrays — except for the fact that you might be slightly more likely to think of a static vector as a “scalar-like” thing unto itself.

---

<div class="post-metadata">

### Author: ![Juser](https://avatars.discourse-cdn.com/v4/letter/j/34f0e0/32.png) [@Juser](https://discourse.julialang.org/u/Juser)
#### Post date: [July 27, 2018, 10:02pm UTC](https://discourse.julialang.org/t/broadcasting-with-vectors-of-static-vectors/12693/3 "2018-07-27T22:02:57Z")

</div>

@mbauman, won’t this apply + rather than .+? This should yield the same result, but + under-performs .+ for speed (IIRC).

The poor-man’s solution that I was going to suggest was to write your own addition function that iterates over vectors and then applies .+ to each vector. (Or, better yet, that goes element-by-element.)

---

<div class="post-metadata">

### Author: ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)
#### Post date: [July 27, 2018, 10:08pm UTC](https://discourse.julialang.org/t/broadcasting-with-vectors-of-static-vectors/12693/4 "2018-07-27T22:08:16Z")

</div>

> [@Juser](#):
>
> won’t this apply + rather than .+? This should yield the same result, but + under-performs .+ for speed (IIRC).

Yes, it will apply `+` elementwise — broadcasting only works at the outermost level. It should have the same performance in this case, but it’s true that it won’t fuse if there are other operations.

---

<div class="post-metadata">

### Author: ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)
#### Post date: [July 27, 2018, 10:10pm UTC](https://discourse.julialang.org/t/broadcasting-with-vectors-of-static-vectors/12693/5 "2018-07-27T22:10:50Z")

</div>

How about  
`[v .+ Vec(2, 2, 2) for v in a]`  
?

---

<div class="post-metadata">

### Author: ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)
#### Post date: [July 27, 2018, 10:59pm UTC](https://discourse.julialang.org/t/broadcasting-with-vectors-of-static-vectors/12693/6 "2018-07-27T22:59:41Z")

</div>

In case you ever wonder how to deal with something thats nested very deep, I think I found an alright way of making a function that recursively broadcasts a single argument function. Here’s your example:

```julia
using StaticArrays
const Vec = SVector{3, Float64}

isbroadcastscalar(x) = Base.Broadcast.BroadcastStyle(typeof(x)) == Base.Broadcast.DefaultArrayStyle{0}()
function recursive_broadcast(f::Function)
    function (args...)
        if isbroadcastscalar(arr)
            f(arr)
        else
            recursive_broadcast(f).(arr)
        end
    end
end

a=[Vec(i,i,i) for i in 1:5]
b = Vec(2,2,2)

julia> recursive_broadcast(x -> x + b)(a)
5-element Array{SArray{Tuple{3},Any,1,3},1}:
 [[3.0, 3.0, 3.0], [3.0, 3.0, 3.0], [3.0, 3.0, 3.0]]
 [[4.0, 4.0, 4.0], [4.0, 4.0, 4.0], [4.0, 4.0, 4.0]]
 [[5.0, 5.0, 5.0], [5.0, 5.0, 5.0], [5.0, 5.0, 5.0]]
 [[6.0, 6.0, 6.0], [6.0, 6.0, 6.0], [6.0, 6.0, 6.0]]
 [[7.0, 7.0, 7.0], [7.0, 7.0, 7.0], [7.0, 7.0, 7.0]]

```

---

<div class="post-metadata">

### Author: ![tomlee](https://avatars.discourse-cdn.com/v4/letter/t/f08c70/32.png) [@tomlee](https://discourse.julialang.org/u/tomlee)
#### Post date: [July 28, 2018, 12:21am UTC](https://discourse.julialang.org/t/broadcasting-with-vectors-of-static-vectors/12693/7 "2018-07-28T00:21:41Z")

</div>

Thanks everyone! I didn’t know wrapping with a tuple would work to force something to act as a scalar. Good to know!

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [July 29, 2018, 5:57pm UTC](https://discourse.julialang.org/t/broadcasting-with-vectors-of-static-vectors/12693/8 "2018-07-29T17:57:48Z")

</div>

It is [documented in the Arrays chapter](https://docs.julialang.org/en/latest/manual/arrays/#Broadcasting-1):

> treats any argument that is not an array, tuple or `Ref` (except for `Ptr`) as a “scalar”

but perhaps that could be emphasized further.

---

<div class="post-metadata">

### Author: ![tomlee](https://avatars.discourse-cdn.com/v4/letter/t/f08c70/32.png) [@tomlee](https://discourse.julialang.org/u/tomlee)
#### Post date: [July 29, 2018, 11:19pm UTC](https://discourse.julialang.org/t/broadcasting-with-vectors-of-static-vectors/12693/9 "2018-07-29T23:19:25Z")

</div>

When you say that “it” is documented - are you referring to the fact that my initial example will attempt to broadcast a 5-element vector and a 3-element vector, or that wrapping in another container negates this?

I understood why my initial example behaved as it did - that is obvious/documented enough IMO. I wasn’t clear on how to change the expression to make it do what I wanted. I haven’t seen it documented that wrapping an argument in a one-element container makes that argument act as a scalar. I would take a stab at helping document it, but I don’t fully understand why it works like that.

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [July 30, 2018, 6:00am UTC](https://discourse.julialang.org/t/broadcasting-with-vectors-of-static-vectors/12693/10 "2018-07-30T06:00:39Z")

</div>

I meant that the ways of “escaping” broadcast are documented.

---

<div class="post-metadata">

### Author: ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)
#### Post date: [July 30, 2018, 2:44pm UTC](https://discourse.julialang.org/t/broadcasting-with-vectors-of-static-vectors/12693/11 "2018-07-30T14:44:32Z")

</div>

> [@tomlee](#):
>
> I haven’t seen it documented that wrapping an argument in a one-element container makes that argument act as a scalar.

Perhaps the language of “protecting” or “escaping” makes this feel like a special case — but it’s not at all. It’s just that a one-element container will repeat that one element such that it fills the final shape of the broadcast operation. That is, it just falls out of how broadcast works on the outer shapes of containers.

We could probably do a better job of explaining this in the manual, and an example like this would definitely be a nice addition.

---

<div class="post-metadata">

### Author: ![tomlee](https://avatars.discourse-cdn.com/v4/letter/t/f08c70/32.png) [@tomlee](https://discourse.julialang.org/u/tomlee)
#### Post date: [July 30, 2018, 10:07pm UTC](https://discourse.julialang.org/t/broadcasting-with-vectors-of-static-vectors/12693/12 "2018-07-30T22:07:26Z")

</div>

> [@mbauman](#):
>
> It’s just that a one-element container will repeat that one element such that it fills the final shape of the broadcast operation.

This! This is what I was missing in my understanding. Thanks!

I’ll try to find some time to contribute to the manual (the least I can do given how much value I have got out of julia.)
