diff --git a/src/blockaxis.jl b/src/blockaxis.jl index b6c151ae..1f4730d0 100644 --- a/src/blockaxis.jl +++ b/src/blockaxis.jl @@ -406,9 +406,13 @@ end @propagate_inbounds getindex(b::AbstractBlockedUnitRange, KR::BlockSlice) = b[KR.block] getindex(b::AbstractBlockedUnitRange, KR::AbstractVector{<:Block{1}}) = mortar([b[K] for K in KR]) -getindex(b::AbstractBlockedUnitRange, KR::AbstractVector{<:BlockIndexRange{1}}) = mortar([b[K] for K in KR]) -getindex(b::AbstractBlockedUnitRange, KR::AbstractVector{<:BlockIndex{1}}) = [b[K] for K in KR] +getindex(b::AbstractBlockedUnitRange, KR::AbstractVector{<:AbstractVector{<:Block{1}}}) = mortar([b[K] for K in KR]) getindex(b::AbstractBlockedUnitRange, Kkr::BlockIndexRange{1}) = b[block(Kkr)][Kkr.indices...] +getindex(b::AbstractBlockedUnitRange, KR::AbstractVector{<:BlockIndex{1}}) = [b[K] for K in KR] +getindex(b::AbstractBlockedUnitRange, KR::AbstractVector{<:BlockIndexRange{1}}) = mortar([b[K] for K in KR]) +getindex(b::AbstractBlockedUnitRange, KR::AbstractVector{<:AbstractVector{<:BlockIndex{1}}}) = mortar([b[K] for K in KR]) +getindex(b::AbstractBlockedUnitRange, KR::AbstractVector{<:AbstractVector{<:BlockIndexRange{1}}}) = mortar([b[K] for K in KR]) +getindex(b::AbstractBlockedUnitRange, KR::AbstractVector{<:AbstractVector{<:AbstractVector{<:BlockIndex{1}}}}) = mortar([b[K] for K in KR]) _searchsortedfirst(a::AbstractVector, k) = searchsortedfirst(a, k) function _searchsortedfirst(a::Tuple, k) diff --git a/src/views.jl b/src/views.jl index d66834e1..28dd308a 100644 --- a/src/views.jl +++ b/src/views.jl @@ -26,30 +26,40 @@ to_index(::BlockRange) = throw(ArgumentError("BlockRange must be converted by to @inline to_indices(A, inds, I::Tuple{Block{1}, Vararg{Any}}) = (unblock(A, inds, I), to_indices(A, _maybetail(inds), tail(I))...) -@inline to_indices(A, inds, I::Tuple{BlockRange{1,R}, Vararg{Any}}) where R = +@inline to_indices(A, inds, I::Tuple{BlockRange{1}, Vararg{Any}}) = + (unblock(A, inds, I), to_indices(A, _maybetail(inds), tail(I))...) +@inline to_indices(A, inds, I::Tuple{AbstractVector{<:Block{1}}, Vararg{Any}}) = + (unblock(A, inds, I), to_indices(A, _maybetail(inds), tail(I))...) +@inline to_indices(A, inds, I::Tuple{AbstractVector{<:BlockRange{1}}, Vararg{Any}}) = + (unblock(A, inds, I), to_indices(A, _maybetail(inds), tail(I))...) +@inline to_indices(A, inds, I::Tuple{AbstractVector{<:AbstractVector{<:Block{1}}}, Vararg{Any}}) = (unblock(A, inds, I), to_indices(A, _maybetail(inds), tail(I))...) @inline to_indices(A, inds, I::Tuple{BlockIndex{1}, Vararg{Any}}) = (inds[1][I[1]], to_indices(A, _maybetail(inds), tail(I))...) -@inline to_indices(A, inds, I::Tuple{BlockIndexRange{1,R}, Vararg{Any}}) where R = - (unblock(A, inds, I), to_indices(A, _maybetail(inds), tail(I))...) -@inline to_indices(A, inds, I::Tuple{AbstractVector{Block{1,R}}, Vararg{Any}}) where R = +@inline to_indices(A, inds, I::Tuple{BlockIndexRange{1}, Vararg{Any}}) = (unblock(A, inds, I), to_indices(A, _maybetail(inds), tail(I))...) @inline to_indices(A, inds, I::Tuple{AbstractVector{<:BlockIndex{1}}, Vararg{Any}}) = (unblock(A, inds, I), to_indices(A, _maybetail(inds), tail(I))...) @inline to_indices(A, inds, I::Tuple{AbstractVector{<:BlockIndexRange{1}}, Vararg{Any}}) = (unblock(A, inds, I), to_indices(A, _maybetail(inds), tail(I))...) +@inline to_indices(A, inds, I::Tuple{AbstractVector{<:AbstractVector{<:BlockIndex{1}}}, Vararg{Any}}) = + (unblock(A, inds, I), to_indices(A, _maybetail(inds), tail(I))...) +@inline to_indices(A, inds, I::Tuple{AbstractVector{<:AbstractVector{<:BlockIndexRange{1}}}, Vararg{Any}}) = + (unblock(A, inds, I), to_indices(A, _maybetail(inds), tail(I))...) +@inline to_indices(A, inds, I::Tuple{AbstractVector{<:AbstractVector{<:AbstractVector{<:BlockIndex{1}}}}, Vararg{Any}}) = + (unblock(A, inds, I), to_indices(A, _maybetail(inds), tail(I))...) # splat out higher dimensional blocks # this mimics view of a CartesianIndex @inline to_indices(A, inds, I::Tuple{Block, Vararg{Any}}) = to_indices(A, inds, (Block.(I[1].n)..., tail(I)...)) +@inline to_indices(A, inds, I::Tuple{BlockRange, Vararg{Any}}) = + to_indices(A, inds, (BlockRange.(tuple.(I[1].indices))..., tail(I)...)) @inline to_indices(A, inds, I::Tuple{BlockIndex, Vararg{Any}}) = to_indices(A, inds, (BlockIndex.(I[1].I, I[1].α)..., tail(I)...)) @inline to_indices(A, inds, I::Tuple{BlockIndexRange, Vararg{Any}}) = to_indices(A, inds, (BlockIndexRange.(Block.(I[1].block.n), tuple.(I[1].indices))..., tail(I)...)) -@inline to_indices(A, inds, I::Tuple{BlockRange, Vararg{Any}}) = - to_indices(A, inds, (BlockRange.(tuple.(I[1].indices))..., tail(I)...)) # In 0.7, we need to override to_indices to avoid calling linearindices @inline to_indices(A, I::Tuple{BlockIndexRange, Vararg{Any}}) = to_indices(A, axes(A), I) @@ -57,8 +67,13 @@ to_index(::BlockRange) = throw(ArgumentError("BlockRange must be converted by to @inline to_indices(A, I::Tuple{Block, Vararg{Any}}) = to_indices(A, axes(A), I) @inline to_indices(A, I::Tuple{BlockRange, Vararg{Any}}) = to_indices(A, axes(A), I) @inline to_indices(A, I::Tuple{AbstractVector{<:Block{1}}, Vararg{Any}}) = to_indices(A, axes(A), I) +@inline to_indices(A, I::Tuple{AbstractVector{<:BlockRange{1}}, Vararg{Any}}) = to_indices(A, axes(A), I) +@inline to_indices(A, I::Tuple{AbstractVector{<:AbstractVector{<:Block{1}}}, Vararg{Any}}) = to_indices(A, axes(A), I) @inline to_indices(A, I::Tuple{AbstractVector{<:BlockIndex{1}}, Vararg{Any}}) = to_indices(A, axes(A), I) @inline to_indices(A, I::Tuple{AbstractVector{<:BlockIndexRange{1}}, Vararg{Any}}) = to_indices(A, axes(A), I) +@inline to_indices(A, I::Tuple{AbstractVector{<:AbstractVector{<:BlockIndex{1}}}, Vararg{Any}}) = to_indices(A, axes(A), I) +@inline to_indices(A, I::Tuple{AbstractVector{<:AbstractVector{<:BlockIndexRange{1}}}, Vararg{Any}}) = to_indices(A, axes(A), I) +@inline to_indices(A, I::Tuple{AbstractVector{<:AbstractVector{<:AbstractVector{<:BlockIndex{1}}}}, Vararg{Any}}) = to_indices(A, axes(A), I) @propagate_inbounds reindex(idxs::Tuple{BlockSlice{<:BlockRange}, Vararg{Any}}, subidxs::Tuple{BlockSlice{<:BlockIndexRange}, Vararg{Any}}) = diff --git a/test/test_blockarrays.jl b/test/test_blockarrays.jl index 286bba42..0139276f 100644 --- a/test/test_blockarrays.jl +++ b/test/test_blockarrays.jl @@ -1069,6 +1069,21 @@ end @test a[[Block(1)[1:2], Block(2)[1:2]], [Block(1)[1:2], Block(2)[1:2]]] == [a[Block(1,1)[1:2,1:2]] a[Block(1,2)[1:2,1:2]]; a[Block(2,1)[1:2,1:2]] a[Block(2,2)[1:2,1:2]]] @test a[[Block(1)[1], Block(2)[2]], [Block(1)[1:2], Block(2)[1:2]]] == [a[Block(1)[1],Block(1)[1:2]]' a[Block(1)[1], Block(2)[1:2]]'; a[Block(2)[2],Block(1)[1:2]]' a[Block(2)[2], Block(2)[1:2]]'] end + @testset "Blocked block-vector indexing (#359)" begin + for a in (BlockArray(randn(14, 14), 2:5, 2:5), BlockedArray(randn(14, 14), 2:5, 2:5)) + for I in ( + [Block.(1:2), Block.(3:4)], + [[Block(1), Block(3)], [Block(2), Block(4)]], + [[Block(1)[1:2], Block(3)[1:2]], [Block(2)[1:2], Block(4)[1:2]]], + [[[Block(1)[1], Block(1)[2]], [Block(3)[1], Block(3)[2]]], [[Block(2)[1], Block(2)[2]], [Block(4)[1], Block(4)[2]]]], + ) + b = a[I, I] + for (i, j) in Iterators.product(1:length(I), 1:length(I)) + @test a[I[i], I[j]] == b[Block(i), Block(j)] + end + end + end + end end end # module