Skip to content

Commit 11c28ef

Browse files
jagotdlfivefifty
authored andcommitted
Ensure block-bandwidths BlockSkylineMatrix products are not larger than necessary (#21)
1 parent 3d06e72 commit 11c28ef

File tree

2 files changed

+66
-3
lines changed

2 files changed

+66
-3
lines changed

src/linalg.jl

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,28 @@ end
9999
*(A::Matrix, B::BandedBlockBandedMatrix) = materialize(Mul(A,B))
100100

101101

102+
function add_bandwidths(A::AbstractBlockBandedMatrix,B::AbstractBlockBandedMatrix)
103+
Al,Au = colblockbandwidths(A)
104+
Bl,Bu = colblockbandwidths(B)
105+
106+
l = copy(Al)
107+
u = copy(Au)
108+
109+
for (v,Bv) in [(l,Bl),(u,Bu)]
110+
n = length(v)
111+
for i = 1:n
112+
sel = max(i-Au[i],1):min(i+Al[i],n)
113+
isempty(sel) && continue
114+
v[i] += maximum(Bv[sel])
115+
end
116+
end
117+
118+
l,u
119+
end
120+
121+
add_bandwidths(A::BlockBandedMatrix,B::BlockBandedMatrix) =
122+
colblockbandwidths(A) .+ colblockbandwidths(B)
123+
102124
function similar(M::MatMulMat{<:AbstractBlockBandedLayout,<:AbstractBlockBandedLayout}, ::Type{T}) where T
103125
A,B = M.factors
104126
Arows, Acols = A.block_sizes.block_sizes.cumul_sizes
@@ -115,8 +137,8 @@ function similar(M::MatMulMat{<:AbstractBlockBandedLayout,<:AbstractBlockBandedL
115137
end
116138
n,m = size(A,1), size(B,2)
117139

118-
l, u = blockbandwidths(A) .+ blockbandwidths(B)
119-
BlockBandedMatrix{T}(undef, BlockBandedSizes(BlockSizes((Arows,Bcols)), l, u))
140+
l,u = add_bandwidths(A,B)
141+
BlockSkylineMatrix{T}(undef, BlockSkylineSizes(BlockSizes((Arows,Bcols)), l, u))
120142
end
121143

122144
function similar(M::MatMulMat{BandedBlockBandedColumnMajor,BandedBlockBandedColumnMajor}, ::Type{T}) where T

test/test_blockskyline.jl

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
21
using LazyArrays, BlockBandedMatrices, LinearAlgebra, Random, Test
2+
import BlockBandedMatrices: colblockbandwidths
33

44
Random.seed!(0)
55

@@ -26,4 +26,45 @@ Random.seed!(0)
2626
@view(V[:,2]) .= Mul(A, @view(V[:,1]))
2727
@test V[:,2] reference
2828
end
29+
30+
@testset "BlockSkylineMatrix multiplication" begin
31+
rows = [3, 1, 2, 1, 2, 1, 2, 1, 2, 1, 3]
32+
l,u = [1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1], [1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1]
33+
34+
M = BlockSkylineMatrix{Float64}(undef, (rows,rows), (l,u))
35+
M.data .= 1
36+
37+
d = Diagonal(1.0:size(M,2))
38+
D = BandedBlockBandedMatrix(d, (rows,rows), (0,0), (0,0))
39+
40+
MD = M*D
41+
@test MD isa BlockSkylineMatrix
42+
@test MD == Matrix(M)*d
43+
@test colblockbandwidths(MD) == (l,u)
44+
45+
MM = M*M
46+
@test MM isa BlockSkylineMatrix
47+
@test MM == Matrix(M)^2
48+
# Ensure correct (minimal) bandedness of product
49+
MMl,MMu = colblockbandwidths(MM)
50+
@test MMl[1:7] == [3,4,3,4,3,4,3]
51+
@test all(MMl[8:10] .≥ [3,2,1])
52+
@test all(MMu[2:4] .≥ [1,2,3])
53+
@test MMu[5:11] == [3,4,3,4,3,4,3]
54+
55+
N = BlockBandedMatrix{Float64}(undef, (rows,rows), (1,1))
56+
N.data .= 1
57+
NN = N*N
58+
# We don't want a BlockBandedMatrix^2 to become a general
59+
# BlockSkylineMatrix
60+
@test NN isa BlockBandedMatrix
61+
@test NN == Matrix(N)^2
62+
63+
rows = [9, 4, 1, 10, 6]
64+
O = BlockSkylineMatrix{Int64}(undef, (rows,rows), ([-2, 2, 0, 2, -1],[-1, 2, 1, 0, -1]))
65+
O.data .= 1
66+
OO = O*O
67+
@test OO isa BlockSkylineMatrix
68+
@test OO == Matrix(O)^2
69+
end
2970
end

0 commit comments

Comments
 (0)