Skip to content

Commit 9b23fcb

Browse files
authored
Better support for BlockRange indexing (#69)
* BlockRange indexing produces (Banded)BlockBandedMatrix * v0.8.2 * generalise sublayout
1 parent a3b87f1 commit 9b23fcb

File tree

7 files changed

+82
-29
lines changed

7 files changed

+82
-29
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "BlockBandedMatrices"
22
uuid = "ffab5731-97b5-5995-9138-79e8c1846df0"
3-
version = "0.8.1"
3+
version = "0.8.2"
44

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

src/AbstractBlockBandedMatrix.jl

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,24 @@
1-
####
2-
# Matrix memory layout traits
3-
#
4-
# if MemoryLayout(A) returns BandedColumnMajor, you must override
5-
# pointer and leadingdimension
6-
# in addition to the banded matrix interface
7-
####
81

2+
"""
3+
AbstractBlockBandedLayout
4+
5+
isa a `MemoryLayout` that indicates that the array implements the block-banded
6+
interface.
7+
"""
98
abstract type AbstractBlockBandedLayout <: AbstractBlockLayout end
9+
10+
"""
11+
AbstractBandedBlockBandedLayout
12+
13+
isa a `MemoryLayout` that indicates that the array implements the banded-block-banded
14+
interface.
15+
"""
1016
abstract type AbstractBandedBlockBandedLayout <: AbstractBlockBandedLayout end
1117

18+
19+
struct BandedBlockBandedLayout <: AbstractBandedBlockBandedLayout end
20+
struct BlockBandedLayout <: AbstractBlockBandedLayout end
21+
1222
struct BandedBlockBandedColumns{LAY} <: AbstractBandedBlockBandedLayout end
1323
struct BandedBlockBandedRows{LAY} <: AbstractBandedBlockBandedLayout end
1424
struct BlockBandedColumns{LAY} <: AbstractBlockBandedLayout end

src/BandedBlockBandedMatrix.jl

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -316,13 +316,18 @@ end
316316
end
317317

318318
## structured matrix methods ##
319-
function Base.replace_in_print_matrix(A::BandedBlockBandedMatrix, i::Integer, j::Integer, s::AbstractString)
319+
function _bandedblockbanded_replace_in_print_matrix(A, i, j, s)
320320
bi = findblockindex.(axes(A), (i,j))
321321
I,J = block.(bi)
322322
i,j = blockindex.(bi)
323-
-A.l Int(J-I)  A.u && -A.λ j-i A.μ ? s : Base.replace_with_centered_mark(s)
323+
l,u = blockbandwidths(A)
324+
λ,μ = subblockbandwidths(A)
325+
-l Int(J-I)  u && -λ j-i μ ? s : Base.replace_with_centered_mark(s)
324326
end
325327

328+
Base.replace_in_print_matrix(A::BandedBlockBandedMatrix, i::Integer, j::Integer, s::AbstractString) =
329+
_bandedblockbanded_replace_in_print_matrix(A, i, j, s)
330+
326331

327332
############
328333
# Indexing #
@@ -411,32 +416,43 @@ sublayout(::BandedBlockBandedColumnMajor, ::Type{<:Tuple{BlockSlice{Block1},Bloc
411416
sublayout(::BandedBlockBandedColumnMajor, ::Type{<:Tuple{BlockSlice{BlockRange1},BlockSlice{Block1}}}) = BandedBlockBandedColumnMajor()
412417
sublayout(::BandedBlockBandedColumnMajor, ::Type{<:Tuple{BlockSlice{BlockRange1},BlockSlice{BlockIndexRange1}}}) = BandedBlockBandedColumnMajor()
413418

419+
sublayout(::AbstractBandedBlockBandedLayout, ::Type{<:Tuple{BlockSlice{Block1},BlockSlice{Block1}}}) = BandedLayout()
420+
sublayout(::AbstractBandedBlockBandedLayout, ::Type{<:Tuple{BlockSlice{BlockIndexRange1},BlockSlice{BlockIndexRange1}}}) = BandedLayout()
421+
sublayout(::AbstractBandedBlockBandedLayout, ::Type{<:Tuple{BlockSlice{BlockIndexRange1},BlockSlice{Block1}}}) = BandedLayout()
422+
sublayout(::AbstractBandedBlockBandedLayout, ::Type{<:Tuple{BlockSlice{Block1},BlockSlice{BlockIndexRange1}}}) = BandedLayout()
423+
sublayout(::AbstractBandedBlockBandedLayout, ::Type{<:Tuple{BlockSlice{BlockRange1},BlockSlice{BlockRange1}}}) = BandedBlockBandedLayout()
424+
sublayout(::AbstractBandedBlockBandedLayout, ::Type{<:Tuple{BlockSlice{Block1},BlockSlice{BlockRange1}}}) = BandedBlockBandedLayout()
425+
sublayout(::AbstractBandedBlockBandedLayout, ::Type{<:Tuple{BlockSlice{BlockRange1},BlockSlice{Block1}}}) = BandedBlockBandedLayout()
426+
sublayout(::AbstractBandedBlockBandedLayout, ::Type{<:Tuple{BlockSlice{BlockRange1},BlockSlice{BlockIndexRange1}}}) = BandedBlockBandedLayout()
427+
428+
429+
sub_materialize(::AbstractBandedBlockBandedLayout, V, _) = BandedBlockBandedMatrix(V)
430+
414431
isbanded(A::SubArray{<:Any,2,<:BandedBlockBandedMatrix}) = MemoryLayout(typeof(A)) == BandedColumnMajor()
415432
isbandedblockbanded(A::SubArray{<:Any,2,<:BandedBlockBandedMatrix}) = MemoryLayout(typeof(A)) == BandedBlockBandedColumnMajor()
416433

417434

418-
subblockbandwidths(V::SubBandedBlockBandedMatrix) = subblockbandwidths(parent(V))
435+
subblockbandwidths(V::SubArray{<:Any,2,<:Any,<:Tuple{<:BlockSlice{BlockRange1},<:BlockSlice{BlockRange1}}}) =
436+
subblockbandwidths(parent(V))
419437

420-
function blockbandwidths(V::SubBandedBlockBandedMatrix{<:Any,BlockRange1,Block1})
438+
function blockbandwidths(V::SubArray{<:Any,2,<:Any,<:Tuple{<:BlockSlice{BlockRange1},<:BlockSlice{Block1}}})
421439
A = parent(V)
422-
423440
KR = parentindices(V)[1].block.indices[1]
424441
J = parentindices(V)[2].block
425442
shift = Int(KR[1])-Int(J)
426443
blockbandwidth(A,1) - shift, blockbandwidth(A,2) + shift
427444
end
428445

429-
function blockbandwidths(V::SubBandedBlockBandedMatrix{<:Any,Block1,BlockRange1})
446+
function blockbandwidths(V::SubArray{<:Any,2,<:Any,<:Tuple{<:BlockSlice{<:Block1},<:BlockSlice{<:BlockRange1}}})
430447
A = parent(V)
431-
432448
K = parentindices(V)[1].block
433449
JR = parentindices(V)[2].block.indices[1]
434450
shift = Int(K)-Int(JR[1])
435-
436-
blockbandwidth(A,1) - shift, blockbandwidth(A,2) + shift
451+
l,u = blockbandwidths(A)
452+
l - shift, u + shift
437453
end
438454

439-
function blockbandwidths(V::SubBandedBlockBandedMatrix{<:Any,BlockRange1,BlockRange1})
455+
function blockbandwidths(V::SubArray{<:Any,2,<:Any,<:Tuple{<:BlockSlice{<:BlockRange1},<:BlockSlice{<:BlockRange1}}})
440456
A = parent(V)
441457

442458
KR = parentindices(V)[1].block.indices[1]

src/BlockBandedMatrices.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import SparseArrays: sparse
2323

2424
import ArrayLayouts: BlasMatLmulVec,
2525
triangularlayout, UpperTriangularLayout, TriangularLayout, MatLdivVec,
26-
triangulardata, sublayout,
26+
triangulardata, sublayout, sub_materialize,
2727
AbstractColumnMajor, DenseColumnMajor, ColumnMajor,
2828
DiagonalLayout, MulAdd, mul, colsupport, rowsupport,
2929
_qr, _factorize, _copyto!
@@ -38,7 +38,7 @@ import BandedMatrices: isbanded, bandwidths, bandwidth, banded_getindex, colrang
3838
inbands_setindex!, inbands_getindex, banded_setindex!,
3939
banded_generic_axpy!,
4040
BlasFloat, banded_dense_axpy!, MemoryLayout,
41-
BandedColumnMajor,
41+
BandedLayout, BandedColumnMajor,
4242
BandedSubBandedMatrix, bandeddata, tribandeddata,
4343
_BandedMatrix, colstart, colstop, rowstart, rowstop,
4444
BandedStyle, _fill_lmul!, bandshift,
@@ -50,7 +50,7 @@ export BandedBlockBandedMatrix, BlockBandedMatrix, BlockSkylineMatrix, blockband
5050

5151
const Block1 = Block{1,Int}
5252
const BlockRange1 = BlockRange{1,Tuple{UnitRange{Int}}}
53-
const BlockIndexRange1 = BlockIndexRange{1,Tuple{UnitRange{Int}}}
53+
const BlockIndexRange1 = BlockIndexRange{1,Tuple{UnitRange{Int}}}
5454

5555
blockcolrange(A...) = blockcolsupport(A...)
5656
blockrowrange(A...) = blockrowsupport(A...)

src/linalg.jl

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,9 @@ function blockbandwidths(V::SubBlockSkylineMatrix{<:Any,LL,UU,BlockRange1,BlockR
7777
KR = parentindices(V)[1].block.indices[1]
7878
JR = parentindices(V)[2].block.indices[1]
7979

80-
@assert KR[1] == JR[1] == 1
81-
blockbandwidths(A)
80+
shift = KR[1] - JR[1]
81+
l,u = blockbandwidths(A)
82+
l-shift, u+shift
8283
end
8384

8485

@@ -92,6 +93,10 @@ sublayout(::BlockBandedColumnMajor, ::Type{<:Tuple{<:BlockSlice{BlockRange1}, <:
9293
sublayout(::BlockBandedColumnMajor, ::Type{<:Tuple{<:BlockSlice{BlockRange1}, <:BlockSlice{BlockIndexRange1}}}) = ColumnMajor()
9394
sublayout(::BlockBandedColumnMajor, ::Type{<:Tuple{<:BlockSlice{BlockIndexRange1}, <:BlockSlice{BlockIndexRange1}}}) = ColumnMajor()
9495

96+
isblockbanded(V::SubArray{<:Any,2,<:Any,<:Tuple{<:BlockSlice{BlockRange1}, <:BlockSlice{BlockRange1}}}) =
97+
isblockbanded(parent(V))
98+
99+
sub_materialize(::AbstractBlockBandedLayout, V, _) = BlockBandedMatrix(V)
95100

96101
strides(V::SubBlockSkylineMatrix{<:Any,LL,UU,<:Union{BlockRange1,Block1},Block1}) where {LL,UU} =
97102
(1,parent(V).block_sizes.block_strides[Int(parentindices(V)[2].block)])

test/test_bandedblockbanded.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,9 @@ import BlockBandedMatrices: _BandedBlockBandedMatrix, blockcolsupport, blockrows
298298
@test B isa BandedBlockBandedMatrix
299299
@test blockbandwidths(V) == blockbandwidths(B) == (2,0)
300300
@test subblockbandwidths(V) == subblockbandwidths(B) == subblockbandwidths(A) == (λ,μ)
301-
@test B == V
301+
@test B == V == A[Block.(2:3), Block.(3:4)]
302+
303+
@test A[Block.(2:3), Block.(3:4)] isa BandedBlockBandedMatrix
302304

303305
x = randn(size(B,2))
304306
y = similar(x, size(B,1))

test/test_blockbanded.jl

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import Base.Broadcast: materialize!
1111
cols = rows = 1:N
1212

1313
@test Matrix(BlockBandedMatrix(Zeros(sum(rows),sum(cols)), rows, cols, (l,u))) ==
14-
Array(BlockBandedMatrix(Zeros(sum(rows),sum(cols)), rows, cols, (l,u))) ==
14+
Array(BlockBandedMatrix(Zeros(sum(rows),sum(cols)), rows, cols, (l,u))) ==
1515
zeros(Float64, 10, 10)
1616

1717
@test Matrix(BlockBandedMatrix{Int}(Zeros(sum(rows),sum(cols)), rows,cols, (l,u))) ==
@@ -35,13 +35,11 @@ import Base.Broadcast: materialize!
3535
N = M = 4
3636
cols = rows = 1:N
3737
A = BlockBandedMatrix{Int}(undef, rows,cols, (l,u))
38-
A.data .= 1:length(A.data)
38+
A.data .= 1:length(A.data)
3939

4040
@test A[1,1] == 1
4141
@test A[1,3] == 10
4242

43-
44-
4543
@test blockbandwidth(A,1) == 1
4644
@test blockbandwidths(A) == (l,u)
4745

@@ -92,12 +90,34 @@ import Base.Broadcast: materialize!
9290
@test ret[1,2] == 0
9391
end
9492

93+
@testset "block-banded matrix interface for blockranges" begin
94+
l , u = 1,1
95+
N = M = 4
96+
cols = rows = 1:N
97+
A = BlockBandedMatrix{Int}(undef, rows,cols, (l,u))
98+
A.data .= 1:length(A.data)
99+
100+
V = view(A, Block.(2:3), Block.(3:4))
101+
@test isblockbanded(V)
102+
103+
B = BlockBandedMatrix(V)
104+
@test B isa BlockBandedMatrix
105+
@test blockbandwidths(V) == blockbandwidths(B) == (2,0)
106+
@test B == V == A[Block.(2:3), Block.(3:4)]
107+
108+
@test A[Block.(2:3), Block.(3:4)] isa BlockBandedMatrix
109+
110+
x = randn(size(B,2))
111+
y = similar(x, size(B,1))
112+
@test all((similar(y) .= MulAdd(B, x)) .=== (similar(y) .= MulAdd(V,x)))
113+
end
114+
95115
@testset "BlockBandedMatrix indexing" begin
96116
l , u = 1,1
97117
N = M = 10
98118
cols = rows = 1:N
99119
A = BlockBandedMatrix{Float64}(undef, rows,cols, (l,u))
100-
A.data .= 1:length(A.data)
120+
A.data .= 1:length(A.data)
101121

102122
A[1,1] = 5
103123
@test A[1,1] == 5

0 commit comments

Comments
 (0)