# A better way to assign to \[:, :, ... k\]?

**URL:** <https://discourse.julialang.org/t/a-better-way-to-assign-to-k/5678>\
**Category:** New to Julia\
**Tags:** hdf5\
**Created:** [September 2, 2017, 1:37am UTC](https://discourse.julialang.org/t/a-better-way-to-assign-to-k/5678 "2017-09-02T01:37:52Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![tuckermcclure](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tuckermcclure/32/1187_2.png) [@tuckermcclure](https://discourse.julialang.org/u/tuckermcclure)\
**Post date:** [September 2, 2017, 1:37am UTC](https://discourse.julialang.org/t/a-better-way-to-assign-to-k/5678/1 "2017-09-02T01:37:52Z")

</div>

I’m writing a utility that collects a user’s n-dimensional matrices over time and stores them in an n+1 dimensional array. Something like this:

```julia
storage[:, :, k] = input

```

But of course I can’t literally type those colons, because the input could be anything (as long as it’s consistent from call to call). So I’ve written this to store the input matrix:

```julia
num_input_dims = length(size(input))
storage[repeat([:], num_input_dims), k] = input

```

For what it’s worth, in my case `storage` is actually part of an HDF5 file with a space preallocated for all of the data the user will pass in. The syntax for `[:, :, :, k]` is what the HDF5 package uses for input, and I don’t think strides will work for it.

My syntax above just feels a little silly, and I’m wondering if there’s a better way.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [September 2, 2017, 1:52am UTC](https://discourse.julialang.org/t/a-better-way-to-assign-to-k/5678/2 "2017-09-02T01:52:16Z")

</div>

I think [`slicedim()`](https://docs.julialang.org/en/latest/stdlib/arrays/#Base.slicedim) does what you’re looking for.

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [September 2, 2017, 2:12am UTC](https://discourse.julialang.org/t/a-better-way-to-assign-to-k/5678/3 "2017-09-02T02:12:32Z")

</div>

EllipsisNotation.jl at least gives nice syntax: `storage[..,k]`. In was fine for performance, but when we made it more generic it doesn’t infer properly anymore so you may want to use an older version, or help us finish it up 😛.

[https://github.com/ChrisRackauckas/EllipsisNotation.jl](https://github.com/ChrisRackauckas/EllipsisNotation.jl)

---

<div class="post-metadata">

**Author:** ![bramtayl](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bramtayl/32/3614_2.png) [@bramtayl](https://discourse.julialang.org/u/bramtayl)\
**Post date:** [September 2, 2017, 2:47am UTC](https://discourse.julialang.org/t/a-better-way-to-assign-to-k/5678/4 "2017-09-02T02:47:10Z")

</div>

Lispy tuple programming!

```julia
replace_last(t, i) = first(t), replace_last(Base.tail(t), i)...
replace_last(t::Tuple{T}, i) where T = (i,)

test = rand(5, 5, 5)
test_indices = indices(test)
test[replace_last(test_indices, 1)...]

```

Should be super-performant.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [September 2, 2017, 5:54am UTC](https://discourse.julialang.org/t/a-better-way-to-assign-to-k/5678/5 "2017-09-02T05:54:55Z")

</div>

Why can’t you use a (pre-allocated) vector of n-dimensional matrices?

---

<div class="post-metadata">

**Author:** ![tuckermcclure](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tuckermcclure/32/1187_2.png) [@tuckermcclure](https://discourse.julialang.org/u/tuckermcclure)\
**Post date:** [September 2, 2017, 5:06pm UTC](https://discourse.julialang.org/t/a-better-way-to-assign-to-k/5678/6 "2017-09-02T17:06:03Z")

</div>

> [@rdeits](#):
>
> I think slicedim() does what you’re looking for.

Thanks, but if I understand correctly, this would be for reading, and I need to write with `setindex!` (it’s the method the HDF5 package has writing to data in files). Have I missed something?

> [@ChrisRackauckas](#):
>
> EllipsisNotation.jl at least gives nice syntax: storage[…,k]

This is more elegant than what I had. My code now looks like (taken from EllipsisNotation.jl):

```julia
colons = (Colon() for i in 1:length(size(input)))
storage[colons..., k] = input

```

> [@bramtayl](#):
>
> Lispy tuple programming!

Nice. I’m going with @ChrisRackauckas’s suggestion for clarity, but I wonder if this recursive implementation is any faster?

> [@DNF](#):
>
> Why can’t you use a (pre-allocated) vector of n-dimensional matrices?

One could; it just won’t work for my application, where `storage` is (must be) a multidimensional array.

Thanks all. You helped me retire a TODO in my code, find a bunch of new functions, and figure out why @bramtayl’s second `replace_last` method would be interpreted as the base case.

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [September 2, 2017, 5:12pm UTC](https://discourse.julialang.org/t/a-better-way-to-assign-to-k/5678/7 "2017-09-02T17:12:54Z")

</div>

> [@tuckermcclure](#):
>
> Nice. I’m going with @ChrisRackauckas’s suggestion for clarity, but I wonder if this recursive implementation is any faster?

Only if you hit the splatting penalty, i.e. have more than 16 dimensions. The issue with EllipsisNotation.jl is a little bit different and has to do with inferrability when it generalized. If it infers correctly, any implementation should be about the same speed.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [September 2, 2017, 5:14pm UTC](https://discourse.julialang.org/t/a-better-way-to-assign-to-k/5678/8 "2017-09-02T17:14:43Z")

</div>

FWIW assigning to the last index is slow(er) since Julia is column major.

Edit. This is nonsense.

---

<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:** [September 2, 2017, 9:52pm UTC](https://discourse.julialang.org/t/a-better-way-to-assign-to-k/5678/9 "2017-09-02T21:52:27Z")

</div>

By assigning to

```julia
storage[:, :, k]

```

Isn’t he effectively assigning through the first two axis? That is, I thought the above would basically sort of be equivalent to:

```julia
for in 1:size(storage,2)
  for j in 1:size(storage,1)
    storage[j, i, k]
  end
end

```

in terms of memory access pattern, and that the whole block from both cases should be contiguous.  
Am I mistaken, or did I misinterpret something?

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [September 3, 2017, 5:21am UTC](https://discourse.julialang.org/t/a-better-way-to-assign-to-k/5678/10 "2017-09-03T05:21:15Z")

</div>

Yes, sorry. I don’t know what I was thinking…
