Skip to content

Commit 0303eaf

Browse files
authored
Support tuples in blockedrange (#165)
* Support tuples in blockedrange * simplify length for BlockedUnitRange * Update blockaxis.jl * Update test_blockindices.jl * v0.15.1
1 parent 528134d commit 0303eaf

File tree

4 files changed

+58
-31
lines changed

4 files changed

+58
-31
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "BlockArrays"
22
uuid = "8e7c35d0-a365-5155-bbbb-fb81a777f24e"
3-
version = "0.15"
3+
version = "0.15.1"
44

55
[deps]
66
ArrayLayouts = "4c555306-a7a7-4459-81d9-ec55ddd5c99a"

src/blockarray.jl

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,13 @@ struct BlockArray{T, N, R <: AbstractArray{<:AbstractArray{T,N},N}, BS<:NTuple{N
6767
end
6868

6969
# Auxilary outer constructors
70-
@inline _BlockArray(blocks::R, block_sizes::Vararg{AbstractVector{Int}, N}) where {T, N, R<:AbstractArray{<:AbstractArray{T,N},N}} =
70+
@inline _BlockArray(blocks::R, block_sizes::Vararg{AbstractVector{<:Integer}, N}) where {T, N, R<:AbstractArray{<:AbstractArray{T,N},N}} =
7171
_BlockArray(blocks, map(blockedrange, block_sizes))
7272

7373
# support non-concrete eltypes in blocks
7474
_BlockArray(blocks::R, block_axes::BS) where {T, N, R<:AbstractArray{<:AbstractArray{V,N} where V,N}, BS<:NTuple{N,AbstractUnitRange{Int}}} =
7575
_BlockArray(convert(AbstractArray{AbstractArray{mapreduce(eltype,promote_type,blocks),N},N}, blocks), block_axes)
76-
_BlockArray(blocks::R, block_sizes::Vararg{AbstractVector{Int}, N}) where {T, N, R<:AbstractArray{<:AbstractArray{V,N} where V,N}} =
76+
_BlockArray(blocks::R, block_sizes::Vararg{AbstractVector{<:Integer}, N}) where {T, N, R<:AbstractArray{<:AbstractArray{V,N} where V,N}} =
7777
_BlockArray(convert(AbstractArray{AbstractArray{mapreduce(eltype,promote_type,blocks),N},N}, blocks), block_sizes...)
7878

7979
const BlockMatrix{T, R <: AbstractMatrix{<:AbstractMatrix{T}}} = BlockArray{T, 2, R}
@@ -84,7 +84,7 @@ const BlockVecOrMat{T, R} = Union{BlockMatrix{T, R}, BlockVector{T, R}}
8484
# Constructors #
8585
################
8686

87-
@inline _BlockArray(::Type{R}, block_sizes::Vararg{AbstractVector{Int}, N}) where {T, N, R<:AbstractArray{<:AbstractArray{T,N},N}} =
87+
@inline _BlockArray(::Type{R}, block_sizes::Vararg{AbstractVector{<:Integer}, N}) where {T, N, R<:AbstractArray{<:AbstractArray{T,N},N}} =
8888
_BlockArray(R, map(blockedrange,block_sizes))
8989

9090
function _BlockArray(::Type{R}, baxes::NTuple{N,AbstractUnitRange{Int}}) where {T, N, R<:AbstractArray{<:AbstractArray{T,N},N}}
@@ -93,7 +93,7 @@ function _BlockArray(::Type{R}, baxes::NTuple{N,AbstractUnitRange{Int}}) where {
9393
_BlockArray(blocks, baxes)
9494
end
9595

96-
@inline undef_blocks_BlockArray(::Type{R}, block_sizes::Vararg{AbstractVector{Int}, N}) where {T, N, R<:AbstractArray{<:AbstractArray{T,N},N}} =
96+
@inline undef_blocks_BlockArray(::Type{R}, block_sizes::Vararg{AbstractVector{<:Integer}, N}) where {T, N, R<:AbstractArray{<:AbstractArray{T,N},N}} =
9797
_BlockArray(R, block_sizes...)
9898

9999
"""
@@ -109,16 +109,16 @@ julia> BlockArray(undef_blocks, Matrix{Float64}, [1,3], [2,2])
109109
#undef #undef │ #undef #undef
110110
```
111111
"""
112-
@inline BlockArray(::UndefBlocksInitializer, ::Type{R}, block_sizes::Vararg{AbstractVector{Int}, N}) where {T, N, R<:AbstractArray{T,N}} =
112+
@inline BlockArray(::UndefBlocksInitializer, ::Type{R}, block_sizes::Vararg{AbstractVector{<:Integer}, N}) where {T, N, R<:AbstractArray{T,N}} =
113113
undef_blocks_BlockArray(Array{R,N}, block_sizes...)
114114

115-
@inline BlockArray{T}(::UndefBlocksInitializer, block_sizes::Vararg{AbstractVector{Int}, N}) where {T, N} =
115+
@inline BlockArray{T}(::UndefBlocksInitializer, block_sizes::Vararg{AbstractVector{<:Integer}, N}) where {T, N} =
116116
BlockArray(undef_blocks, Array{T,N}, block_sizes...)
117117

118-
@inline BlockArray{T,N}(::UndefBlocksInitializer, block_sizes::Vararg{AbstractVector{Int}, N}) where {T, N} =
118+
@inline BlockArray{T,N}(::UndefBlocksInitializer, block_sizes::Vararg{AbstractVector{<:Integer}, N}) where {T, N} =
119119
BlockArray(undef_blocks, Array{T,N}, block_sizes...)
120120

121-
@inline BlockArray{T,N,R}(::UndefBlocksInitializer, block_sizes::Vararg{AbstractVector{Int}, N}) where {T, N, R<:AbstractArray{<:AbstractArray{T,N},N}} =
121+
@inline BlockArray{T,N,R}(::UndefBlocksInitializer, block_sizes::Vararg{AbstractVector{<:Integer}, N}) where {T, N, R<:AbstractArray{<:AbstractArray{T,N},N}} =
122122
undef_blocks_BlockArray(R, block_sizes...)
123123

124124
@generated function initialized_blocks_BlockArray(::Type{R}, baxes::NTuple{N,AbstractUnitRange{Int}}) where R<:AbstractArray{V,N} where {T,N,V<:AbstractArray{T,N}}
@@ -134,7 +134,7 @@ julia> BlockArray(undef_blocks, Matrix{Float64}, [1,3], [2,2])
134134
end
135135

136136

137-
initialized_blocks_BlockArray(::Type{R}, block_sizes::Vararg{AbstractVector{Int}, N}) where {T, N, R<:AbstractArray{<:AbstractArray{T,N},N}} =
137+
initialized_blocks_BlockArray(::Type{R}, block_sizes::Vararg{AbstractVector{<:Integer}, N}) where {T, N, R<:AbstractArray{<:AbstractArray{T,N},N}} =
138138
initialized_blocks_BlockArray(R, map(blockedrange,block_sizes))
139139

140140
@inline BlockArray{T}(::UndefInitializer, baxes::NTuple{N,AbstractUnitRange{Int}}) where {T, N} =
@@ -149,20 +149,20 @@ initialized_blocks_BlockArray(::Type{R}, block_sizes::Vararg{AbstractVector{Int}
149149
@inline BlockArray{T,N,R,BS}(::UndefInitializer, baxes::BS) where {T, N, R<:AbstractArray{<:AbstractArray{T,N},N}, BS<:NTuple{N,AbstractUnitRange{Int}}} =
150150
initialized_blocks_BlockArray(R, baxes)
151151

152-
@inline BlockArray{T}(::UndefInitializer, block_sizes::Vararg{AbstractVector{Int}, N}) where {T, N} =
152+
@inline BlockArray{T}(::UndefInitializer, block_sizes::Vararg{AbstractVector{<:Integer}, N}) where {T, N} =
153153
initialized_blocks_BlockArray(Array{Array{T,N},N}, block_sizes...)
154154

155-
@inline BlockArray{T, N}(::UndefInitializer, block_sizes::Vararg{AbstractVector{Int}, N}) where {T, N} =
155+
@inline BlockArray{T, N}(::UndefInitializer, block_sizes::Vararg{AbstractVector{<:Integer}, N}) where {T, N} =
156156
initialized_blocks_BlockArray(Array{Array{T,N},N}, block_sizes...)
157157

158-
@inline BlockArray{T, N, R}(::UndefInitializer, block_sizes::Vararg{AbstractVector{Int}, N}) where {T, N, R<:AbstractArray{<:AbstractArray{T,N},N}} =
158+
@inline BlockArray{T, N, R}(::UndefInitializer, block_sizes::Vararg{AbstractVector{<:Integer}, N}) where {T, N, R<:AbstractArray{<:AbstractArray{T,N},N}} =
159159
initialized_blocks_BlockArray(R, block_sizes...)
160160

161161

162162
@inline BlockArray{T,N,R,BS}(::UndefInitializer, sizes::NTuple{N,Int}) where {T, N, R<:AbstractArray{<:AbstractArray{T,N},N}, BS<:NTuple{N,AbstractUnitRange{Int}}} =
163163
BlockArray{T,N,R,BS}(undef, convert(BS, map(Base.OneTo, sizes)))
164164

165-
function BlockArray{T}(arr::AbstractArray{V, N}, block_sizes::Vararg{AbstractVector{Int}, N}) where {T,V,N}
165+
function BlockArray{T}(arr::AbstractArray{V, N}, block_sizes::Vararg{AbstractVector{<:Integer}, N}) where {T,V,N}
166166
for i in 1:N
167167
if sum(block_sizes[i]) != size(arr, i)
168168
throw(DimensionMismatch("block size for dimension $i: $(block_sizes[i]) does not sum to the array size: $(size(arr, i))"))
@@ -171,7 +171,7 @@ function BlockArray{T}(arr::AbstractArray{V, N}, block_sizes::Vararg{AbstractVec
171171
BlockArray{T}(arr, map(blockedrange,block_sizes))
172172
end
173173

174-
BlockArray(arr::AbstractArray{T, N}, block_sizes::Vararg{AbstractVector{Int}, N}) where {T,N} =
174+
BlockArray(arr::AbstractArray{T, N}, block_sizes::Vararg{AbstractVector{<:Integer}, N}) where {T,N} =
175175
BlockArray{T}(arr, block_sizes...)
176176

177177
@generated function BlockArray{T}(arr::AbstractArray{T, N}, baxes::NTuple{N,AbstractUnitRange{Int}}) where {T,N}
@@ -194,18 +194,18 @@ BlockArray(arr::AbstractArray{T, N}, baxes::NTuple{N,AbstractUnitRange{Int}}) wh
194194
BlockArray{T}(arr, baxes)
195195

196196
BlockVector(blocks::AbstractVector, baxes::Tuple{AbstractUnitRange{Int}}) = BlockArray(blocks, baxes)
197-
BlockVector(blocks::AbstractVector, block_sizes::AbstractVector{Int}) = BlockArray(blocks, block_sizes)
197+
BlockVector(blocks::AbstractVector, block_sizes::AbstractVector{<:Integer}) = BlockArray(blocks, block_sizes)
198198
BlockMatrix(blocks::AbstractMatrix, baxes::NTuple{2,AbstractUnitRange{Int}}) = BlockArray(blocks, baxes)
199-
BlockMatrix(blocks::AbstractMatrix, block_sizes::Vararg{AbstractVector{Int},2}) = BlockArray(blocks, block_sizes...)
199+
BlockMatrix(blocks::AbstractMatrix, block_sizes::Vararg{AbstractVector{<:Integer},2}) = BlockArray(blocks, block_sizes...)
200200

201201
BlockArray{T}::UniformScaling, baxes::NTuple{2,AbstractUnitRange{Int}}) where T = BlockArray{T}(Matrix(λ, map(length,baxes)...), baxes)
202-
BlockArray{T}::UniformScaling, block_sizes::Vararg{AbstractVector{Int}, 2}) where T = BlockArray{T}(λ, map(blockedrange,block_sizes))
203-
BlockArray::UniformScaling{T}, block_sizes::Vararg{AbstractVector{Int}, 2}) where T = BlockArray{T}(λ, block_sizes...)
202+
BlockArray{T}::UniformScaling, block_sizes::Vararg{AbstractVector{<:Integer}, 2}) where T = BlockArray{T}(λ, map(blockedrange,block_sizes))
203+
BlockArray::UniformScaling{T}, block_sizes::Vararg{AbstractVector{<:Integer}, 2}) where T = BlockArray{T}(λ, block_sizes...)
204204
BlockArray::UniformScaling{T}, baxes::NTuple{2,AbstractUnitRange{Int}}) where T = BlockArray{T}(λ, baxes)
205205
BlockMatrix::UniformScaling, baxes::NTuple{2,AbstractUnitRange{Int}}) = BlockArray(λ, baxes)
206-
BlockMatrix::UniformScaling, block_sizes::Vararg{AbstractVector{Int},2}) = BlockArray(λ, block_sizes...)
206+
BlockMatrix::UniformScaling, block_sizes::Vararg{AbstractVector{<:Integer},2}) = BlockArray(λ, block_sizes...)
207207
BlockMatrix{T}::UniformScaling, baxes::NTuple{2,AbstractUnitRange{Int}}) where T = BlockArray{T}(λ, baxes)
208-
BlockMatrix{T}::UniformScaling, block_sizes::Vararg{AbstractVector{Int},2}) where T = BlockArray{T}(λ, block_sizes...)
208+
BlockMatrix{T}::UniformScaling, block_sizes::Vararg{AbstractVector{<:Integer},2}) where T = BlockArray{T}(λ, block_sizes...)
209209

210210
"""
211211
mortar(blocks::AbstractArray)
@@ -244,7 +244,7 @@ true
244244
mortar(blocks::AbstractArray{R, N}, baxes::NTuple{N,AbstractUnitRange{Int}}) where {R, N} =
245245
_BlockArray(blocks, baxes)
246246

247-
mortar(blocks::AbstractArray{R, N}, block_sizes::Vararg{AbstractVector{Int}, N}) where {R, N} =
247+
mortar(blocks::AbstractArray{R, N}, block_sizes::Vararg{AbstractVector{<:Integer}, N}) where {R, N} =
248248
_BlockArray(blocks, block_sizes...)
249249

250250
mortar(blocks::AbstractArray) = mortar(blocks, sizes_from_blocks(blocks)...)

src/blockaxis.jl

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,16 @@ const DefaultBlockAxis = BlockedUnitRange{Vector{Int}}
5353

5454
BlockedUnitRange(::BlockedUnitRange) = throw(ArgumentError("Forbidden due to ambiguity"))
5555
_blocklengths2blocklasts(blocks) = cumsum(blocks) # extra level to allow changing default cumsum behaviour
56-
@inline blockedrange(blocks::AbstractVector{Int}) = _BlockedUnitRange(_blocklengths2blocklasts(blocks))
56+
@inline blockedrange(blocks::Union{Tuple,AbstractVector}) = _BlockedUnitRange(_blocklengths2blocklasts(blocks))
5757

58-
@inline blockfirsts(a::BlockedUnitRange) = [a.first; @view(a.lasts[1:end-1]) .+ 1]
58+
@inline blockfirsts(a::BlockedUnitRange) = [a.first; @views(a.lasts[1:end-1]) .+ 1]
5959
@inline blocklasts(a::BlockedUnitRange) = a.lasts
60-
@inline blocklengths(a::BlockedUnitRange) = [first(a.lasts)-a.first+1; diff(a.lasts)]
60+
61+
_diff(a::AbstractVector) = diff(a)
62+
_diff(a::Tuple) = diff(collect(a))
63+
@inline blocklengths(a::BlockedUnitRange) = [first(a.lasts)-a.first+1; _diff(a.lasts)]
64+
65+
length(a::BlockedUnitRange) = isempty(a.lasts) ? 0 : Integer(last(a.lasts))
6166

6267
"""
6368
blockisequal(a::AbstractUnitRange{Int}, b::AbstractUnitRange{Int})
@@ -105,7 +110,9 @@ julia> blockaxes(A)[1]
105110
Block(2)
106111
```
107112
"""
108-
blockaxes(b::BlockedUnitRange) = (Block.(axes(b.lasts,1)),)
113+
blockaxes(b::BlockedUnitRange) = _blockaxes(b.lasts)
114+
_blockaxes(b::AbstractVector) = (Block.(axes(b,1)),)
115+
_blockaxes(b::Tuple) = (Block.(Base.OneTo(length(b))),)
109116
blockaxes(b) = blockaxes.(axes(b), 1)
110117

111118
"""
@@ -186,10 +193,7 @@ blocksizes(A,i) = blocklengths(axes(A,i))
186193
axes(b::BlockedUnitRange) = (_BlockedUnitRange(blocklasts(b) .- (first(b)-1)),)
187194
unsafe_indices(b::BlockedUnitRange) = axes(b)
188195
first(b::BlockedUnitRange) = b.first
189-
_last(b::BlockedUnitRange, _) = isempty(blocklasts(b)) ? first(b)-1 : last(blocklasts(b))
190-
last(b::BlockedUnitRange) = _last(b, axes(blocklasts(b),1))
191-
_length(b::BlockedUnitRange, _) = Base.invoke(length, Tuple{AbstractUnitRange{Int}}, b)
192-
length(b::BlockedUnitRange) = _length(b, axes(blocklasts(b),1))
196+
last(b::BlockedUnitRange) = isempty(blocklasts(b)) ? first(b)-1 : last(blocklasts(b))
193197

194198
function getindex(b::BlockedUnitRange, K::Block{1})
195199
k = Integer(K)
@@ -223,9 +227,16 @@ function getindex(b::BlockedUnitRange, KR::BlockRange{1,Tuple{Base.OneTo{Int}}})
223227
_BlockedUnitRange(first(b),cs[Base.OneTo(j)])
224228
end
225229

230+
_searchsortedfirst(a::AbstractVector, k) = searchsortedfirst(a, k)
231+
function _searchsortedfirst(a::Tuple, k)
232+
k  first(a) && return 1
233+
1+_searchsortedfirst(tail(a), k)
234+
end
235+
_searchsortedfirst(a::Tuple{}, k) = 1
236+
226237
function findblock(b::BlockedUnitRange, k::Integer)
227238
@boundscheck k in b || throw(BoundsError(b,k))
228-
Block(searchsortedfirst(blocklasts(b), k))
239+
Block(_searchsortedfirst(blocklasts(b), k))
229240
end
230241

231242
Base.dataids(b::BlockedUnitRange) = Base.dataids(blocklasts(b))
@@ -320,3 +331,9 @@ function blocklengths(a::BlockedUnitRange{<:AbstractRange})
320331
@assert first(a.lasts)-a.first+1 == st
321332
Fill(st,length(a.lasts))
322333
end
334+
335+
336+
# TODO: Remove
337+
338+
function _last end
339+
function _length end

test/test_blockindices.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,16 @@ end
301301
@test blockisequal(blockedrange(SVector(1,2,3)), blockedrange([1,2,3]))
302302
@test @allocated(blockedrange(SVector(1,2,3))) == 0
303303
end
304+
305+
@testset "Tuples" begin
306+
# we support Tuples in addition to SVectors for InfiniteArrays.jl, which has
307+
# infinite block sizes
308+
s = blockedrange((5,big(100_000_000)^2))
309+
@test blocklengths(s) == [5,big(100_000_000)^2]
310+
@test blockaxes(s) == (Block.(1:2),)
311+
@test findblock(s,3) == Block(1)
312+
@test findblock(s,big(100_000_000)) == Block(2)
313+
end
304314
end
305315

306316
@testset "BlockSlice" begin

0 commit comments

Comments
 (0)