# Broadcast for Array of Array

**URL:** <https://discourse.julialang.org/t/broadcast-for-array-of-array/29604>\
**Category:** New to Julia\
**Tags:** broadcast, arrays\
**Created:** [October 7, 2019, 4:25pm UTC](https://discourse.julialang.org/t/broadcast-for-array-of-array/29604 "2019-10-07T16:25:23Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![hasanOryx](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hasanoryx/32/5373_2.png) [@hasanOryx](https://discourse.julialang.org/u/hasanOryx)\
**Post date:** [October 7, 2019, 4:25pm UTC](https://discourse.julialang.org/t/broadcast-for-array-of-array/29604/1 "2019-10-07T16:25:23Z")

</div>

I’ve the below function

```julia
sigmoid(z::Real) = one(z) / (one(z) + exp(-z))

```

And want to broadcast it for all the element of x, where:

```julia
X = [
           [1, 2, 3],
           [3, 4, 5],
           [5, 6, 7]
       ]

```

I tried the normal way but failed

```julia
sigmoid.(X)

```

---

<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:** [October 7, 2019, 4:30pm UTC](https://discourse.julialang.org/t/broadcast-for-array-of-array/29604/2 "2019-10-07T16:30:47Z")

</div>

Broadcast works on the immediate elements of its arguments — in this case, the elements of `X` are themselves arrays, thus `sigmoid.(X)` is passing those inner arrays to `sigmoid`. You need to go down a second layer; often this is clearest with a comprehension:

```julia
[sigmoid.(inner_array) for inner_array in X]

```

---

<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:** [October 7, 2019, 4:37pm UTC](https://discourse.julialang.org/t/broadcast-for-array-of-array/29604/3 "2019-10-07T16:37:17Z")

</div>

Another way is to just do

```julia
(x -> sigmoid.(x)).(X)

```

This creates an anonymous function (`x -> sigmoid.(x)`) whose whole point is to broadcast `sigmoid` and then you can broadcast that function.

Not to beat a dead horse, but I do wish we had a cleaner way to do recursive broadcast. Maybe something like `@. sigmoid(X) recursive` where the flag `recursive` tells it to keep apply broadcasting until it reaches a scalar.

---

<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:** [October 7, 2019, 4:44pm UTC](https://discourse.julialang.org/t/broadcast-for-array-of-array/29604/4 "2019-10-07T16:44:26Z")

</div>

If wishes were horses, there’d be twenty different resurrected horse zombies running around, each doing broadcast just slightly differently. If you’ll pardon the mixed metaphor.

---

<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:** [October 7, 2019, 4:59pm UTC](https://discourse.julialang.org/t/broadcast-for-array-of-array/29604/5 "2019-10-07T16:59:38Z")

</div>

I think it’s kinda ironic that 3 hours ago the OP posted this thread: [Sigmoid function in Julia - #4 by hasanOryx](https://discourse.julialang.org/t/sigmoid-function-in-julia/29594/4) where he was told “don’t define elementwise functions on arrays, just use broadcast.” But now when he runs into a nested array it becomes clear that the broadcast machinery isn’t general enough to do what he wants.

I guess I just don’t understand why recursive broadcast is always dismissed out of hand.

---

<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:** [October 7, 2019, 5:03pm UTC](https://discourse.julialang.org/t/broadcast-for-array-of-array/29604/6 "2019-10-07T17:03:22Z")

</div>

Because this is a #user:first-steps question. Let’s describe the status quo here, and not bog new users down with potential new and/or competing designs.

---

<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:** [October 7, 2019, 5:28pm UTC](https://discourse.julialang.org/t/broadcast-for-array-of-array/29604/7 "2019-10-07T17:28:44Z")

</div>

Maybe it should also be metioned that, instead of an array of arrays, you are often better off with one higher-dimensional array, in this case a matrix. Some languages don’t distinguish these concepts, but Julia does.

```julia
julia> M = [1 2 3; 3 4 5; 5 6 7]
3×3 Array{Int64,2}:
 1 2 3
 3 4 5
 5 6 7

julia> transpose(M) == reduce(hcat, X)
true

julia> sigmoid.(M)
3×3 Array{Float64,2}:
 0.731059 0.880797 0.952574
 0.952574 0.982014 0.993307
 0.993307 0.997527 0.999089

```

---

<div class="post-metadata">

**Author:** ![hasanOryx](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hasanoryx/32/5373_2.png) [@hasanOryx](https://discourse.julialang.org/u/hasanOryx)\
**Post date:** [October 7, 2019, 5:33pm UTC](https://discourse.julialang.org/t/broadcast-for-array-of-array/29604/8 "2019-10-07T17:33:41Z")

</div>

Thanks, actually the input come like an output of a previous operation if you can help me to fix it to match your approach, it will be very helpful:

```julia
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
x, y = split_seq(a, 3)

function split_seq(sequence::Array, n_steps::Int)
    x, y = [], []
    for (index, value) in enumerate(sequence)
        if index <= length(sequence) - n_steps
            seq_x, seq_y = sequence[index:index+n_steps-1], sequence[index+n_steps]
            push!(x, seq_x)
            push!(y, seq_y)
        end
    end
    return x, y
end

```

Then I get `x` as:

```bash
7-element Array{Any,1}:
 [1, 2, 3]
 [2, 3, 4]
 [3, 4, 5]
 [4, 5, 6]
 [5, 6, 7]
 [6, 7, 8]
 [7, 8, 9]

```

---

<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:** [October 7, 2019, 5:40pm UTC](https://discourse.julialang.org/t/broadcast-for-array-of-array/29604/9 "2019-10-07T17:40:02Z")

</div>

Here are some ways…

```julia
julia> reduce(hcat, @view a[i:i+2] for i=1:length(a)-2)
3×8 Array{Int64,2}:
 1 2 3 4 5 6 7 8
 2 3 4 5 6 7 8 9
 3 4 5 6 7 8 9 10

julia> reduce(vcat, a[i:i+2]' for i=1:length(a)-2)
8×3 Array{Int64,2}:
 1 2 3
 2 3 4
...

```

You could also just make a new array & fill it in with loops, which may well be fastest (if you care) but won’t fit on one line.

---

<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:** [October 7, 2019, 5:53pm UTC](https://discourse.julialang.org/t/broadcast-for-array-of-array/29604/10 "2019-10-07T17:53:39Z")

</div>

I think I’d use a two-dimensional comprehension here:

```julia
split_seq(sequence, n) = [sequence[offset+column] for offset in 0:n-1, column in 1:length(sequence)-n+1]

```

Or if you really want to be clever —perhaps too clever — you can use broadcast to select your indices (but this won’t be quite as efficient as the above):

```julia
split_seq(sequence, n) = sequence[(0:n-1) .+ transpose(1:end-n+1)]

```

---

<div class="post-metadata">

**Author:** ![hasanOryx](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hasanoryx/32/5373_2.png) [@hasanOryx](https://discourse.julialang.org/u/hasanOryx)\
**Post date:** [October 7, 2019, 5:58pm UTC](https://discourse.julialang.org/t/broadcast-for-array-of-array/29604/11 "2019-10-07T17:58:24Z")

</div>

> [@mbauman](#):
>
> sequence[offset+column]

Perfectly done, but did not get how this code generated a 2D array?

---

<div class="post-metadata">

**Author:** ![hasanOryx](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hasanoryx/32/5373_2.png) [@hasanOryx](https://discourse.julialang.org/u/hasanOryx)\
**Post date:** [October 7, 2019, 6:02pm UTC](https://discourse.julialang.org/t/broadcast-for-array-of-array/29604/12 "2019-10-07T18:02:47Z")

</div>

nice, so my function became:

```julia
function split_seq(sequence::Array, n_steps::Int)
    x = reduce(vcat, sequence[i:i+n_steps-1]' for i=1:length(sequence)-n_steps)
    y = reduce(vcat, sequence[i+n_steps]' for i=1:length(sequence)-n_steps)
    return x, y
end

```

---

<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:** [October 7, 2019, 6:04pm UTC](https://discourse.julialang.org/t/broadcast-for-array-of-array/29604/13 "2019-10-07T18:04:38Z")

</div>

[https://docs.julialang.org/en/v1/manual/arrays/#Comprehensions-1](https://docs.julialang.org/en/v1/manual/arrays/#Comprehensions-1)

We could probably use an example for the multi-dimensional capability, but the trick is that there are two comma-separated `for` loops. It creates the Cartesian product of the two, using the first to generate the rows and the second to generate the columns.

```julia
julia> [row+10*col for row in 1:4, col in 1:5]
4×5 Array{Int64,2}:
 11 21 31 41 51
 12 22 32 42 52
 13 23 33 43 53
 14 24 34 44 54

```

---

<div class="post-metadata">

**Author:** ![hasanOryx](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hasanoryx/32/5373_2.png) [@hasanOryx](https://discourse.julialang.org/u/hasanOryx)\
**Post date:** [October 7, 2019, 6:31pm UTC](https://discourse.julialang.org/t/broadcast-for-array-of-array/29604/14 "2019-10-07T18:31:40Z")

</div>

Thanks, and hope you be patent with my questions:

I tried the below and got 2 different answers:

```julia
split_seq(sequence, n) = [sequence[offset+column] for offset in 0:n-1, column in 1:length(sequence)-n+1]

a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
x = split_seq(a, 3)
@show x

```

Answer:

```bash
x = ([1 2 3; 2 3 4; 3 4 5; 4 5 6; 5 6 7; 6 7 8; 7 8 9], [4, 5, 6, 7, 8, 9, 10])

```

Other way, without creating a function:

```julia
sequence = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
z = [sequence[offset+column] for offset in 0:3-1, column in 1:length(sequence)-3+1]
@show z

```

Answer:

```bash
z = [1 2 3 4 5 6 7 8; 2 3 4 5 6 7 8 9; 3 4 5 6 7 8 9 10]

```

---

<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:** [October 7, 2019, 6:46pm UTC](https://discourse.julialang.org/t/broadcast-for-array-of-array/29604/15 "2019-10-07T18:46:40Z")

</div>

I believe that’s because you already have multiple `split_seq` methods defined in your current Julia session — and your original definition is taking precedence because it’s _more specific_. If you look at `methods(split_seq)`, I believe you’ll see two (or more) things listed:

```julia
julia> methods(split_seq)
# 2 methods for generic function "split_seq":
[1] split_seq(sequence::Array, n_steps::Int64) in Main at REPL[100]:1
[2] split_seq(sequence, n) in Main at REPL[96]:1

```

For simple definitions like these, I wouldn’t put types on the arguments — you can rely on duck-typing to accept lots of arguments, and there’s no difference in speed/efficiency.

---

<div class="post-metadata">

**Author:** ![davidanthoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/davidanthoff/32/223493_2.png) [@davidanthoff](https://discourse.julialang.org/u/davidanthoff)\
**Post date:** [October 7, 2019, 7:01pm UTC](https://discourse.julialang.org/t/broadcast-for-array-of-array/29604/16 "2019-10-07T19:01:01Z")

</div>

[Here](https://github.com/JuliaLang/julia/issues/20502) is an issue with an idea for nested broadcasts, for those that want to discuss potential enhancements around this in Julia itself. The debate there is quite outdated, though.

---

<div class="post-metadata">

**Author:** ![hasanOryx](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hasanoryx/32/5373_2.png) [@hasanOryx](https://discourse.julialang.org/u/hasanOryx)\
**Post date:** [October 7, 2019, 7:46pm UTC](https://discourse.julialang.org/t/broadcast-for-array-of-array/29604/17 "2019-10-07T19:46:06Z")

</div>

Thanks a lot
