# Broadcast over a specific dimension of array

**URL:** https://discourse.julialang.org/t/broadcast-over-a-specific-dimension-of-array/43158
**Category:** General Usage
**Tags:** question
**Created:** [July 16, 2020, 3:34am UTC](https://discourse.julialang.org/t/broadcast-over-a-specific-dimension-of-array/43158 "2020-07-16T03:34:02Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![white-c](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/white-c/32/16410_2.png) [@white-c](https://discourse.julialang.org/u/white-c)
#### Post date: [July 16, 2020, 3:34am UTC](https://discourse.julialang.org/t/broadcast-over-a-specific-dimension-of-array/43158/1 "2020-07-16T03:34:03Z")

</div>

Hello, Julians!

I have a 3 dimensional complex F64 array. I want to run the inv() over the inner two dimensions and broadcast along the outer dimension. When I try simple broadcasting inv.(A) I get different results than if I do a for-loop. How do I specify the dimension I want to broadcast over?

---

<div class="post-metadata">

### Author: ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)
#### Post date: [July 16, 2020, 3:48am UTC](https://discourse.julialang.org/t/broadcast-over-a-specific-dimension-of-array/43158/2 "2020-07-16T03:48:51Z")

</div>

The easiest solution would be to have a `Vector` of `Matrix` objects. That said, it is very rare for `inv` to be the best method for solving problems. What’s the usecase?

---

<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 16, 2020, 4:07am UTC](https://discourse.julialang.org/t/broadcast-over-a-specific-dimension-of-array/43158/3 "2020-07-16T04:07:26Z")

</div>

Broadcast is completely point-wise. That is, it applies to every element in the array, not slices thereof. Thus if you want to use broadcast across slices like this, you need to use some sort of array-of-arrays structure.

---

<div class="post-metadata">

### Author: ![white-c](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/white-c/32/16410_2.png) [@white-c](https://discourse.julialang.org/u/white-c)
#### Post date: [July 16, 2020, 5:12am UTC](https://discourse.julialang.org/t/broadcast-over-a-specific-dimension-of-array/43158/4 "2020-07-16T05:12:17Z")

</div>

The matrix represents the mapping of inputs to outputs of an electrical circuit. The outer dimension represents how that matrix changes at different frequency points. So to flip the mapping from outputs to inputs I just need to invert the matrix, but I want to do it at each frequency so I need to invert the matrix for each matrix along the array. It sounds like a 1D array of 2D arrays would be the best approach.

---

<div class="post-metadata">

### Author: ![white-c](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/white-c/32/16410_2.png) [@white-c](https://discourse.julialang.org/u/white-c)
#### Post date: [July 16, 2020, 5:32am UTC](https://discourse.julialang.org/t/broadcast-over-a-specific-dimension-of-array/43158/5 "2020-07-16T05:32:41Z")

</div>

It looks like `mapslices` might be the method I was looking for. But, perhaps there is a better way to do what I want than iterating over the outer dimension?

---

<div class="post-metadata">

### Author: ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)
#### Post date: [July 16, 2020, 6:11am UTC](https://discourse.julialang.org/t/broadcast-over-a-specific-dimension-of-array/43158/6 "2020-07-16T06:11:34Z")

</div>

> It sounds like a 1D array of 2D arrays would be the best approach.

`map` or `broadcast` with `eachslice` can yield a 1D array of 2D arrays:

```julia
julia> x = rand(3,3,4);

julia> inv.(eachslice(x, dims=3))
4-element Array{Array{Float64,2},1}:
 [-1.6590312226570239 2.0793019606694854 0.5372029679273337; -0.41725584494784745 -0.16227671804840568 1.4356241190356016; 3.1581583049406534 -1.8836845469856938 -1.3709070403858319]
 [2.2504272336124984 -1.3387872100956475 -1.3175125593090484; -0.6955200736976385 2.3904260659293395 -0.15231503786728723; -1.6588907341843613 -5.504678105886818 6.354210163417449]
 [-6.522265014454815 11.007596635562658 -0.8997442890195426; 5.918653872368978 -6.235209223176827 -0.20055712370467133; 3.1672517888989637 -7.134447496548201 2.0670158780550607]
 [1.257897188987869 0.5534734488273791 -3.7933556798265524; -1.3639997740291203 1.2156395483916482 3.2530995922802717; -1.1021239862109267 -3.2404755836203387 21.985361866828296]

julia> map(inv, eachslice(x, dims=3))
4-element Array{Array{Float64,2},1}:
 [-1.6590312226570239 2.0793019606694854 0.5372029679273337; -0.41725584494784745 -0.16227671804840568 1.4356241190356016; 3.1581583049406534 -1.8836845469856938 -1.3709070403858319]
 [2.2504272336124984 -1.3387872100956475 -1.3175125593090484; -0.6955200736976385 2.3904260659293395 -0.15231503786728723; -1.6588907341843613 -5.504678105886818 6.354210163417449]
 [-6.522265014454815 11.007596635562658 -0.8997442890195426; 5.918653872368978 -6.235209223176827 -0.20055712370467133; 3.1672517888989637 -7.134447496548201 2.0670158780550607]
 [1.257897188987869 0.5534734488273791 -3.7933556798265524; -1.3639997740291203 1.2156395483916482 3.2530995922802717; -1.1021239862109267 -3.2404755836203387 21.985361866828296]

julia> mapslices(inv, x, dims=(1,2))
3×3×4 Array{Float64,3}:
[:, :, 1] =
 -1.65903 2.0793 0.537203
 -0.417256 -0.162277 1.43562
  3.15816 -1.88368 -1.37091

[:, :, 2] =
  2.25043 -1.33879 -1.31751
 -0.69552 2.39043 -0.152315
 -1.65889 -5.50468 6.35421

[:, :, 3] =
 -6.52227 11.0076 -0.899744
  5.91865 -6.23521 -0.200557
  3.16725 -7.13445 2.06702

[:, :, 4] =
  1.2579 0.553473 -3.79336
 -1.364 1.21564 3.2531
 -1.10212 -3.24048 21.9854

```

---

<div class="post-metadata">

### Author: ![white-c](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/white-c/32/16410_2.png) [@white-c](https://discourse.julialang.org/u/white-c)
#### Post date: [July 16, 2020, 2:58pm UTC](https://discourse.julialang.org/t/broadcast-over-a-specific-dimension-of-array/43158/7 "2020-07-16T14:58:54Z")

</div>

Thanks, everyone, for the help.

---

<div class="post-metadata">

### Author: ![Philippe\_Maincon1](https://avatars.discourse-cdn.com/v4/letter/p/ec9cab/32.png) [@Philippe\_Maincon1](https://discourse.julialang.org/u/Philippe_Maincon1)
#### Post date: [April 8, 2021, 10:23am UTC](https://discourse.julialang.org/t/broadcast-over-a-specific-dimension-of-array/43158/8 "2021-04-08T10:23:28Z")

</div>

I found this thread because I had the same question, essentialy. I was not satisfied with the answers because I wanted

- a `view`
- high performance

So I created a typestable, zero allocation (so it is fast) method for `selectdim`. Like `selectdim` it returns a `view`. Unlike Julia’s version, its second argument must be a `Val`.

```julia
@generated function Base.selectdim(a,::Val{d},i) where{d}
    precols = ()
    pstcols = ()
    for i = 1:d-1
        precols = (precols...,:)
    end
    for i = 1:ndims(a)-d
        pstcols = (pstcols...,:)
    end
    return quote
        return view(a,$(precols...),i,$(pstcols...))
    end
end

a = randn(2,4,5)
g = selectdim(a,Val(3),2) # view to a[:,:,2]

```
