Skip to content

Commit ff8d25a

Browse files
authored
Add support for BlockBidiagonal (#77)
* Add support for BlockBidiagonal * v0.8.8 * Fix I - A
1 parent 5d4297d commit ff8d25a

File tree

4 files changed

+54
-6
lines changed

4 files changed

+54
-6
lines changed

Project.toml

Lines changed: 3 additions & 3 deletions
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.7"
3+
version = "0.8.8"
44

55
[deps]
66
ArrayLayouts = "4c555306-a7a7-4459-81d9-ec55ddd5c99a"
@@ -17,8 +17,8 @@ Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
1717

1818
[compat]
1919
ArrayLayouts = "0.3.3"
20-
BandedMatrices = "0.15.10"
21-
BlockArrays = "0.12.7"
20+
BandedMatrices = "0.15.14"
21+
BlockArrays = "0.12.9"
2222
FillArrays = "0.8.10"
2323
MatrixFactorizations = "0.4.1"
2424
julia = "1.2"

src/BlockBandedMatrices.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ import BandedMatrices: isbanded, bandwidths, bandwidth, banded_getindex, colrang
4545
_banded_colval, _banded_rowval, _banded_nzval # for sparse
4646

4747
export BandedBlockBandedMatrix, BlockBandedMatrix, BlockSkylineMatrix, blockbandwidth, blockbandwidths,
48-
subblockbandwidth, subblockbandwidths, Ones, Zeros, Fill, Block, BlockTridiagonal, isblockbanded
48+
subblockbandwidth, subblockbandwidths, Ones, Zeros, Fill, Block, BlockTridiagonal, BlockBidiagonal, isblockbanded
4949

5050

5151
const Block1 = Block{1,Int}

src/interfaceimpl.jl

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,12 @@ function sizes_from_blocks(A::Diagonal, _)
3636
end
3737

3838

39-
# Block Tridiagonal
39+
# Block Bi/Tridiagonal
4040
const BlockTridiagonal{T,VT<:Matrix{T}} = BlockMatrix{T,<:Tridiagonal{VT}}
41+
const BlockBidiagonal{T,VT<:Matrix{T}} = BlockMatrix{T,<:Bidiagonal{VT}}
4142

4243
BlockTridiagonal(A,B,C) = mortar(Tridiagonal(A,B,C))
44+
BlockBidiagonal(A, B, uplo) = mortar(Bidiagonal(A,B,uplo))
4345

4446
function sizes_from_blocks(A::Tridiagonal, _)
4547
# for k = 1:length(A.du)
@@ -51,9 +53,26 @@ function sizes_from_blocks(A::Tridiagonal, _)
5153
(size.(A.d, 1), size.(A.d,2))
5254
end
5355

56+
function sizes_from_blocks(A::Bidiagonal, _)
57+
# for k = 1:length(A.du)
58+
# size(A.du[k],1) == sz[1][k] || throw(ArgumentError("block sizes of upper diagonal inconsisent with diagonal"))
59+
# size(A.du[k],2) == sz[2][k+1] || throw(ArgumentError("block sizes of upper diagonal inconsisent with diagonal"))
60+
# size(A.dl[k],1) == sz[1][k+1] || throw(ArgumentError("block sizes of lower diagonal inconsisent with diagonal"))
61+
# size(A.dl[k],2) == sz[2][k] || throw(ArgumentError("block sizes of lower diagonal inconsisent with diagonal"))
62+
# end
63+
(size.(A.dv, 1), size.(A.dv,2))
64+
end
65+
5466
blockbandwidths(A::BlockArray) = bandwidths(A.blocks)
5567
isblockbanded(A::BlockArray) = isbanded(A.blocks)
5668

69+
@inline function getblock(block_arr::BlockBidiagonal{T,VT}, K::Int, J::Int) where {T,VT<:AbstractMatrix}
70+
@boundscheck blockcheckbounds(block_arr, K, J)
71+
l,u = blockbandwidths(block_arr)
72+
-l  (J-K)  u || return convert(VT, Zeros{T}(length.(getindex.(axes(block_arr),(Block(K),Block(J))))...))
73+
block_arr.blocks[K,J]
74+
end
75+
5776
@inline function getblock(block_arr::BlockTridiagonal{T,VT}, K::Int, J::Int) where {T,VT<:AbstractMatrix}
5877
@boundscheck blockcheckbounds(block_arr, K, J)
5978
abs(J-K) 2 && return convert(VT, Zeros{T}(length.(getindex.(axes(block_arr),(Block(K),Block(J))))...))
@@ -70,7 +89,15 @@ for op in (:-, :+)
7089
end
7190
function $op::UniformScaling, A::BlockTridiagonal)
7291
checksquareblocks(A)
73-
mortar(Tridiagonal(A.blocks.dl, broadcast($op, Ref(λ), A.blocks.d), A.blocks.du))
92+
mortar(Tridiagonal(broadcast($op,A.blocks.dl), broadcast($op, Ref(λ), A.blocks.d), broadcast($op,A.blocks.du)))
93+
end
94+
function $op(A::BlockBidiagonal, λ::UniformScaling)
95+
checksquareblocks(A)
96+
mortar(Bidiagonal(broadcast($op, A.blocks.dv, Ref(λ)), A.blocks.ev, A.blocks.uplo))
97+
end
98+
function $op::UniformScaling, A::BlockBidiagonal)
99+
checksquareblocks(A)
100+
mortar(Bidiagonal(broadcast($op, Ref(λ), A.blocks.dv), broadcast($op,A.blocks.ev), A.blocks.uplo))
74101
end
75102
end
76103
end

test/test_misc.jl

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,25 @@ import BandedMatrices: bandwidths, AbstractBandedMatrix, BandedStyle, bandeddata
2121
@test BandedMatrix(V) == V
2222
end
2323

24+
@testset "Block Bidiagonal" begin
25+
Bu = BlockBidiagonal(fill([1 2],4), fill([3 4],3), :U)
26+
Bl = BlockBidiagonal(fill([1 2],4), fill([3 4],3), :L)
27+
@test blockbandwidths(Bu) == (0,1)
28+
@test blockbandwidths(Bl) == (1,0)
29+
@test isblockbanded(Bu)
30+
@test isblockbanded(Bl)
31+
@test Bu[Block(1,1)] == Bl[Block(1,1)] == [1 2]
32+
@test @inferred(Bu[Block(1,2)]) == @inferred(Bl[Block(2,1)]) == [3 4]
33+
@test @inferred(getblock(Bu,1,3)) == @inferred(Bu[Block(1,3)]) == [0 0]
34+
@test_throws DimensionMismatch Bu+I
35+
Bu = BlockBidiagonal(fill([1 2; 1 2],4), fill([3 4; 3 4],3), :U)
36+
Bl = BlockBidiagonal(fill([1 2; 1 2],4), fill([3 4; 3 4],3), :L)
37+
@test Bu+I == I+Bu == mortar(Bidiagonal(fill([2 2; 1 3],4), fill([3 4; 3 4],3), :U)) == Matrix(Bu) + I
38+
@test Bl+I == I+Bl == mortar(Bidiagonal(fill([2 2; 1 3],4), fill([3 4; 3 4],3), :L)) == Matrix(Bl) + I
39+
@test Bu-I == mortar(Bidiagonal(fill([0 2; 1 1],4), fill([3 4; 3 4],3), :U)) == Matrix(Bu) - I
40+
@test I-Bu == mortar(Bidiagonal(fill([0 -2; -1 -1],4), fill(-[3 4; 3 4],3), :U)) == I - Matrix(Bu)
41+
end
42+
2443
@testset "Block Tridiagonal" begin
2544
A = BlockTridiagonal(fill([1 2],3), fill([3 4],4), fill([4 5],3))
2645
@test blockbandwidths(A) == (1,1)
@@ -31,4 +50,6 @@ end
3150
@test_throws DimensionMismatch A+I
3251
A = BlockTridiagonal(fill([1 2; 1 2],3), fill([3 4; 3 4],4), fill([4 5; 4 5],3))
3352
@test A+I == I+A == mortar(Tridiagonal(fill([1 2; 1 2],3), fill([4 4; 3 5],4), fill([4 5; 4 5],3))) == Matrix(A) + I
53+
@test A-I == mortar(Tridiagonal(fill([1 2; 1 2],3), fill([2 4; 3 3],4), fill([4 5; 4 5],3))) == Matrix(A) - I
54+
@test I-A == mortar(Tridiagonal(fill(-[1 2; 1 2],3), fill([-2 -4; -3 -3],4), fill(-[4 5; 4 5],3))) == I - Matrix(A)
3455
end

0 commit comments

Comments
 (0)