@@ -216,22 +216,111 @@ function to_blockindices(a::AbstractBlockedUnitRange{<:Integer}, I::UnitRange{<:
216
216
)
217
217
end
218
218
219
- struct BlockIndexVector{T<: Integer ,I<: AbstractVector{T} ,TB<: Integer } < :
220
- AbstractVector{BlockIndex{1 ,Tuple{TB},Tuple{T}}}
221
- block:: Block{1,TB}
219
+ struct GenericBlockIndex{N,TI<: Tuple{Vararg{Integer,N}} ,Tα<: Tuple{Vararg{Any,N}} }
220
+ I:: TI
221
+ α:: T α
222
+ end
223
+ @inline function GenericBlockIndex (a:: NTuple{N,Block{1}} , b:: Tuple ) where {N}
224
+ return GenericBlockIndex (Int .(a), b)
225
+ end
226
+ @inline function GenericBlockIndex (:: Tuple{} , b:: Tuple{} )
227
+ return GenericBlockIndex {0,Tuple{},Tuple{}} ((), ())
228
+ end
229
+ @inline GenericBlockIndex (a:: Integer , b) = GenericBlockIndex ((a,), (b,))
230
+ @inline GenericBlockIndex (a:: Tuple , b) = GenericBlockIndex (a, (b,))
231
+ @inline GenericBlockIndex (a:: Integer , b:: Tuple ) = GenericBlockIndex ((a,), b)
232
+ @inline GenericBlockIndex () = GenericBlockIndex ((), ())
233
+ @inline GenericBlockIndex (a:: Block , b:: Tuple ) = GenericBlockIndex (a. n, b)
234
+ @inline GenericBlockIndex (a:: Block , b) = GenericBlockIndex (a, (b,))
235
+ @inline function GenericBlockIndex (
236
+ I:: Tuple{Vararg{Integer,N}} , α:: Tuple{Vararg{Any,M}}
237
+ ) where {M,N}
238
+ M <= N || throw (ArgumentError (" number of indices must not exceed the number of blocks" ))
239
+ α2 = ntuple (k -> k <= M ? α[k] : 1 , N)
240
+ GenericBlockIndex (I, α2)
241
+ end
242
+ BlockArrays. block (b:: GenericBlockIndex ) = Block (b. I... )
243
+ BlockArrays. blockindex (b:: GenericBlockIndex{1} ) = b. α[1 ]
244
+ function GenericBlockIndex (indcs:: Tuple{Vararg{GenericBlockIndex{1},N}} ) where {N}
245
+ GenericBlockIndex (block .(indcs), blockindex .(indcs))
246
+ end
247
+ function print_tuple_elements (io:: IO , @nospecialize (t))
248
+ if ! isempty (t)
249
+ print (io, t[1 ])
250
+ for n in t[2 : end ]
251
+ print (io, " , " , n)
252
+ end
253
+ end
254
+ return nothing
255
+ end
256
+ function Base. show (io:: IO , B:: GenericBlockIndex )
257
+ show (io, Block (B. I... ))
258
+ print (io, " [" )
259
+ print_tuple_elements (io, B. α)
260
+ print (io, " ]" )
261
+ return nothing
262
+ end
263
+
264
+ using Base: @propagate_inbounds
265
+ @propagate_inbounds function Base. getindex (b:: AbstractVector , K:: GenericBlockIndex{1} )
266
+ return b[Block (K. I[1 ])][K. α[1 ]]
267
+ end
268
+ @propagate_inbounds function Base. getindex (
269
+ b:: AbstractArray{T,N} , K:: GenericBlockIndex{N}
270
+ ) where {T,N}
271
+ return b[block (K)][K. α... ]
272
+ end
273
+ @propagate_inbounds function Base. getindex (
274
+ b:: AbstractArray , K:: GenericBlockIndex{1} , J:: GenericBlockIndex{1} ...
275
+ )
276
+ return b[GenericBlockIndex (tuple (K, J... ))]
277
+ end
278
+
279
+ function blockindextype (TB:: Type{<:Integer} , TI:: Vararg{Type{<:Integer},N} ) where {N}
280
+ return BlockIndex{N,NTuple{N,TB},Tuple{TI... }}
281
+ end
282
+ function blockindextype (TB:: Type{<:Integer} , TI:: Vararg{Type,N} ) where {N}
283
+ return GenericBlockIndex{N,NTuple{N,TB},Tuple{TI... }}
284
+ end
285
+
286
+ struct BlockIndexVector{N,I<: NTuple{N,AbstractVector} ,TB<: Integer ,BT} <: AbstractArray{BT,N}
287
+ block:: Block{N,TB}
222
288
indices:: I
289
+ function BlockIndexVector (
290
+ 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)
294
+ end
295
+ end
296
+ function BlockIndexVector (block:: Block{1} , indices:: AbstractVector )
297
+ return BlockIndexVector (block, (indices,))
298
+ end
299
+ Base. size (a:: BlockIndexVector ) = length .(a. indices)
300
+ function Base. getindex (a:: BlockIndexVector{N} , I:: Vararg{Integer,N} ) where {N}
301
+ return a. block[map ((r, i) -> r[i], a. indices, I)... ]
223
302
end
224
- Base. length (a:: BlockIndexVector ) = length (a. indices)
225
- Base. size (a:: BlockIndexVector ) = (length (a),)
226
- BlockArrays. Block (a:: BlockIndexVector ) = a. block
227
- Base. getindex (a:: BlockIndexVector , I:: Integer ) = Block (a)[a. indices[I]]
228
- Base. copy (a:: BlockIndexVector ) = BlockIndexVector (a. block, copy (a. indices))
303
+ BlockArrays. block (b:: BlockIndexVector ) = b. block
304
+ BlockArrays. Block (b:: BlockIndexVector ) = b. block
305
+
306
+ Base. copy (a:: BlockIndexVector ) = BlockIndexVector (a. block, copy .(a. indices))
307
+
308
+ using ArrayLayouts: LayoutArray
309
+ @propagate_inbounds Base. getindex (b:: AbstractArray{T,N} , K:: BlockIndexVector{N} ) where {T,N} = b[block (
310
+ K
311
+ )][K. indices... ]
312
+ @propagate_inbounds Base. getindex (b:: LayoutArray{T,N} , K:: BlockIndexVector{N} ) where {T,N} = b[block (
313
+ K
314
+ )][K. indices... ]
315
+ @propagate_inbounds Base. getindex (b:: LayoutArray{T,1} , K:: BlockIndexVector{1} ) where {T} = b[block (
316
+ K
317
+ )][K. indices... ]
229
318
230
319
function to_blockindices (a:: AbstractBlockedUnitRange{<:Integer} , I:: AbstractArray{Bool} )
231
320
I_blocks = blocks (BlockedVector (I, blocklengths (a)))
232
321
I′_blocks = map (eachindex (I_blocks)) do b
233
322
I_b = findall (I_blocks[b])
234
- BlockIndexVector (Block (b), I_b)
323
+ return BlockIndexVector (Block (b), I_b)
235
324
end
236
325
return mortar (filter (! isempty, I′_blocks))
237
326
end
0 commit comments