Skip to content

Commit b86a915

Browse files
authored
Support for compact operators (#88)
* Support for compact operators * Support general padded * don't use .data for PaddedLayout * Don't grow cols so fast * v0.5.14 * v0.5.15 * chop! results to avoid too much data * Update infbanded.jl * Update Project.toml * fix resizing * Drop Julia v1.5 * increase coverage * fix resizedata_chop! * Update runtests.jl
1 parent 53cbf97 commit b86a915

File tree

9 files changed

+130
-28
lines changed

9 files changed

+130
-28
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
os:
1615
- ubuntu-latest
1716
- macOS-latest

Project.toml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "InfiniteLinearAlgebra"
22
uuid = "cde9dba0-b1de-11e9-2c62-0bab9446c55c"
3-
version = "0.5.14"
3+
version = "0.6.0"
44

55
[deps]
66
ArrayLayouts = "4c555306-a7a7-4459-81d9-ec55ddd5c99a"
@@ -17,18 +17,18 @@ MatrixFactorizations = "a3b82374-2e81-5b9e-98ce-41277c0e4c87"
1717
SemiseparableMatrices = "f8ebbe35-cbfb-4060-bf7f-b10e4670cf57"
1818

1919
[compat]
20-
ArrayLayouts = "0.7.2"
20+
ArrayLayouts = "0.7.5"
2121
BandedMatrices = "0.16.9"
22-
BlockArrays = "0.15, 0.16"
23-
BlockBandedMatrices = "0.10"
24-
DSP = "0.6, 0.7"
22+
BlockArrays = "0.16"
23+
BlockBandedMatrices = "0.11"
24+
DSP = "0.7"
2525
FillArrays = "0.11, 0.12"
26-
InfiniteArrays = "0.11, 0.12"
26+
InfiniteArrays = "0.12"
2727
LazyArrays = "0.21.8"
28-
LazyBandedMatrices = "0.6"
28+
LazyBandedMatrices = "0.7"
2929
MatrixFactorizations = "0.8"
3030
SemiseparableMatrices = "0.2.7"
31-
julia = "1.5"
31+
julia = "1.6"
3232

3333
[extras]
3434
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"

examples/blocktridiagonal.jl

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
using Revise, InfiniteLinearAlgebra, BlockBandedMatrices, BandedMatrices, BlockArrays, InfiniteArrays, FillArrays, LazyArrays, Test
1+
using InfiniteLinearAlgebra, BlockBandedMatrices, BandedMatrices, BlockArrays, InfiniteArrays, FillArrays, LazyArrays, Test
22

33
A = BlockTridiagonal(Vcat([fill(1.0,2,1),Matrix(1.0I,2,2),Matrix(1.0I,2,2),Matrix(1.0I,2,2)],Fill(Matrix(1.0I,2,2), ∞)),
44
Vcat([zeros(1,1)], Fill(zeros(2,2), ∞)),
55
Vcat([fill(1.0,1,2),Matrix(1.0I,2,2)], Fill(Matrix(1.0I,2,2), ∞)))
66

77

8-
BlockBandedMatrix(A)
9-
isb
8+

src/InfiniteLinearAlgebra.jl

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,36 @@ function ArrayLayouts._power_by_squaring(_, ::NTuple{2,InfiniteCardinal{0}}, A::
5959
end
6060
end
6161

62+
63+
function chop!(c::AbstractVector, tol::Real)
64+
@assert tol >= 0
65+
66+
@inbounds for k=length(c):-1:1
67+
if abs(c[k]) > tol
68+
resize!(c,k)
69+
return c
70+
end
71+
end
72+
resize!(c,0)
73+
c
74+
end
75+
76+
function chop(A::AbstractMatrix, tol)
77+
for k = size(A,1):-1:1
78+
if norm(view(A,k,:))>tol
79+
A=A[1:k,:]
80+
break
81+
end
82+
end
83+
for j = size(A,2):-1:1
84+
if norm(view(A,:,j))>tol
85+
A=A[:,1:j]
86+
break
87+
end
88+
end
89+
return A
90+
end
91+
6292
export Vcat, Fill, ql, ql!, ∞, ContinuousSpectrumError, BlockTridiagonal
6393

6494
include("infconv.jl")

src/banded/infbanded.jl

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,10 @@ _BandedMatrix(::PertToeplitzLayout, A::AbstractMatrix) =
367367

368368
sub_materialize(_, V, ::Tuple{<:BlockedUnitRange{<:InfRanges}}) = V
369369
sub_materialize(::AbstractBlockLayout, V, ::Tuple{<:BlockedUnitRange{<:InfRanges}}) = V
370+
function sub_materialize(::PaddedLayout, v::AbstractVector{T}, ax::Tuple{<:BlockedUnitRange{<:InfRanges}}) where T
371+
dat = paddeddata(v)
372+
PseudoBlockVector(Vcat(sub_materialize(dat), Zeros{T}(∞)), ax)
373+
end
370374

371375
##
372376
# UniformScaling
@@ -428,12 +432,15 @@ _bandedfill_mul(M::MulAdd, ::Tuple{Any,InfAxes}, ::Tuple{InfAxes,InfAxes}) = App
428432
_bandedfill_mul(M::MulAdd, ::Tuple{InfAxes,InfAxes}, ::Tuple{InfAxes,Any}) = ApplyArray(*, M.A, M.B)
429433
_bandedfill_mul(M::MulAdd, ::Tuple{Any,InfAxes}, ::Tuple{InfAxes,Any}) = ApplyArray(*, M.A, M.B)
430434

431-
mulreduce(M::Mul{<:BandedColumns{<:AbstractFillLayout}, <:PertToeplitzLayout}) = ApplyArray(M)
435+
mulreduce(M::Mul{BandedToeplitzLayout, BandedToeplitzLayout}) = ApplyArray(M)
436+
mulreduce(M::Mul{BandedToeplitzLayout}) = ApplyArray(M)
437+
mulreduce(M::Mul{<:Any, BandedToeplitzLayout}) = ApplyArray(M)
438+
mulreduce(M::Mul{<:BandedColumns{<:AbstractFillLayout}, PertToeplitzLayout}) = ApplyArray(M)
432439
mulreduce(M::Mul{<:PertToeplitzLayout, <:BandedColumns{<:AbstractFillLayout}}) = ApplyArray(M)
433-
mulreduce(M::Mul{<:BandedColumns{<:AbstractFillLayout}, <:BandedToeplitzLayout}) = ApplyArray(M)
434-
mulreduce(M::Mul{<:BandedToeplitzLayout, <:BandedColumns{<:AbstractFillLayout}}) = ApplyArray(M)
435-
mulreduce(M::Mul{<:AbstractQLayout, <:BandedToeplitzLayout}) = ApplyArray(M)
436-
mulreduce(M::Mul{<:AbstractQLayout, <:PertToeplitzLayout}) = ApplyArray(M)
440+
mulreduce(M::Mul{<:BandedColumns{<:AbstractFillLayout}, BandedToeplitzLayout}) = ApplyArray(M)
441+
mulreduce(M::Mul{BandedToeplitzLayout, <:BandedColumns{<:AbstractFillLayout}}) = ApplyArray(M)
442+
mulreduce(M::Mul{<:AbstractQLayout, BandedToeplitzLayout}) = ApplyArray(M)
443+
mulreduce(M::Mul{<:AbstractQLayout, PertToeplitzLayout}) = ApplyArray(M)
437444

438445

439446
function _bidiag_forwardsub!(M::Ldiv{<:Any,<:PaddedLayout})

src/infqr.jl

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ partialqr!(F::AdaptiveQRFactors, n) = partialqr!(F.data, n)
164164
_view_QRPackedQ(A, kr, jr) = QRPackedQ(view(A.factors.data.data.data,kr,jr), view(A.τ.data.τ,jr))
165165
function materialize!(M::MatLmulVec{<:QRPackedQLayout{<:AdaptiveLayout},<:PaddedLayout})
166166
A,B = M.A,M.B
167-
sB = B.datasize[1]
167+
sB = size(paddeddata(B),1)
168168
partialqr!(A.factors.data,sB)
169169
jr = oneto(sB)
170170
m = maximum(colsupport(A,jr))
@@ -175,6 +175,39 @@ function materialize!(M::MatLmulVec{<:QRPackedQLayout{<:AdaptiveLayout},<:Padded
175175
B
176176
end
177177

178+
function resizedata_chop!(v::CachedVector, tol)
179+
c = paddeddata(v)
180+
n = length(c)
181+
k_tol = n
182+
for k = n:-1:1
183+
if abs(c[k]) > tol
184+
v.datasize = (k_tol,)
185+
return v
186+
end
187+
end
188+
v.datasize = (0,)
189+
v
190+
end
191+
192+
function resizedata_chop!(v::PseudoBlockVector, tol)
193+
c = paddeddata(v.blocks)
194+
n = length(c)
195+
k_tol = n
196+
for k = n:-1:1
197+
if abs(c[k]) > tol
198+
k_tol = k
199+
break
200+
end
201+
end
202+
ax = axes(v,1)
203+
K = findblock(ax,k_tol)
204+
n2 = last(ax[K])
205+
resize!(v.blocks.data, n2)
206+
zero!(view(v.blocks.data, n+1:n2))
207+
v.blocks.datasize = (n2,)
208+
v
209+
end
210+
178211
_norm(x::Number) = abs(x)
179212

180213
function materialize!(M::MatLmulVec{<:AdjQRPackedQLayout{<:AdaptiveLayout},<:PaddedLayout})
@@ -190,7 +223,8 @@ function materialize!(M::MatLmulVec{<:AdjQRPackedQLayout{<:AdaptiveLayout},<:Pad
190223
if mA != mB
191224
throw(DimensionMismatch("matrix A has dimensions ($mA,$nA) but B has dimensions ($mB, $nB)"))
192225
end
193-
sB = B.datasize[1]
226+
Bdata = paddeddata(B)
227+
sB = size(Bdata,1)
194228
l,u = bandwidths(A.factors)
195229
if l == 0 # diagonal special case
196230
return B
@@ -205,16 +239,17 @@ function materialize!(M::MatLmulVec{<:AdjQRPackedQLayout{<:AdaptiveLayout},<:Pad
205239
cs_max = maximum(cs)
206240
kr = j:cs_max
207241
resizedata!(B, min(cs_max,mB))
208-
if (j > sB && maximum(_norm,view(B.data,j:last(colsupport(A.factors,j)))) tol)
242+
Bdata = paddeddata(B)
243+
if (j > sB && maximum(_norm,view(Bdata,j:last(colsupport(A.factors,j)))) tol)
209244
break
210245
end
211246
partialqr!(A.factors.data, min(cs_max,nA))
212247
Q_N = _view_QRPackedQ(A, kr, jr)
213-
lmul!(Q_N', view(B.data, kr))
248+
lmul!(Q_N', view(Bdata, kr))
214249
jr = last(jr)+1:min(last(jr)+COLGROWTH,nA)
215250
end
216251
end
217-
B
252+
resizedata_chop!(B, tol)
218253
end
219254

220255
function resizedata!(B::PseudoBlockVector, M::Block{1})
@@ -230,10 +265,10 @@ end
230265

231266
function materialize!(M::MatLmulVec{<:QRPackedQLayout{<:AdaptiveLayout{<:AbstractBlockBandedLayout}},<:PaddedLayout})
232267
A,B_in = M.A,M.B
233-
sB = B_in.datasize[1]
268+
sB = length(paddeddata(B_in))
234269
ax1,ax2 = axes(A.factors.data.data)
235270
B = PseudoBlockVector(B_in, (ax2,))
236-
SB = findblock(ax2, length(B_in.data))
271+
SB = findblock(ax2, sB)
237272
partialqr!(A.factors.data,SB)
238273
JR = Block(1):SB
239274
M = maximum(blockcolsupport(A.factors,JR))
@@ -248,12 +283,12 @@ function materialize!(M::MatLmulVec{<:AdjQRPackedQLayout{<:AdaptiveLayout{<:Abst
248283
adjA,B_in = M.A,M.B
249284
A = adjA.parent
250285
T = eltype(M)
251-
COLGROWTH = 1000 # rate to grow columns
286+
COLGROWTH = 300 # rate to grow columns
252287
tol = 1E-30
253288
ax1 = axes(A.factors.data.data,1)
254289
B = PseudoBlockVector(B_in, (ax1,))
255290

256-
SB = findblock(ax1, length(B_in.data))
291+
SB = findblock(ax1, length(paddeddata(B_in)))
257292
MA, NA = blocksize(A.factors.data.data.array)
258293
JR = Block(1):findblock(ax1,COLGROWTH)
259294

@@ -278,7 +313,7 @@ function materialize!(M::MatLmulVec{<:AdjQRPackedQLayout{<:AdaptiveLayout{<:Abst
278313
JR = last(JR)+1:findblock(ax1,last(jr)+COLGROWTH)
279314
end
280315
end
281-
B
316+
resizedata_chop!(B, tol)
282317
end
283318

284319

test/runtests.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,16 @@ import LazyArrays: colsupport, MemoryLayout, ApplyLayout, LazyArrayStyle, argume
1313
import InfiniteArrays: OneToInf, oneto, RealInfinity
1414
import LazyBandedMatrices: BroadcastBandedBlockBandedLayout, BroadcastBandedLayout, LazyBandedLayout
1515

16+
@testset "chop" begin
17+
a = randn(5)
18+
b = [a; zeros(5)]
19+
InfiniteLinearAlgebra.chop!(b, eps())
20+
@test b == a
21+
22+
A = randn(5,5)
23+
@test InfiniteLinearAlgebra.chop([A zeros(5,2); zeros(2,5) zeros(2,2)],eps()) == A
24+
end
25+
1626
include("test_infconv.jl")
1727
include("test_infbanded.jl")
1828

test/test_compact.jl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using InfiniteLinearAlgebra, FillArrays, LazyArrays, ArrayLayouts, Test
2+
3+
@testset "Compact" begin
4+
A = ApplyMatrix(hvcat, 2, randn(5,5), Zeros(5,∞), Zeros(∞,5), Zeros(∞,∞))
5+
b = [randn(10); zeros(∞)];
6+
@test ((I + A) \ b)[1:10] (I+A)[1:10,1:10] \ b[1:10]
7+
8+
C = zeros(∞,∞);
9+
C[1:5,1:5] .= randn.()
10+
@test_skip ((I + C) \ b)[1:10] (I+C)[1:10,1:10] \ b[1:10]
11+
end

test/test_infbanded.jl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ import BandedMatrices: _BandedMatrix
4141
@test A[:,3:end] isa InfToeplitz
4242

4343
@test (A + 2I)[1:10,1:10] == (2I + A)[1:10,1:10] == A[1:10,1:10] + 2I
44+
@test (A*A)[1:10,1:10] A[1:10,1:16]A[1:16,1:10]
45+
@test (A * Fill(2,∞))[1:10] 2A[1:10,1:16]*ones(16)
46+
@test (Fill(2,∞,∞)*A)[1:10,1:10] fill(2,10,13)A[1:13,1:10]
4447

4548
@test MemoryLayout(Tridiagonal(Fill(1,∞), Fill(2,∞), Fill(3,∞))) isa TridiagonalToeplitzLayout
4649
@test MemoryLayout(Bidiagonal(Fill(1,∞), Fill(2,∞), :U)) isa BidiagonalToeplitzLayout
@@ -64,6 +67,14 @@ import BandedMatrices: _BandedMatrix
6467
@test T isa InfiniteLinearAlgebra.TriToeplitz
6568
@test (T + 2I)[1:10,1:10] == (2I + T)[1:10,1:10] == T[1:10,1:10] + 2I
6669
end
70+
71+
@testset "constant data" begin
72+
A = BandedMatrix(1 => Fill(2im,∞), 2 => Fill(-1,∞), 3 => Fill(2,∞), -2 => Fill(-4,∞), -3 => Fill(-2im,∞))
73+
B = _BandedMatrix(Fill(2,4,∞), ∞, 1,2)
74+
@test (B*B)[1:10,1:10] B[1:10,1:14]B[1:14,1:10]
75+
@test (A*B)[1:10,1:10] A[1:10,1:14]B[1:14,1:10]
76+
@test (B*A)[1:10,1:10] B[1:10,1:14]A[1:14,1:10]
77+
end
6778
end
6879

6980
@testset "Pert-Toeplitz" begin

0 commit comments

Comments
 (0)