@@ -22,109 +22,26 @@ const AbstractBlockVector{T} = AbstractBlockArray{T, 1}
22
22
const AbstractBlockVecOrMat{T} = Union{AbstractBlockMatrix{T}, AbstractBlockVector{T}}
23
23
24
24
block2string (b, s) = string (join (map (string,b), ' ×' ), " -blocked " , Base. dims2string (s))
25
- Base. summary (a:: AbstractBlockArray ) = string (block2string (nblocks (a), size (a)), " " , typeof (a))
25
+ _block_summary (a) = string (block2string (blocksize (a), size (a)), " " , typeof (a))
26
+ Base. summary (a:: AbstractBlockArray ) = _block_summary (a)
26
27
_show_typeof (io, a) = show (io, typeof (a))
27
- function Base . summary (io:: IO , a:: AbstractBlockArray )
28
- print (io, block2string (nblocks (a), size (a)))
28
+ function _block_summary (io, a)
29
+ print (io, block2string (blocksize (a), size (a)))
29
30
print (io, ' ' )
30
31
_show_typeof (io, a)
31
32
end
32
- Base. similar (block_array:: AbstractBlockArray{T} ) where {T} = similar (block_array, T)
33
- Base. IndexStyle (:: Type{<:AbstractBlockArray} ) = IndexCartesian ()
34
-
35
- """
36
- nblocks(A, [dim...])
37
-
38
- Returns a tuple containing the number of blocks in a block array. Optionally you can specify
39
- the dimension(s) you want the number of blocks for.
40
-
41
- ```jldoctest; setup = quote using BlockArrays end
42
- julia> A = BlockArray(rand(5,4,6), [1,4], [1,2,1], [1,2,2,1]);
43
-
44
- julia> nblocks(A)
45
- (2, 3, 4)
46
-
47
- julia> nblocks(A, 2)
48
- 3
49
-
50
- julia> nblocks(A, 3, 2)
51
- (4, 3)
52
- ```
53
- """
54
- nblocks (block_array:: AbstractArray , i:: Integer ) = nblocks (block_array)[i]
55
-
56
- nblocks (block_array:: AbstractArray , i:: Vararg{Integer, N} ) where {N} =
57
- nblocks (blocksizes (block_array), i... )
58
-
59
-
60
- """
61
- Block(inds...)
62
-
63
- A `Block` is simply a wrapper around a set of indices or enums so that it can be used to dispatch on. By
64
- indexing a `AbstractBlockArray` with a `Block` the a block at that block index will be returned instead of
65
- a single element.
66
-
67
- ```jldoctest; setup = quote using BlockArrays end
68
- julia> A = BlockArray(ones(2,3), [1, 1], [2, 1])
69
- 2×2-blocked 2×3 BlockArray{Float64,2}:
70
- 1.0 1.0 │ 1.0
71
- ──────────┼─────
72
- 1.0 1.0 │ 1.0
73
-
74
- julia> A[Block(1, 1)]
75
- 1×2 Array{Float64,2}:
76
- 1.0 1.0
77
- ```
78
- """
79
- struct Block{N, T}
80
- n:: NTuple{N, T}
81
- Block {N, T} (n:: NTuple{N, T} ) where {N, T} = new {N, T} (n)
82
- end
33
+ Base. summary (io:: IO , a:: AbstractBlockArray ) = _block_summary (io, a)
83
34
35
+ # avoid to_shape which complicates axes
36
+ Base. similar (a:: AbstractBlockArray{T} ) where {T} = similar (a, T)
37
+ Base. similar (a:: AbstractBlockArray , :: Type{T} ) where {T} = similar (a, T, axes (a))
38
+ Base. similar (a:: AbstractBlockArray{T} , dims:: Tuple ) where {T} = similar (a, T, dims)
84
39
85
- Block {N, T} (n:: Vararg{T, N} ) where {N,T} = Block {N, T} (n)
86
- Block {N} (n:: Vararg{T, N} ) where {N,T} = Block {N, T} (n)
87
- Block () = Block {0,Int} ()
88
- Block (n:: Vararg{T, N} ) where {N,T} = Block {N, T} (n)
89
- Block {1} (n:: Tuple{T} ) where {T} = Block {1, T} (n)
90
- Block {N} (n:: NTuple{N, T} ) where {N,T} = Block {N, T} (n)
91
- Block (n:: NTuple{N, T} ) where {N,T} = Block {N, T} (n)
92
-
93
- @inline function Block (blocks:: NTuple{N, Block{1, T}} ) where {N,T}
94
- Block {N, T} (ntuple (i -> blocks[i]. n[1 ], Val (N)))
95
- end
96
-
97
-
98
- # The following code is taken from CartesianIndex
99
- @inline (+ )(index:: Block{N} ) where {N} = Block {N} (map (+ , index. n))
100
- @inline (- )(index:: Block{N} ) where {N} = Block {N} (map (- , index. n))
101
-
102
- @inline (+ )(index1:: Block{N} , index2:: Block{N} ) where {N} =
103
- Block {N} (map (+ , index1. n, index2. n))
104
- @inline (- )(index1:: Block{N} , index2:: Block{N} ) where {N} =
105
- Block {N} (map (- , index1. n, index2. n))
106
- @inline min (index1:: Block{N} , index2:: Block{N} ) where {N} =
107
- Block {N} (map (min, index1. n, index2. n))
108
- @inline max (index1:: Block{N} , index2:: Block{N} ) where {N} =
109
- Block {N} (map (max, index1. n, index2. n))
110
-
111
- @inline (+ )(i:: Integer , index:: Block ) = index+ i
112
- @inline (+ )(index:: Block{N} , i:: Integer ) where {N} = Block {N} (map (x-> x+ i, index. n))
113
- @inline (- )(index:: Block{N} , i:: Integer ) where {N} = Block {N} (map (x-> x- i, index. n))
114
- @inline (- )(i:: Integer , index:: Block{N} ) where {N} = Block {N} (map (x-> i- x, index. n))
115
- @inline (* )(a:: Integer , index:: Block{N} ) where {N} = Block {N} (map (x-> a* x, index. n))
116
- @inline (* )(index:: Block , a:: Integer ) = * (a,index)
117
-
118
- # comparison
119
- @inline isless (I1:: Block{N} , I2:: Block{N} ) where {N} = Base. IteratorsMD. _isless (0 , I1. n, I2. n)
120
-
121
- # conversions
122
- convert (:: Type{T} , index:: Block{1} ) where {T<: Number } = convert (T, index. n[1 ])
123
- convert (:: Type{T} , index:: Block ) where {T<: Tuple } = convert (T, index. n)
40
+ Base. IndexStyle (:: Type{<:AbstractBlockArray} ) = IndexCartesian ()
124
41
125
- Int (index :: Block{1} ) = Int (index . n[ 1 ])
126
- Integer (index :: Block{1} ) = index . n[ 1 ]
127
- Number (index :: Block{1} ) = index . n[ 1 ]
42
+ # need to overload axes to return BlockAxis
43
+ @inline size (block_array :: AbstractBlockArray ) = map (length, axes (block_array))
44
+ @inline axes (block_array :: AbstractBlockArray ) = throw ( error ( " axes for " , typeof (block_array), " is not implemented " ))
128
45
129
46
"""
130
47
getblock(A, inds...)
@@ -222,10 +139,12 @@ struct BlockBoundsError <: Exception
222
139
a:: Any
223
140
i:: Any
224
141
BlockBoundsError () = new ()
225
- BlockBoundsError (a:: AbstractBlockArray ) = new (a)
226
- BlockBoundsError (a:: AbstractBlockArray , @nospecialize (i)) = new (a,i)
142
+ BlockBoundsError (a:: AbstractArray ) = new (a)
143
+ BlockBoundsError (a:: AbstractArray , @nospecialize (i)) = new (a,i)
227
144
end
228
145
146
+ BlockBoundsError (a:: AbstractArray , I:: Block ) = BlockBoundsError (a, I. n)
147
+
229
148
function Base. showerror (io:: IO , ex:: BlockBoundsError )
230
149
print (io, " BlockBoundsError" )
231
150
if isdefined (ex, :a )
@@ -250,7 +169,7 @@ specialize this method if they need to provide custom block bounds checking beha
250
169
julia> A = BlockArray(rand(2,3), [1,1], [2,1]);
251
170
252
171
julia> blockcheckbounds(A, 3, 2)
253
- ERROR: BlockBoundsError: attempt to access 2×2-blocked 2×3 BlockArray{Float64,2,Array{Array{Float64,2},2},BlockArrays.BlockSizes{2, Tuple{Array{Int64,1}, Array{Int64,1}}}} at block index [3,2]
172
+ ERROR: BlockBoundsError: attempt to access 2×2-blocked 2×3 BlockArray{Float64,2,Array{Array{Float64,2},2},Tuple{BlockedUnitRange{ Array{Int64,1}},BlockedUnitRange{ Array{Int64,1}}}} at block index [3,2]
254
173
[...]
255
174
```
256
175
"""
@@ -263,14 +182,12 @@ ERROR: BlockBoundsError: attempt to access 2×2-blocked 2×3 BlockArray{Float64,
263
182
end
264
183
265
184
@inline function blockcheckbounds (:: Type{Bool} , A:: AbstractArray{T, N} , i:: Vararg{Integer, N} ) where {T,N}
266
- n = nblocks (A)
185
+ n = blockaxes (A)
267
186
k = 0
268
187
for idx in 1 : N # using enumerate here will allocate
269
188
k += 1
270
189
@inbounds _i = i[idx]
271
- if _i <= 0 || _i > n[k]
272
- return false
273
- end
190
+ Block (_i) in n[k] || return false
274
191
end
275
192
return true
276
193
end
0 commit comments