diff --git a/src/FastAlmostBandedMatrices.jl b/src/FastAlmostBandedMatrices.jl index 6d0ca48..20119d8 100644 --- a/src/FastAlmostBandedMatrices.jl +++ b/src/FastAlmostBandedMatrices.jl @@ -2,8 +2,15 @@ module FastAlmostBandedMatrices import PrecompileTools: @setup_workload, @compile_workload -using ArrayInterface, ArrayLayouts, ConcreteStructs, LazyArrays, LinearAlgebra, - MatrixFactorizations +import ArrayInterface +import ArrayLayouts +import ArrayLayouts: LayoutMatrix, LayoutVector, Ldiv, Lmul, TriangularLayout +import ConcreteStructs: @concrete +import LazyArrays: LazyArray, Mul +import LinearAlgebra +import LinearAlgebra: LowerTriangular, NoPivot, UnitLowerTriangular, UnitUpperTriangular, + UpperTriangular, diagind, lmul!, lu, qr, rank, triu! +import MatrixFactorizations # The BandedMatrices.jl surface that FastAlmostBandedMatrices reexports (see the second # `export` below), so that `using FastAlmostBandedMatrices` on its own is enough to build @@ -640,22 +647,26 @@ end _almostbanded_widerect_ldiv!(::QR{T}, B) where {T} = error("Not implemented") -const UpperLayoutMatrix{T} = UpperTriangular{T, <:LayoutMatrix{T}} - -for Typ in - (:StridedVector, :StridedMatrix, :AbstractVecOrMat, :UpperLayoutMatrix, :LayoutMatrix) - @eval function ldiv!(A::QR{T, <:AlmostBandedMatrix}, B::$Typ{T}) where {T} - m, n = size(A) - return if m == n - _almostbanded_square_ldiv!(A, B) - elseif n > m - _almostbanded_widerect_ldiv!(A, B) - else - _almostbanded_longrect_ldiv!(A, B) - end +function _almostbanded_ldiv!(A::QR, B) + m, n = size(A) + return if m == n + _almostbanded_square_ldiv!(A, B) + elseif n > m + _almostbanded_widerect_ldiv!(A, B) + else + _almostbanded_longrect_ldiv!(A, B) end end +ldiv!(A::QR{T, <:AlmostBandedMatrix}, B::StridedVector{T}) where {T} = + _almostbanded_ldiv!(A, B) +ldiv!(A::QR{T, <:AlmostBandedMatrix}, B::StridedMatrix{T}) where {T} = + _almostbanded_ldiv!(A, B) +ldiv!(A::QR{T, <:AlmostBandedMatrix}, B::LayoutVector{T}) where {T} = + _almostbanded_ldiv!(A, B) +ldiv!(A::QR{T, <:AlmostBandedMatrix}, B::LayoutMatrix{T}) where {T} = + _almostbanded_ldiv!(A, B) + # needed for adaptive QR function Base.materialize!(M::Lmul{<:QRPackedQLayout{<:AlmostBandedLayout}}) return lmul!(QRPackedQ(bandpart(M.A.factors), M.A.τ), M.B) @@ -670,6 +681,12 @@ triangularlayout(::Type{Tri}, ::ML) where {Tri, ML <: AlmostBandedLayout} = Tri{ @inline function __arguments(x::LazyArray, ::AlmostBandedMatrix, ::Val) return LazyArrays.arguments(x) end +@inline function __arguments(x::LazyArray, ::AlmostBandedMatrix, ::Val{false}) + return LazyArrays.arguments(x) +end +@inline function __arguments(x::LazyArray, ::AlmostBandedMatrix, ::Val{true}) + return LazyArrays.arguments(x) +end @inline __arguments(x::Mul, ::AlmostBandedMatrix, ::Val) = (x.A, x.B) @inline __arguments(x::AbstractArray, ::AlmostBandedMatrix, ::Val{false}) = (nothing, x) @inline function __arguments(x::AbstractArray, A::AlmostBandedMatrix, ::Val{true}) diff --git a/test/core_tests.jl b/test/core_tests.jl index 14729fd..8fc8035 100644 --- a/test/core_tests.jl +++ b/test/core_tests.jl @@ -173,6 +173,8 @@ end @test A \ b ≈ Matrix(A) \ b @test all(A \ b .=== F \ b) @test all(A \ b .=== F.R \ (F.Q' * b)) + @test ldiv!(F, copy(b)) ≈ Matrix(A) \ b + @test ldiv!(F, reshape(copy(b), :, 1)) ≈ reshape(Matrix(A) \ b, :, 1) Q̃ = QRPackedQ(F.factors, F.τ) @test Matrix(Q̃) ≈ Matrix(F.Q) @test lmul!(Q̃, copy(b)) ≈ lmul!(F.Q, copy(b)) ≈ Matrix(F.Q) * b diff --git a/test/qa/qa.jl b/test/qa/qa.jl index a77dba6..6a9e2ce 100644 --- a/test/qa/qa.jl +++ b/test/qa/qa.jl @@ -15,10 +15,6 @@ run_qa( # `Band` and `BandError` are reexported but carry no docstring upstream in # BandedMatrices.jl, so the public-API docstring check has nothing to find for them. api_docs_kwargs = (; ignore = (:Band, :BandError)), - # 19 method ambiguities, all in FastAlmostBandedMatrices' own ldiv!/__arguments - # against ArrayLayouts/LinearAlgebra Triangular/Factorization methods. - # https://github.com/SciML/FastAlmostBandedMatrices.jl/issues/71 - aqua_broken = (:ambiguities,), ei_kwargs = (; # Non-public names this package legitimately extends/uses from upstream: # ArrayLayouts MatLdivVec/sublayout/triangulardata/triangularlayout/_qr/_qr!/ @@ -42,9 +38,4 @@ run_qa( ), ), ), - # 31 names implicitly imported via the package's `using ArrayInterface, ArrayLayouts, - # ConcreteStructs, LazyArrays, LinearAlgebra, ...`; explicit-import conversion tracked - # separately. - # https://github.com/SciML/FastAlmostBandedMatrices.jl/issues/71 - ei_broken = (:no_implicit_imports,), )