From a1ca41c0b97de63944100c31339ad1704fac9cda Mon Sep 17 00:00:00 2001 From: Sheehan Olver Date: Sat, 8 Feb 2025 11:02:37 +0000 Subject: [PATCH 1/8] Add AdaptiveBlock/BandedLayout --- Project.toml | 2 +- src/infqr.jl | 48 ++++++++++++++++++++++++++++------------------ test/test_infqr.jl | 2 +- 3 files changed, 31 insertions(+), 21 deletions(-) diff --git a/Project.toml b/Project.toml index 6b5c318..bd0e122 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "InfiniteLinearAlgebra" uuid = "cde9dba0-b1de-11e9-2c62-0bab9446c55c" -version = "0.9.1" +version = "0.10" [deps] ArrayLayouts = "4c555306-a7a7-4459-81d9-ec55ddd5c99a" diff --git a/src/infqr.jl b/src/infqr.jl index d7b42ac..19207fd 100644 --- a/src/infqr.jl +++ b/src/infqr.jl @@ -93,10 +93,20 @@ struct AdaptiveQRFactors{T,DM<:AbstractMatrix{T},M<:AbstractMatrix{T}} <: Layout data::AdaptiveQRData{T,DM,M} end -struct AdaptiveLayout{M} <: AbstractLazyLayout end -MemoryLayout(::Type{AdaptiveQRFactors{T,DM,M}}) where {T,DM,M} = AdaptiveLayout{typeof(MemoryLayout(DM))}() -triangularlayout(::Type{Tri}, ::ML) where {Tri, ML<:AdaptiveLayout} = Tri{ML}() -transposelayout(A::AdaptiveLayout{ML}) where ML = AdaptiveLayout{typeof(transposelayout(ML()))}() +struct AdaptiveLayout <: AbstractLazyLayout end +struct AdaptiveBandedLayout <: AbstractLazyBandedLayout end +struct AdaptiveBlockBandedLayout <: AbstractLazyBlockBandedLayout end + +const AdaptiveLayouts = Union{AdaptiveLayout,AdaptiveBandedLayout,AdaptiveBlockBandedLayout} + +adaptivelayout(_) = AdaptiveLayout() +adaptivelayout(::BandedLayouts) = AdaptiveBandedLayout() +adaptivelayout(::BlockBandedLayouts) = AdaptiveBlockBandedLayout() + + +MemoryLayout(::Type{AdaptiveQRFactors{T,DM,M}}) where {T,DM,M} =adaptivelayout(MemoryLayout(DM)) +triangularlayout(::Type{Tri}, ::ML) where {Tri, ML<:AdaptiveLayouts} = Tri{ML}() +transposelayout(A::AdaptiveLayouts) = A size(F::AdaptiveQRFactors) = size(F.data.data) axes(F::AdaptiveQRFactors) = axes(F.data.data) @@ -164,7 +174,7 @@ factorize_layout(::BandedLayouts, ::NTuple{2,OneToInf{Int}}, A) = qr(A) factorize_layout(::AbstractBandedLayout, ::NTuple{2,OneToInf{Int}}, A) = qr(A) -cache_layout(::TriangularLayout{UPLO, UNIT, <:AdaptiveLayout}, A::AbstractMatrix) where {UPLO, UNIT} = A # already cached +cache_layout(::TriangularLayout{UPLO, UNIT, <:AdaptiveLayouts}, A::AbstractMatrix) where {UPLO, UNIT} = A # already cached partialqr!(F::QR, n) = partialqr!(F.factors, n) partialqr!(F::AdaptiveQRFactors, n) = partialqr!(F.data, n) @@ -181,7 +191,7 @@ getindex(Q::QRPackedQ{<:Any,<:AdaptiveQRFactors,<:AdaptiveQRTau}, I::AbstractVec ######### _view_QRPackedQ(A, kr, jr) = QRPackedQ(view(A.factors.data.data.data,kr,jr), view(A.τ.data.τ,jr)) -function materialize!(M::MatLmulVec{<:QRPackedQLayout{<:AdaptiveLayout},<:AbstractPaddedLayout}) +function materialize!(M::MatLmulVec{<:QRPackedQLayout{<:AdaptiveLayouts},<:AbstractPaddedLayout}) A,B = M.A,M.B sB = size(paddeddata(B),1) partialqr!(A.factors.data,sB) @@ -223,7 +233,7 @@ end _norm(x::Number) = abs(x) -function materialize!(M::MatLmulVec{<:AdjQRPackedQLayout{<:AdaptiveLayout},<:AbstractPaddedLayout}; tolerance=floatmin(real(eltype(M)))) +function materialize!(M::MatLmulVec{<:AdjQRPackedQLayout{<:AdaptiveLayouts},<:AbstractPaddedLayout}; tolerance=floatmin(real(eltype(M)))) adjA,B = M.A,M.B COLGROWTH = 1000 # rate to grow columns @@ -274,7 +284,7 @@ function _view_QRPackedQ(A, KR::BlockRange, JR::BlockRange) QRPackedQ(view(A.factors.data.data.data,KR,JR), view(A.τ.data.τ,jr)) end -function materialize!(M::MatLmulVec{<:QRPackedQLayout{<:AdaptiveLayout{<:AbstractBlockBandedLayout}},<:AbstractPaddedLayout}) +function materialize!(M::MatLmulVec{QRPackedQLayout{AdaptiveBlockBandedLayout},<:AbstractPaddedLayout}) A,B_in = M.A,M.B sB = length(paddeddata(B_in)) ax1,ax2 = axes(A.factors.data.data) @@ -290,7 +300,7 @@ function materialize!(M::MatLmulVec{<:QRPackedQLayout{<:AdaptiveLayout{<:Abstrac B end -function materialize!(M::MatLmulVec{<:AdjQRPackedQLayout{<:AdaptiveLayout{<:AbstractBlockBandedLayout}},<:AbstractPaddedLayout}; tolerance=1E-30) +function materialize!(M::MatLmulVec{AdjQRPackedQLayout{AdaptiveBlockBandedLayout},<:AbstractPaddedLayout}; tolerance=1E-30) adjA,B_in = M.A,M.B A = parent(adjA) T = eltype(M) @@ -367,15 +377,15 @@ ldiv!(F::QR{<:Any,<:AdaptiveQRFactors}, b::LayoutVector; kwds...) = ldiv!(F.R, l factorize(A::BandedMatrix{<:Any,<:Any,<:OneToInf}) = qr(A) qr(A::SymTridiagonal{T,<:AbstractFill{T,1,Tuple{OneToInf{Int}}}}) where T = adaptiveqr(A) -simplifiable(M::Mul{<:QRPackedQLayout{<:AdaptiveLayout}}) = Val(false) -simplifiable(M::Mul{<:QRPackedQLayout{<:AdaptiveLayout},<:QRPackedQLayout{<:AdaptiveLayout}}) = Val(false) -simplifiable(M::Mul{<:QRPackedQLayout{<:AdaptiveLayout},<:LazyLayouts}) = Val(false) -simplifiable(M::Mul{<:Any,<:QRPackedQLayout{<:AdaptiveLayout}}) = Val(false) -simplifiable(M::Mul{<:LazyLayouts,<:QRPackedQLayout{<:AdaptiveLayout}}) = Val(false) +simplifiable(M::Mul{<:QRPackedQLayout{<:AdaptiveLayouts}}) = Val(false) +simplifiable(M::Mul{<:QRPackedQLayout{<:AdaptiveLayouts},<:QRPackedQLayout{<:AdaptiveLayouts}}) = Val(false) +simplifiable(M::Mul{<:QRPackedQLayout{<:AdaptiveLayouts},<:LazyLayouts}) = Val(false) +simplifiable(M::Mul{<:Any,<:QRPackedQLayout{<:AdaptiveLayouts}}) = Val(false) +simplifiable(M::Mul{<:LazyLayouts,<:QRPackedQLayout{<:AdaptiveLayouts}}) = Val(false) -copy(M::Mul{<:QRPackedQLayout{<:AdaptiveLayout},<:QRPackedQLayout{<:AdaptiveLayout}}) = simplify(M) -copy(M::Mul{<:QRPackedQLayout{<:AdaptiveLayout}}) = simplify(M) -copy(M::Mul{<:QRPackedQLayout{<:AdaptiveLayout},<:LazyLayouts}) = simplify(M) -copy(M::Mul{<:Any,<:QRPackedQLayout{<:AdaptiveLayout}}) = simplify(M) -copy(M::Mul{<:LazyLayouts,<:QRPackedQLayout{<:AdaptiveLayout}}) = simplify(M) +copy(M::Mul{<:QRPackedQLayout{<:AdaptiveLayouts},<:QRPackedQLayout{<:AdaptiveLayouts}}) = simplify(M) +copy(M::Mul{<:QRPackedQLayout{<:AdaptiveLayouts}}) = simplify(M) +copy(M::Mul{<:QRPackedQLayout{<:AdaptiveLayouts},<:LazyLayouts}) = simplify(M) +copy(M::Mul{<:Any,<:QRPackedQLayout{<:AdaptiveLayouts}}) = simplify(M) +copy(M::Mul{<:LazyLayouts,<:QRPackedQLayout{<:AdaptiveLayouts}}) = simplify(M) diff --git a/test/test_infqr.jl b/test/test_infqr.jl index 3a0e0f9..0e2ebe8 100644 --- a/test/test_infqr.jl +++ b/test/test_infqr.jl @@ -44,7 +44,7 @@ import SemiseparableMatrices: AlmostBandedLayout, VcatAlmostBandedLayout @testset "col/rowsupport" begin A = _BandedMatrix(Vcat(Ones(1,∞), (1:∞)', Ones(1,∞)), ℵ₀, 1, 1) F = qr(A) - @test MemoryLayout(typeof(F.factors)) isa AdaptiveLayout{BandedColumns{DenseColumnMajor}} + @test MemoryLayout(typeof(F.factors)) isa AdaptiveBandedLayout @test bandwidths(F.factors) == (1,2) @test colsupport(F.factors,1) == 1:2 @test colsupport(F.factors,5) == 3:6 From a5037f216c311601604a0e2b5e3c630605a96abf Mon Sep 17 00:00:00 2001 From: Sheehan Olver Date: Sat, 8 Feb 2025 12:41:59 +0000 Subject: [PATCH 2/8] Fix tests --- src/InfiniteLinearAlgebra.jl | 4 ++-- src/infqr.jl | 2 +- test/test_infqr.jl | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/InfiniteLinearAlgebra.jl b/src/InfiniteLinearAlgebra.jl index 2e60767..cb0a07b 100644 --- a/src/InfiniteLinearAlgebra.jl +++ b/src/InfiniteLinearAlgebra.jl @@ -42,14 +42,14 @@ import LazyArrays: AbstractCachedMatrix, AbstractCachedVector, AbstractLazyLayou applybroadcaststyle, applylayout, arguments, cacheddata, paddeddata, resizedata!, simplifiable, simplify, islazy, islazy_layout, cache_getindex, cache_layout -import LazyBandedMatrices: AbstractLazyBandedBlockBandedLayout, AbstractLazyBandedLayout, ApplyBandedLayout, BlockVec, +import LazyBandedMatrices: AbstractLazyBandedBlockBandedLayout, AbstractLazyBandedLayout, AbstractLazyBlockBandedLayout, ApplyBandedLayout, BlockVec, BroadcastBandedLayout, KronTravBandedBlockBandedLayout, LazyBandedLayout, _block_interlace_axes, _krontrav_axes, krontravargs const StructuredLayoutTypes{Lay} = Union{SymmetricLayout{Lay}, HermitianLayout{Lay}, TriangularLayout{'L','N',Lay}, TriangularLayout{'U','N',Lay}, TriangularLayout{'L','U',Lay}, TriangularLayout{'U','U',Lay}} const BandedLayouts = Union{AbstractBandedLayout, StructuredLayoutTypes{<:AbstractBandedLayout}} - +const BlockBandedLayouts = Union{AbstractBlockBandedLayout, BlockLayout{<:AbstractBandedLayout}, StructuredLayoutTypes{<:AbstractBlockBandedLayout}} import LinearAlgebra: AbstractQ, AdjointQ, AdjOrTrans, factorize, matprod, qr diff --git a/src/infqr.jl b/src/infqr.jl index 19207fd..a284f8f 100644 --- a/src/infqr.jl +++ b/src/infqr.jl @@ -300,7 +300,7 @@ function materialize!(M::MatLmulVec{QRPackedQLayout{AdaptiveBlockBandedLayout},< B end -function materialize!(M::MatLmulVec{AdjQRPackedQLayout{AdaptiveBlockBandedLayout},<:AbstractPaddedLayout}; tolerance=1E-30) +function materialize!(M::MatLmulVec{<:AdjQRPackedQLayout{AdaptiveBlockBandedLayout},<:AbstractPaddedLayout}; tolerance=1E-30) adjA,B_in = M.A,M.B A = parent(adjA) T = eltype(M) diff --git a/test/test_infqr.jl b/test/test_infqr.jl index 0e2ebe8..28a02ed 100644 --- a/test/test_infqr.jl +++ b/test/test_infqr.jl @@ -3,7 +3,7 @@ using InfiniteLinearAlgebra, LinearAlgebra, BandedMatrices, InfiniteArrays, Matr import LazyArrays: colsupport, rowsupport, MemoryLayout, DenseColumnMajor, TriangularLayout, resizedata!, arguments import LazyBandedMatrices: BroadcastBandedLayout, InvDiagTrav, BroadcastBandedBlockBandedLayout import BandedMatrices: _BandedMatrix, _banded_qr!, BandedColumns -import InfiniteLinearAlgebra: partialqr!, AdaptiveQRData, AdaptiveLayout, adaptiveqr +import InfiniteLinearAlgebra: partialqr!, AdaptiveQRData, AdaptiveLayout, AdaptiveBandedLayout, adaptiveqr import SemiseparableMatrices: AlmostBandedLayout, VcatAlmostBandedLayout From b77c57fa4b11748924c3038fabb3c8da9690785f Mon Sep 17 00:00:00 2001 From: Sheehan Olver Date: Sat, 8 Feb 2025 13:04:59 +0000 Subject: [PATCH 3/8] Remove over-templating --- src/infcholesky.jl | 20 ++++++++++++--- src/infqr.jl | 62 +++++++++++++++++++++++----------------------- test/test_infqr.jl | 4 +-- 3 files changed, 49 insertions(+), 37 deletions(-) diff --git a/src/infcholesky.jl b/src/infcholesky.jl index f382aaf..8ccbacc 100644 --- a/src/infcholesky.jl +++ b/src/infcholesky.jl @@ -1,6 +1,6 @@ -mutable struct AdaptiveCholeskyFactors{T,DM<:AbstractMatrix{T},M<:AbstractMatrix{T}} <: LazyMatrix{T} - data::CachedMatrix{T,DM,M} +mutable struct AdaptiveCholeskyFactors{T,DM<:AbstractMatrix{T}} <: LazyMatrix{T} + data::CachedMatrix{T,DM} ncols::Int end @@ -16,7 +16,19 @@ function AdaptiveCholeskyFactors(::SymmetricBandedLayouts, S::AbstractMatrix{T}) AdaptiveCholeskyFactors(CachedArray(data,A), 0) end AdaptiveCholeskyFactors(A::AbstractMatrix{T}) where T = AdaptiveCholeskyFactors(MemoryLayout(A), A) -MemoryLayout(::Type{AdaptiveCholeskyFactors{T,DM,M}}) where {T,DM,M} = AdaptiveLayout{typeof(MemoryLayout(DM))}() + +struct AdaptiveCholeskyFactorsLayout <: AbstractLazyLayout end +struct AdaptiveCholeskyFactorsBandedLayout <: AbstractLazyBandedLayout end +struct AdaptiveCholeskyFactorsBlockBandedLayout <: AbstractLazyBlockBandedLayout end + +const AdaptiveCholeskyFactorsLayouts = Union{AdaptiveCholeskyFactorsLayout,AdaptiveCholeskyFactorsBandedLayout,AdaptiveCholeskyFactorsBlockBandedLayout} + +adaptivecholeskyfactorslayout(_) = AdaptiveCholeskyFactorsLayout() +adaptivecholeskyfactorslayout(::BandedLayouts) = AdaptiveCholeskyFactorsBandedLayout() +adaptivecholeskyfactorslayout(::BlockBandedLayouts) = AdaptiveCholeskyFactorsBlockBandedLayout() + + +MemoryLayout(::Type{AdaptiveCholeskyFactors{T,DM}}) where {T,DM} = adaptivecholeskyfactorslayout(MemoryLayout(DM)) copy(A::AdaptiveCholeskyFactors) = AdaptiveCholeskyFactors(copy(A.data), copy(A.ncols)) copy(A::Adjoint{T,<:AdaptiveCholeskyFactors}) where T = copy(parent(A))' @@ -74,7 +86,7 @@ end colsupport(F::AdjOrTrans{<:Any,<:AdaptiveCholeskyFactors}, j) = rowsupport(parent(F), j) rowsupport(F::AdjOrTrans{<:Any,<:AdaptiveCholeskyFactors}, j) = colsupport(parent(F), j) -function materialize!(M::MatLdivVec{<:TriangularLayout{'L','N',<:AdaptiveLayout},<:AbstractPaddedLayout}) +function materialize!(M::MatLdivVec{<:TriangularLayout{'L','N',<:AdaptiveCholeskyFactorsLayouts},<:AbstractPaddedLayout}) A,B = M.A,M.B T = eltype(M) COLGROWTH = 1000 # rate to grow columns diff --git a/src/infqr.jl b/src/infqr.jl index a284f8f..3cc1f65 100644 --- a/src/infqr.jl +++ b/src/infqr.jl @@ -1,6 +1,6 @@ -mutable struct AdaptiveQRData{T,DM<:AbstractMatrix{T},M<:AbstractMatrix{T}} - data::CachedMatrix{T,DM,M} +mutable struct AdaptiveQRData{T,DM<:AbstractMatrix{T}} + data::CachedMatrix{T,DM} τ::Vector{T} ncols::Int end @@ -89,24 +89,24 @@ partialqr!(F::AdaptiveQRData{<:Any,<:BlockSkylineMatrix}, n::Int) = partialqr!(F, findblock(axes(F.data,2), n)) -struct AdaptiveQRFactors{T,DM<:AbstractMatrix{T},M<:AbstractMatrix{T}} <: LayoutMatrix{T} - data::AdaptiveQRData{T,DM,M} +struct AdaptiveQRFactors{T,DM<:AbstractMatrix{T}} <: LayoutMatrix{T} + data::AdaptiveQRData{T,DM} end -struct AdaptiveLayout <: AbstractLazyLayout end -struct AdaptiveBandedLayout <: AbstractLazyBandedLayout end -struct AdaptiveBlockBandedLayout <: AbstractLazyBlockBandedLayout end +struct AdaptiveQRFactorsLayout <: AbstractLazyLayout end +struct AdaptiveQRFactorsBandedLayout <: AbstractLazyBandedLayout end +struct AdaptiveQRFactorsBlockBandedLayout <: AbstractLazyBlockBandedLayout end -const AdaptiveLayouts = Union{AdaptiveLayout,AdaptiveBandedLayout,AdaptiveBlockBandedLayout} +const AdaptiveQRFactorsLayouts = Union{AdaptiveQRFactorsLayout,AdaptiveQRFactorsBandedLayout,AdaptiveQRFactorsBlockBandedLayout} -adaptivelayout(_) = AdaptiveLayout() -adaptivelayout(::BandedLayouts) = AdaptiveBandedLayout() -adaptivelayout(::BlockBandedLayouts) = AdaptiveBlockBandedLayout() +adaptiveqrfactorslayout(_) = AdaptiveQRFactorsLayout() +adaptiveqrfactorslayout(::BandedLayouts) = AdaptiveQRFactorsBandedLayout() +adaptiveqrfactorslayout(::BlockBandedLayouts) = AdaptiveQRFactorsBlockBandedLayout() -MemoryLayout(::Type{AdaptiveQRFactors{T,DM,M}}) where {T,DM,M} =adaptivelayout(MemoryLayout(DM)) -triangularlayout(::Type{Tri}, ::ML) where {Tri, ML<:AdaptiveLayouts} = Tri{ML}() -transposelayout(A::AdaptiveLayouts) = A +MemoryLayout(::Type{AdaptiveQRFactors{T,DM}}) where {T,DM} =adaptiveqrfactorslayout(MemoryLayout(DM)) +triangularlayout(::Type{Tri}, ::ML) where {Tri, ML<:AdaptiveQRFactorsLayouts} = Tri{ML}() +transposelayout(A::AdaptiveQRFactorsLayouts) = A size(F::AdaptiveQRFactors) = size(F.data.data) axes(F::AdaptiveQRFactors) = axes(F.data.data) @@ -146,8 +146,8 @@ rowsupport(F::QRPackedQ{<:Any,<:AdaptiveQRFactors}, j) = first(rowsupport(F.fact blockcolsupport(F::QRPackedQ{<:Any,<:AdaptiveQRFactors}, j) = blockcolsupport(F.factors, j) -struct AdaptiveQRTau{T,DM<:AbstractMatrix{T},M<:AbstractMatrix{T}} <: LayoutVector{T} - data::AdaptiveQRData{T,DM,M} +struct AdaptiveQRTau{T,DM<:AbstractMatrix{T}} <: LayoutVector{T} + data::AdaptiveQRData{T,DM} end size(F::AdaptiveQRTau) = (size(F.data.data,1),) @@ -174,7 +174,7 @@ factorize_layout(::BandedLayouts, ::NTuple{2,OneToInf{Int}}, A) = qr(A) factorize_layout(::AbstractBandedLayout, ::NTuple{2,OneToInf{Int}}, A) = qr(A) -cache_layout(::TriangularLayout{UPLO, UNIT, <:AdaptiveLayouts}, A::AbstractMatrix) where {UPLO, UNIT} = A # already cached +cache_layout(::TriangularLayout{UPLO, UNIT, <:AdaptiveQRFactorsLayouts}, A::AbstractMatrix) where {UPLO, UNIT} = A # already cached partialqr!(F::QR, n) = partialqr!(F.factors, n) partialqr!(F::AdaptiveQRFactors, n) = partialqr!(F.data, n) @@ -191,7 +191,7 @@ getindex(Q::QRPackedQ{<:Any,<:AdaptiveQRFactors,<:AdaptiveQRTau}, I::AbstractVec ######### _view_QRPackedQ(A, kr, jr) = QRPackedQ(view(A.factors.data.data.data,kr,jr), view(A.τ.data.τ,jr)) -function materialize!(M::MatLmulVec{<:QRPackedQLayout{<:AdaptiveLayouts},<:AbstractPaddedLayout}) +function materialize!(M::MatLmulVec{<:QRPackedQLayout{<:AdaptiveQRFactorsLayouts},<:AbstractPaddedLayout}) A,B = M.A,M.B sB = size(paddeddata(B),1) partialqr!(A.factors.data,sB) @@ -233,7 +233,7 @@ end _norm(x::Number) = abs(x) -function materialize!(M::MatLmulVec{<:AdjQRPackedQLayout{<:AdaptiveLayouts},<:AbstractPaddedLayout}; tolerance=floatmin(real(eltype(M)))) +function materialize!(M::MatLmulVec{<:AdjQRPackedQLayout{<:AdaptiveQRFactorsLayouts},<:AbstractPaddedLayout}; tolerance=floatmin(real(eltype(M)))) adjA,B = M.A,M.B COLGROWTH = 1000 # rate to grow columns @@ -284,7 +284,7 @@ function _view_QRPackedQ(A, KR::BlockRange, JR::BlockRange) QRPackedQ(view(A.factors.data.data.data,KR,JR), view(A.τ.data.τ,jr)) end -function materialize!(M::MatLmulVec{QRPackedQLayout{AdaptiveBlockBandedLayout},<:AbstractPaddedLayout}) +function materialize!(M::MatLmulVec{QRPackedQLayout{AdaptiveQRFactorsBlockBandedLayout},<:AbstractPaddedLayout}) A,B_in = M.A,M.B sB = length(paddeddata(B_in)) ax1,ax2 = axes(A.factors.data.data) @@ -300,7 +300,7 @@ function materialize!(M::MatLmulVec{QRPackedQLayout{AdaptiveBlockBandedLayout},< B end -function materialize!(M::MatLmulVec{<:AdjQRPackedQLayout{AdaptiveBlockBandedLayout},<:AbstractPaddedLayout}; tolerance=1E-30) +function materialize!(M::MatLmulVec{<:AdjQRPackedQLayout{AdaptiveQRFactorsBlockBandedLayout},<:AbstractPaddedLayout}; tolerance=1E-30) adjA,B_in = M.A,M.B A = parent(adjA) T = eltype(M) @@ -377,15 +377,15 @@ ldiv!(F::QR{<:Any,<:AdaptiveQRFactors}, b::LayoutVector; kwds...) = ldiv!(F.R, l factorize(A::BandedMatrix{<:Any,<:Any,<:OneToInf}) = qr(A) qr(A::SymTridiagonal{T,<:AbstractFill{T,1,Tuple{OneToInf{Int}}}}) where T = adaptiveqr(A) -simplifiable(M::Mul{<:QRPackedQLayout{<:AdaptiveLayouts}}) = Val(false) -simplifiable(M::Mul{<:QRPackedQLayout{<:AdaptiveLayouts},<:QRPackedQLayout{<:AdaptiveLayouts}}) = Val(false) -simplifiable(M::Mul{<:QRPackedQLayout{<:AdaptiveLayouts},<:LazyLayouts}) = Val(false) -simplifiable(M::Mul{<:Any,<:QRPackedQLayout{<:AdaptiveLayouts}}) = Val(false) -simplifiable(M::Mul{<:LazyLayouts,<:QRPackedQLayout{<:AdaptiveLayouts}}) = Val(false) +simplifiable(M::Mul{<:QRPackedQLayout{<:AdaptiveQRFactorsLayouts}}) = Val(false) +simplifiable(M::Mul{<:QRPackedQLayout{<:AdaptiveQRFactorsLayouts},<:QRPackedQLayout{<:AdaptiveQRFactorsLayouts}}) = Val(false) +simplifiable(M::Mul{<:QRPackedQLayout{<:AdaptiveQRFactorsLayouts},<:LazyLayouts}) = Val(false) +simplifiable(M::Mul{<:Any,<:QRPackedQLayout{<:AdaptiveQRFactorsLayouts}}) = Val(false) +simplifiable(M::Mul{<:LazyLayouts,<:QRPackedQLayout{<:AdaptiveQRFactorsLayouts}}) = Val(false) -copy(M::Mul{<:QRPackedQLayout{<:AdaptiveLayouts},<:QRPackedQLayout{<:AdaptiveLayouts}}) = simplify(M) -copy(M::Mul{<:QRPackedQLayout{<:AdaptiveLayouts}}) = simplify(M) -copy(M::Mul{<:QRPackedQLayout{<:AdaptiveLayouts},<:LazyLayouts}) = simplify(M) -copy(M::Mul{<:Any,<:QRPackedQLayout{<:AdaptiveLayouts}}) = simplify(M) -copy(M::Mul{<:LazyLayouts,<:QRPackedQLayout{<:AdaptiveLayouts}}) = simplify(M) +copy(M::Mul{<:QRPackedQLayout{<:AdaptiveQRFactorsLayouts},<:QRPackedQLayout{<:AdaptiveQRFactorsLayouts}}) = simplify(M) +copy(M::Mul{<:QRPackedQLayout{<:AdaptiveQRFactorsLayouts}}) = simplify(M) +copy(M::Mul{<:QRPackedQLayout{<:AdaptiveQRFactorsLayouts},<:LazyLayouts}) = simplify(M) +copy(M::Mul{<:Any,<:QRPackedQLayout{<:AdaptiveQRFactorsLayouts}}) = simplify(M) +copy(M::Mul{<:LazyLayouts,<:QRPackedQLayout{<:AdaptiveQRFactorsLayouts}}) = simplify(M) diff --git a/test/test_infqr.jl b/test/test_infqr.jl index 28a02ed..3c19d17 100644 --- a/test/test_infqr.jl +++ b/test/test_infqr.jl @@ -3,7 +3,7 @@ using InfiniteLinearAlgebra, LinearAlgebra, BandedMatrices, InfiniteArrays, Matr import LazyArrays: colsupport, rowsupport, MemoryLayout, DenseColumnMajor, TriangularLayout, resizedata!, arguments import LazyBandedMatrices: BroadcastBandedLayout, InvDiagTrav, BroadcastBandedBlockBandedLayout import BandedMatrices: _BandedMatrix, _banded_qr!, BandedColumns -import InfiniteLinearAlgebra: partialqr!, AdaptiveQRData, AdaptiveLayout, AdaptiveBandedLayout, adaptiveqr +import InfiniteLinearAlgebra: partialqr!, AdaptiveQRData, AdaptiveQRFactorsBandedLayout, adaptiveqr import SemiseparableMatrices: AlmostBandedLayout, VcatAlmostBandedLayout @@ -44,7 +44,7 @@ import SemiseparableMatrices: AlmostBandedLayout, VcatAlmostBandedLayout @testset "col/rowsupport" begin A = _BandedMatrix(Vcat(Ones(1,∞), (1:∞)', Ones(1,∞)), ℵ₀, 1, 1) F = qr(A) - @test MemoryLayout(typeof(F.factors)) isa AdaptiveBandedLayout + @test MemoryLayout(typeof(F.factors)) isa AdaptiveQRFactorsBandedLayout @test bandwidths(F.factors) == (1,2) @test colsupport(F.factors,1) == 1:2 @test colsupport(F.factors,5) == 3:6 From af49355711dca4957f080f4736f95bba1ee3d18e Mon Sep 17 00:00:00 2001 From: Sheehan Olver Date: Sat, 8 Feb 2025 13:28:22 +0000 Subject: [PATCH 4/8] start Y + I tests --- src/InfiniteLinearAlgebra.jl | 2 +- src/infcholesky.jl | 2 ++ test/test_bidiagonalconjugation.jl | 7 +++++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/InfiniteLinearAlgebra.jl b/src/InfiniteLinearAlgebra.jl index cb0a07b..7bed4f2 100644 --- a/src/InfiniteLinearAlgebra.jl +++ b/src/InfiniteLinearAlgebra.jl @@ -118,7 +118,7 @@ pad(c::Transpose, ax, bx) = transpose(pad(parent(c), bx, ax)) pad(c::Adjoint, ax, bx) = adjoint(pad(parent(c), bx, ax)) pad(c::BlockVec, ax::BlockedOneTo{Int,<:InfStepRange}) = BlockVec(pad(c.args[1], size(c.args[1],1), ∞)) -export ∞, ContinuousSpectrumError, BlockTridiagonal +export ∞, ContinuousSpectrumError, BlockTridiagonal, TridiagonalConjugation, BidiagonalConjugation include("banded/hessenbergq.jl") diff --git a/src/infcholesky.jl b/src/infcholesky.jl index 8ccbacc..9a36aec 100644 --- a/src/infcholesky.jl +++ b/src/infcholesky.jl @@ -29,6 +29,8 @@ adaptivecholeskyfactorslayout(::BlockBandedLayouts) = AdaptiveCholeskyFactorsBlo MemoryLayout(::Type{AdaptiveCholeskyFactors{T,DM}}) where {T,DM} = adaptivecholeskyfactorslayout(MemoryLayout(DM)) +triangularlayout(::Type{Tri}, ::ML) where {Tri, ML<:AdaptiveCholeskyFactorsLayouts} = Tri{ML}() +transposelayout(A::AdaptiveCholeskyFactorsLayouts) = A copy(A::AdaptiveCholeskyFactors) = AdaptiveCholeskyFactors(copy(A.data), copy(A.ncols)) copy(A::Adjoint{T,<:AdaptiveCholeskyFactors}) where T = copy(parent(A))' diff --git a/test/test_bidiagonalconjugation.jl b/test/test_bidiagonalconjugation.jl index 52f528e..be80b97 100644 --- a/test/test_bidiagonalconjugation.jl +++ b/test/test_bidiagonalconjugation.jl @@ -192,5 +192,12 @@ end Y = SymTridiagonalConjugation(R, X) n = 100_000 @test Y[n,n+1] ≈ 1/2 + + @testset "Y+I" begin + Y+I + Y-I + I+Y + I-Y + end end end \ No newline at end of file From 2692797be4112c866dc844634ec43d6133786178 Mon Sep 17 00:00:00 2001 From: Sheehan Olver Date: Sat, 8 Feb 2025 16:07:48 +0000 Subject: [PATCH 5/8] Y+I fixes --- src/banded/tridiagonalconjugation.jl | 9 +++++---- src/infcholesky.jl | 2 ++ src/infqr.jl | 2 +- test/test_bidiagonalconjugation.jl | 22 +++++++++------------- 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/banded/tridiagonalconjugation.jl b/src/banded/tridiagonalconjugation.jl index 9e46d3f..953ce18 100644 --- a/src/banded/tridiagonalconjugation.jl +++ b/src/banded/tridiagonalconjugation.jl @@ -290,14 +290,15 @@ getindex(K::SubArray{<:Any,1,<:TridiagonalConjugationBand}, k::AbstractInfUnitRa copy(A::TridiagonalConjugationBand) = A # immutable -const TridiagonalConjugation{T} = Tridiagonal{T, TridiagonalConjugationBand{T}} -const SymTridiagonalConjugation{T} = SymTridiagonal{T, TridiagonalConjugationBand{T}} +# Use LazyBandedMatrices.Tridiagonal to support algebra +const TridiagonalConjugation{T} = LazyBandedMatrices.Tridiagonal{T, TridiagonalConjugationBand{T}, TridiagonalConjugationBand{T}, TridiagonalConjugationBand{T}} +const SymTridiagonalConjugation{T} = LazyBandedMatrices.SymTridiagonal{T, TridiagonalConjugationBand{T}, TridiagonalConjugationBand{T}} function TridiagonalConjugation(R, X, Y...) data = TridiagonalConjugationData(R, X, Y...) - Tridiagonal(TridiagonalConjugationBand(data, :dl), TridiagonalConjugationBand(data, :d), TridiagonalConjugationBand(data, :du)) + LazyBandedMatrices.Tridiagonal(TridiagonalConjugationBand(data, :dl), TridiagonalConjugationBand(data, :d), TridiagonalConjugationBand(data, :du)) end function SymTridiagonalConjugation(R, X, Y...) data = TridiagonalConjugationData(R, X, Y...) - SymTridiagonal(TridiagonalConjugationBand(data, :d), TridiagonalConjugationBand(data, :du)) + LazyBandedMatrices.SymTridiagonal(TridiagonalConjugationBand(data, :d), TridiagonalConjugationBand(data, :du)) end \ No newline at end of file diff --git a/src/infcholesky.jl b/src/infcholesky.jl index 9a36aec..e9898d7 100644 --- a/src/infcholesky.jl +++ b/src/infcholesky.jl @@ -36,6 +36,8 @@ copy(A::AdaptiveCholeskyFactors) = AdaptiveCholeskyFactors(copy(A.data), copy(A. copy(A::Adjoint{T,<:AdaptiveCholeskyFactors}) where T = copy(parent(A))' copy(A::Transpose{T,<:AdaptiveCholeskyFactors}) where T = transpose(copy(parent(A))) +cache_layout(::TriangularLayout{'U', 'N', AdaptiveCholeskyFactorsBandedLayout}, A::AbstractMatrix) = A # already cached + function partialcholesky!(F::AdaptiveCholeskyFactors{T,<:BandedMatrix}, n::Int) where T if n > F.ncols _,u = bandwidths(F.data.array) diff --git a/src/infqr.jl b/src/infqr.jl index 3cc1f65..8c686bb 100644 --- a/src/infqr.jl +++ b/src/infqr.jl @@ -5,7 +5,7 @@ mutable struct AdaptiveQRData{T,DM<:AbstractMatrix{T}} ncols::Int end -function AdaptiveQRData(::Union{SymmetricLayout{<:AbstractBandedLayout},AbstractBandedLayout}, A::AbstractMatrix{T}) where T +function AdaptiveQRData(::BandedLayouts, A::AbstractMatrix{T}) where T l,u = bandwidths(A) FT = float(T) data = BandedMatrix{FT}(undef,(2l+u+1,0),(l,l+u)) # pad super diff --git a/test/test_bidiagonalconjugation.jl b/test/test_bidiagonalconjugation.jl index be80b97..ccc9707 100644 --- a/test/test_bidiagonalconjugation.jl +++ b/test/test_bidiagonalconjugation.jl @@ -185,19 +185,15 @@ end R,X = (_BandedMatrix(Vcat(-Ones(1,∞)/2, Zeros(1,∞), Hcat(Ones(1,1),Ones(1,∞)/2)), ℵ₀, 0,2), LazyBandedMatrices.Tridiagonal(Vcat(1.0, Fill(1/2,∞)), Zeros(∞), Fill(1/2,∞))) - Y = TridiagonalConjugation(R, X) - n = 100_000 - @test Y[n,n+1] ≈ 1/2 - - Y = SymTridiagonalConjugation(R, X) - n = 100_000 - @test Y[n,n+1] ≈ 1/2 - - @testset "Y+I" begin - Y+I - Y-I - I+Y - I-Y + for Y in (TridiagonalConjugation(R, X), SymTridiagonalConjugation(R, X)) + n = 100_000 + @test Y[n,n+1] ≈ 1/2 + + @testset "Y+I" begin + @test (Y+I)[1:10,1:10] == (I+Y)[1:10,1:10] == I + Y[1:10,1:10] + @test (Y-I)[1:10,1:10] == Y[1:10,1:10] - I + @test (I-Y)[1:10,1:10] == I - Y[1:10,1:10] + end end end end \ No newline at end of file From dfbff3065e9fd345169418c55e8d2697088367b1 Mon Sep 17 00:00:00 2001 From: Sheehan Olver Date: Tue, 11 Feb 2025 20:18:02 +0000 Subject: [PATCH 6/8] avoid ambiguities --- src/InfiniteLinearAlgebra.jl | 5 ++++- src/infqr.jl | 11 +++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/InfiniteLinearAlgebra.jl b/src/InfiniteLinearAlgebra.jl index 7bed4f2..13091e9 100644 --- a/src/InfiniteLinearAlgebra.jl +++ b/src/InfiniteLinearAlgebra.jl @@ -48,7 +48,10 @@ import LazyBandedMatrices: AbstractLazyBandedBlockBandedLayout, AbstractLazyBand const StructuredLayoutTypes{Lay} = Union{SymmetricLayout{Lay}, HermitianLayout{Lay}, TriangularLayout{'L','N',Lay}, TriangularLayout{'U','N',Lay}, TriangularLayout{'L','U',Lay}, TriangularLayout{'U','U',Lay}} -const BandedLayouts = Union{AbstractBandedLayout, StructuredLayoutTypes{<:AbstractBandedLayout}} +LazyArraysBandedMatricesExt = Base.get_extension(LazyArrays, :LazyArraysBandedMatricesExt) + +const BandedLazyLayouts = LazyArraysBandedMatricesExt.BandedLazyLayouts +const BandedLayouts = LazyArraysBandedMatricesExt.BandedLayouts const BlockBandedLayouts = Union{AbstractBlockBandedLayout, BlockLayout{<:AbstractBandedLayout}, StructuredLayoutTypes{<:AbstractBlockBandedLayout}} import LinearAlgebra: AbstractQ, AdjointQ, AdjOrTrans, factorize, matprod, qr diff --git a/src/infqr.jl b/src/infqr.jl index 8c686bb..1d10af7 100644 --- a/src/infqr.jl +++ b/src/infqr.jl @@ -384,8 +384,11 @@ simplifiable(M::Mul{<:Any,<:QRPackedQLayout{<:AdaptiveQRFactorsLayouts}}) = Val( simplifiable(M::Mul{<:LazyLayouts,<:QRPackedQLayout{<:AdaptiveQRFactorsLayouts}}) = Val(false) -copy(M::Mul{<:QRPackedQLayout{<:AdaptiveQRFactorsLayouts},<:QRPackedQLayout{<:AdaptiveQRFactorsLayouts}}) = simplify(M) +copy(M::Mul{<:QRPackedQLayout{<:AdaptiveQRFactorsLayouts}, <:QRPackedQLayout{<:AdaptiveQRFactorsLayouts}}) = simplify(M) copy(M::Mul{<:QRPackedQLayout{<:AdaptiveQRFactorsLayouts}}) = simplify(M) -copy(M::Mul{<:QRPackedQLayout{<:AdaptiveQRFactorsLayouts},<:LazyLayouts}) = simplify(M) -copy(M::Mul{<:Any,<:QRPackedQLayout{<:AdaptiveQRFactorsLayouts}}) = simplify(M) -copy(M::Mul{<:LazyLayouts,<:QRPackedQLayout{<:AdaptiveQRFactorsLayouts}}) = simplify(M) +copy(M::Mul{<:AdaptiveQRFactorsLayouts, <:BandedLazyLayouts}) = simplify(M) +copy(M::Mul{<:QRPackedQLayout{<:AdaptiveQRFactorsLayouts}, <:BandedLazyLayouts}) = simplify(M) +copy(M::Mul{<:QRPackedQLayout{<:AdaptiveQRFactorsLayouts}, <:LazyLayouts}) = simplify(M) +copy(M::Mul{<:Any, <:QRPackedQLayout{<:AdaptiveQRFactorsLayouts}}) = simplify(M) +copy(M::Mul{<:LazyLayouts, <:QRPackedQLayout{<:AdaptiveQRFactorsLayouts}}) = simplify(M) +copy(M::Mul{<:BandedLazyLayouts, <:QRPackedQLayout{<:AdaptiveQRFactorsLayouts}}) = simplify(M) \ No newline at end of file From 18840a5fc734da6fd72221a64710ade01974ee8d Mon Sep 17 00:00:00 2001 From: Sheehan Olver Date: Wed, 12 Feb 2025 15:28:49 +0000 Subject: [PATCH 7/8] LazyArrays v2.6 --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index bd0e122..79b79d7 100644 --- a/Project.toml +++ b/Project.toml @@ -26,7 +26,7 @@ FillArrays = "1.0" InfiniteArrays = "0.15" InfiniteRandomArrays = "0.2" Infinities = "0.1" -LazyArrays = "2.5" +LazyArrays = "2.6" LazyBandedMatrices = "0.11" LinearAlgebra = "1" MatrixFactorizations = "3.0" From 7d3e4d131b5d62d59f6db2f8fe892093f40f5681 Mon Sep 17 00:00:00 2001 From: Sheehan Olver Date: Wed, 12 Feb 2025 19:45:58 +0000 Subject: [PATCH 8/8] increase coverage --- src/InfiniteLinearAlgebra.jl | 2 +- src/infcholesky.jl | 5 +++-- src/infqr.jl | 5 +++-- test/test_infqr.jl | 25 ++++++++++++++++++++++++- 4 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/InfiniteLinearAlgebra.jl b/src/InfiniteLinearAlgebra.jl index 13091e9..dc168e1 100644 --- a/src/InfiniteLinearAlgebra.jl +++ b/src/InfiniteLinearAlgebra.jl @@ -40,7 +40,7 @@ import LazyArrays: AbstractCachedMatrix, AbstractCachedVector, AbstractLazyLayou CachedArray, CachedLayout, CachedMatrix, CachedVector, LazyArrayStyle, LazyLayout, LazyLayouts, LazyMatrix, LazyVector, AbstractPaddedLayout, PaddedColumns, _broadcast_sub_arguments, applybroadcaststyle, applylayout, arguments, cacheddata, paddeddata, resizedata!, simplifiable, - simplify, islazy, islazy_layout, cache_getindex, cache_layout + simplify, islazy, islazy_layout, cache_getindex, cache_layout, AbstractInvLayout import LazyBandedMatrices: AbstractLazyBandedBlockBandedLayout, AbstractLazyBandedLayout, AbstractLazyBlockBandedLayout, ApplyBandedLayout, BlockVec, BroadcastBandedLayout, KronTravBandedBlockBandedLayout, LazyBandedLayout, diff --git a/src/infcholesky.jl b/src/infcholesky.jl index e9898d7..af9e77b 100644 --- a/src/infcholesky.jl +++ b/src/infcholesky.jl @@ -23,9 +23,10 @@ struct AdaptiveCholeskyFactorsBlockBandedLayout <: AbstractLazyBlockBandedLayout const AdaptiveCholeskyFactorsLayouts = Union{AdaptiveCholeskyFactorsLayout,AdaptiveCholeskyFactorsBandedLayout,AdaptiveCholeskyFactorsBlockBandedLayout} -adaptivecholeskyfactorslayout(_) = AdaptiveCholeskyFactorsLayout() +# TODO: support other than Banded +# adaptivecholeskyfactorslayout(_) = AdaptiveCholeskyFactorsLayout() adaptivecholeskyfactorslayout(::BandedLayouts) = AdaptiveCholeskyFactorsBandedLayout() -adaptivecholeskyfactorslayout(::BlockBandedLayouts) = AdaptiveCholeskyFactorsBlockBandedLayout() +# adaptivecholeskyfactorslayout(::BlockBandedLayouts) = AdaptiveCholeskyFactorsBlockBandedLayout() MemoryLayout(::Type{AdaptiveCholeskyFactors{T,DM}}) where {T,DM} = adaptivecholeskyfactorslayout(MemoryLayout(DM)) diff --git a/src/infqr.jl b/src/infqr.jl index 1d10af7..3807584 100644 --- a/src/infqr.jl +++ b/src/infqr.jl @@ -106,7 +106,7 @@ adaptiveqrfactorslayout(::BlockBandedLayouts) = AdaptiveQRFactorsBlockBandedLayo MemoryLayout(::Type{AdaptiveQRFactors{T,DM}}) where {T,DM} =adaptiveqrfactorslayout(MemoryLayout(DM)) triangularlayout(::Type{Tri}, ::ML) where {Tri, ML<:AdaptiveQRFactorsLayouts} = Tri{ML}() -transposelayout(A::AdaptiveQRFactorsLayouts) = A +# transposelayout(A::AdaptiveQRFactorsLayouts) = A size(F::AdaptiveQRFactors) = size(F.data.data) axes(F::AdaptiveQRFactors) = axes(F.data.data) @@ -174,7 +174,7 @@ factorize_layout(::BandedLayouts, ::NTuple{2,OneToInf{Int}}, A) = qr(A) factorize_layout(::AbstractBandedLayout, ::NTuple{2,OneToInf{Int}}, A) = qr(A) -cache_layout(::TriangularLayout{UPLO, UNIT, <:AdaptiveQRFactorsLayouts}, A::AbstractMatrix) where {UPLO, UNIT} = A # already cached +cache_layout(::TriangularLayout{'U', 'N', AdaptiveQRFactorsBandedLayout}, A::AbstractMatrix) = A # already cached partialqr!(F::QR, n) = partialqr!(F.factors, n) partialqr!(F::AdaptiveQRFactors, n) = partialqr!(F.data, n) @@ -382,6 +382,7 @@ simplifiable(M::Mul{<:QRPackedQLayout{<:AdaptiveQRFactorsLayouts},<:QRPackedQLay simplifiable(M::Mul{<:QRPackedQLayout{<:AdaptiveQRFactorsLayouts},<:LazyLayouts}) = Val(false) simplifiable(M::Mul{<:Any,<:QRPackedQLayout{<:AdaptiveQRFactorsLayouts}}) = Val(false) simplifiable(M::Mul{<:LazyLayouts,<:QRPackedQLayout{<:AdaptiveQRFactorsLayouts}}) = Val(false) +simplifiable(M::Mul{<:AbstractInvLayout,<:QRPackedQLayout{<:AdaptiveQRFactorsLayouts}}) = Val(false) copy(M::Mul{<:QRPackedQLayout{<:AdaptiveQRFactorsLayouts}, <:QRPackedQLayout{<:AdaptiveQRFactorsLayouts}}) = simplify(M) diff --git a/test/test_infqr.jl b/test/test_infqr.jl index 3c19d17..dc82c13 100644 --- a/test/test_infqr.jl +++ b/test/test_infqr.jl @@ -1,6 +1,6 @@ using InfiniteLinearAlgebra, LinearAlgebra, BandedMatrices, InfiniteArrays, MatrixFactorizations, LazyArrays, FillArrays, SpecialFunctions, Test, SemiseparableMatrices, LazyBandedMatrices, BlockArrays, BlockBandedMatrices, ArrayLayouts -import LazyArrays: colsupport, rowsupport, MemoryLayout, DenseColumnMajor, TriangularLayout, resizedata!, arguments +import LazyArrays: colsupport, rowsupport, MemoryLayout, DenseColumnMajor, TriangularLayout, resizedata!, arguments, simplifiable import LazyBandedMatrices: BroadcastBandedLayout, InvDiagTrav, BroadcastBandedBlockBandedLayout import BandedMatrices: _BandedMatrix, _banded_qr!, BandedColumns import InfiniteLinearAlgebra: partialqr!, AdaptiveQRData, AdaptiveQRFactorsBandedLayout, adaptiveqr @@ -165,6 +165,29 @@ import SemiseparableMatrices: AlmostBandedLayout, VcatAlmostBandedLayout @test F\b ≈ F\view(b,:) @test_broken F\b ≈ ldiv!(F, view(copy(b),:)) end + + @testset "cache/mul" begin + A = _BandedMatrix(Vcat(Ones(1,∞), (1:∞)', Ones(1,∞)), ℵ₀, 1, 1) + Q,R = qr(A) + @test cache(R) ≡ R + + @test simplifiable(*, R, A) == Val(false) + @test simplifiable(*, A, R) == Val(false) + @test simplifiable(*, parent(R), A) == Val(false) + @test simplifiable(*, A, parent(R)) == Val(false) + @test simplifiable(*, inv(R), A) == Val(false) + @test simplifiable(*, A, inv(R)) == Val(false) + @test simplifiable(*, inv(R), Q) == Val(false) + @test simplifiable(*, Q, inv(R)) == Val(false) + @test simplifiable(*, Symmetric(inv(R)), Q) == Val(false) + @test simplifiable(*, Q, Symmetric(inv(R))) == Val(false) + @test (R * A)[1:10,1:10] ≈ R[1:10,1:11] * A[1:11,1:10] + @test (Q * A)[1:10,1:10] ≈ Q[1:10,1:11] * A[1:11,1:10] + @test mul(Q, Symmetric(inv(R))) isa ApplyArray # several bugs avoided heree + @test mul(Symmetric(inv(R)), Q) isa ApplyArray # several bugs avoided heree + @test (parent(R) * A)[1:10,1:10] ≈ parent(R)[1:10,1:11] * A[1:11,1:10] + + end end @testset "almost-banded" begin