Skip to content

Commit 5223611

Browse files
authored
Merge branch 'master' into mf/blockrange_struct_constructor
2 parents 1e1a849 + 0c73bef commit 5223611

File tree

7 files changed

+86
-9
lines changed

7 files changed

+86
-9
lines changed

src/blockbroadcast.jl

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,15 @@ BlockStyle(::Val{N}) where {N} = BlockStyle{N}()
1515
BlockedStyle(::Val{N}) where {N} = BlockedStyle{N}()
1616
BlockStyle{M}(::Val{N}) where {N,M} = BlockStyle{N}()
1717
BlockedStyle{M}(::Val{N}) where {N,M} = BlockedStyle{N}()
18-
BroadcastStyle(::Type{<:BlockArray{<:Any,N}}) where {N} = BlockStyle{N}()
19-
BroadcastStyle(::Type{<:BlockedArray{<:Any,N}}) where {N} = BlockedStyle{N}()
20-
BroadcastStyle(::Type{<:AdjOrTrans{<:Any,<:BlockArray{<:Any,N}}}) where {N} = BlockStyle{2}()
21-
BroadcastStyle(::Type{<:AdjOrTrans{<:Any,<:BlockedArray{<:Any,N}}}) where {N} = BlockedStyle{2}()
18+
blockbroadcaststyle(::AbstractArrayStyle{N}) where {N} = BlockStyle{N}()
19+
blockedbroadcaststyle(::AbstractArrayStyle{N}) where {N} = BlockedStyle{N}()
20+
21+
BroadcastStyle(::Type{<:BlockArray{<:Any,N,Blocks}}) where {N,Blocks} = blockbroadcaststyle(BroadcastStyle(Blocks))
22+
BroadcastStyle(::Type{<:BlockedArray{<:Any,N,Blocks}}) where {N,Blocks} = blockedbroadcaststyle(BroadcastStyle(Blocks))
23+
BroadcastStyle(::Type{<:Adjoint{T,<:BlockArray{<:Any,N,Blocks}}}) where {T,N,Blocks} = blockbroadcaststyle(BroadcastStyle(Adjoint{T,Blocks}))
24+
BroadcastStyle(::Type{<:Transpose{T,<:BlockArray{<:Any,N,Blocks}}}) where {T,N,Blocks} = blockbroadcaststyle(BroadcastStyle(Transpose{T,Blocks}))
25+
BroadcastStyle(::Type{<:Adjoint{T,<:BlockedArray{<:Any,N,Blocks}}}) where {T,N,Blocks} = blockedbroadcaststyle(BroadcastStyle(Adjoint{T,Blocks}))
26+
BroadcastStyle(::Type{<:Transpose{T,<:BlockedArray{<:Any,N,Blocks}}}) where {T,N,Blocks} = blockedbroadcaststyle(BroadcastStyle(Transpose{T,Blocks}))
2227

2328
BroadcastStyle(::DefaultArrayStyle{N}, b::AbstractBlockStyle{M}) where {M,N} = typeof(b)(Val(max(M,N)))
2429
BroadcastStyle(a::AbstractBlockStyle{N}, ::DefaultArrayStyle{M}) where {M,N} = typeof(a)(Val(max(M,N)))
@@ -271,3 +276,13 @@ for op in (:*, :\)
271276
broadcasted(::AbstractBlockStyle, ::typeof($op), a::AbstractArray{T}, b::Ones{V}) where {T,V} = LinearAlgebra.copy_oftype(a, Base.promote_op(*, T, V))
272277
end
273278
end
279+
280+
281+
282+
###
283+
# Ranges
284+
###
285+
286+
broadcasted(::DefaultArrayStyle{1}, ::typeof(+), r::AbstractBlockedUnitRange, x::Integer) = _BlockedUnitRange(first(r) + x, blocklasts(r) .+ x)
287+
broadcasted(::DefaultArrayStyle{1}, ::typeof(+), x::Integer, r::AbstractBlockedUnitRange) = _BlockedUnitRange(x + first(r), x .+ blocklasts(r))
288+
broadcasted(::DefaultArrayStyle{1}, ::typeof(-), r::AbstractBlockedUnitRange, x::Integer) = _BlockedUnitRange(first(r) - x, blocklasts(r) .- x)

src/blockindices.jl

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,8 @@ getindex(B::Block{N}, inds::Vararg{AbstractUnitRange{<:Integer},N}) where N = Bl
211211
getindex(B::Block{1}, inds::Colon) = B
212212
getindex(B::Block{1}, inds::Base.Slice) = B
213213

214-
@propagate_inbounds getindex(B::BlockIndexRange{1}, kr::AbstractUnitRange{<:Integer}) = BlockIndexRange(B.block, B.indices[1][kr])
214+
getindex(B::BlockIndexRange{0}) = B.block[]
215+
@propagate_inbounds getindex(B::BlockIndexRange{N}, kr::Vararg{AbstractUnitRange{<:Integer},N}) where {N} = BlockIndexRange(B.block, map(getindex, B.indices, kr))
215216
@propagate_inbounds getindex(B::BlockIndexRange{N}, inds::Vararg{Int,N}) where N = B.block[Base.reindex(B.indices, inds)...]
216217

217218
eltype(R::BlockIndexRange) = eltype(typeof(R))
@@ -290,6 +291,27 @@ _indices(B) = B
290291

291292
Block(bs::BlockSlice{<:BlockIndexRange}) = Block(bs.block)
292293

294+
"""
295+
BlockedSlice(blocks, indices)
296+
297+
Represents blocked indices attached to a collection of corresponding blocks.
298+
299+
Upon calling `to_indices()`, a collection of blocks are converted to BlockedSlice objects to represent
300+
the indices over which the blocks span.
301+
302+
This mimics the relationship between `Colon` and `Base.Slice`, `Block` and `BlockSlice`, etc.
303+
"""
304+
struct BlockedSlice{BB,T<:Integer,INDS<:AbstractVector{T}} <: AbstractVector{T}
305+
blocks::BB
306+
indices::INDS
307+
end
308+
309+
for f in (:axes, :size)
310+
@eval $f(S::BlockedSlice) = $f(S.indices)
311+
end
312+
313+
@propagate_inbounds getindex(S::BlockedSlice, i::Integer) = getindex(S.indices, i)
314+
@propagate_inbounds getindex(S::BlockedSlice, k::Block{1}) = BlockSlice(S.blocks[Int(k)], getindex(S.indices, k))
293315

294316
struct BlockRange{N,R<:NTuple{N,AbstractUnitRange{<:Integer}}} <: AbstractArray{Block{N,Int},N}
295317
indices::R

src/blocks.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Return the array-of-arrays view to `a` such that
77
blocks(a)[i₁, i₂, ..., iₙ] == a[Block(i₁), Block(i₂), ..., Block(iₙ)]
88
```
99
10-
This function does not copy the blocks and give a mutable viwe to the original
10+
This function does not copy the blocks and give a mutable view to the original
1111
array. This is an "inverse" of [`mortar`](@ref).
1212
1313
# Examples

src/views.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ function unblock(A, inds, I)
1111
end
1212

1313
_blockslice(B, a::AbstractUnitRange) = BlockSlice(B, a)
14-
_blockslice(B, a) = a # drop block structure
14+
_blockslice(B, a) = BlockedSlice(B, a)
1515

1616
# Allow `ones(2)[Block(1)[1:1], Block(1)[1:1]]` which is
1717
# similar to `ones(2)[1:1, 1:1]`.
@@ -150,10 +150,11 @@ block(A::Block) = A
150150
@inline view(block_arr::AbstractBlockArray{<:Any,N}, blocks::Vararg{BlockSlice1, N}) where N =
151151
view(block_arr, map(block,blocks)...)
152152

153-
const BlockSlices = Union{Base.Slice,BlockSlice{<:BlockRange{1}}}
153+
const BlockSlices = Union{Base.Slice,BlockSlice{<:BlockRange{1}},BlockedSlice}
154154
# view(V::SubArray{<:Any,N,NTuple{N,BlockSlices}},
155155

156156
_block_reindex(b::BlockSlice, i::Block{1}) = b.block[Int(i)]
157+
_block_reindex(b::BlockedSlice, i::Block{1}) = b.blocks[Int(i)]
157158
_block_reindex(b::Slice, i::Block{1}) = i
158159

159160
@inline view(V::SubArray{<:Any,N,<:AbstractBlockArray,<:NTuple{N,BlockSlices}}, block::Block{N}) where N =

test/test_blockbroadcast.jl

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,24 @@ using StaticArrays
193193
@test blockisequal(axes(A .* Ones(axes(A))), axes(Ones(axes(A)) .* A), axes(A .* ones(6)))
194194
end
195195

196+
@testset "Blocked unit range broadcast" begin
197+
r = blockedrange([2,3])
198+
@test r .+ 3 == blockedrange(4, [2,3])
199+
@test blocklengths(r .+ 3) == [2,3]
200+
@test 3 .+ r == blockedrange(4, [2,3])
201+
@test blocklengths(3 .+ r .+ 3) == [2,3]
202+
@test r .- 3 == blockedrange(-2, [2,3])
203+
@test blocklengths(r .- 3) == [2,3]
204+
205+
r = blockedrange(2, [2,3])
206+
@test r .+ 3 == blockedrange(5, [2,3])
207+
@test blocklengths(r .+ 3) == [2,3]
208+
@test 3 .+ r == blockedrange(5, [2,3])
209+
@test blocklengths(3 .+ r .+ 3) == [2,3]
210+
@test r .- 3 == blockedrange(-1, [2,3])
211+
@test blocklengths(r .- 3) == [2,3]
212+
end
213+
196214
@testset "type inference" begin
197215
u = BlockArray(randn(5), [2,3]);
198216
A = zeros(size(u))

test/test_blockindices.jl

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ module TestBlockIndices
22

33
using BlockArrays, FillArrays, Test, StaticArrays, ArrayLayouts
44
using OffsetArrays
5-
import BlockArrays: BlockIndex, BlockIndexRange, BlockSlice
5+
import BlockArrays: BlockIndex, BlockIndexRange, BlockSlice, BlockedSlice
66

77
@testset "Blocks" begin
88
@test Int(Block(2)) === Integer(Block(2)) === Number(Block(2)) === 2
@@ -90,6 +90,8 @@ import BlockArrays: BlockIndex, BlockIndexRange, BlockSlice
9090
@test Block(1,1)[1,1] == BlockIndex((1,1),(1,1)) == BlockIndex((1,1),(1,))
9191
@test Block(1,1)[1:2,1:2] == BlockIndexRange(Block(1,1),(1:2,1:2))
9292
@test Block(1)[1:3][1:2] == BlockIndexRange(Block(1),1:2)
93+
@test Block(1,1)[2:4,2:4][2:3,2:3] == BlockIndexRange(Block(1,1),(3:4,3:4))
94+
@test BlockIndexRange(Block(),())[] == BlockIndex()
9395
@test BlockIndex((2,2,2),(2,)) == BlockIndex((2,2,2),(2,1,)) == BlockIndex((2,2,2),(2,1,1))
9496
@test BlockIndex(2,(2,)) === BlockIndex((2,),(2,))
9597
@test BlockIndex(UInt(2),(2,)) === BlockIndex((UInt(2),),(2,))
@@ -835,6 +837,16 @@ end
835837
end
836838
end
837839

840+
@testset "BlockedSlice" begin
841+
b = BlockedSlice([Block(2), Block(1)], mortar([3:5, 1:2]))
842+
@test length(b) == 5
843+
for i in eachindex(b.indices)
844+
@test b[i] === b.indices[i]
845+
end
846+
@test b[Block(1)] === BlockSlice(Block(2), 3:5)
847+
@test b[Block(2)] === BlockSlice(Block(1), 1:2)
848+
end
849+
838850
#=
839851
[1,1 1,2] | [1,3 1,4 1,5]
840852
--------------------------

test/test_blockrange.jl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,15 @@ using BlockArrays, Test
2929
@test view(A, Block.(1:2)) == [1,2,3]
3030
@test A[Block.(1:2)] == [1,2,3]
3131

32+
V = view(A, [Block(3), Block(2)])
33+
@test V == [4, 5, 6, 2, 3]
34+
I = parentindices(V)[1]
35+
@test I isa BlockArrays.BlockedSlice{<:Vector{<:Block{1}}}
36+
@test V[Block(1)] == 4:6
37+
@test V[Block(2)] == 2:3
38+
@test view(V, Block(1)) === view(A, Block(3))
39+
@test view(V, Block(2)) === view(A, Block(2))
40+
3241
A = BlockArray(reshape(collect(1:(6*12)),6,12), 1:3, 3:5)
3342

3443
@test view(A, Block.(1:2), Block.(1:2)) == A[1:3,1:7]

0 commit comments

Comments
 (0)