Skip to content

Commit ee57d11

Browse files
authored
Redefine blocksizes (#399)
* Redefine blocksizes * Revert change to docstring * Add tests, fix some tests, add docstring * Fix more tests * Add test Project.toml * Git ignore vim temp files * Fixes to test Project.toml * Another test Project.toml fix * Move code, change type design, better code coverage * Backwards compatibility. Fix doctest. * Fix tests * Redesign BlockSizes to be AbstractArray subtype
1 parent 928dea7 commit ee57d11

File tree

9 files changed

+86
-45
lines changed

9 files changed

+86
-45
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@ src/.DS_Store
99
Manifest.toml
1010
Manifest-v*.*.toml
1111
.DS_Store
12+
.*.swp
1213
build

src/blockaxis.jl

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -353,35 +353,6 @@ blocksize(A) = map(length, blockaxes(A))
353353
blocksize(A,i) = length(blockaxes(A,i))
354354
@inline blocklength(t) = prod(blocksize(t))
355355

356-
"""
357-
blocksizes(A::AbstractArray)
358-
blocksizes(A::AbstractArray, i::Int)
359-
360-
Return the tuple of the sizes of blocks along each
361-
dimension. See also size and blocksize.
362-
363-
# Examples
364-
```jldoctest
365-
julia> A = BlockArray(ones(3,3),[2,1],[1,1,1])
366-
2×3-blocked 3×3 BlockMatrix{Float64}:
367-
1.0 │ 1.0 │ 1.0
368-
1.0 │ 1.0 │ 1.0
369-
─────┼───────┼─────
370-
1.0 │ 1.0 │ 1.0
371-
372-
julia> blocksizes(A)
373-
([2, 1], [1, 1, 1])
374-
375-
julia> blocksizes(A,2)
376-
3-element Vector{Int64}:
377-
1
378-
1
379-
1
380-
```
381-
"""
382-
blocksizes(A) = map(blocklengths, axes(A))
383-
blocksizes(A,i) = blocklengths(axes(A,i))
384-
385356
axes(b::AbstractBlockedUnitRange) = (BlockedOneTo(blocklasts(b) .- (first(b)-oneunit(eltype(b)))),)
386357
unsafe_indices(b::AbstractBlockedUnitRange) = axes(b)
387358
# ::Integer works around case where blocklasts might return different type

src/blocks.jl

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ BlocksView(a::AbstractArray{S,N}) where {S,N} =
7676
Base.IteratorEltype(::Type{<:BlocksView}) = Base.EltypeUnknown()
7777

7878
Base.size(a::BlocksView) = blocksize(a.array)
79-
Base.axes(a::BlocksView) = map(br -> only(br.indices), blockaxes(a.array))
79+
Base.axes(a::BlocksView) = map(br -> Int.(br), blockaxes(a.array))
8080

8181
#=
8282
This is broken for now. See: https://github.com/JuliaArrays/BlockArrays.jl/issues/120
@@ -92,3 +92,48 @@ This is broken for now. See: https://github.com/JuliaArrays/BlockArrays.jl/issue
9292
copyto!(a[i...], b)
9393
a
9494
end
95+
96+
"""
97+
blocksizes(A::AbstractArray)
98+
blocksizes(A::AbstractArray, d::Integer)
99+
100+
Return an iterator over the sizes of each block.
101+
See also size and blocksize.
102+
103+
# Examples
104+
```jldoctest
105+
julia> A = BlockArray(ones(3,3),[2,1],[1,1,1])
106+
2×3-blocked 3×3 BlockMatrix{Float64}:
107+
1.0 │ 1.0 │ 1.0
108+
1.0 │ 1.0 │ 1.0
109+
─────┼───────┼─────
110+
1.0 │ 1.0 │ 1.0
111+
112+
julia> blocksizes(A)
113+
2×3 BlockArrays.BlockSizes{Tuple{Int64, Int64}, 2, BlockMatrix{Float64, Matrix{Matrix{Float64}}, Tuple{BlockedOneTo{Int64, Vector{Int64}}, BlockedOneTo{Int64, Vector{Int64}}}}}:
114+
(2, 1) (2, 1) (2, 1)
115+
(1, 1) (1, 1) (1, 1)
116+
117+
julia> blocksizes(A)[1,2]
118+
(2, 1)
119+
120+
julia> blocksizes(A,2)
121+
3-element Vector{Int64}:
122+
1
123+
1
124+
1
125+
```
126+
"""
127+
blocksizes(A::AbstractArray) = BlockSizes(A)
128+
blocksizes(A::AbstractArray, d::Integer) = blocklengths(axes(A, d))
129+
130+
struct BlockSizes{T,N,A<:AbstractArray{<:Any,N}} <: AbstractArray{T,N}
131+
array::A
132+
end
133+
BlockSizes(a::AbstractArray{<:Any,N}) where {N} =
134+
BlockSizes{Tuple{eltype.(axes(a))...},N,typeof(a)}(a)
135+
136+
size(bs::BlockSizes) = blocksize(bs.array)
137+
axes(bs::BlockSizes) = map(br -> Int.(br), blockaxes(bs.array))
138+
@propagate_inbounds getindex(a::BlockSizes{T,N}, i::Vararg{Int,N}) where {T,N} =
139+
size(view(a.array, Block.(i)...))

test/test_blockarrayinterface.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@ end
1515
A = randn(5)
1616
@test blocksize(A) == (1,)
1717
@test blocksize(A, 1) == 1
18-
@test blocksizes(A) == ([5],)
19-
@test blocksizes(A, 1) == [5]
18+
@test blocklengths.(axes(A)) == ([5],)
19+
@test blocklengths(axes(A, 1)) == [5]
20+
@test blocksizes(A) == [(5,)]
2021
@test A[Block(1)] == A
2122
view(A, Block(1))[1] = 2
2223
@test A[1] == 2

test/test_blockarrays.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,8 @@ end
109109

110110
# test that BlockArrays may be created from immutable arrays
111111
B = BlockArray(reshape(1:9,3,3), [2,1], [2,1])
112-
@test blocksizes(B) == ([2,1], [2,1])
112+
@test blocklengths.(axes(B)) == ([2,1], [2,1])
113+
@test blocksizes(B) == [(2,2) (2,1); (1,2) (1,1)]
113114
@test B == reshape([1:9;],3,3)
114115
@test blocks(B) isa Matrix{Matrix{Int}}
115116

test/test_blockdeque.jl

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,8 @@ using BlockArrays, Test
167167
@test pop!(B) == 6
168168
@test B == 1:5
169169
@test !any(isempty, blocks(B))
170-
@test blocksizes(B,1) == [1,2,2]
170+
@test blocklengths(axes(B,1)) == [1,2,2]
171+
@test blocksizes(B) == [(1,), (2,), (2,)]
171172
end
172173
end
173174

@@ -183,13 +184,15 @@ using BlockArrays, Test
183184
A = BlockArray([1:6;], [2,2,2])
184185
@test popfirst!(A) == 1
185186
@test A == 2:6
186-
@test blocksizes(A,1) == [1,2,2]
187+
@test blocklengths(axes(A,1)) == [1,2,2]
188+
@test blocksizes(A) == [(1,), (2,), (2,)]
187189

188190
@testset "empty blocks" begin
189191
B = BlockArray([1:6;], [0,0,1,2,3])
190192
@test popfirst!(B) == 1
191193
@test B == 2:6
192-
@test blocksizes(B,1) == [2,3]
194+
@test blocklengths(axes(B,1)) == [2,3]
195+
@test blocksizes(B) == [(2,), (3,)]
193196
@test !any(isempty, blocks(B))
194197
end
195198
end

test/test_blockindices.jl

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -786,13 +786,6 @@ end
786786
@test eltype(blocklengths(r)) === UInt16
787787
end
788788

789-
@testset "blocksizes" begin
790-
x = blockedrange(2:4)
791-
@test blocksizes(x,1) === 2:4
792-
y = blockedrange([2:4;])
793-
@test blocksizes(x,1) == blocksizes(y,1)
794-
end
795-
796789
@testset "show" begin
797790
b = blockedrange([1,2])
798791
@test repr(b) == "$BlockedOneTo($([1,3]))"

test/test_blocklinalg.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,12 +101,14 @@ bview(a, b) = Base.invoke(view, Tuple{AbstractArray,Any}, a, b)
101101
v = BlockArray(rand(6), 1:3)
102102
w = A * v
103103
@test w isa BlockArray
104-
@test blocksizes(w,1) == fill(2, 3)
104+
@test blocklengths(axes(w,1)) == fill(2, 3)
105+
@test blocksizes(w) == [(2,), (2,), (2,)]
105106
@test w Array(A) * v A * Array(v) Array(A) * Array(v)
106107

107108
z = A * w
108109
@test z isa BlockArray
109-
@test blocksizes(z,1) == fill(2, 3)
110+
@test blocklengths(axes(z,1)) == fill(2, 3)
111+
@test blocksizes(z) == [(2,), (2,), (2,)]
110112
@test z Array(A) * w A * Array(w) Array(A) * Array(w)
111113
end
112114

test/test_blocks.jl

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,4 +105,28 @@ using Test, BlockArrays
105105
end
106106
end
107107

108+
@testset "blocksizes" begin
109+
@testset "blocksizes" begin
110+
v = Array(reshape(1:20, (5, 4)))
111+
A = BlockArray(v, [2, 3], [3, 1])
112+
@test blocklengths.(axes(A)) == ([2, 3], [3, 1])
113+
bs = @inferred(blocksizes(A))
114+
@test @inferred(size(bs)) == (2, 2)
115+
@test @inferred(length(bs)) == 4
116+
@test @inferred(axes(bs)) == (1:2, 1:2)
117+
@test @inferred(eltype(bs)) === Tuple{Int,Int}
118+
@test bs == [(2, 3) (2, 1); (3, 3) (3, 1)]
119+
@test @inferred(bs[1, 1]) == (2, 3)
120+
@test @inferred(bs[2, 1]) == (3, 3)
121+
@test @inferred(bs[1, 2]) == (2, 1)
122+
@test @inferred(bs[2, 2]) == (3, 1)
123+
@test @inferred(bs[1]) == (2, 3)
124+
@test @inferred(bs[2]) == (3, 3)
125+
@test @inferred(bs[3]) == (2, 1)
126+
@test @inferred(bs[4]) == (3, 1)
127+
@test blocksizes(A, 1) == [2, 3]
128+
@test blocksizes(A, 2) == [3, 1]
129+
end
130+
end
131+
108132
end # module

0 commit comments

Comments
 (0)