Skip to content

Commit ef7785d

Browse files
authored
Add InfiniteArrays extension (#137)
* Add InfiniteArrays extension * Create test_lazybandedinf.jl * simplify imports * Add InfiniteArrays extension * compiles * tests pass * Update Project.toml * test ∞-banded * Update test_blockconcat.jl * Update test_blockconcat.jl
1 parent f78d65b commit ef7785d

File tree

6 files changed

+266
-12
lines changed

6 files changed

+266
-12
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ jobs:
3636
fail-fast: false
3737
matrix:
3838
version:
39-
- '1.10'
40-
- '^1.11.0-0'
39+
- 'lts'
40+
- '1'
4141
os:
4242
- ubuntu-latest
4343
- macOS-latest
@@ -66,4 +66,4 @@ jobs:
6666
- uses: codecov/codecov-action@v5
6767
with:
6868
token: ${{ secrets.CODECOV_TOKEN }}
69-
file: lcov.info
69+
files: lcov.info

Project.toml

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "LazyBandedMatrices"
22
uuid = "d7e5e226-e90b-4449-9968-0f923699bf6f"
33
authors = ["Sheehan Olver <[email protected]>"]
4-
version = "0.10.4"
4+
version = "0.11.0"
55

66
[deps]
77
ArrayLayouts = "4c555306-a7a7-4459-81d9-ec55ddd5c99a"
@@ -15,20 +15,28 @@ MatrixFactorizations = "a3b82374-2e81-5b9e-98ce-41277c0e4c87"
1515
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
1616
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
1717

18+
[weakdeps]
19+
InfiniteArrays = "4858937d-0d70-526a-a4dd-2d5cb5dd786c"
20+
21+
[extensions]
22+
LazyBandedMatricesInfiniteArraysExt = "InfiniteArrays"
23+
1824
[compat]
1925
ArrayLayouts = "1.2.1"
2026
BandedMatrices = "1.0"
2127
BlockArrays = "1.0"
2228
BlockBandedMatrices = "0.13"
2329
FillArrays = "1.0"
24-
LazyArrays = "2.0"
30+
InfiniteArrays = "0.15"
31+
LazyArrays = "2.2.3"
2532
MatrixFactorizations = "3.0"
2633
StaticArrays = "1.0"
2734
julia = "1.10"
2835

2936
[extras]
37+
InfiniteArrays = "4858937d-0d70-526a-a4dd-2d5cb5dd786c"
3038
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
3139
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
3240

3341
[targets]
34-
test = ["Random", "Test"]
42+
test = ["InfiniteArrays", "Random", "Test"]
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
module LazyBandedMatricesInfiniteArraysExt
2+
using LazyBandedMatrices, InfiniteArrays
3+
using LazyBandedMatrices.BlockArrays
4+
using LazyBandedMatrices.ArrayLayouts
5+
6+
import Base: BroadcastStyle, copy, OneTo, oneto
7+
import LazyBandedMatrices: _krontrav_axes, _block_interlace_axes, _broadcast_sub_arguments, AbstractLazyBandedBlockBandedLayout, KronTravBandedBlockBandedLayout, krontravargs
8+
import InfiniteArrays: InfFill, TridiagonalToeplitzLayout, BidiagonalToeplitzLayout, LazyArrayStyle, OneToInf
9+
import LazyBandedMatrices.ArrayLayouts: MemoryLayout, sublayout, RangeCumsum, Mul
10+
import LazyBandedMatrices.BlockArrays: sizes_from_blocks, BlockedOneTo, BlockSlice1, BlockSlice
11+
import LazyBandedMatrices.LazyArrays: BroadcastBandedLayout
12+
13+
const OneToInfCumsum = RangeCumsum{Int,OneToInf{Int}}
14+
15+
MemoryLayout(::Type{<:LazyBandedMatrices.Bidiagonal{<:Any,<:InfFill}}) = BidiagonalToeplitzLayout()
16+
BroadcastStyle(::Type{<:LazyBandedMatrices.Bidiagonal{<:Any,<:InfFill}}) = LazyArrayStyle{2}()
17+
18+
for Typ in (:(LazyBandedMatrices.Tridiagonal{<:Any,<:InfFill,<:InfFill,<:InfFill}),
19+
:(LazyBandedMatrices.SymTridiagonal{<:Any,<:InfFill,<:InfFill}))
20+
@eval begin
21+
MemoryLayout(::Type{<:$Typ}) = TridiagonalToeplitzLayout()
22+
BroadcastStyle(::Type{<:$Typ}) = LazyArrayStyle{2}()
23+
end
24+
end
25+
26+
LazyBandedMatrices.unitblocks(a::OneToInf) = blockedrange(Ones{Int}(length(a)))
27+
28+
29+
###
30+
# KronTrav
31+
###
32+
33+
_krontrav_axes(A::OneToInf{Int}, B::OneToInf{Int}) = blockedrange(oneto(length(A)))
34+
35+
36+
struct InfKronTravBandedBlockBandedLayout <: AbstractLazyBandedBlockBandedLayout end
37+
MemoryLayout(::Type{<:KronTrav{<:Any,2,<:Any,NTuple{2,BlockedOneTo{Int,OneToInfCumsum}}}}) = InfKronTravBandedBlockBandedLayout()
38+
39+
sublayout(::InfKronTravBandedBlockBandedLayout, ::Type{<:NTuple{2,BlockSlice1}}) = BroadcastBandedLayout{typeof(*)}()
40+
sublayout(::InfKronTravBandedBlockBandedLayout, ::Type{<:NTuple{2,BlockSlice{BlockRange{1,Tuple{OneTo{Int}}}}}}) = KronTravBandedBlockBandedLayout()
41+
42+
copy(M::Mul{InfKronTravBandedBlockBandedLayout, InfKronTravBandedBlockBandedLayout}) = KronTrav((krontravargs(M.A) .* krontravargs(M.B))...)
43+
44+
_broadcast_sub_arguments(::InfKronTravBandedBlockBandedLayout, M, V) = _broadcast_sub_arguments(KronTravBandedBlockBandedLayout(), M, V)
45+
46+
sizes_from_blocks(A::LazyBandedMatrices.Tridiagonal, ::NTuple{2,OneToInf{Int}}) = size.(A.d, 1), size.(A.d,2)
47+
sizes_from_blocks(A::LazyBandedMatrices.Bidiagonal, ::NTuple{2,OneToInf{Int}}) = size.(A.dv, 1), size.(A.dv,2)
48+
49+
50+
_block_interlace_axes(::Int, ax::Tuple{BlockedOneTo{Int,OneToInf{Int}}}...) = (blockedrange(Fill(length(ax), ∞)),)
51+
52+
_block_interlace_axes(nbc::Int, ax::NTuple{2,BlockedOneTo{Int,OneToInf{Int}}}...) =
53+
(blockedrange(Fill(length(ax) ÷ nbc, ∞)),blockedrange(Fill(mod1(length(ax),nbc), ∞)))
54+
55+
56+
end

src/LazyBandedMatrices.jl

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,15 @@ import ArrayLayouts: MemoryLayout, bidiagonallayout, bidiagonaluplo, diagonaldat
1616
colsupport, rowsupport, sublayout, sub_materialize, _copyto!
1717
import LazyArrays: ApplyLayout, AbstractPaddedLayout, PaddedLayout, PaddedColumns, BroadcastLayout, LazyArrayStyle, LazyLayout,
1818
arguments, call, tuple_type_memorylayouts, paddeddata, _broadcast_sub_arguments, resizedata!,
19-
_cumsum, convexunion, applylayout
19+
_cumsum, convexunion, applylayout, AbstractLazyBandedLayout, ApplyBandedLayout, BroadcastBandedLayout, LazyBandedLayout
2020
import BandedMatrices: AbstractBandedMatrix, BandedStyle, bandwidths, isbanded
2121
import BlockBandedMatrices: AbstractBlockBandedLayout, AbstractBandedBlockBandedLayout, BlockRange1, Block1, blockbandwidths, subblockbandwidths,
2222
BlockBandedStyle, BandedBlockBandedStyle, isblockbanded, isbandedblockbanded
2323
import BlockArrays: BlockSlices, BlockSlice1, BlockSlice, blockvec, AbstractBlockLayout, blockcolsupport, blockrowsupport, BlockLayout, block, blockindex, viewblock, AbstractBlockedUnitRange
2424

25-
const LazyArraysBandedMatricesExt = Base.get_extension(LazyArrays, :LazyArraysBandedMatricesExt)
25+
2626
const LazyArraysBlockBandedMatricesExt = Base.get_extension(LazyArrays, :LazyArraysBlockBandedMatricesExt)
2727

28-
const BroadcastBandedLayout = LazyArraysBandedMatricesExt.BroadcastBandedLayout
29-
const AbstractLazyBandedLayout = LazyArraysBandedMatricesExt.AbstractLazyBandedLayout
30-
const ApplyBandedLayout = LazyArraysBandedMatricesExt.ApplyBandedLayout
31-
const LazyBandedLayout = LazyArraysBandedMatricesExt.LazyBandedLayout
3228
const AbstractLazyBlockBandedLayout = LazyArraysBlockBandedMatricesExt.AbstractLazyBlockBandedLayout
3329
const BroadcastBandedBlockBandedLayout = LazyArraysBlockBandedMatricesExt.BroadcastBandedBlockBandedLayout
3430
const ApplyBlockBandedLayout = LazyArraysBlockBandedMatricesExt.ApplyBlockBandedLayout

test/runtests.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ include("test_special.jl")
88
include("test_misc.jl")
99
include("test_blockkron.jl")
1010
include("test_blockconcat.jl")
11+
include("test_lazybandedinf.jl")

test/test_lazybandedinf.jl

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
using LazyBandedMatrices, InfiniteArrays, ArrayLayouts, LazyArrays, BlockArrays, BandedMatrices, BlockBandedMatrices, LinearAlgebra, Test
2+
using InfiniteArrays: TridiagonalToeplitzLayout, BidiagonalToeplitzLayout, TridiagonalToeplitzLayout
3+
using Base: oneto
4+
using BlockArrays: blockcolsupport
5+
using LazyArrays: arguments
6+
using LazyBandedMatrices: BroadcastBandedBlockBandedLayout
7+
8+
const InfiniteArraysBlockArraysExt = Base.get_extension(InfiniteArrays, :InfiniteArraysBlockArraysExt)
9+
const LazyBandedMatricesInfiniteArraysExt = Base.get_extension(LazyBandedMatrices, :LazyBandedMatricesInfiniteArraysExt)
10+
11+
const OneToInfBlocks = InfiniteArraysBlockArraysExt.OneToInfBlocks
12+
const InfKronTravBandedBlockBandedLayout = LazyBandedMatricesInfiniteArraysExt.InfKronTravBandedBlockBandedLayout
13+
14+
@testset "∞ LazyBandedMatrices" begin
15+
@test MemoryLayout(LazyBandedMatrices.Tridiagonal(Fill(1,∞), Zeros(∞), Fill(3,∞))) isa TridiagonalToeplitzLayout
16+
@test MemoryLayout(LazyBandedMatrices.Bidiagonal(Fill(1,∞), Zeros(∞), :U)) isa BidiagonalToeplitzLayout
17+
@test MemoryLayout(LazyBandedMatrices.SymTridiagonal(Fill(1,∞), Zeros(∞))) isa TridiagonalToeplitzLayout
18+
19+
T = LazyBandedMatrices.Tridiagonal(Fill(1,∞), Zeros(∞), Fill(3,∞))
20+
@test T[2:∞,3:∞] isa SubArray
21+
@test exp.(T) isa BroadcastMatrix
22+
@test exp.(T)[2:∞,3:∞][1:10,1:10] == exp.(T[2:∞,3:∞])[1:10,1:10] == exp.(T[2:11,3:12])
23+
@test exp.(T)[2:∞,3:∞] isa BroadcastMatrix
24+
@test exp.(T[2:∞,3:∞]) isa BroadcastMatrix
25+
26+
B = LazyBandedMatrices.Bidiagonal(Fill(1,∞), Zeros(∞), :U)
27+
@test B[2:∞,3:∞] isa SubArray
28+
@test exp.(B) isa BroadcastMatrix
29+
@test exp.(B)[2:∞,3:∞][1:10,1:10] == exp.(B[2:∞,3:∞])[1:10,1:10] == exp.(B[2:11,3:12])
30+
@test exp.(B)[2:∞,3:∞] isa BroadcastMatrix
31+
32+
@testset "Diagonal{Fill} * Bidiagonal" begin
33+
A, B = Diagonal(Fill(2,∞)) , LazyBandedMatrices.Bidiagonal(exp.(1:∞), exp.(1:∞), :L)
34+
@test (A*B)[1:10,1:10] (B*A)[1:10,1:10] 2B[1:10,1:10]
35+
end
36+
37+
@testset "∞-unit blocks" begin
38+
@test unitblocks(oneto(∞)) blockedrange(Ones{Int}(∞))
39+
@test unitblocks(2:∞) == 2:
40+
41+
@test unitblocks(oneto(∞))[Block.(2:∞)] == 2:
42+
end
43+
44+
@testset "concat" begin
45+
a = unitblocks(1:∞)
46+
b = exp.(a)
47+
c = BlockBroadcastArray(vcat, a, b)
48+
@test length(c) ==
49+
@test blocksize(c) == (∞,)
50+
@test c[Block(5)] == [a[5], b[5]]
51+
52+
A = unitblocks(BandedMatrix(0 => 1:∞, 1 => Fill(2.0, ∞), -1 => Fill(3.0, ∞)))
53+
B = BlockBroadcastArray(hvcat, 2, A, Zeros(axes(A)), Zeros(axes(A)), A)
54+
@test B[Block(3, 3)] == [A[3, 3] 0; 0 A[3, 3]]
55+
@test B[Block(3, 4)] == [A[3, 4] 0; 0 A[3, 4]]
56+
@test B[Block(3, 5)] == [A[3, 5] 0; 0 A[3, 5]]
57+
@test blockbandwidths(B) == (1, 1)
58+
@test subblockbandwidths(B) == (0, 0)
59+
@test B[Block.(1:10), Block.(1:10)] isa BlockSkylineMatrix
60+
61+
C = BlockBroadcastArray(hvcat, 2, A, A, A, A)
62+
@test C[Block(3, 3)] == fill(A[3, 3], 2, 2)
63+
@test C[Block(3, 4)] == fill(A[3, 4], 2, 2)
64+
@test C[Block(3, 5)] == fill(A[3, 5], 2, 2)
65+
@test blockbandwidths(C) == (1, 1)
66+
@test subblockbandwidths(C) == (1, 1)
67+
@test B[Block.(1:10), Block.(1:10)] isa BlockSkylineMatrix
68+
end
69+
70+
@testset "DiagTrav" begin
71+
C = zeros(∞,∞);
72+
C[1:3,1:4] .= [1 2 3 4; 5 6 7 8; 9 10 11 12]
73+
A = DiagTrav(C)
74+
@test blockcolsupport(A) == Block.(1:6)
75+
@test A[Block.(1:7)] == [1; 5; 2; 9; 6; 3; 0; 10; 7; 4; 0; 0; 11; 8; 0; 0; 0; 0; 12; zeros(9)]
76+
77+
C = zeros(∞,4);
78+
C[1:3,1:4] .= [1 2 3 4; 5 6 7 8; 9 10 11 12]
79+
A = DiagTrav(C)
80+
@test A[Block.(1:7)] == [1; 5; 2; 9; 6; 3; 0; 10; 7; 4; 0; 0; 11; 8; 0; 0; 0; 12; zeros(4)]
81+
82+
C = zeros(3,∞);
83+
C[1:3,1:4] .= [1 2 3 4; 5 6 7 8; 9 10 11 12]
84+
A = DiagTrav(C)
85+
@test A[Block.(1:7)] == [1; 5; 2; 9; 6; 3; 10; 7; 4; 11; 8; 0; 12; zeros(5)]
86+
end
87+
88+
@testset "KronTrav" begin
89+
Δ = BandedMatrix(1 => Ones(∞), -1 => Ones(∞)) / 2
90+
A = KronTrav- 2I, Eye(∞))
91+
@test axes(A, 1) isa OneToInfBlocks
92+
V = view(A, Block.(Base.OneTo(3)), Block.(Base.OneTo(3)))
93+
94+
@test MemoryLayout(A) isa InfKronTravBandedBlockBandedLayout
95+
@test MemoryLayout(V) isa LazyBandedMatrices.KronTravBandedBlockBandedLayout
96+
97+
@test A[Block.(Base.OneTo(3)), Block.(Base.OneTo(3))] isa KronTrav
98+
99+
u = A * [1; zeros(∞)]
100+
@test u[1:3] == A[1:3, 1]
101+
@test bandwidths(view(A, Block(1, 1))) == (1, 1)
102+
103+
@test A*A isa KronTrav
104+
@test (A*A)[Block.(Base.OneTo(3)), Block.(Base.OneTo(3))] A[Block.(1:3), Block.(1:4)]A[Block.(1:4), Block.(1:3)]
105+
end
106+
107+
@testset "BlockHcat copyto!" begin
108+
n = mortar(Fill.(oneto(∞), oneto(∞)))
109+
k = mortar(Base.OneTo.(oneto(∞)))
110+
111+
a = b = c = 0.0
112+
dat = BlockHcat(
113+
BroadcastArray((n, k, b, bc1) -> (k + b - 1) * (n + k + bc1) / (2k + bc1), n, k, b, b + c - 1),
114+
BroadcastArray((n, k, abc, bc, bc1) -> (n + k + abc) * (k + bc) / (2k + bc1), n, k, a + b + c, b + c, b + c - 1)
115+
)
116+
N = 1000
117+
KR = Block.(Base.OneTo(N))
118+
V = view(dat, Block.(Base.OneTo(N)), :)
119+
@test MemoryLayout(V) isa LazyArrays.ApplyLayout{typeof(hcat)}
120+
@test BlockedArray(V)[Block.(1:5), :] == dat[Block.(1:5), :]
121+
V = view(dat', :, Block.(Base.OneTo(N)))
122+
@test MemoryLayout(V) isa LazyArrays.ApplyLayout{typeof(vcat)}
123+
a = dat.arrays[1]'
124+
N = 100
125+
KR = Block.(Base.OneTo(N))
126+
v = view(a, :, KR)
127+
@time r = BlockedArray(v)
128+
@test v == r
129+
end
130+
131+
@testset "Symmetric" begin
132+
k = mortar(Base.OneTo.(oneto(∞)))
133+
n = mortar(Fill.(oneto(∞), oneto(∞)))
134+
135+
dat = BlockHcat(
136+
BlockBroadcastArray(hcat, float.(k), Zeros((axes(n, 1),)), float.(n)),
137+
Zeros((axes(n, 1), Base.OneTo(3))),
138+
Zeros((axes(n, 1), Base.OneTo(3))))
139+
M = BlockBandedMatrices._BandedBlockBandedMatrix(dat', axes(k, 1), (1, 1), (1, 1))
140+
Ms = Symmetric(M)
141+
@test blockbandwidths(M) == (1, 1)
142+
@test blockbandwidths(Ms) == (1, 1)
143+
@test Ms[Block.(1:5), Block.(1:5)] == Symmetric(M[Block.(1:5), Block.(1:5)])
144+
@test Ms[Block.(1:5), Block.(1:5)] isa BandedBlockBandedMatrix
145+
146+
b = [ones(10); zeros(∞)]
147+
@test (Ms * b)[Block.(1:6)] == Ms[Block.(1:6), Block.(1:4)]*ones(10)
148+
@test ((Ms * Ms) * b)[Block.(1:6)] == (Ms * (Ms * b))[Block.(1:6)]
149+
@test ((Ms + Ms) * b)[Block.(1:6)] == (2*(Ms * b))[Block.(1:6)]
150+
151+
dat = BlockBroadcastArray(hcat, float.(k), Zeros((axes(n, 1),)), float.(n))
152+
M = BlockBandedMatrices._BandedBlockBandedMatrix(dat', axes(k, 1), (-1, 1), (1, 1))
153+
Ms = Symmetric(M)
154+
@test Symmetric((M+M)[Block.(1:10), Block.(1:10)]) == (Ms+Ms)[Block.(1:10), Block.(1:10)]
155+
end
156+
157+
@testset "BlockBidiagonal" begin
158+
B = mortar(LazyBandedMatrices.Bidiagonal(Fill([1 2; 3 4], ∞), Fill([1 2; 3 4], ∞), :U));
159+
#TODO: copy BlockBidiagonal code from BlockBandedMatrices to LazyBandedMatrices
160+
@test B[Block(2, 3)] == [1 2; 3 4]
161+
@test_broken B[Block(1, 3)] == Zeros(2, 2)
162+
end
163+
164+
@testset "KronTrav" begin
165+
Δ = BandedMatrix(1 => Ones(∞) / 2, -1 => Ones(∞))
166+
A = KronTrav(Δ, Eye(∞))
167+
@test A[Block(100, 101)] isa BandedMatrix
168+
@test A[Block(100, 100)] isa BandedMatrix
169+
@test A[Block.(1:5), Block.(1:5)] isa BandedBlockBandedMatrix
170+
B = KronTrav(Eye(∞), Δ)
171+
@test B[Block(100, 101)] isa BandedMatrix
172+
@test B[Block(100, 100)] isa BandedMatrix
173+
V = view(A + B, Block.(1:5), Block.(1:5))
174+
@test MemoryLayout(typeof(V)) isa BroadcastBandedBlockBandedLayout{typeof(+)}
175+
@test arguments(V) == (A[Block.(1:5), Block.(1:5)], B[Block.(1:5), Block.(1:5)])
176+
@test (A+B)[Block.(1:5), Block.(1:5)] == A[Block.(1:5), Block.(1:5)] + B[Block.(1:5), Block.(1:5)]
177+
178+
@test blockbandwidths(A + B) == (1, 1)
179+
@test blockbandwidths(2A) == (1, 1)
180+
@test blockbandwidths(2 * (A + B)) == (1, 1)
181+
182+
@test subblockbandwidths(A + B) == (1, 1)
183+
@test subblockbandwidths(2A) == (1, 1)
184+
@test subblockbandwidths(2 * (A + B)) == (1, 1)
185+
end
186+
187+
@testset "BlockTridiagonal" begin
188+
T = mortar(LazyBandedMatrices.Tridiagonal(Fill([1 2; 3 4], ∞), Fill([1 2; 3 4], ∞), Fill([1 2; 3 4], ∞)));
189+
#TODO: copy BlockBidiagonal code from BlockBandedMatrices to LazyBandedMatrices
190+
@test T[Block(2, 2)] == [1 2; 3 4]
191+
@test_broken T[Block(1, 3)] == Zeros(2, 2)
192+
end
193+
end

0 commit comments

Comments
 (0)