Skip to content

Commit

Permalink
handle zero dimensional DimIndices (#766)
Browse files Browse the repository at this point in the history
* handle zero dimensional Dimindices

* fix and test zero dimensional getindex and view on DimIndices

* zero dim constructor not needed

* getindex not needed
  • Loading branch information
rafaqz authored Aug 16, 2024
1 parent 1e4af16 commit 183d1d3
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 6 deletions.
17 changes: 11 additions & 6 deletions src/dimindices.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ for f in (:getindex, :dotview, :view)
rebuild(di; dims=(dims(di, 1)[i],))
@eval @propagate_inbounds Base.$f(dg::AbstractDimArrayGenerator, i::Integer) =
Base.$f(dg, Tuple(CartesianIndices(dg)[i])...)
if f == :view
@eval @propagate_inbounds Base.$f(A::AbstractDimArrayGenerator) = A
else
@eval @propagate_inbounds Base.$f(::AbstractDimArrayGenerator) = ()
end
end

@inline Base.permutedims(A::AbstractDimArrayGenerator{<:Any,2}) =
Expand Down Expand Up @@ -163,12 +168,12 @@ that defines a `dims` method can be passed in.
- `order`: determines the order of the points, the same as the order of `dims` by default.
"""
struct DimPoints{T,N,D<:DimTuple,O} <: AbstractDimIndices{T,N,D}
struct DimPoints{T,N,D<:Tuple{Vararg{Dimension}},O} <: AbstractDimIndices{T,N,D}
dims::D
order::O
end
DimPoints(dims::DimTuple; order=dims) = DimPoints(dims, order)
function DimPoints(dims::DimTuple, order::DimTuple)
DimPoints(dims::Tuple; order=dims) = DimPoints(dims, order)
function DimPoints(dims::Tuple, order::Tuple)
order = map(d -> basetypeof(d)(), order)
T = Tuple{map(eltype, dims)...}
N = length(dims)
Expand Down Expand Up @@ -239,15 +244,15 @@ Using `At` would make sure we only use exact interpolation,
while `Contains` with sampling of `Intervals` would make sure that
each values is taken only from an Interval that is present in the lookups.
"""
struct DimSelectors{T,N,D<:Tuple{Dimension,Vararg{Dimension}},S<:Tuple} <: AbstractDimIndices{T,N,D}
struct DimSelectors{T,N,D<:Tuple{Vararg{Dimension}},S<:Tuple} <: AbstractDimIndices{T,N,D}
dims::D
selectors::S
end
function DimSelectors(dims::DimTuple; atol=nothing, selectors=At())
function DimSelectors(dims::Tuple{Vararg{Dimension}}; atol=nothing, selectors=At())
s = _format_selectors(dims, selectors, atol)
DimSelectors(dims, s)
end
function DimSelectors(dims::DimTuple, selectors::Tuple)
function DimSelectors(dims::Tuple{Vararg{Dimension}}, selectors::Tuple)
T = typeof(map(rebuild, dims, selectors))
N = length(dims)
dims = N > 0 ? _format(dims) : dims
Expand Down
34 changes: 34 additions & 0 deletions test/dimindices.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ A = zeros(X(4.0:7.0), Y(10.0:12.0))

@testset "DimIndices" begin
di = @inferred DimIndices(A)
@test eltype(di) == Tuple{X{Int64}, Y{Int64}}
ci = CartesianIndices(A)
@test @inferred val.(collect(di)) == Tuple.(collect(ci))
@test A[di] == view(A, di) == A
Expand Down Expand Up @@ -40,6 +41,17 @@ A = zeros(X(4.0:7.0), Y(10.0:12.0))
@test @inferred A1[X=1, Y=1][di[:]] isa DimArray{Float64,1}
# Indexing with no matching dims is like [] (?)
@test @inferred view(A1, X=1, Y=1, Ti=1)[di[:]] == 0.0

@testset "zero dimensional" begin
di0 = DimIndices(())
@test di0[] == ()
@test view(di0) == di0
@test first(di0) == ()
@test eltype(di0) == Tuple{}
@test ndims(di0) == 0
@test dims(di0) == ()
@test size(di0) == ()
end
end

@testset "DimPoints" begin
Expand All @@ -53,6 +65,17 @@ end
@test_throws ArgumentError DimPoints(nothing)
# Vector
@test @inferred DimPoints(X(1.0:2.0)) == [(1.0,), (2.0,)]

@testset "zero dimensional" begin
dp0 = DimPoints(())
@test dp0[] == ()
@test view(dp0) == dp0
@test first(dp0) == ()
@test eltype(dp0) == Tuple{}
@test ndims(dp0) == 0
@test dims(dp0) == ()
@test size(dp0) == ()
end
end

@testset "DimSelectors" begin
Expand All @@ -77,6 +100,17 @@ end
@test @inferred DimSelectors(X(1.0:2.0)) ==
[(X(At(1.0; atol=eps(Float64))),), (X(At(2.0; atol=eps(Float64))),)]

@testset "zero dimensional" begin
ds0 = DimSelectors(())
@test ds0[] == ()
@test view(ds0) == ds0
@test first(ds0) == ()
@test eltype(ds0) == Tuple{}
@test ndims(ds0) == 0
@test dims(ds0) == ()
@test size(ds0) == ()
end

@testset "atol" begin
dsa = @inferred DimSelectors(A; atol=0.3)
# Mess up the lookups a little...
Expand Down

0 comments on commit 183d1d3

Please sign in to comment.