@@ -244,6 +244,15 @@ BlockArrays.blockindex(b::GenericBlockIndex{1}) = b.α[1]
244
244
function GenericBlockIndex (indcs:: Tuple{Vararg{GenericBlockIndex{1},N}} ) where {N}
245
245
GenericBlockIndex (block .(indcs), blockindex .(indcs))
246
246
end
247
+
248
+ function Base. checkindex (
249
+ :: Type{Bool} , axis:: AbstractBlockedUnitRange , ind:: GenericBlockIndex{1}
250
+ )
251
+ return checkindex (Bool, axis, block (ind)) &&
252
+ checkbounds (Bool, axis[block (ind)], blockindex (ind))
253
+ end
254
+ Base. to_index (i:: GenericBlockIndex ) = i
255
+
247
256
function print_tuple_elements (io:: IO , @nospecialize (t))
248
257
if ! isempty (t)
249
258
print (io, t[1 ])
@@ -261,6 +270,13 @@ function Base.show(io::IO, B::GenericBlockIndex)
261
270
return nothing
262
271
end
263
272
273
+ # https://github.com/JuliaArrays/BlockArrays.jl/blob/v1.6.3/src/views.jl#L31-L32
274
+ _maybetail (:: Tuple{} ) = ()
275
+ _maybetail (t:: Tuple ) = Base. tail (t)
276
+ @inline function Base. to_indices (A, inds, I:: Tuple{GenericBlockIndex{1},Vararg{Any}} )
277
+ return (inds[1 ][I[1 ]], to_indices (A, _maybetail (inds), Base. tail (I))... )
278
+ end
279
+
264
280
using Base: @propagate_inbounds
265
281
@propagate_inbounds function Base. getindex (b:: AbstractVector , K:: GenericBlockIndex{1} )
266
282
return b[Block (K. I[1 ])][K. α[1 ]]
@@ -276,35 +292,65 @@ end
276
292
return b[GenericBlockIndex (tuple (K, J... ))]
277
293
end
278
294
279
- function blockindextype (TB:: Type{<:Integer} , TI:: Vararg{Type{<:Integer},N} ) where {N}
280
- return BlockIndex{N,NTuple{N,TB},Tuple{TI... }}
295
+ # TODO : Delete this once `BlockArrays.BlockIndex` is generalized.
296
+ @inline function Base. to_indices (
297
+ A, inds, I:: Tuple{AbstractVector{<:GenericBlockIndex{1}},Vararg{Any}}
298
+ )
299
+ return (unblock (A, inds, I), to_indices (A, _maybetail (inds), Base. tail (I))... )
281
300
end
282
- function blockindextype (TB:: Type{<:Integer} , TI:: Vararg{Type,N} ) where {N}
283
- return GenericBlockIndex{N,NTuple{N,TB},Tuple{TI... }}
301
+
302
+ # This is a specialization of `BlockArrays.unblock`:
303
+ # https://github.com/JuliaArrays/BlockArrays.jl/blob/v1.6.3/src/views.jl#L8-L11
304
+ # that is used in the `to_indices` logic for blockwise slicing in
305
+ # BlockArrays.jl.
306
+ # TODO : Ideally this would be defined in BlockArrays.jl once the slicing
307
+ # there is made more generic.
308
+ function BlockArrays. unblock (A, inds, I:: Tuple{GenericBlockIndex{1},Vararg{Any}} )
309
+ B = first (I)
310
+ return _blockslice (B, inds[1 ][B])
284
311
end
285
312
286
- struct BlockIndexVector{N,I<: NTuple{N,AbstractVector} ,TB<: Integer ,BT} <: AbstractArray{BT,N}
313
+ # Work around the fact that it is type piracy to define
314
+ # `Base.getindex(a::Block, b...)`.
315
+ _getindex (a:: Block{N} , b:: Vararg{Any,N} ) where {N} = GenericBlockIndex (a, b)
316
+ _getindex (a:: Block{N} , b:: Vararg{Integer,N} ) where {N} = a[b... ]
317
+ # Fix ambiguity.
318
+ _getindex (a:: Block{0} ) = a[]
319
+
320
+ struct BlockIndexVector{N,BT,I<: NTuple{N,AbstractVector} ,TB<: Integer } <: AbstractArray{BT,N}
287
321
block:: Block{N,TB}
288
322
indices:: I
289
- function BlockIndexVector (
323
+ function BlockIndexVector {N,BT} (
290
324
block:: Block{N,TB} , indices:: I
291
- ) where {N,I<: NTuple{N,AbstractVector} ,TB<: Integer }
292
- BT = blockindextype (TB, eltype .(indices)... )
293
- return new {N,I,TB,BT} (block, indices)
325
+ ) where {N,BT,I<: NTuple{N,AbstractVector} ,TB<: Integer }
326
+ return new {N,BT,I,TB} (block, indices)
294
327
end
295
328
end
329
+ function BlockIndexVector {1,BT} (block:: Block{1} , indices:: AbstractVector ) where {BT}
330
+ return BlockIndexVector {1,BT} (block, (indices,))
331
+ end
332
+ function BlockIndexVector (
333
+ block:: Block{N,TB} , indices:: NTuple{N,AbstractVector}
334
+ ) where {N,TB<: Integer }
335
+ BT = Base. promote_op (_getindex, typeof (block), eltype .(indices)... )
336
+ return BlockIndexVector {N,BT} (block, indices)
337
+ end
296
338
function BlockIndexVector (block:: Block{1} , indices:: AbstractVector )
297
339
return BlockIndexVector (block, (indices,))
298
340
end
299
341
Base. size (a:: BlockIndexVector ) = length .(a. indices)
300
342
function Base. getindex (a:: BlockIndexVector{N} , I:: Vararg{Integer,N} ) where {N}
301
- return a . block[ map ((r, i) -> r[i], a. indices, I)... ]
343
+ return _getindex ( Block (a), getindex .( a. indices, I)... )
302
344
end
303
345
BlockArrays. block (b:: BlockIndexVector ) = b. block
304
346
BlockArrays. Block (b:: BlockIndexVector ) = b. block
305
347
306
348
Base. copy (a:: BlockIndexVector ) = BlockIndexVector (a. block, copy .(a. indices))
307
349
350
+ function Base. getindex (b:: AbstractBlockedUnitRange , Kkr:: BlockIndexVector{1} )
351
+ return b[block (Kkr)][Kkr. indices... ]
352
+ end
353
+
308
354
using ArrayLayouts: LayoutArray
309
355
@propagate_inbounds Base. getindex (b:: AbstractArray{T,N} , K:: BlockIndexVector{N} ) where {T,N} = b[block (
310
356
K
@@ -316,6 +362,30 @@ using ArrayLayouts: LayoutArray
316
362
K
317
363
)][K. indices... ]
318
364
365
+ function blockedunitrange_getindices (
366
+ a:: AbstractBlockedUnitRange ,
367
+ indices:: BlockVector{<:BlockIndex{1},<:Vector{<:BlockIndexVector{1}}} ,
368
+ )
369
+ return mortar (map (b -> a[b], blocks (indices)))
370
+ end
371
+ function blockedunitrange_getindices (
372
+ a:: AbstractBlockedUnitRange ,
373
+ indices:: BlockVector{<:GenericBlockIndex{1},<:Vector{<:BlockIndexVector{1}}} ,
374
+ )
375
+ return mortar (map (b -> a[b], blocks (indices)))
376
+ end
377
+
378
+ # This is a specialization of `BlockArrays.unblock`:
379
+ # https://github.com/JuliaArrays/BlockArrays.jl/blob/v1.6.3/src/views.jl#L8-L11
380
+ # that is used in the `to_indices` logic for blockwise slicing in
381
+ # BlockArrays.jl.
382
+ # TODO : Ideally this would be defined in BlockArrays.jl once the slicing
383
+ # there is made more generic.
384
+ function BlockArrays. unblock (A, inds, I:: Tuple{BlockIndexVector{1},Vararg{Any}} )
385
+ B = first (I)
386
+ return _blockslice (B, inds[1 ][B])
387
+ end
388
+
319
389
function to_blockindices (a:: AbstractBlockedUnitRange{<:Integer} , I:: AbstractArray{Bool} )
320
390
I_blocks = blocks (BlockedVector (I, blocklengths (a)))
321
391
I′_blocks = map (eachindex (I_blocks)) do b
0 commit comments