# Broadcasting across a nested array

**URL:** <https://discourse.julialang.org/t/broadcasting-across-a-nested-array/21700>\
**Category:** General Usage\
**Tags:** broadcasting\
**Created:** [March 10, 2019, 12:21pm UTC](https://discourse.julialang.org/t/broadcasting-across-a-nested-array/21700 "2019-03-10T12:21:48Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![robsmith11](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/robsmith11/32/29641_2.png) [@robsmith11](https://discourse.julialang.org/u/robsmith11)\
**Post date:** [March 10, 2019, 12:21pm UTC](https://discourse.julialang.org/t/broadcasting-across-a-nested-array/21700/1 "2019-03-10T12:21:48Z")

</div>

I was expecting the following to work:

```julia
julia> [10, 100] .+ [[5, 5], [6, 6], [7, 7]]
ERROR: DimensionMismatch("arrays could not be broadcast to a common size")

```

What is the correct syntax? Or is broadcasting only supported for scalars across arrays, not arrays across nested arrays?

---

<div class="post-metadata">

**Author:** ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)\
**Post date:** [March 10, 2019, 12:26pm UTC](https://discourse.julialang.org/t/broadcasting-across-a-nested-array/21700/2 "2019-03-10T12:26:42Z")

</div>

Try wrapping the first operand in a `Ref` to help Julia understand it is a “scalar”:

```julia
julia> Ref([10, 100]) .+ [[5, 5], [6, 6], [7, 7]]
 3-element Array{Array{Int64,1},1}:
  [15, 105]
  [16, 106]
  [17, 107]

```

  

* * *

This discussion contains a lot more details:

> [@recent broadcast changes (iterate by default), scalar struct, and \`@.\`](https://discourse.julialang.org/t/recent-broadcast-changes-iterate-by-default-scalar-struct-and/11178):
>
> The current broadcasting behavior is non-intuitive when used with @. Julia Version 0.7.0-DEV.5222, Commit 7144b6b816 (2018-05-25 20:23 UTC) This is a minimal example, stripped down from a real use case. struct Material a::Float64 end chi(m::Material, energy) = m.a / energy m1 = Material(1.0) energy = 1.5:0.5:2.5 chi1 = @. chi(m1, energy) ┌ Warning: broadcast will default to iterating over its arguments in the future. Wrap arguments of │ type `x::Material` with `Ref(x)` to ensure they b…

including some alternative ways of doing this, for example turning the “scalar” argument to a 1-Tuple:

```julia
julia> ([10, 100],) .+ [[5, 5], [6, 6], [7, 7]]
3-element Array{Array{Int64,1},1}:
 [15, 105]
 [16, 106]
 [17, 107]

```

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [March 10, 2019, 11:27pm UTC](https://discourse.julialang.org/t/broadcasting-across-a-nested-array/21700/3 "2019-03-10T23:27:15Z")

</div>

But be careful with this approach, as it’s far from general: e.g. if you replace `+` with `*` it will not work, and `/` will give surprising result.

---

<div class="post-metadata">

**Author:** ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)\
**Post date:** [March 11, 2019, 12:06am UTC](https://discourse.julialang.org/t/broadcasting-across-a-nested-array/21700/4 "2019-03-11T00:06:14Z")

</div>

> [@aplavin](#):
>
> But be careful with this approach, as it’s far from general

I would say that the technique is general in that it does broadcast the operation, whatever it is (either `+` or `*` or `/`). Of course, said operation has to be defined for the “scalar” operands, which is what the error is about in your examples.

To elaborate on your `*` example:

```julia-auto
julia> Ref([1,2]) .* [[3,4], [5,6]]
ERROR: MethodError: no method matching *(::Array{Int64,1}, ::Array{Int64,1})

```

does not work because `[1,2] * [3,4]` does not work. In other words, the `*` operator is correctly broadcasted, but this yields something which is not well defined. For example, the first item in the resulting array should be:

```julia-auto
julia> [1,2]*[3,4]
ERROR: MethodError: no method matching *(::Array{Int64,1}, ::Array{Int64,1})

```

In order to perform the element-wise product of two arrays, you’d need to broadcast the `*` operator a first time:

```julia-auto
julia> [1,2].*[3,4]
2-element Array{Int64,1}:
 3
 8

```

Therefore, it is this element-wise `*` operator which needs to be broadcasted a second time over arrays of arrays operands. One way of doing that is the following:

```julia-auto
julia> ((x,y)->(x.*y)).(Ref([1,2]), [[3,4], [5,6]])
2-element Array{Array{Int64,1},1}:
 [3, 8] 
 [5, 12]

```

which is merely a shortcut for something like:

```julia-auto
julia> elemwise_prod(x, y) = x .* y
elemwise_prod (generic function with 1 method)

julia> elemwise_prod.(Ref([1,2]), [[3,4], [5,6]])
2-element Array{Array{Int64,1},1}:
 [3, 8] 
 [5, 12]

```

---

<div class="post-metadata">

**Author:** ![robsmith11](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/robsmith11/32/29641_2.png) [@robsmith11](https://discourse.julialang.org/u/robsmith11)\
**Post date:** [March 11, 2019, 1:30am UTC](https://discourse.julialang.org/t/broadcasting-across-a-nested-array/21700/5 "2019-03-11T01:30:22Z")

</div>

Out of curiosity, is there a reason there aren’t standard element-wise operators (+,-,\*,/,^, etc.) for arrays so that broadcasting across nested arrays could be more convenient (not require 2 levels of broadcasting)?

I get that matrix multiplication and inversion should be convenient as well, but maybe other operators could have been chosen rather than overloading \* and /, as is done in other array-focused languages.

---

<div class="post-metadata">

**Author:** ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)\
**Post date:** [March 11, 2019, 8:07am UTC](https://discourse.julialang.org/t/broadcasting-across-a-nested-array/21700/6 "2019-03-11T08:07:06Z")

</div>

I think it is because, as you said, for \* you would not know whether the default semantic should be elementwise or in a matrix way.

Instead of defining by default a semantic which would be surprising for a large number of users, I would tend to think the language designers made the safe choice of erroring out. This way forces users to explicitly define what they want.

As for another operator, I don’t know. Do you have a suggestion in mind ? I actually wouldn’t be surprised if there was a set of UTF8 operators distinguishing between the two operations.

---

<div class="post-metadata">

**Author:** ![robsmith11](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/robsmith11/32/29641_2.png) [@robsmith11](https://discourse.julialang.org/u/robsmith11)\
**Post date:** [March 11, 2019, 12:50pm UTC](https://discourse.julialang.org/t/broadcasting-across-a-nested-array/21700/7 "2019-03-11T12:50:14Z")

</div>

For example, R uses %\*% for matrix multiplication, so that \* still works for element- wise multiplication of vectors or matrices.

Another language that I use, kdb+/q (an APL-like language for financial data), is similar: matrix multiplication with the `mmu` operator and elements-wise multiplication with \*.

---

<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:** [March 11, 2019, 1:19pm UTC](https://discourse.julialang.org/t/broadcasting-across-a-nested-array/21700/8 "2019-03-11T13:19:39Z")

</div>

The key to understanding Julia’s design choice is that _neither arithmetic operators nor number types get “special treatment”_:

1. `*` is just an operator like any other. It is usually defined for rings, ie objects for which some notion of multiplication (commutative or non-commutative) makes sense. This includes real and complex numbers, `ForwardDiff.Dual` numbers, matrices, strings… the list is literally endless since you can always define new methods.

2. Subtypes of `<:Number` or `<:AbstractMatrix` are types like any other. So if you prefer, you can write completely generic code, eg for a power calculation by doubling, without knowing which type you are dealing with — it is enough to know that `*` is supported.

The broadcasting machinery is designed to take care of your use case. At the moment, you have to use something like the solution by @ffevotte, which may look cumbersome but has the advantage of being transparent and consistent with the language.

Other design choices, eg like R’s, are certainly possible, but they break the generic interfaces which are highly valued by experienced Julia users.

---

<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:** [March 11, 2019, 3:43pm UTC](https://discourse.julialang.org/t/broadcasting-across-a-nested-array/21700/9 "2019-03-11T15:43:46Z")

</div>

> [@robsmith11](#):
>
> For example, R uses %\*% for matrix multiplication, so that \* still works for element- wise multiplication of vectors or matrices.

But _we do have that distinction!_ It’s the difference between `*` and `.*`. Of course, the problem you’re running into is that you want to do broadcasting down two levels, and indeed we don’t have a syntax for that operation.

While it feels like it’d be nice to support this directly with a syntax, I often find it’s best to simply use a comprehension in these cases. I also think comprehensions are much more readable than broadcasting broadcast-enabled anonymous functions (like ffevotte suggests) or a theoretical syntax that would allow us to throw more dots at the problem.

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [March 12, 2019, 7:02am UTC](https://discourse.julialang.org/t/broadcasting-across-a-nested-array/21700/10 "2019-03-12T07:02:36Z")

</div>

> [@Tamas\_Papp](#):
>
> - `*` is just an operator like any other. It is usually defined for rings, ie objects for which some notion of multiplication (commutative or non-commutative) makes sense. This includes real and complex numbers, `ForwardDiff.Dual` numbers, matrices, strings… the list is literally endless since you can always define new methods.

Vectors, tuples and arrays of numbers form a ring (and field) with elementwise operations as well, and as you say it’s not more or less special than e.g. matrices. It’s also likely that elementwise operations are way more widely used in general than matrix ones. However, in julia matrix operations certainly look like they are treated in a special way.

> the list is literally endless since you can always define new methods.

But we cannot do that for elementwise-operations field on arrays, as operators are already defined to mean matrix operations. Numpy approach sounds more reasonable _in this regard_ - there is a general `array` type as a container with elemenwise operations, and `matrix` type (which could be a zero-overhead wrapper in julia) with matrix operations.

---

<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:** [March 12, 2019, 7:23am UTC](https://discourse.julialang.org/t/broadcasting-across-a-nested-array/21700/11 "2019-03-12T07:23:22Z")

</div>

> [@aplavin](#):
>
> It’s also likely that elementwise operations are way more widely used in general than matrix ones.

I am not sure about this. Depends on what you do I guess.

> [@aplavin](#):
>
> However, in julia matrix operations certainly look like they are treated in a special way.

It is unclear what you mean here; in any case they aren’t. Matrix operations are functions like any other functions, eg look at [`*`](https://github.com/JuliaLang/julia/blob/master/stdlib/LinearAlgebra/src/matmul.jl).

> [@aplavin](#):
>
> But we cannot do that for elementwise-operations field on arrays, as operators are already defined to mean matrix operations.

It would be more correct to say that _some_ functions have methods for matrices (where it makes sense), but most functions of course don’t. Again, whether a function has an infix operator form is not really relevant here, they are all functions.

> [@aplavin](#):
>
> Numpy approach sounds more reasonable _in this regard_ - there is a general `array` type as a container with elemenwise operations, and `matrix` type (which could be a zero-overhead wrapper in julia) with matrix operations.

That’s perhaps a matter of taste — if I understand the proposal correctly, I would need to know whether `A` and `B` are wrapped to make sense of `A * B`. Yet in Julia, for many operations I don’t really need to know and I am very happy about that.

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [March 12, 2019, 7:32am UTC](https://discourse.julialang.org/t/broadcasting-across-a-nested-array/21700/12 "2019-03-12T07:32:27Z")

</div>

> It is unclear what you mean here; in any case they aren’t. Matrix operations are functions like any other functions, eg look at [`*`](https://github.com/JuliaLang/julia/blob/master/stdlib/LinearAlgebra/src/matmul.jl).

> Again, whether a function has an infix operator form is not really relevant here, they are all functions.

Of course they are just functions, no question about that. My point is a lot of operations which are defined for arrays in Base have the matrix meaning, which (as you say) is just one possible field formed by arrays. Btw, only by 2-dimensional arrays, as opposed to elementwise operations forming a field for arbitrarily sized arrays.

> That’s perhaps a matter of taste — if I understand the proposal correctly, I would need to know whether `A` and `B` are wrapped to make sense of `A * B` . Yet in Julia, for many operations I don’t really need to know and I am very happy about that.

When one typically works with just arrays without any matrix structure in them and occasionally needs matrix operations, this makes a lot of sense. As opposed to `a / b` for two vectors giving a 2-dimensional array.

---

<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:** [March 12, 2019, 7:40am UTC](https://discourse.julialang.org/t/broadcasting-across-a-nested-array/21700/13 "2019-03-12T07:40:09Z")

</div>

> [@aplavin](#):
>
> Btw, only by 2-dimensional arrays, as opposed to elementwise operations forming a field for arbitrarily sized arrays.

A choice had to be made, and you have the elementwise form available with very convenient syntax that is _also_ consistent with the rest of the language. What’s not to like? 🕶

> [@aplavin](#):
>
> As opposed to `a / b` for two vectors giving a 2-dimensional array.

I don’t know if you are aware of this, but these issues were considered very carefully in the design of the API of what eventually became `LinearAlgebra`. If you are interested in the discussions, search for closed issues on “taking seriously” and follow the pointers (and prepare to spend about a day reading 😉).

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [March 12, 2019, 7:48am UTC](https://discourse.julialang.org/t/broadcasting-across-a-nested-array/21700/14 "2019-03-12T07:48:15Z")

</div>

> [@Tamas\_Papp](#):
>
> A choice had to be made, and you have the elementwise form available with very convenient syntax that is _also_ consistent with the rest of the language. What’s not to like? 🕶

Not quite sure what exactly you mean by convenient syntax, in the context of this thread: `((x,y)->(x.*y)).(Ref([1,2]), [[3,4], [5,6]])`? As opposed to just `Ref([1,2]) .* [[3,4], [5,6]]` if arithmetic was elementwise by default.

> I don’t know if you are aware of this, but these issues were considered very carefully in the design of the API of what eventually became `LinearAlgebra` . If you are interested in the discussions, search for closed issues on “taking seriously” and follow the pointers (and prepare to spend about a day reading 😉).

Sure, I saw a few of those threads (read only parts of them). But reading and understanding arguments there doesn’t mean I agree with the choice (of course, nothing can be changed here in julia). The final choice seems to be very matrix-centric, even though matrices don’t even appear in a large number of programs and scripts (I’m quite sure it’s true for the majority of programs; less so for scientific programming, but even there matrices are far from always needed).

---

<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:** [March 12, 2019, 8:41am UTC](https://discourse.julialang.org/t/broadcasting-across-a-nested-array/21700/15 "2019-03-12T08:41:16Z")

</div>

> [@aplavin](#):
>
> of course, nothing can be changed here in julia

This is not true — if you came up with a coherent proposal in the form of a PR that improves things significantly, I am sure it would be given due consideration for 2.0.

Note, however, that the bar for major overhauls is very high at this point, and requires a much more convincing argument than just citing isolated syntax examples from other languages. This is because all of these syntactic and semantic elements of the current API form a (more or less) coherent whole, and changing just one thing has a lot of ramifications. This is why a PR is the preferred way of arguing for something: when you do all the changes to make the tests run, you need to tackle problems that are easy to miss in a discussion.

An alternative (and less costly) route would be writing a package that defines your desired semantics for a couple of operators (I am sure you could find some nice Unicode ones). This would allow you to experiment, and if others find your solution an improvement, you could find it much easier to argue for a change in `Base`.

> [@aplavin](#):
>
> matrices don’t even appear in a large number of programs and scripts (I’m quite sure it’s true for the majority of programs; less so for scientific programming, but even there matrices are far from always needed)

Matrices are pervasive in scientific programming, and Julia is a scientific programming language.

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [March 12, 2019, 8:53am UTC](https://discourse.julialang.org/t/broadcasting-across-a-nested-array/21700/16 "2019-03-12T08:53:06Z")

</div>

I’m certainly not an expert in language design, and unlikely to propose some solution which is better than the current one and still fits the overall existing ecosystem. Judging as a language user, however, I’ve definitely experienced and seen (among my colleagues trying julia) confusion related to this “priority of matrices”. E.g. arithmetics (this thread), absence of `'` (transpose) operator for non-numeric 2d arrays.

Even though we mostly (with julia) do computing for science, matrix operations still appear rather infrequently. And where do you get the “Julia is a scientific programming language” line from? The homepage seems to promote it as a general purpose, fitting various areas (of course scientific computing is an important one of these, and mentioned at the homepage among others).

---

<div class="post-metadata">

**Author:** ![improbable22](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/improbable22/32/5464_2.png) [@improbable22](https://discourse.julialang.org/u/improbable22)\
**Post date:** [March 12, 2019, 10:33am UTC](https://discourse.julialang.org/t/broadcasting-across-a-nested-array/21700/17 "2019-03-12T10:33:29Z")

</div>

Acting on arrays, having both `*` and `.*` available is really all you can ask for. Defaulting to `*` really is correct for matrices, and people do use them a lot; defaulting to `.*` may make sense if your language is less general-purpose, more focused on unstructured lists of numbers. But it’s one more pixel! And the fact that `.` fuses is often very useful, `2 .* x .+ y` becomes one operation.

Acting on arrays of arrays (of arrays!) there are more possible options. This is less common in Julia than some places, as there are proper N-dimensional arrays. The one you are suggesting, of element-wise to the 2nd level when that exists, isn’t a built-in symbol. But you can easily make one, here’s a crude first go:

```julia
julia> +₂(x, y) = .+(x, y)

julia> +₂(x::AbstractArray{<:Number}, y::AbstractArray{<:AbstractArray}) = Ref(x) .+ y # and the reverse...

julia> [10 100] +₂ [5, 5]
2×2 Array{Int64,2}:
 15 105
 15 105

julia> [10, 100] +₂ [[5, 5], [6, 6], [7, 7]]
3-element Array{Array{Int64,1},1}:
 [15, 105]
 [16, 106]
 [17, 107]

```

Here’s the list of [allowed unicode symbols which are like +](https://github.com/JuliaLang/julia/blob/a882d9bf183fc93319002c9158f406f0755c202e/src/julia-parser.scm#L27) instead of decorating.

I also wish there was a shorter way to write `permutedims`, there have been various suggestions.

---

<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:** [March 12, 2019, 10:46am UTC](https://discourse.julialang.org/t/broadcasting-across-a-nested-array/21700/18 "2019-03-12T10:46:03Z")

</div>

> [@aplavin](#):
>
> confusion related to this “priority of matrices”. E.g. arithmetics (this thread), absence of `'` (transpose) operator for non-numeric 2d arrays.

As I [wrote above](https://discourse.julialang.org/t/broadcasting-across-a-nested-array/21700/8), what you perceive as “priority of matrices” is in fact just a logical consequence of treating `*` as a general operator on rings. Programming with generic constructs is baked into the design of Julia from the beginning. The same applies to `'` (and perhaps you missed the single-argument method for `permutedims`, which does the non-recursive “transpose”).

Again, if you truly hate these things, they are very easy to override for your own use.

But if you (and your colleagues) just find them _surprising_, just consider the possibility that they have been designed rather carefully and do form a coherent whole, and in this sense are quite elegant. Just give it some time.

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [March 12, 2019, 11:00am UTC](https://discourse.julialang.org/t/broadcasting-across-a-nested-array/21700/19 "2019-03-12T11:00:07Z")

</div>

> [@Tamas\_Papp](#):
>
> “priority of matrices” is in fact just a logical consequence of treating `*` as a general operator on rings

No, it is a consequence of _choosing_ the “matrix-field” for arrays as the default instead of “elementwise-field”. It would be just as consistent with the other choice of default, and some unicode operator for matrices instead of `*` and `/`.

---

<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:** [March 12, 2019, 11:34am UTC](https://discourse.julialang.org/t/broadcasting-across-a-nested-array/21700/20 "2019-03-12T11:34:35Z")

</div>

But we already have a way to do elementwise operations via _broadcasting_, which has [other advantages](https://julialang.org/blog/2017/01/moredots).

What would be the point of a parallel syntax that does not benefit from fusion?

[Next page](https://discourse.julialang.org/t/broadcasting-across-a-nested-array/21700.md?page=2)
