@@ -207,19 +207,68 @@ end
207207checkbounds (:: 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
217217end
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
224273It 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"""
261310BlockIndexRange
262311
312+ BlockIndexRange (block:: Block{N} , inds:: Tuple{Vararg{AbstractUnitRange{<:Integer},N}} ) where {N} =
313+ BlockIndices (block, inds)
263314BlockIndexRange (block:: Block{N} , inds:: Vararg{AbstractUnitRange{<:Integer},N} ) where {N} =
264- BlockIndexRange (block,inds)
315+ BlockIndices (block,inds)
265316
266317function BlockIndexRange (inds:: Tuple{BlockIndexRange{1},Vararg{BlockIndexRange{1}}} )
267318 BlockIndexRange (Block (block .(inds)), map (ind -> ind. indices[1 ], inds))
268319end
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
274325getindex (:: Block{0} ) = BlockIndex ()
275326getindex (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)
277328getindex (B:: Block{1} , inds:: Colon ) = B
278329getindex (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
299350end
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
304355end
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
339391Upon 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
342394This mimics the relationship between `Colon` and `Base.Slice`.
343395"""
@@ -347,7 +399,7 @@ struct BlockSlice{BB,T<:Integer,INDS<:AbstractUnitRange{T}} <: AbstractUnitRange
347399end
348400
349401Block (bs:: BlockSlice{<:Block} ) = bs. block
350-
402+ Block (bs :: BlockSlice{<:BlockIndices} ) = Block (bs . block)
351403
352404for 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
0 commit comments