Skip to content

Commit d0e0e27

Browse files
Introduce BlockIndices that generalizes BlockIndexRange to non-contiguous slicing (#483)
Introduce `BlockIndices` that generalizes `BlockIndexRange` to non-contiguous slicing, such as `A[Block(2)[[1, 3]]]`. `BlockIndexRange` is now a type alias for `BlockIndices` when the indices are unit ranges. Closes #419. Split off from #462. --------- Co-authored-by: Sheehan Olver <[email protected]>
1 parent 2f61a7d commit d0e0e27

File tree

9 files changed

+144
-57
lines changed

9 files changed

+144
-57
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "BlockArrays"
22
uuid = "8e7c35d0-a365-5155-bbbb-fb81a777f24e"
3-
version = "1.7.2"
3+
version = "1.8"
44

55
[deps]
66
ArrayLayouts = "4c555306-a7a7-4459-81d9-ec55ddd5c99a"

docs/src/lib/internals.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ BlockedOneTo
2323
BlockedUnitRange
2424
BlockRange
2525
BlockIndexRange
26+
BlockIndices
2627
BlockSlice
2728
unblock
2829
SubBlockIterator

src/BlockArrays.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ using LinearAlgebra, ArrayLayouts, FillArrays
44
# AbstractBlockArray interface exports
55
export AbstractBlockArray, AbstractBlockMatrix, AbstractBlockVector, AbstractBlockVecOrMat
66
export Block, getblock, getblock!, setblock!, eachblock, blocks
7-
export blockaxes, blocksize, blocklength, blockcheckbounds, BlockBoundsError, BlockIndex, BlockIndexRange
7+
export blockaxes, blocksize, blocklength, blockcheckbounds, BlockBoundsError, BlockIndex, BlockIndexRange, BlockIndices
88
export blocksizes, blocklengths, blocklasts, blockfirsts, blockisequal, blockequals, blockisapprox
99
export eachblockaxes
1010
export BlockRange, blockedrange, BlockedUnitRange, BlockedOneTo

src/blockaxis.jl

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
@propagate_inbounds getindex(b::AbstractArray, K::BlockIndex{1}, J::BlockIndex{1}...) =
88
b[BlockIndex(tuple(K, J...))]
99

10-
@propagate_inbounds getindex(b::AbstractArray{T,N}, K::BlockIndexRange{N}) where {T,N} = b[block(K)][K.indices...]
11-
@propagate_inbounds getindex(b::LayoutArray{T,N}, K::BlockIndexRange{N}) where {T,N} = b[block(K)][K.indices...]
12-
@propagate_inbounds getindex(b::LayoutArray{T,1}, K::BlockIndexRange{1}) where {T} = b[block(K)][K.indices...]
10+
@propagate_inbounds getindex(b::AbstractArray{T,N}, K::BlockIndices{N}) where {T,N} = b[block(K)][K.indices...]
11+
@propagate_inbounds getindex(b::LayoutArray{T,N}, K::BlockIndices{N}) where {T,N} = b[block(K)][K.indices...]
12+
@propagate_inbounds getindex(b::LayoutArray{T,1}, K::BlockIndices{1}) where {T} = b[block(K)][K.indices...]
1313

1414
function findblockindex(b::AbstractVector, k::Integer)
1515
@boundscheck k in b || throw(BoundsError())
@@ -539,11 +539,11 @@ end
539539

540540
getindex(b::AbstractBlockedUnitRange, KR::AbstractVector{<:Block{1}}) = mortar([b[K] for K in KR])
541541
getindex(b::AbstractBlockedUnitRange, KR::AbstractVector{<:AbstractVector{<:Block{1}}}) = mortar([b[K] for K in KR])
542-
getindex(b::AbstractBlockedUnitRange, Kkr::BlockIndexRange{1}) = b[block(Kkr)][Kkr.indices...]
542+
getindex(b::AbstractBlockedUnitRange, Kkr::BlockIndices{1}) = b[block(Kkr)][Kkr.indices...]
543543
getindex(b::AbstractBlockedUnitRange, KR::AbstractVector{<:BlockIndex{1}}) = [b[K] for K in KR]
544-
getindex(b::AbstractBlockedUnitRange, KR::AbstractVector{<:BlockIndexRange{1}}) = mortar([b[K] for K in KR])
544+
getindex(b::AbstractBlockedUnitRange, KR::AbstractVector{<:BlockIndices{1}}) = mortar([b[K] for K in KR])
545545
getindex(b::AbstractBlockedUnitRange, KR::AbstractVector{<:AbstractVector{<:BlockIndex{1}}}) = mortar([b[K] for K in KR])
546-
getindex(b::AbstractBlockedUnitRange, KR::AbstractVector{<:AbstractVector{<:BlockIndexRange{1}}}) = mortar([b[K] for K in KR])
546+
getindex(b::AbstractBlockedUnitRange, KR::AbstractVector{<:AbstractVector{<:BlockIndices{1}}}) = mortar([b[K] for K in KR])
547547
getindex(b::AbstractBlockedUnitRange, KR::AbstractVector{<:AbstractVector{<:AbstractVector{<:BlockIndex{1}}}}) = mortar([b[K] for K in KR])
548548

549549
_searchsortedfirst(a::AbstractVector, k) = searchsortedfirst(a, k)
@@ -567,7 +567,7 @@ Base.dataids(b::AbstractBlockedUnitRange) = Base.dataids(blocklasts(b))
567567
Base.checkindex(::Type{Bool}, b::BlockRange, K::Integer) = checkindex(Bool, Integer.(b), K)
568568
Base.checkindex(::Type{Bool}, b::AbstractUnitRange{<:Integer}, K::Block{1}) = checkindex(Bool, blockaxes(b,1), Integer(K))
569569

570-
function Base.checkindex(::Type{Bool}, axis::AbstractBlockedUnitRange, ind::BlockIndexRange{1})
570+
function Base.checkindex(::Type{Bool}, axis::AbstractBlockedUnitRange, ind::BlockIndices{1})
571571
checkindex(Bool, axis, first(ind)) && checkindex(Bool, axis, last(ind))
572572
end
573573
function Base.checkindex(::Type{Bool}, axis::AbstractBlockedUnitRange, ind::BlockIndex{1})

src/blockindices.jl

Lines changed: 77 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -207,19 +207,68 @@ end
207207
checkbounds(::Type{Bool}, A::AbstractArray{<:Any,N}, I::AbstractArray{<:BlockIndex{N}}) where N =
208208
all(i -> checkbounds(Bool, A, i), I)
209209

210-
struct BlockIndexRange{N,R<:Tuple{Vararg{AbstractUnitRange{<:Integer},N}},I<:Tuple{Vararg{Integer,N}},BI<:Integer} <: AbstractArray{BlockIndex{N,NTuple{N,BI},I},N}
210+
struct BlockIndices{N,R<:Tuple{Vararg{AbstractVector,N}},I<:Tuple{Vararg{Any,N}},BI} <: AbstractArray{BlockIndex{N,NTuple{N,BI},I},N}
211211
block::Block{N,BI}
212212
indices::R
213-
function BlockIndexRange(block::Block{N,BI}, inds::R) where {N,BI<:Integer,R<:Tuple{Vararg{AbstractUnitRange{<:Integer},N}}}
213+
function BlockIndices(block::Block{N,BI}, inds::R) where {N,BI<:Integer,R<:Tuple{Vararg{AbstractVector,N}}}
214214
I = Tuple{eltype.(inds)...}
215215
return new{N,R,I,BI}(block,inds)
216216
end
217217
end
218218

219+
"""
220+
BlockIndices(block, startind:stopind)
221+
Represents a cartesian product of indices inside a block.
222+
It can be constructed and used to index into `BlockArrays` in the following manner:
223+
```jldoctest
224+
julia> BlockIndices(Block(1,2), ([1,3],[2,4]))
225+
Block(1, 2)[[1, 3], [2, 4]]
226+
227+
julia> Block(1)[[1,3]] == BlockIndices(Block(1), [1,3])
228+
true
229+
230+
julia> Block(1,2)[[1,3],[2,4]] == BlockIndices(Block(1,2), ([1,3],[2,4]))
231+
true
232+
233+
julia> BlockIndices((Block(1)[[1,3]], Block(2)[[2,4]]))
234+
Block(1, 2)[[1, 3], [2, 4]]
235+
236+
julia> arr = Array(reshape(1:25, (5,5)));
237+
238+
julia> a = BlockedArray(arr, [3,2], [1,4])
239+
2×2-blocked 5×5 BlockedMatrix{Int64}:
240+
1 │ 6 11 16 21
241+
2 │ 7 12 17 22
242+
3 │ 8 13 18 23
243+
───┼────────────────
244+
4 │ 9 14 19 24
245+
5 │ 10 15 20 25
246+
247+
julia> a[Block(1,2)[[1,3],[2,4]]]
248+
2×2 Matrix{Int64}:
249+
11 21
250+
13 23
251+
252+
julia> a[Block(2,2)[[2],[2,4]]]
253+
1×2 Matrix{Int64}:
254+
15 25
255+
```
256+
"""
257+
BlockIndices
258+
259+
BlockIndices(block::Block{N}, inds::Vararg{AbstractVector,N}) where {N} =
260+
BlockIndices(block,inds)
261+
function BlockIndices(inds::Tuple{BlockIndices{1},Vararg{BlockIndices{1}}})
262+
BlockIndices(Block(block.(inds)), map(ind -> ind.indices[1], inds))
263+
end
264+
265+
const BlockIndexRange{N,R<:Tuple{Vararg{AbstractUnitRange{<:Integer},N}},I<:Tuple{Vararg{Any,N}},BI} = BlockIndices{N,R,I,BI}
266+
219267
"""
220268
BlockIndexRange(block, startind:stopind)
221269
222-
Represents a cartesian range inside a block.
270+
Represents a cartesian range inside a block. Type alias for `BlockIndices` with
271+
the indices constrained to ranges.
223272
224273
It can be constructed and used to index into `BlockArrays` in the following manner:
225274
@@ -260,60 +309,62 @@ julia> a[Block(2,2)[1:2,3:4]]
260309
"""
261310
BlockIndexRange
262311

312+
BlockIndexRange(block::Block{N}, inds::Tuple{Vararg{AbstractUnitRange{<:Integer},N}}) where {N} =
313+
BlockIndices(block, inds)
263314
BlockIndexRange(block::Block{N}, inds::Vararg{AbstractUnitRange{<:Integer},N}) where {N} =
264-
BlockIndexRange(block,inds)
315+
BlockIndices(block,inds)
265316

266317
function BlockIndexRange(inds::Tuple{BlockIndexRange{1},Vararg{BlockIndexRange{1}}})
267318
BlockIndexRange(Block(block.(inds)), map(ind -> ind.indices[1], inds))
268319
end
269320

270-
block(R::BlockIndexRange) = R.block
321+
block(R::BlockIndices) = R.block
271322

272-
copy(R::BlockIndexRange) = BlockIndexRange(R.block, map(copy, R.indices))
323+
copy(R::BlockIndices) = BlockIndices(R.block, map(copy, R.indices))
273324

274325
getindex(::Block{0}) = BlockIndex()
275326
getindex(B::Block{N}, inds::Vararg{Integer,N}) where N = BlockIndex(B,inds)
276-
getindex(B::Block{N}, inds::Vararg{AbstractUnitRange{<:Integer},N}) where N = BlockIndexRange(B,inds)
327+
getindex(B::Block{N}, inds::Vararg{AbstractVector,N}) where N = BlockIndices(B,inds)
277328
getindex(B::Block{1}, inds::Colon) = B
278329
getindex(B::Block{1}, inds::Base.Slice) = B
279330

280-
getindex(B::BlockIndexRange{0}) = B.block[]
281-
@propagate_inbounds getindex(B::BlockIndexRange{N}, kr::Vararg{AbstractUnitRange{<:Integer},N}) where {N} = BlockIndexRange(B.block, map(getindex, B.indices, kr))
282-
@propagate_inbounds getindex(B::BlockIndexRange{N}, inds::Vararg{Int,N}) where N = B.block[Base.reindex(B.indices, inds)...]
331+
getindex(B::BlockIndices{0}) = B.block[]
332+
@propagate_inbounds getindex(B::BlockIndices{N}, kr::Vararg{AbstractVector,N}) where {N} = BlockIndices(B.block, map(getindex, B.indices, kr))
333+
@propagate_inbounds getindex(B::BlockIndices{N}, inds::Vararg{Int,N}) where N = B.block[Base.reindex(B.indices, inds)...]
283334

284-
eltype(R::BlockIndexRange) = eltype(typeof(R))
285-
eltype(::Type{BlockIndexRange{N}}) where {N} = BlockIndex{N}
286-
eltype(::Type{BlockIndexRange{N,R,I,BI}}) where {N,R,I,BI} = BlockIndex{N,NTuple{N,BI},I}
287-
IteratorSize(::Type{<:BlockIndexRange}) = Base.HasShape{1}()
335+
eltype(R::BlockIndices) = eltype(typeof(R))
336+
eltype(::Type{BlockIndices{N}}) where {N} = BlockIndex{N}
337+
eltype(::Type{BlockIndices{N,R,I,BI}}) where {N,R,I,BI} = BlockIndex{N,NTuple{N,BI},I}
338+
IteratorSize(::Type{<:BlockIndices}) = Base.HasShape{1}()
288339

289340

290-
first(iter::BlockIndexRange) = BlockIndex(iter.block.n, map(first, iter.indices))
291-
last(iter::BlockIndexRange) = BlockIndex(iter.block.n, map(last, iter.indices))
341+
first(iter::BlockIndices) = BlockIndex(iter.block.n, map(first, iter.indices))
342+
last(iter::BlockIndices) = BlockIndex(iter.block.n, map(last, iter.indices))
292343

293-
@inline function iterate(iter::BlockIndexRange)
344+
@inline function iterate(iter::BlockIndices)
294345
iterfirst, iterlast = first(iter), last(iter)
295346
if any(map(>, iterfirst.α, iterlast.α))
296347
return nothing
297348
end
298349
iterfirst, iterfirst
299350
end
300-
@inline function iterate(iter::BlockIndexRange, state)
351+
@inline function iterate(iter::BlockIndices, state)
301352
nextstate = BlockIndex(state.I, inc(state.α, first(iter).α, last(iter).α))
302353
nextstate.α[end] > last(iter.indices[end]) && return nothing
303354
nextstate, nextstate
304355
end
305356

306-
size(iter::BlockIndexRange) = map(dimlength, first(iter).α, last(iter).α)
307-
length(iter::BlockIndexRange) = prod(size(iter))
357+
size(iter::BlockIndices) = map(dimlength, first(iter).α, last(iter).α)
358+
length(iter::BlockIndices) = prod(size(iter))
308359

309360

310-
Block(bs::BlockIndexRange) = bs.block
361+
Block(bs::BlockIndices) = bs.block
311362

312363
##
313364
# checkindex
314365
##
315366

316-
function checkbounds(::Type{Bool}, A::AbstractArray{<:Any,N}, I::BlockIndexRange{N}) where N
367+
function checkbounds(::Type{Bool}, A::AbstractArray{<:Any,N}, I::BlockIndices{N}) where N
317368
bl = block(I)
318369
checkbounds(Bool, A, bl) || return false
319370
# TODO: Replace with `eachblockaxes(A)[bl]` once that is defined.
@@ -334,10 +385,11 @@ end
334385
"""
335386
BlockSlice(block, indices)
336387
337-
Represent an AbstractUnitRange{<:Integer} of indices that attaches a block.
388+
Represents an AbstractUnitRange{<:Integer} of indices attached to a block,
389+
a subblock, or a range of blocks.
338390
339391
Upon calling `to_indices()`, Blocks are converted to BlockSlice objects to represent
340-
the indices over which the Block spans.
392+
the indices over which the block, subblock, or range of blocks spans.
341393
342394
This mimics the relationship between `Colon` and `Base.Slice`.
343395
"""
@@ -347,7 +399,7 @@ struct BlockSlice{BB,T<:Integer,INDS<:AbstractUnitRange{T}} <: AbstractUnitRange
347399
end
348400

349401
Block(bs::BlockSlice{<:Block}) = bs.block
350-
402+
Block(bs::BlockSlice{<:BlockIndices}) = Block(bs.block)
351403

352404
for f in (:axes, :unsafe_indices, :axes1, :first, :last, :size, :length,
353405
:unsafe_length, :start)
@@ -366,8 +418,6 @@ _indices(B) = B
366418
# Avoid creating a SubArray wrapper in certain non-allocating cases
367419
@propagate_inbounds view(C::CartesianIndices{N}, bs::Vararg{BlockSlice,N}) where {N} = view(C, map(x->x.indices, bs)...)
368420

369-
Block(bs::BlockSlice{<:BlockIndexRange}) = Block(bs.block)
370-
371421
"""
372422
BlockedSlice(blocks, indices)
373423

src/show.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,13 +186,13 @@ function Base.show(io::IO, B::BlockIndex)
186186
print(io, "]")
187187
end
188188

189-
function Base.show(io::IO, B::BlockIndexRange)
189+
function Base.show(io::IO, B::BlockIndices)
190190
show(io, Block(B))
191191
print(io, "[")
192192
print_tuple_elements(io, B.indices)
193193
print(io, "]")
194194
end
195-
Base.show(io::IO, ::MIME"text/plain", B::BlockIndexRange) = show(io, B)
195+
Base.show(io::IO, ::MIME"text/plain", B::BlockIndices) = show(io, B)
196196

197197
Base.show(io::IO, mimetype::MIME"text/plain", a::AbstractBlockedUnitRange) =
198198
Base.invoke(show, Tuple{typeof(io),MIME"text/plain",AbstractArray},io, mimetype, a)

src/views.jl

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ unblock(A, ::Tuple{}, I) = BlockSlice(first(I),Base.OneTo(length(I[1])))
2020

2121
to_index(::Block) = throw(ArgumentError("Block must be converted by to_indices(...)"))
2222
to_index(::BlockIndex) = throw(ArgumentError("BlockIndex must be converted by to_indices(...)"))
23-
to_index(::BlockIndexRange) = throw(ArgumentError("BlockIndexRange must be converted by to_indices(...)"))
23+
to_index(::BlockIndices) = throw(ArgumentError("BlockIndices must be converted by to_indices(...)"))
2424
to_index(::BlockRange) = throw(ArgumentError("BlockRange must be converted by to_indices(...)"))
2525

2626

@@ -36,15 +36,15 @@ to_index(::BlockRange) = throw(ArgumentError("BlockRange must be converted by to
3636
(unblock(A, inds, I), to_indices(A, _maybetail(inds), tail(I))...)
3737
@inline to_indices(A, inds, I::Tuple{BlockIndex{1}, Vararg{Any}}) =
3838
(inds[1][I[1]], to_indices(A, _maybetail(inds), tail(I))...)
39-
@inline to_indices(A, inds, I::Tuple{BlockIndexRange{1}, Vararg{Any}}) =
39+
@inline to_indices(A, inds, I::Tuple{BlockIndices{1}, Vararg{Any}}) =
4040
(unblock(A, inds, I), to_indices(A, _maybetail(inds), tail(I))...)
4141
@inline to_indices(A, inds, I::Tuple{AbstractVector{<:BlockIndex{1}}, Vararg{Any}}) =
4242
(unblock(A, inds, I), to_indices(A, _maybetail(inds), tail(I))...)
43-
@inline to_indices(A, inds, I::Tuple{AbstractVector{<:BlockIndexRange{1}}, Vararg{Any}}) =
43+
@inline to_indices(A, inds, I::Tuple{AbstractVector{<:BlockIndices{1}}, Vararg{Any}}) =
4444
(unblock(A, inds, I), to_indices(A, _maybetail(inds), tail(I))...)
4545
@inline to_indices(A, inds, I::Tuple{AbstractVector{<:AbstractVector{<:BlockIndex{1}}}, Vararg{Any}}) =
4646
(unblock(A, inds, I), to_indices(A, _maybetail(inds), tail(I))...)
47-
@inline to_indices(A, inds, I::Tuple{AbstractVector{<:AbstractVector{<:BlockIndexRange{1}}}, Vararg{Any}}) =
47+
@inline to_indices(A, inds, I::Tuple{AbstractVector{<:AbstractVector{<:BlockIndices{1}}}, Vararg{Any}}) =
4848
(unblock(A, inds, I), to_indices(A, _maybetail(inds), tail(I))...)
4949
@inline to_indices(A, inds, I::Tuple{AbstractVector{<:AbstractVector{<:AbstractVector{<:BlockIndex{1}}}}, Vararg{Any}}) =
5050
(unblock(A, inds, I), to_indices(A, _maybetail(inds), tail(I))...)
@@ -58,21 +58,21 @@ to_index(::BlockRange) = throw(ArgumentError("BlockRange must be converted by to
5858
to_indices(A, inds, (BlockRange.(tuple.(I[1].indices))..., tail(I)...))
5959
@inline to_indices(A, inds, I::Tuple{BlockIndex, Vararg{Any}}) =
6060
to_indices(A, inds, (BlockIndex.(I[1].I, I[1].α)..., tail(I)...))
61-
@inline to_indices(A, inds, I::Tuple{BlockIndexRange, Vararg{Any}}) =
62-
to_indices(A, inds, (BlockIndexRange.(Block.(I[1].block.n), tuple.(I[1].indices))..., tail(I)...))
61+
@inline to_indices(A, inds, I::Tuple{BlockIndices, Vararg{Any}}) =
62+
to_indices(A, inds, (BlockIndices.(Block.(I[1].block.n), tuple.(I[1].indices))..., tail(I)...))
6363

6464
# In 0.7, we need to override to_indices to avoid calling linearindices
65-
@inline to_indices(A, I::Tuple{BlockIndexRange, Vararg{Any}}) = to_indices(A, axes(A), I)
65+
@inline to_indices(A, I::Tuple{BlockIndices, Vararg{Any}}) = to_indices(A, axes(A), I)
6666
@inline to_indices(A, I::Tuple{BlockIndex, Vararg{Any}}) = to_indices(A, axes(A), I)
6767
@inline to_indices(A, I::Tuple{Block, Vararg{Any}}) = to_indices(A, axes(A), I)
6868
@inline to_indices(A, I::Tuple{BlockRange, Vararg{Any}}) = to_indices(A, axes(A), I)
6969
@inline to_indices(A, I::Tuple{AbstractVector{<:Block{1}}, Vararg{Any}}) = to_indices(A, axes(A), I)
7070
@inline to_indices(A, I::Tuple{AbstractVector{<:BlockRange{1}}, Vararg{Any}}) = to_indices(A, axes(A), I)
7171
@inline to_indices(A, I::Tuple{AbstractVector{<:AbstractVector{<:Block{1}}}, Vararg{Any}}) = to_indices(A, axes(A), I)
7272
@inline to_indices(A, I::Tuple{AbstractVector{<:BlockIndex{1}}, Vararg{Any}}) = to_indices(A, axes(A), I)
73-
@inline to_indices(A, I::Tuple{AbstractVector{<:BlockIndexRange{1}}, Vararg{Any}}) = to_indices(A, axes(A), I)
73+
@inline to_indices(A, I::Tuple{AbstractVector{<:BlockIndices{1}}, Vararg{Any}}) = to_indices(A, axes(A), I)
7474
@inline to_indices(A, I::Tuple{AbstractVector{<:AbstractVector{<:BlockIndex{1}}}, Vararg{Any}}) = to_indices(A, axes(A), I)
75-
@inline to_indices(A, I::Tuple{AbstractVector{<:AbstractVector{<:BlockIndexRange{1}}}, Vararg{Any}}) = to_indices(A, axes(A), I)
75+
@inline to_indices(A, I::Tuple{AbstractVector{<:AbstractVector{<:BlockIndices{1}}}, Vararg{Any}}) = to_indices(A, axes(A), I)
7676
@inline to_indices(A, I::Tuple{AbstractVector{<:AbstractVector{<:AbstractVector{<:BlockIndex{1}}}}, Vararg{Any}}) = to_indices(A, axes(A), I)
7777

7878
## BlockedLogicalIndex
@@ -119,8 +119,8 @@ checkindex(::Type{Bool}, inds::AbstractUnitRange, i::BlockedLogicalIndex) = chec
119119
(blockcollect(I[1]), ensure_indexable(tail(I))...)
120120

121121
@propagate_inbounds reindex(idxs::Tuple{BlockSlice{<:BlockRange}, Vararg{Any}},
122-
subidxs::Tuple{BlockSlice{<:BlockIndexRange}, Vararg{Any}}) =
123-
(BlockSlice(BlockIndexRange(Block(idxs[1].block.indices[1][Int(subidxs[1].block.block)]),
122+
subidxs::Tuple{BlockSlice{<:BlockIndices}, Vararg{Any}}) =
123+
(BlockSlice(BlockIndices(Block(idxs[1].block.indices[1][Int(subidxs[1].block.block)]),
124124
subidxs[1].block.indices),
125125
idxs[1].indices[subidxs[1].indices]),
126126
reindex(tail(idxs), tail(subidxs))...)
@@ -143,36 +143,36 @@ _splatmap(f, t::Tuple) = (f(t[1])..., _splatmap(f, tail(t))...)
143143
# path in `AbstractBlockStyle` broadcasting.
144144
@propagate_inbounds function Base.unsafe_view(
145145
A::BlockArray{<:Any, N},
146-
I::Vararg{BlockSlice{<:BlockIndexRange{1}}, N}) where {N}
146+
I::Vararg{BlockSlice{<:BlockIndices{1}}, N}) where {N}
147147
B = view(A, map(block, I)...)
148148
return view(B, _splatmap(x -> x.block.indices, I)...)
149149
end
150150

151151
@propagate_inbounds function Base.unsafe_view(
152152
A::BlockedArray{<:Any, N},
153-
I::Vararg{BlockSlice{<:BlockIndexRange{1}}, N}) where {N}
153+
I::Vararg{BlockSlice{<:BlockIndices{1}}, N}) where {N}
154154
return view(A.blocks, map(x -> x.indices, I)...)
155155
end
156156

157157
@propagate_inbounds function Base.unsafe_view(
158158
A::ReshapedArray{<:Any, N, <:AbstractBlockArray{<:Any, M}},
159-
I::Vararg{BlockSlice{<:BlockIndexRange{1}}, N}) where {N, M}
159+
I::Vararg{BlockSlice{<:BlockIndices{1}}, N}) where {N, M}
160160
# Note: assuming that I[M+1:end] are verified to be singletons
161161
return reshape(view(A.parent, I[1:M]...), Val(N))
162162
end
163163

164164
@propagate_inbounds function Base.unsafe_view(
165165
A::Array,
166-
I1::BlockSlice{<:BlockIndexRange{1}},
167-
Is::Vararg{BlockSlice{<:BlockIndexRange{1}}},
166+
I1::BlockSlice{<:BlockIndices{1}},
167+
Is::Vararg{BlockSlice{<:BlockIndices{1}}},
168168
)
169169
I = (I1, Is...)
170170
@assert ndims(A) == length(I)
171171
return view(A, map(x -> x.indices, I)...)
172172
end
173173

174-
# make sure we reindex correctrly
175-
@inline function Base._maybe_reindex(V, I::Tuple{BlockSlice{<:BlockIndexRange{1}}, Vararg{Any}}, ::Tuple{})
174+
# make sure we reindex correctly
175+
@inline function Base._maybe_reindex(V, I::Tuple{BlockSlice{<:BlockIndices{1}}, Vararg{Any}}, ::Tuple{})
176176
@inbounds idxs = to_indices(V.parent, reindex(V.indices, I))
177177
view(V.parent, idxs...)
178178
end

test/test_blockarrays.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -998,6 +998,14 @@ end
998998
@test A[Block(1)[1], Block(1)[1:1]] == BlockArray(A)[Block(1)[1], Block(1)[1:1]] == A[1,1:1]
999999
end
10001000

1001+
@testset "BlockIndices" begin
1002+
a = BlockedArray(randn(5), [2,3])
1003+
@test a[Block(2)[[1,3]]] == a[[3,5]]
1004+
A = BlockedArray(randn(5,5), [2,3], [2,3])
1005+
@test A[Block(2,2)[[1,3],[2,3]]] == A[[3,5],[4,5]]
1006+
@test A[Block(2,2)[[1,3],1:2]] == A[[3,5],3:4]
1007+
end
1008+
10011009
@testset "BlockIndexRange blocks" begin
10021010
a = mortar([Block(1)[1:2], Block(3)[2:3]])
10031011
@test a[Block(1)] === Block(1)[1:2]

0 commit comments

Comments
 (0)