Skip to content

Commit 21c1476

Browse files
committed
Add more tests
1 parent d9c8b02 commit 21c1476

File tree

3 files changed

+165
-4
lines changed

3 files changed

+165
-4
lines changed

src/BlockArraysExtensions/BlockArraysExtensions.jl

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,20 @@ for f in (:axes, :unsafe_indices, :axes1, :first, :last, :size, :length, :unsafe
6868
end
6969
Base.getindex(S::BlockIndices, i::Integer) = getindex(S.indices, i)
7070

71-
function _blockslice(x, y::AbstractUnitRange{<:Integer})
71+
# Generalization of to `BlockArrays._blockslice`:
72+
# https://github.com/JuliaArrays/BlockArrays.jl/blob/v1.6.3/src/views.jl#L13-L14
73+
# Used by `BlockArrays.unblock`, which is used in `to_indices`
74+
# to convert relative blockwise slices to absolute slices, but in a way
75+
# that preserves the original relative blockwise slice information.
76+
# TODO: Ideally this would be handled in BlockArrays.jl
77+
# once slicing like `A[Block(1)[[1, 2]]]` is supported.
78+
function _blockslice(x, y::AbstractUnitRange)
7279
return BlockSlice(x, y)
7380
end
74-
function _blockslice(x, y::AbstractVector{<:Integer})
81+
function _blockslice(x, y::AbstractVector)
7582
return BlockIndices(x, y)
7683
end
84+
7785
function Base.getindex(S::BlockIndices, i::BlockSlice{<:Block{1}})
7886
# TODO: Check that `i.indices` is consistent with `S.indices`.
7987
# It seems like this isn't handling the case where `i` is a

src/BlockArraysExtensions/blockedunitrange.jl

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,24 @@ end
292292
return b[GenericBlockIndex(tuple(K, J...))]
293293
end
294294

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))...)
300+
end
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])
311+
end
312+
295313
# Work around the fact that it is type piracy to define
296314
# `Base.getindex(a::Block, b...)`.
297315
_getindex(a::Block{N}, b::Vararg{Any,N}) where {N} = GenericBlockIndex(a, b)
@@ -357,6 +375,17 @@ function blockedunitrange_getindices(
357375
return mortar(map(b -> a[b], blocks(indices)))
358376
end
359377

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+
360389
function to_blockindices(a::AbstractBlockedUnitRange{<:Integer}, I::AbstractArray{Bool})
361390
I_blocks = blocks(BlockedVector(I, blocklengths(a)))
362391
I′_blocks = map(eachindex(I_blocks)) do b

test/test_genericblockindex.jl

Lines changed: 126 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,23 @@
11
using BlockArrays:
2-
Block, BlockIndex, BlockedArray, BlockedVector, block, blockedrange, blockindex, mortar
3-
using BlockSparseArrays: BlockSparseArrays, BlockIndexVector, GenericBlockIndex
2+
Block,
3+
BlockIndex,
4+
BlockSlice,
5+
BlockedArray,
6+
BlockedVector,
7+
block,
8+
blockedrange,
9+
blockindex,
10+
mortar
11+
using BlockSparseArrays:
12+
BlockSparseArrays,
13+
BlockIndexVector,
14+
BlockIndices,
15+
GenericBlockIndex,
16+
blocksparsezeros,
17+
blockedunitrange_getindices,
18+
to_block,
19+
to_block_indices,
20+
to_blockindexrange
421
using Test: @test, @test_broken, @testset
522

623
# blockrange
@@ -157,4 +174,111 @@ using Test: @test, @test_broken, @testset
157174
i = GenericBlockIndex(Block(2), 2)
158175
@test to_indices(a, (i, i)) == (4, 4)
159176
@test to_indices(a, axes(a), (i, i)) == (4, 4)
177+
178+
r = blockedrange([2, 3])
179+
i = mortar([BlockIndexVector(Block(2), [1, 3]), BlockIndexVector(Block(1), [2])])
180+
@test blockedunitrange_getindices(r, i) == mortar([[3, 5], [2]])
181+
182+
r = blockedrange([2, 3])
183+
T = GenericBlockIndex{1,Tuple{Int},Tuple{Int}}
184+
i = mortar([
185+
BlockIndexVector{1,T}(Block(2), [1, 3]), BlockIndexVector{1,T}(Block(1), [2])
186+
])
187+
@test blockedunitrange_getindices(r, i) == mortar([[3, 5], [2]])
188+
189+
# Internal functions.
190+
@test to_block(Block(2)) === Block(2)
191+
@test to_block(Block(2)[2:3]) === Block(2)
192+
@test to_block(BlockIndexVector(Block(2), [1, 3])) === Block(2)
193+
@test to_block_indices(Block(2)) === (:)
194+
@test to_block_indices(Block(2)[2:3]) === 2:3
195+
@test to_block_indices(BlockIndexVector(Block(2), [1, 3])) == [1, 3]
196+
197+
a = blocksparsezeros([2, 3], [2, 3])
198+
i = Block(2)[2:3]
199+
@test to_indices(a, (i, i)) ===
200+
to_indices(a, axes(a), (i, i)) ===
201+
(BlockSlice(i, 4:5), BlockSlice(i, 4:5))
202+
203+
a = blocksparsezeros([2, 3], [2, 3])
204+
i = mortar([Block(2)[2:3], Block(1)[2:2]])
205+
for I in (to_indices(a, (i, i)), to_indices(a, axes(a), (i, i)))
206+
for Iⱼ in I
207+
@test Iⱼ == BlockIndices(i, mortar([4:5, 2:2]))
208+
@test Iⱼ isa BlockIndices
209+
@test Iⱼ.blocks == i
210+
@test Iⱼ.indices == mortar([4:5, 2:2])
211+
end
212+
end
213+
214+
a = blocksparsezeros([2, 3], [2, 3])
215+
i = BlockIndexVector(Block(2), [1, 3])
216+
for I in (to_indices(a, (i, i)), to_indices(a, axes(a), (i, i)))
217+
for Iⱼ in I
218+
@test Iⱼ == BlockIndices(i, [3, 5])
219+
@test Iⱼ isa BlockIndices
220+
@test Iⱼ.blocks == i
221+
@test Iⱼ.indices == [3, 5]
222+
end
223+
end
224+
225+
a = blocksparsezeros([2, 3], [2, 3])
226+
T = GenericBlockIndex{1,Tuple{Int},Tuple{Int}}
227+
i = BlockIndexVector{1,T}(Block(2), [1, 3])
228+
for I in (to_indices(a, (i, i)), to_indices(a, axes(a), (i, i)))
229+
for Iⱼ in I
230+
@test Iⱼ == BlockIndices(i, [3, 5])
231+
@test Iⱼ isa BlockIndices
232+
@test Iⱼ.blocks == i
233+
@test Iⱼ.indices == [3, 5]
234+
end
235+
end
236+
237+
a = blocksparsezeros([2, 3], [2, 3])
238+
i = mortar([BlockIndexVector(Block(2), [1, 3]), BlockIndexVector(Block(1), [2])])
239+
for I in (to_indices(a, (i, i)), to_indices(a, axes(a), (i, i)))
240+
for Iⱼ in I
241+
@test Iⱼ == BlockIndices(i, mortar([[3, 5], [2]]))
242+
@test Iⱼ isa BlockIndices
243+
@test Iⱼ.blocks == i
244+
@test Iⱼ.indices == mortar([[3, 5], [2]])
245+
end
246+
end
247+
248+
a = blocksparsezeros([2, 3], [2, 3])
249+
i = [BlockIndexVector(Block(2), [1, 3]), BlockIndexVector(Block(1), [2])]
250+
for I in (to_indices(a, (i, i)), to_indices(a, axes(a), (i, i)))
251+
for Iⱼ in I
252+
@test Iⱼ == BlockIndices(mortar(i), mortar([[3, 5], [2]]))
253+
@test Iⱼ isa BlockIndices
254+
@test Iⱼ.blocks == mortar(i)
255+
@test Iⱼ.indices == mortar([[3, 5], [2]])
256+
end
257+
end
258+
259+
a = blocksparsezeros([2, 3], [2, 3])
260+
T = GenericBlockIndex{1,Tuple{Int},Tuple{Int}}
261+
i = mortar([
262+
BlockIndexVector{1,T}(Block(2), [1, 3]), BlockIndexVector{1,T}(Block(1), [2])
263+
])
264+
for I in (to_indices(a, (i, i)), to_indices(a, axes(a), (i, i)))
265+
for Iⱼ in I
266+
@test Iⱼ == BlockIndices(i, mortar([[3, 5], [2]]))
267+
@test Iⱼ isa BlockIndices
268+
@test Iⱼ.blocks == i
269+
@test Iⱼ.indices == mortar([[3, 5], [2]])
270+
end
271+
end
272+
273+
a = blocksparsezeros([2, 3], [2, 3])
274+
T = GenericBlockIndex{1,Tuple{Int},Tuple{Int}}
275+
i = [BlockIndexVector{1,T}(Block(2), [1, 3]), BlockIndexVector{1,T}(Block(1), [2])]
276+
for I in (to_indices(a, (i, i)), to_indices(a, axes(a), (i, i)))
277+
for Iⱼ in I
278+
@test Iⱼ == BlockIndices(mortar(i), mortar([[3, 5], [2]]))
279+
@test Iⱼ isa BlockIndices
280+
@test Iⱼ.blocks == mortar(i)
281+
@test Iⱼ.indices == mortar([[3, 5], [2]])
282+
end
283+
end
160284
end

0 commit comments

Comments
 (0)