Skip to content

Add AdaptiveBlock/BandedLayout #195

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Feb 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -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"
Expand All @@ -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"
Expand Down
13 changes: 8 additions & 5 deletions src/InfiniteLinearAlgebra.jl
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,19 @@ 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, 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}}

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

Expand Down Expand Up @@ -118,7 +121,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")

Expand Down
9 changes: 5 additions & 4 deletions src/banded/tridiagonalconjugation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
25 changes: 21 additions & 4 deletions src/infcholesky.jl
Original file line number Diff line number Diff line change
@@ -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

Expand All @@ -16,12 +16,29 @@ 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}

# TODO: support other than Banded
# adaptivecholeskyfactorslayout(_) = AdaptiveCholeskyFactorsLayout()
adaptivecholeskyfactorslayout(::BandedLayouts) = AdaptiveCholeskyFactorsBandedLayout()
# adaptivecholeskyfactorslayout(::BlockBandedLayouts) = AdaptiveCholeskyFactorsBlockBandedLayout()


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))'
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)
Expand Down Expand Up @@ -74,7 +91,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
Expand Down
70 changes: 42 additions & 28 deletions src/infqr.jl
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@

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

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
Expand Down Expand Up @@ -89,14 +89,24 @@
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{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 AdaptiveQRFactorsLayout <: AbstractLazyLayout end
struct AdaptiveQRFactorsBandedLayout <: AbstractLazyBandedLayout end
struct AdaptiveQRFactorsBlockBandedLayout <: AbstractLazyBlockBandedLayout end

const AdaptiveQRFactorsLayouts = Union{AdaptiveQRFactorsLayout,AdaptiveQRFactorsBandedLayout,AdaptiveQRFactorsBlockBandedLayout}

adaptiveqrfactorslayout(_) = AdaptiveQRFactorsLayout()
adaptiveqrfactorslayout(::BandedLayouts) = AdaptiveQRFactorsBandedLayout()
adaptiveqrfactorslayout(::BlockBandedLayouts) = AdaptiveQRFactorsBlockBandedLayout()


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)
Expand Down Expand Up @@ -136,8 +146,8 @@
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),)
Expand All @@ -164,7 +174,7 @@
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{'U', 'N', AdaptiveQRFactorsBandedLayout}, A::AbstractMatrix) = A # already cached

partialqr!(F::QR, n) = partialqr!(F.factors, n)
partialqr!(F::AdaptiveQRFactors, n) = partialqr!(F.data, n)
Expand All @@ -181,7 +191,7 @@
#########

_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{<:AdaptiveQRFactorsLayouts},<:AbstractPaddedLayout})
A,B = M.A,M.B
sB = size(paddeddata(B),1)
partialqr!(A.factors.data,sB)
Expand Down Expand Up @@ -223,7 +233,7 @@

_norm(x::Number) = abs(x)

function materialize!(M::MatLmulVec{<:AdjQRPackedQLayout{<:AdaptiveLayout},<: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

Expand Down Expand Up @@ -274,7 +284,7 @@
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{AdaptiveQRFactorsBlockBandedLayout},<:AbstractPaddedLayout})

Check warning on line 287 in src/infqr.jl

View check run for this annotation

Codecov / codecov/patch

src/infqr.jl#L287

Added line #L287 was not covered by tests
A,B_in = M.A,M.B
sB = length(paddeddata(B_in))
ax1,ax2 = axes(A.factors.data.data)
Expand All @@ -290,7 +300,7 @@
B
end

function materialize!(M::MatLmulVec{<:AdjQRPackedQLayout{<:AdaptiveLayout{<:AbstractBlockBandedLayout}},<: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)
Expand Down Expand Up @@ -367,15 +377,19 @@
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)


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)
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)
simplifiable(M::Mul{<:AbstractInvLayout,<:QRPackedQLayout{<:AdaptiveQRFactorsLayouts}}) = Val(false)


copy(M::Mul{<:QRPackedQLayout{<:AdaptiveQRFactorsLayouts}, <:QRPackedQLayout{<:AdaptiveQRFactorsLayouts}}) = simplify(M)
copy(M::Mul{<: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)
17 changes: 10 additions & 7 deletions test/test_bidiagonalconjugation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -185,12 +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
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
29 changes: 26 additions & 3 deletions test/test_infqr.jl
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
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, AdaptiveLayout, adaptiveqr
import InfiniteLinearAlgebra: partialqr!, AdaptiveQRData, AdaptiveQRFactorsBandedLayout, adaptiveqr
import SemiseparableMatrices: AlmostBandedLayout, VcatAlmostBandedLayout


Expand Down Expand Up @@ -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 AdaptiveQRFactorsBandedLayout
@test bandwidths(F.factors) == (1,2)
@test colsupport(F.factors,1) == 1:2
@test colsupport(F.factors,5) == 3:6
Expand Down Expand Up @@ -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
Expand Down
Loading