Skip to content

Commit 71e486c

Browse files
authored
conj and trans layouts are bandedblockbanded (#118)
* conj and trans layouts are bandedblockbanded * Start blockbandwidths of banded matrix * shifts properly * Support Slice in sublayout * tests pass * Drop Julia v1.5 * add tests * increase coverage
1 parent 478c345 commit 71e486c

File tree

9 files changed

+118
-32
lines changed

9 files changed

+118
-32
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ jobs:
1010
fail-fast: false
1111
matrix:
1212
version:
13-
- '1.5'
14-
- '1'
13+
- '1.6'
1514
- '^1.7.0-0'
1615
os:
1716
- ubuntu-latest

Project.toml

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

55
[deps]
66
ArrayLayouts = "4c555306-a7a7-4459-81d9-ec55ddd5c99a"
@@ -13,12 +13,12 @@ SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
1313
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
1414

1515
[compat]
16-
ArrayLayouts = "0.6.3, 0.7"
16+
ArrayLayouts = "0.7"
1717
BandedMatrices = "0.16.8"
18-
BlockArrays = "0.15.2, 0.16"
18+
BlockArrays = "0.16.6"
1919
FillArrays = "0.11, 0.12"
2020
MatrixFactorizations = "0.7.1, 0.8"
21-
julia = "1.5"
21+
julia = "1.6"
2222

2323
[extras]
2424
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"

src/AbstractBlockBandedMatrix.jl

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,29 +25,35 @@ struct BlockBandedColumns{LAY} <: AbstractBlockBandedLayout end
2525
struct BlockBandedRows{LAY} <: AbstractBlockBandedLayout end
2626

2727
const BandedBlockBandedColumnMajor = BandedBlockBandedColumns{ColumnMajor}
28-
const BandedBlockBandedRowMajor = BandedBlockBandedColumns{RowMajor}
28+
const BandedBlockBandedRowMajor = BandedBlockBandedRows{ColumnMajor}
2929
const BlockBandedColumnMajor = BlockBandedColumns{ColumnMajor}
30-
const BlockBandedRowMajor = BlockBandedColumns{RowMajor}
30+
const BlockBandedRowMajor = BlockBandedRows{ColumnMajor}
3131

32-
transposelayout(::BandedBlockBandedColumnMajor) = BandedBlockBandedRowMajor()
33-
transposelayout(::BandedBlockBandedRowMajor) = BandedBlockBandedColumnMajor()
34-
transposelayout(::BlockBandedColumnMajor) = BlockBandedRowMajor()
35-
transposelayout(::BlockBandedRowMajor) = BlockBandedColumnMajor()
32+
transposelayout(::BandedBlockBandedColumns{Lay}) where Lay = BandedBlockBandedRows{Lay}()
33+
transposelayout(::BandedBlockBandedRows{Lay}) where Lay = BandedBlockBandedColumns{Lay}()
34+
transposelayout(::BlockBandedColumns{Lay}) where Lay = BlockBandedRows{Lay}()
35+
transposelayout(::BlockBandedRows{Lay}) where Lay = BlockBandedColumns{Lay}()
3636

37+
conjlayout(::Type{T}, ::BandedBlockBandedColumns{Lay}) where {T<:Complex,Lay} = BandedBlockBandedColumns{typeof(conjlayout(T,Lay))}()
38+
conjlayout(::Type{T}, ::BandedBlockBandedRows{Lay}) where {T<:Complex,Lay} = BandedBlockBandedRows{typeof(conjlayout(T,Lay))}()
39+
conjlayout(::Type{T}, ::BlockBandedColumns{Lay}) where {T<:Complex,Lay} = BlockBandedColumns{typeof(conjlayout(T,Lay))}()
40+
conjlayout(::Type{T}, ::BlockBandedRows{Lay}) where {T<:Complex,Lay} = BlockBandedRows{typeof(conjlayout(T,Lay))}()
3741

3842

3943
# AbstractBandedMatrix must implement
4044

4145
# A BlockBandedMatrix is a BlockMatrix, but is not a BandedMatrix
4246
abstract type AbstractBlockBandedMatrix{T} <: AbstractBlockMatrix{T} end
47+
MemoryLayout(::Type{<:AbstractBlockBandedMatrix}) = BlockBandedLayout()
4348

4449

4550
"""
4651
blockbandwidths(A)
4752
4853
Returns a tuple containing the upper and lower blockbandwidth of `A`.
4954
"""
50-
blockbandwidths(A::AbstractVecOrMat) = (blocksize(A,1)-1 , blocksize(A,2)-1)
55+
blockbandwidths(A::AbstractVecOrMat) = blockbandwidths(MemoryLayout(A), axes(A), A)
56+
blockbandwidths(_, _, A) = (blocksize(A,1)-1 , blocksize(A,2)-1)
5157

5258
"""
5359
blockbandwidth(A,i)

src/BlockBandedMatrices.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,14 @@ import ArrayLayouts: BlasMatLmulVec, MatLmulVec, MatLmulMat,
2626
triangulardata, sublayout, sub_materialize,
2727
AbstractColumnMajor, DenseColumnMajor, ColumnMajor,
2828
DiagonalLayout, MulAdd, mul, colsupport, rowsupport,
29-
_qr, _factorize, _copyto!, zero!, layout_replace_in_print_matrix
29+
_qr, _factorize, _copyto!, zero!, layout_replace_in_print_matrix,
30+
transposelayout, conjlayout
3031

3132
import BlockArrays: blocksize, blockcheckbounds, BlockedUnitRange, blockisequal, DefaultBlockAxis,
3233
Block, BlockSlice, unblock, block, blockindex,
3334
_blocklengths2blocklasts, BlockIndexRange, sizes_from_blocks, BlockSlice1,
3435
blockcolsupport, blockrowsupport, blockcolstart, blockcolstop, blockrowstart, blockrowstop,
35-
AbstractBlockLayout, BlockLayout, blocks, hasmatchingblocks, BlockStyle
36+
AbstractBlockLayout, BlockLayout, blocks, hasmatchingblocks, BlockStyle, BlockSlices
3637

3738
import BandedMatrices: isbanded, bandwidths, bandwidth, banded_getindex, colrange,
3839
inbands_setindex!, inbands_getindex, banded_setindex!,

src/adjtransblockbanded.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11

22
blockbandwidths(A::AdjOrTrans) = reverse(blockbandwidths(parent(A)))
33
subblockbandwidths(A::AdjOrTrans) = reverse(subblockbandwidths(parent(A)))
4+
transposelayout(::AbstractBlockBandedLayout) = BlockBandedLayout()
5+
transposelayout(::AbstractBandedBlockBandedLayout) = BandedBlockBandedLayout()
6+
conjlayout(::Type{<:Complex}, ::M) where M<:AbstractBandedBlockBandedLayout = ConjLayout{M}()
7+
conjlayout(::Type{<:Complex}, ::M) where M<:AbstractBlockBandedLayout = ConjLayout{M}()

src/interfaceimpl.jl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,17 @@ function blockrowsupport(::AbstractBandedLayout, B, k)
151151
findblock(n,first(rs)):findblock(n,last(rs))
152152
end
153153

154+
# fixed block sizes, we can figure out how far we encroach other blocks by looking at last column
155+
function blockbandwidths(::AbstractBandedLayout, (a,b)::Tuple{BlockedUnitRange{<:AbstractRange}, OneTo{Int}}, A)
156+
l,u = bandwidths(A)
157+
m = min(length(a), l + length(b))
158+
if u 0
159+
Int(findblock(a,m))-1,0
160+
else
161+
Int(findblock(a,m))-1,1-Int(findblock(a,min(length(a),1-u)))
162+
end
163+
end
164+
154165
# ambiguity
155166
sub_materialize(::AbstractBandedLayout, V, ::Tuple{BlockedUnitRange,Base.OneTo{Int}}) = BandedMatrix(V)
156167
sub_materialize(::AbstractBandedLayout, V, ::Tuple{Base.OneTo{Int},BlockedUnitRange}) = BandedMatrix(V)

src/linalg.jl

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,15 +90,14 @@ end
9090
####
9191
# BlockIndexRange subblocks
9292
####
93+
sublayout(::AbstractBlockBandedLayout, ::Type{<:Tuple{<:BlockSlices, <:BlockSlices}}) = BlockBandedLayout()
9394

94-
sublayout(::AbstractBlockBandedLayout, ::Type{<:Tuple{<:BlockSlice{<:BlockRange1}, <:BlockSlice{<:BlockRange1}}}) = BlockBandedLayout()
95-
96-
sublayout(::BlockBandedColumnMajor, ::Type{<:Tuple{<:BlockSlice{<:BlockRange1}, <:BlockSlice{<:BlockRange1}}}) = BlockBandedColumnMajor()
97-
sublayout(::BlockBandedColumnMajor, ::Type{<:Tuple{<:BlockSlice{<:BlockRange1}, <:BlockSlice{Block1}}}) = ColumnMajor()
98-
sublayout(::BlockBandedColumnMajor, ::Type{<:Tuple{<:BlockSlice{<:BlockRange1}, <:BlockSlice{<:BlockIndexRange1}}}) = ColumnMajor()
95+
sublayout(::BlockBandedColumnMajor, ::Type{<:Tuple{<:BlockSlices, <:BlockSlices}}) = BlockBandedColumnMajor()
96+
sublayout(::BlockBandedColumnMajor, ::Type{<:Tuple{<:BlockSlices, <:BlockSlice{Block1}}}) = ColumnMajor()
97+
sublayout(::BlockBandedColumnMajor, ::Type{<:Tuple{<:BlockSlices, <:BlockSlice{<:BlockIndexRange1}}}) = ColumnMajor()
9998
sublayout(::BlockBandedColumnMajor, ::Type{<:Tuple{<:BlockSlice{<:BlockIndexRange1}, <:BlockSlice{<:BlockIndexRange1}}}) = ColumnMajor()
10099

101-
isblockbanded(V::SubArray{<:Any,2,<:Any,<:Tuple{<:BlockSlice{<:BlockRange1}, <:BlockSlice{<:BlockRange1}}}) =
100+
isblockbanded(V::SubArray{<:Any,2,<:Any,<:Tuple{<:BlockSlices, <:BlockSlices}}) =
102101
isblockbanded(parent(V))
103102

104103
sub_materialize(::AbstractBlockBandedLayout, V, _) = BlockBandedMatrix(V)

test/test_adjtransblockbanded.jl

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,41 @@
1-
using BlockBandedMatrices
1+
using BlockBandedMatrices, ArrayLayouts, Test
2+
import BlockBandedMatrices: BandedBlockBandedRowMajor, BandedBlockBandedRows, BandedBlockBandedColumns,BlockBandedRows, BlockBandedColumns
23

34
@testset "Adj/Trans" begin
4-
A = BandedBlockBandedMatrix(randn(ComplexF64,10,14), 1:4,2:5, (1,2), (2,1))
5+
@testset "BandedBlockBanded" begin
6+
A = BandedBlockBandedMatrix(randn(ComplexF64,10,14), 1:4,2:5, (1,2), (2,1))
57

6-
@test A'[Block(1,1)] == A[Block(1,1)]'
7-
@test A'[Block(2,3)] == A[Block(3,2)]'
8-
@test transpose(A)[Block(1,1)] == transpose(A[Block(1,1)])
9-
@test transpose(A)[Block(2,3)] == transpose(A[Block(3,2)])
8+
@test MemoryLayout(transpose(A)) isa BandedBlockBandedRowMajor
9+
@test MemoryLayout(A') isa BandedBlockBandedRows
10+
@test MemoryLayout(transpose(A)') isa BandedBlockBandedColumns
1011

11-
@test blockbandwidths(A') == blockbandwidths(transpose(A)) == (2,1)
12-
@test subblockbandwidths(A') == subblockbandwidths(transpose(A)) == (1,2)
12+
@test A'[Block(1,1)] == A[Block(1,1)]'
13+
@test A'[Block(2,3)] == A[Block(3,2)]'
14+
@test transpose(A)[Block(1,1)] == transpose(A[Block(1,1)])
15+
@test transpose(A)[Block(2,3)] == transpose(A[Block(3,2)])
1316

14-
@test BandedBlockBandedMatrix(A') == A'
15-
@test BandedBlockBandedMatrix(transpose(A)) == transpose(A)
17+
@test blockbandwidths(A') == blockbandwidths(transpose(A)) == (2,1)
18+
@test subblockbandwidths(A') == subblockbandwidths(transpose(A)) == (1,2)
19+
20+
@test BandedBlockBandedMatrix(A') == A'
21+
@test BandedBlockBandedMatrix(transpose(A)) == transpose(A)
22+
end
23+
24+
@testset "BlockBanded" begin
25+
A = BlockBandedMatrix(randn(ComplexF64,10,14), 1:4,2:5, (1,2))
26+
27+
@test MemoryLayout(transpose(A)) isa BlockBandedRows
28+
@test MemoryLayout(A') isa BlockBandedRows
29+
@test MemoryLayout(transpose(A)') isa BlockBandedColumns
30+
31+
@test A'[Block(1,1)] == A[Block(1,1)]'
32+
@test A'[Block(2,3)] == A[Block(3,2)]'
33+
@test transpose(A)[Block(1,1)] == transpose(A[Block(1,1)])
34+
@test transpose(A)[Block(2,3)] == transpose(A[Block(3,2)])
35+
36+
@test blockbandwidths(A') == blockbandwidths(transpose(A)) == (2,1)
37+
38+
@test BlockBandedMatrix(A') == A'
39+
@test BlockBandedMatrix(transpose(A)) == transpose(A)
40+
end
1641
end

test/test_misc.jl

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
using ArrayLayouts, BlockBandedMatrices, BandedMatrices, BlockArrays, LinearAlgebra, Test
2-
import BlockBandedMatrices: AbstractBandedBlockBandedMatrix, block, blockindex, blockcolsupport, blockrowsupport
2+
import BlockBandedMatrices: AbstractBandedBlockBandedMatrix, AbstractBlockBandedMatrix, block, blockindex, blockcolsupport, blockrowsupport
33
import BandedMatrices: bandwidths, AbstractBandedMatrix, BandedStyle, bandeddata, BandedColumns, _BandedMatrix
44

55
struct MyBandedBlockBandedMatrix <: AbstractBandedBlockBandedMatrix{Float64}
@@ -17,6 +17,19 @@ function Base.getindex(A::MyBandedBlockBandedMatrix, k::Int, j::Int)
1717
end
1818

1919

20+
struct MyBlockBandedMatrix <: AbstractBlockBandedMatrix{Float64}
21+
A::BlockMatrix{Float64}
22+
end
23+
24+
BlockBandedMatrices.blockbandwidths(::MyBlockBandedMatrix) = (1,1)
25+
Base.axes(A::MyBlockBandedMatrix) = axes(A.A)
26+
function Base.getindex(A::MyBlockBandedMatrix, k::Int, j::Int)
27+
Kk, Jj = findblockindex(axes(A,1), k), findblockindex(axes(A,2), j)
28+
-1  Int(block(Kk)-block(Jj))  1 || return 0.0
29+
A.A[k,j]
30+
end
31+
32+
2033
@testset "Interfaces" begin
2134
@testset "MyBandedBlockBandedMatrix" begin
2235
A = MyBandedBlockBandedMatrix(BlockMatrix(randn(6,6), 1:3, 1:3))
@@ -35,6 +48,25 @@ end
3548
@test A[Block(2)[1:2],Block.(2:3)] isa PseudoBlockArray
3649
end
3750

51+
@testset "MyBlockBandedMatrix" begin
52+
A = MyBlockBandedMatrix(BlockMatrix(randn(6,6), 1:3, 1:3))
53+
@test MemoryLayout(A) isa BlockBandedMatrices.BlockBandedLayout
54+
@test MemoryLayout(A') isa BlockBandedMatrices.BlockBandedLayout
55+
@test MemoryLayout(transpose(A)) isa BlockBandedMatrices.BlockBandedLayout
56+
@test A[Block(3,3)] == A.A[Block(3,3)]
57+
@test A[Block.(1:3),Block.(1:3)] == A
58+
59+
@test A[Block(3,3)] isa Matrix
60+
@test A[Block(3)[2:3],Block(3)[1:2]] isa Matrix
61+
@test A[Block(3)[2:3],Block(3)] isa Matrix
62+
@test A[Block(3),Block(3)[1:2]] isa Matrix
63+
@test A[Block.(1:3),Block.(1:3)] isa BlockBandedMatrix
64+
@test A[Block(1),Block.(2:3)] isa PseudoBlockArray
65+
@test A[Block.(2:3),Block(1)] isa PseudoBlockArray
66+
@test A[Block.(2:3),Block(2)[1:2]] isa PseudoBlockArray
67+
@test A[Block(2)[1:2],Block.(2:3)] isa PseudoBlockArray
68+
end
69+
3870
@testset "Zeros" begin
3971
Z = Zeros(blockedrange(1:3), blockedrange(1:3))
4072
B = BandedBlockBandedMatrix(Z)
@@ -140,5 +172,14 @@ end
140172
Q = Eye((a,))[Block(2),:]
141173
@test Q isa BandedMatrix
142174
@test blockrowsupport(Q,1) == Block.(2:2)
175+
176+
@testset "constant blocks" begin
177+
a = blockedrange(Fill(2,5))
178+
Q = Eye((a,))[:,Block(2)]
179+
@test blockbandwidths(Q) == (1,-1)
180+
181+
B = _BandedMatrix(randn(5,length(a)), a, 3, 1)
182+
@test blockbandwidths(B) == (4,0)
183+
end
143184
end
144185
end

0 commit comments

Comments
 (0)