Counterintuitive slices of 2d array

236 views
Skip to first unread message

Paweł Biernat

unread,
Apr 16, 2014, 2:05:41 PM4/16/14
to julia...@googlegroups.com
Hi,
consider the 2d array

x=[j+10*i for i=1:2, j=1:2]

I would like to take a slice along the first and the second dimensions, i.e.

julia> x[1:2,1]
2-element Array{Int64,1}:
 
11
 
21

julia
> x[1,1:2]
1x2 Array{Int64,2}:
 
11  12

why is the second result a 2d array?  Shouldn't a slice of 2d array with one (the first or the second) index fixed always be a 1d array?  I understand, that this somewhat reflects the shape of the slice (the first slice is vertically oriented and the second slice is horizontally oriented).  But then, why is the first case a 1d array instead of 2d array?  This seems a little bit inconsistent.  I consider the following behavior much clearer

julia> x[1:2,1:1]
2x1 Array{Int64,2}:
 
11
 
21

julia
> x[1:1,1:2]
1x2 Array{Int64,2}:
 
11  12

julia
> x[1:2,1]
2-element Array{Int64,1}:
 
11 21

julia
> x[1,1:2]
2-element Array{Int64,1}:
 
11 12

This is getting more and more confusing with higher dimensional arrays, when you have to deal with the particular dimension along which you make a slice.  Imagine dealing with x[1,1,1,1:3,1,1] with the range '1:3' possibly exchanging places with fixed index '1' in the same code.  Do I have to count the commas each time I want a slice of high-dimensional array and then deal with the slices as they were 1d, 2d, 3d, ... kd arrays (when effectively they are all 1d arrays)?  I think counting colons is much more intuitive and better reflects the dimensions of the result.  This problem extends to 2d slices of 3d arrays

y=[j+10*i+100*k for i=1:2, j=1:2, k=1:2]

for which slicing gives

julia> y[1,1:2,1:2]
1x2x2 Array{Int64,3}:
[:, :, 1] =
 
111  112

[:, :, 2] =
 
211  212

julia
> y[1:2,1,1:2]
2x1x2 Array{Int64,3}:
[:, :, 1] =
 
111
 
121

[:, :, 2] =
 
211
 
221

julia
> y[1:2,1:2,1]
2x2 Array{Int64,2}:
 
111  112
 
121  122

with the last case clearly distinguishing itself from the two other cases.

Paweł Biernat

unread,
Apr 16, 2014, 2:13:48 PM4/16/14
to julia...@googlegroups.com
Adding a real life use case:

x=[j+10*i for i=1:2, j=1:2]

function f(x::Array{Int,1})
    x
end

and then

julia> f(x[1:2,1])

2-element Array{Int64,1}:
 
11
 
21


julia
> f(x[1,1:2])
ERROR
: no method f(Array{Int64,2})


Bob Nnamtrop

unread,
Apr 16, 2014, 2:54:59 PM4/16/14
to julia...@googlegroups.com
I completely agree with you and would love to see julia drop singleton dimensions indexed with scalar. There is an issue on this with lots of discussion, which was left at the point of waiting til someone implements some code to give it a try (see https://github.com/JuliaLang/julia/issues/5949). Maybe after 0.3 is released there will be some action on this (I am willing to try myself but it does seem like a hard 1st problem to deal with the julia internals).  IMO, there is some underlying tension in julia that revolves around people who primarily use arrays as containers (who generally want this changed) and those who use one and two dimensional arrays as a linear algebra system (some of who do not want it implemented). I am firmly in the camp of using arrays primarily as containers and, in addition to this issue, find it very annoying that the elementwise operators are all are 2nd class citizens (i.e., you must use .*, ./, .+, .-, etc). The fact that the 1st class versions only work on a subset of arrays (i.e., those 1 and 2 dimensional) seems like a poor design choice to me. But this is different to the dripping dimensions indexed by scalars issue where there is still hope for a change.

As a practical version of your function example in your second email is the plot command. You are plotting some slices from some higher dimensional arrays, e.g.

plot(x[2,3,7,:,9], y[2,3,7,:,9])

and you just want to get two one dimensional slices passed into plot with no fuss.

Bob

Paweł Biernat

unread,
Apr 16, 2014, 6:25:36 PM4/16/14
to julia...@googlegroups.com
Thanks for linking to the issue.  It seems that the array slicing is just a tip of the iceberg, I had no idea about the discussion on the algebraic interpretation of n x n arrays and respective operators.  I somewhat understand the arguments behind the need of elementwise operators (although they are still pretty arbitrary), but I find the current state of array slicing really unintuitive.  I am new to Julia and I am constantly impressed by its features but for my work a decent array slicing rules are critical and lack of them is, to me, very annoying.

Alex Dowling

unread,
Sep 17, 2015, 10:03:04 PM9/17/15
to julia-users
I'd like to kick-up this thread again, and ask a related questions:

Let's say I have a 2d array, and take a slice of it. How do I then append the slice with an additional value? The slice is type Array{Float64,2}. Neither push! or append! work.

Thanks,
Alex

Tim Holy

unread,
Sep 17, 2015, 10:24:33 PM9/17/15
to julia...@googlegroups.com
Instead of A[:,2,3,4:7] you can call slice(A,:,2,3,4:7) and it will drop
scalar dimensions. That's available now, and in 0.4 it's fast.

The difference between what we have now and what we will have in the future is
that A[...] will likely become an alias for slice(A,...).

So, no need to lead a frustrated life.

--Tim
Reply all
Reply to author
Forward
0 new messages