Skip to content

Commit

Permalink
Add size(::LinearIndices) method (#25541)
Browse files Browse the repository at this point in the history
Fixes indexing LinearIndices with an array. This is useful in particular
to convert cartesian indices that find() now returns to linear indices.
  • Loading branch information
nalimilan committed Jan 13, 2018
1 parent 5b345ff commit f27f4b8
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 3 deletions.
2 changes: 1 addition & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ This section lists changes that do not have deprecation warnings.
`AbstractDict`, `AbstractString`, `Tuple` and `NamedTuple` objects ([#24774]).
In particular, this means that it returns `CartesianIndex` objects for matrices
and higher-dimensional arrays instead of linear indices as was previously the case.
Use `Int[LinearIndices(size(a))[i] for i in find(f, a)]` to compute linear indices.
Use `LinearIndices(a)[find(f, a)]` to compute linear indices.

* `AbstractSet` objects are now considered equal by `==` and `isequal` if all of their
elements are equal ([#25368]). This has required changing the hashing algorithm
Expand Down
1 change: 1 addition & 0 deletions base/multidimensional.jl
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,7 @@ module IteratorsMD
# AbstractArray implementation
Base.IndexStyle(::Type{LinearIndices{N,R}}) where {N,R} = IndexCartesian()
Base.axes(iter::LinearIndices{N,R}) where {N,R} = iter.indices
Base.size(iter::LinearIndices{N,R}) where {N,R} = length.(iter.indices)
@inline function Base.getindex(iter::LinearIndices{N,R}, I::Vararg{Int, N}) where {N,R}
dims = length.(iter.indices)
#without the inbounds, this is slower than Base._sub2ind(iter.indices, I...)
Expand Down
25 changes: 23 additions & 2 deletions test/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ end
@test LinearIndices()[1] == 1
@test_throws BoundsError LinearIndices()[2]
@test LinearIndices()[1,1] == 1
@test LinearIndices()[] == 1
@test size(LinearIndices()) == ()
@test CartesianIndices()[1] == CartesianIndex()
@test_throws BoundsError CartesianIndices()[2]
end
Expand All @@ -129,6 +131,8 @@ end
@test CartesianIndices((3,))[i] == CartesianIndex(i,)
end
@test LinearIndices((3,))[2,1] == 2
@test LinearIndices((3,))[[1]] == [1]
@test size(LinearIndices((3,))) == (3,)
@test_throws BoundsError CartesianIndices((3,))[2,2]
# ambiguity btw cartesian indexing and linear indexing in 1d when
# indices may be nontraditional
Expand All @@ -140,22 +144,39 @@ end
k = 0
cartesian = CartesianIndices((4,3))
linear = LinearIndices(cartesian)
@test size(cartesian) == size(linear) == (4, 3)
for j = 1:3, i = 1:4
@test linear[i,j] == (k+=1)
k += 1
@test linear[i,j] == linear[k] == k
@test cartesian[k] == CartesianIndex(i,j)
@test LinearIndices(0:3,3:5)[i-1,j+2] == k
@test CartesianIndices(0:3,3:5)[k] == CartesianIndex(i-1,j+2)
end
@test linear[linear] == linear
@test linear[vec(linear)] == vec(linear)
@test linear[cartesian] == linear
@test linear[vec(cartesian)] == vec(linear)
@test cartesian[linear] == cartesian
@test cartesian[vec(linear)] == vec(cartesian)
@test cartesian[cartesian] == cartesian
@test cartesian[vec(cartesian)] == vec(cartesian)
end

@testset "3-dimensional" begin
l = 0
for k = 1:2, j = 1:3, i = 1:4
@test LinearIndices((4,3,2))[i,j,k] == (l+=1)
l += 1
@test LinearIndices((4,3,2))[i,j,k] == l
@test LinearIndices((4,3,2))[l] == l
@test CartesianIndices((4,3,2))[i,j,k] == CartesianIndex(i,j,k)
@test CartesianIndices((4,3,2))[l] == CartesianIndex(i,j,k)
@test LinearIndices(1:4,1:3,1:2)[i,j,k] == l
@test LinearIndices(1:4,1:3,1:2)[l] == l
@test CartesianIndices(1:4,1:3,1:2)[i,j,k] == CartesianIndex(i,j,k)
@test CartesianIndices(1:4,1:3,1:2)[l] == CartesianIndex(i,j,k)
@test LinearIndices(0:3,3:5,-101:-100)[i-1,j+2,k-102] == l
@test LinearIndices(0:3,3:5,-101:-100)[l] == l
@test CartesianIndices(0:3,3:5,-101:-100)[i,j,k] == CartesianIndex(i-1, j+2, k-102)
@test CartesianIndices(0:3,3:5,-101:-100)[l] == CartesianIndex(i-1, j+2, k-102)
end

Expand Down

0 comments on commit f27f4b8

Please sign in to comment.