# Way to slice an array of unknown number of dimensions?

This might be naive, but I couldn’t find an answer else where:

Let `A` be an Nd-array, where Nd is unknown exactly till runtime, e.g., only sure that `Nd>=3`.
Is there a good way to slice it along, e.g., the `n<=3`th dimension?

For comparison, in numpy, one can do:

``````>>> A = numpy.ones((3,3,3,3));
>>> A[1,:]
array([[[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]],
[[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]],
[[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]]])
``````

This made things each for me, as the slice is shape-ready for broadcasting operations on `A` afterwards.

Thanks.

3 Likes

I think with constant folding, you could construct an argument to the API of this package that would be type stable.

There is also EllipsisNotation.jl. Also see https://github.com/JuliaLang/julia/issues/5405.

2 Likes

Thanks! I will check out those modules.

So I guess, for `≤ v1.1`, it’s yet a missing feature.

More like `<= v1.3`.

You can also just use `selectdim` for this. For your case

``````julia> A=ones(3,3,3,3);

julia> selectdim(A, 1, 1)
3×3×3 view(::Array{Float64,4}, 1, :, :, :) with eltype Float64:
[:, :, 1] =
1.0  1.0  1.0
1.0  1.0  1.0
1.0  1.0  1.0

[:, :, 2] =
1.0  1.0  1.0
1.0  1.0  1.0
1.0  1.0  1.0

[:, :, 3] =
1.0  1.0  1.0
1.0  1.0  1.0
1.0  1.0  1.0
``````

selects the first slice along the first dimension.

6 Likes

That actually works very well for me!
Thanks!

Played with `selectdim` for a little. `selectdim` is smooth for r-value, (retrieve).
For l-value, (assign), one need `copyto!(selectdim(...), new_val)`, etc.

IMHO, it’s a bit more of a workaround, than the feature wanted, `A[1, ..]` (syntax sugar provided in `EllipsisNotation`).

See @simeonschaub 's reply for a better way of using `selectdim` as l-value. (not `copyto!`)

Have you tried `selectdim(A, 1, 1) .= new_val`?

ah, I see, thanks for that!
That feels a bit tricky, I thought same sized array copy would go smooth through `=`.

I think it makes sense that you need `.=`. If you type `selectdim(A, 1, 1) = new_val` then Julia interprets this as a function definition, i.e., Julia thinks you are trying to make a function called `selectdim` with arguments `A`, `1`, and `1` that returns `new_val`. But `1` is an invalid argument name, hence the error `ERROR: syntax: "1" is not a valid function argument name`. (On the other hand, `selectdim(A, d, i) = new_val` would quietly create a function that accepts 3 arguments and always returns `new_val`.)

Additionally, `selectdim(...)` returns an object, and it doesn’t make sense to assign an object to a value, just as `1 = 2` doesn’t make sense.

Agreed, it just feels a bit extra mind work to me, especially when I had `p=selecdim(...)`, then, few lines later, having `p.=c`:
“wait, why do I need an element-wise assignment here between two same sized variable…, oh…, it’s a `view` and `=` doesn’t go through”.
Probably I am just not used to `view`, and expected pointer-like behavior from it…

The key isn’t the `view`, it’s the difference between `A = X`, `A[I] = X` and `A .= X`.

The first just creates a new name — an alias — for `X`. The second updates an existing `A` at the given indices to contain `X`. The third updates all indices of an existing `A` to contain `X`. All three of these forms are special syntaxes. This includes the second one — “indexed assignment” — so pulling out the indexing away from the `=` will mean something different.

You can use views in the latter two expressions to further restrict the indices. But you cannot use views in the first one because it’s not doing any updating at all!

3 Likes

Thanks a lot!
It is very helpful knowing that `A=X` is creating an alias. I wish this clarification could be in the doc.

As discussed multiple times here (search the forum), calling it an alias is not helpful.

Generally, code like

``````A = X
``````

simply makes `A` and `X` have the same value, in the sense that `A === X`, ie (quoting from `?===`)

in the sense that no program could distinguish them

This applies to all kinds of values: integers, strings, and arrays. For arrays, neither is an an alias of the other, they are the same. Consequently, for a function like

``````f(Z) = (Z[1] = 2; nothing)
``````

both `f(A)` and `f(X)` after `A = X` should just modify the same array, otherwise a program could distinguish them.

It’s an alias in the sense of normal English language alias. Like how the FBI would use the word alias. For some folks that’s what makes it click. For others it does indeed just muddy the waters based upon how they’ve used “aliasing” in the context of computer languages. Perhaps when I use that word I should clarify it’s the FBI’s alias — just two names for the same thing.

This is where I find more confusion — I think it’s easier to say that `A` and `X` don’t have or hold values, they’re just names. That’s it.

As always with mental models and teaching, your mileage may vary.

1 Like

If you prefer that usage, you can say that after `A = X`, `A` and `X` are variables that refer to the same value.

Sorry, since I don’t follow criminal news of the US I am not sure how the FBI uses aliases.

I just think the term is misleading if it suggests that one of those variables is “the original” or is distinguished in some sense. I find that this interpretation is quite common when people talk about aliases.