diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1053fdc..8233e3e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,9 +20,8 @@ jobs: fail-fast: false matrix: version: - - '1.9' + - 'lts' - '1' - - '^1.11.0-0' os: - ubuntu-latest - macOS-latest diff --git a/Project.toml b/Project.toml index 6574b2e..fdd1b54 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "MatrixFactorizations" uuid = "a3b82374-2e81-5b9e-98ce-41277c0e4c87" -version = "3.0.1" +version = "3.1" [deps] ArrayLayouts = "4c555306-a7a7-4459-81d9-ec55ddd5c99a" @@ -18,7 +18,7 @@ MatrixFactorizationsBandedMatricesExt = "BandedMatrices" [compat] ArrayLayouts = "1.9.2" BandedMatrices = "1.6" -julia = "1.9" +julia = "1.10" [extras] BandedMatrices = "aae01518-5342-5314-be14-df237901396f" diff --git a/src/MatrixFactorizations.jl b/src/MatrixFactorizations.jl index 162240c..c90b621 100644 --- a/src/MatrixFactorizations.jl +++ b/src/MatrixFactorizations.jl @@ -12,13 +12,8 @@ import LinearAlgebra: cholesky, cholesky!, norm, diag, eigvals!, eigvals, eigen! checknonsingular, ipiv2perm, copytri!, issuccess, RealHermSymComplexHerm, cholcopy, checkpositivedefinite, char_uplo, copymutable_oftype -if VERSION ≥ v"1.10-" - using LinearAlgebra: TransposeFactorization, AdjointFactorization -else - const TransposeFactorization = Transpose - const AdjointFactorization = Adjoint -end +using LinearAlgebra: TransposeFactorization, AdjointFactorization import Base: getindex, setindex!, *, +, -, ==, <, <=, >, >=, /, ^, \, transpose, showerror, reindex, checkbounds, @propagate_inbounds @@ -53,6 +48,8 @@ const TransposeFact = isdefined(LinearAlgebra, :TransposeFactorization) ? Linear # objects are flexible in size when multiplied from the left, or its adjoint # from the right. abstract type LayoutQ{T} <: AbstractQ{T} end + + @_layoutlmul LayoutQ @_layoutlmul AdjointQtype{<:Any,<:LayoutQ} @_layoutrmul LayoutQ @@ -109,30 +106,6 @@ end *(A::AbstractTriangular, B::LayoutQ) = mul(A, B) *(A::AbstractTriangular, B::AdjointQtype{<:Any,<:LayoutQ}) = mul(A, B) -if VERSION < v"1.10-" - (*)(Q::LayoutQ, b::StridedVector) = _mul(Q, b) - (*)(Q::LayoutQ, B::StridedMatrix) = _mul(Q, B) - (*)(Q::LayoutQ, B::Adjoint{<:Any,<:StridedVecOrMat}) = _mul(Q, B) - (*)(A::StridedMatrix, adjQ::AdjointQtype{<:Any,<:LayoutQ}) = _mul(A, adjQ) - (*)(A::Adjoint{<:Any,<:StridedMatrix}, adjQ::AdjointQtype{<:Any,<:LayoutQ}) = _mul(A, adjQ) - - Base.@propagate_inbounds getindex(Q::LayoutQ, i::Int, j::Int) = Q[:, j][i] - function getindex(Q::LayoutQ, ::Colon, j::Int) - y = zeros(eltype(Q), size(Q, 2)) - y[j] = 1 - lmul!(Q, y) - end - Base.@propagate_inbounds layout_getindex(A::LayoutQ, I::CartesianIndex) = A[to_indices(A, (I,))...] - Base.@propagate_inbounds layout_getindex(A::LayoutQ, I::Int...) = - Base.invoke(Base.getindex, Tuple{AbstractQ, typeof.(I)...}, A, I...) - Base.@propagate_inbounds layout_getindex(A::LayoutQ, I::AbstractVector{Int}, J::AbstractVector{Int}) = - hcat((A[:, j][I] for j in J)...) - - (*)(Q::LayoutQ, adjQ::Adjoint{<:Any,<:LayoutQ}) = mul(Q, adjQ) - (*)(adjQ::Adjoint{<:Any,<:LayoutQ}, Q::LayoutQ) = mul(adjQ, Q) - (*)(adjQ::Adjoint{<:Any,<:LayoutQ}, adjP::Adjoint{<:Any,<:LayoutQ}) = mul(adjQ, adjP) -end - axes(Q::LayoutQ, dim::Integer) = axes(getfield(Q, :factors), dim == 2 ? 1 : dim) axes(Q::LayoutQ) = axes(Q, 1), axes(Q, 2) copy(Q::LayoutQ) = Q diff --git a/src/polar.jl b/src/polar.jl index 57983ef..5c10530 100644 --- a/src/polar.jl +++ b/src/polar.jl @@ -486,11 +486,6 @@ mutable struct QDWHUpdater{T} <: PolarUpdater L::T # a lower bound for the smallest singluar value of each update matrix U end - -if VERSION < v"1.7-" - ColumnNorm() = Val(true) -end - function update_U!(upd::QDWHUpdater, U::Matrix{T}) where {T} piv = upd.piv L = upd.L diff --git a/src/ql.jl b/src/ql.jl index 5764fcd..c6d0575 100644 --- a/src/ql.jl +++ b/src/ql.jl @@ -265,15 +265,7 @@ Matrix{T}(Q::QLPackedQ{S}) where {T,S} = convert(Matrix{T}, lmul!(Q, Matrix{S}(I, size(Q, 1), min(size(Q.factors)...)))) Matrix(Q::QLPackedQ{S}) where {S} = Matrix{S}(Q) -if VERSION < v"1.10-" - AbstractMatrix{T}(Q::QLPackedQ{T}) where {T} = Q - AbstractMatrix{T}(Q::QLPackedQ) where {T} = QLPackedQ{T}(Q) - convert(::Type{AbstractMatrix{T}}, Q::QLPackedQ) where {T} = QLPackedQ{T}(Q) - convert(::Type{AbstractMatrix{T}}, adjQ::Adjoint{<:Any,<:QLPackedQ}) where {T} = - (QLPackedQ{T}(parent(adjQ)))' -else - AbstractMatrix{T}(Q::QLPackedQ) where {T} = Matrix{T}(Q) -end +AbstractMatrix{T}(Q::QLPackedQ) where {T} = Matrix{T}(Q) size(Q::QLPackedQ, dim::Integer) = size(getfield(Q, :factors), dim == 2 ? 1 : dim) diff --git a/src/qr.jl b/src/qr.jl index 4e9e57f..397c9af 100644 --- a/src/qr.jl +++ b/src/qr.jl @@ -160,6 +160,9 @@ struct QRPackedQ{T,S<:AbstractMatrix{T},Tau<:AbstractVector{T}} <: LayoutQ{T} new{T,S,Tau}(factors, τ) end end + + + QRPackedQ(factors::AbstractMatrix{T}, τ::AbstractVector{T}) where {T} = QRPackedQ{T,typeof(factors),typeof(τ)}(factors, τ) function QRPackedQ{T}(factors::AbstractMatrix, τ::AbstractVector) where {T} QRPackedQ(convert(AbstractMatrix{T}, factors), convert(AbstractVector{T}, τ)) @@ -176,15 +179,7 @@ Matrix{T}(Q::QRPackedQ{S}) where {T,S} = convert(Matrix{T}, lmul!(Q, Matrix{S}(I, size(Q, 1), min(size(Q.factors)...)))) Matrix(Q::QRPackedQ{S}) where {S} = Matrix{S}(Q) -if VERSION < v"1.10-" - AbstractMatrix{T}(Q::QRPackedQ{T}) where {T} = Q - AbstractMatrix{T}(Q::QRPackedQ) where {T} = QRPackedQ{T}(Q) - convert(::Type{AbstractMatrix{T}}, Q::QRPackedQ) where {T} = QRPackedQ{T}(Q) - convert(::Type{AbstractMatrix{T}}, adjQ::Adjoint{<:Any,<:QRPackedQ}) where {T} = - (QRPackedQ{T}(parent(adjQ)))' -else - AbstractMatrix{T}(Q::QRPackedQ) where {T} = Matrix{T}(Q) -end +AbstractMatrix{T}(Q::QRPackedQ) where {T} = Matrix{T}(Q) size(F::QR, dim::Integer) = size(getfield(F, :factors), dim) size(F::QR) = size(getfield(F, :factors)) diff --git a/src/rq.jl b/src/rq.jl index 97b71a8..4499ca1 100644 --- a/src/rq.jl +++ b/src/rq.jl @@ -122,16 +122,7 @@ Matrix(Q::RQPackedQ{S}) where {S} = Matrix{S}(Q) AbstractQ{T}(Q::RQPackedQ{T}) where {T} = Q AbstractQ{T}(Q::RQPackedQ) where {T} = RQPackedQ{T}(Q) convert(::Type{AbstractQ{T}}, Q::RQPackedQ) where {T} = RQPackedQ{T}(Q) - -if VERSION < v"1.10-" - AbstractMatrix{T}(Q::RQPackedQ{T}) where {T} = Q - AbstractMatrix{T}(Q::RQPackedQ) where {T} = RQPackedQ{T}(Q) - convert(::Type{AbstractMatrix{T}}, Q::RQPackedQ) where {T} = RQPackedQ{T}(Q) - convert(::Type{AbstractMatrix{T}}, adjQ::Adjoint{<:Any,<:RQPackedQ}) where {T} = - (RQPackedQ{T}(parent(adjQ)))' -else - AbstractMatrix{T}(Q::RQPackedQ) where {T} = Matrix{T}(Q) -end +AbstractMatrix{T}(Q::RQPackedQ) where {T} = Matrix{T}(Q) Base.size(Q::RQPackedQ, dim::Integer) = size(getfield(Q, :factors), dim == 1 ? 2 : dim) Base.size(Q::RQPackedQ) = size(Q, 1), size(Q, 2) diff --git a/src/ul.jl b/src/ul.jl index f572c17..bb19af9 100644 --- a/src/ul.jl +++ b/src/ul.jl @@ -99,9 +99,7 @@ end # ul!(A.data, pivot; check = check) # end -if VERSION < v"1.7-" - _checknonsingular(info, ::Val{Pivot}) where Pivot = checknonsingular(info, Val{Pivot}()) -elseif VERSION < v"1.11-" +if VERSION < v"1.11-" _checknonsingular(info, ::Val{true}) = checknonsingular(info, RowMaximum()) _checknonsingular(info, ::Val{false}) = checknonsingular(info, NoPivot()) else diff --git a/test/test_ql.jl b/test/test_ql.jl index 67369bc..a23a027 100644 --- a/test/test_ql.jl +++ b/test/test_ql.jl @@ -95,11 +95,7 @@ using MatrixFactorizations, ArrayLayouts, Test sq = size(q.factors, 1) @test *(LowerTriangular(Matrix{eltyb}(I, sq, sq)), adjoint(q))*squareQ(q) ≈ Matrix(I, a_1, a_1) atol=5000ε if eltya != Int - if VERSION < v"1.10-" - @test Matrix{eltyb}(I, a_1, a_1)*q ≈ convert(AbstractMatrix{tab}, q) - else - @test Matrix{eltyb}(I, a_1, a_1)*q ≈ squareQ(convert(LinearAlgebra.AbstractQ{tab}, q)) - end + @test Matrix{eltyb}(I, a_1, a_1)*q ≈ squareQ(convert(LinearAlgebra.AbstractQ{tab}, q)) end end end @@ -214,4 +210,9 @@ using MatrixFactorizations, ArrayLayouts, Test @test rowsupport(Q, 4) ≡ colsupport(Q', 4) ≡ Base.OneTo(5) @test colsupport(Q, 4) ≡ rowsupport(Q', 4) ≡ 3:10 end + + @testset "AbstractMatrix conversion" begin + Q = ql(randn(5,5)).Q + @test AbstractMatrix{Float64}(Q) isa Matrix{Float64} + end end \ No newline at end of file diff --git a/test/test_qr.jl b/test/test_qr.jl index dcd59df..52ce8f2 100644 --- a/test/test_qr.jl +++ b/test/test_qr.jl @@ -61,11 +61,7 @@ rectangularQ(Q::LinearAlgebra.AbstractQ) = Matrix(Q) # convert(Array, Q) sq = size(q.factors, 2) @test *(Matrix{eltyb}(I, sq, sq), adjoint(q)) * squareQ(q) ≈ Matrix(I, sq, sq) atol=5000ε if eltya != Int - if VERSION < v"1.10-" - @test Matrix{eltyb}(I, a_1, a_1)*q ≈ convert(AbstractMatrix{tab}, q) - else - @test Matrix{eltyb}(I, a_1, a_1)*q ≈ squareQ(convert(LinearAlgebra.AbstractQ{tab}, q)) - end + @test Matrix{eltyb}(I, a_1, a_1)*q ≈ squareQ(convert(LinearAlgebra.AbstractQ{tab}, q)) ac = copy(a) @test qrunblocked!(a[:, 1:5])\b == qrunblocked!(view(ac, :, 1:5))\b end @@ -91,11 +87,7 @@ rectangularQ(Q::LinearAlgebra.AbstractQ) = Matrix(Q) # convert(Array, Q) sq = size(q.factors, 1) @test *(LowerTriangular(Matrix{eltyb}(I, sq, sq)), adjoint(q))*squareQ(q) ≈ Matrix(I, a_1, a_1) atol=5000ε if eltya != Int - if VERSION < v"1.10-" - @test Matrix{eltyb}(I, a_1, a_1)*q ≈ convert(AbstractMatrix{tab}, q) - else - @test Matrix{eltyb}(I, a_1, a_1)*q ≈ squareQ(convert(LinearAlgebra.AbstractQ{tab}, q)) - end + @test Matrix{eltyb}(I, a_1, a_1)*q ≈ squareQ(convert(LinearAlgebra.AbstractQ{tab}, q)) end end end @@ -208,4 +200,9 @@ rectangularQ(Q::LinearAlgebra.AbstractQ) = Matrix(Q) # convert(Array, Q) @test rowsupport(Q, 4) ≡ colsupport(Q', 4) ≡ 3:10 @test colsupport(Q, 4) ≡ rowsupport(Q', 4) ≡ Base.OneTo(5) end + + @testset "AbstractMatrix conversion" begin + Q = qrunblocked(randn(5,5)).Q + @test AbstractMatrix{Float64}(Q) isa Matrix{Float64} + end end diff --git a/test/test_reversecholesky.jl b/test/test_reversecholesky.jl index 82a0829..a7654d2 100644 --- a/test/test_reversecholesky.jl +++ b/test/test_reversecholesky.jl @@ -298,10 +298,7 @@ end # complex, failing D[2, 2] = 0.0 + 0im - if VERSION ≥ v"1.10" - @test_throws PosDefException reversecholesky(D) - end - + @test_throws PosDefException reversecholesky(D) # InexactError for Int @test_throws InexactError reversecholesky!(Diagonal([2, 1])) diff --git a/test/test_rq.jl b/test/test_rq.jl index 7146355..45b595b 100644 --- a/test/test_rq.jl +++ b/test/test_rq.jl @@ -105,11 +105,7 @@ const Our=MatrixFactorizations sq = size(q.factors, 2) @test *(Matrix{eltyb}(I, sq, sq), adjoint(q)) * q ≈ Matrix(I, sq, sq) atol=5000ε if eltya != Int - if VERSION < v"1.10-" - @test Matrix{eltyb}(I, a_1, a_1)*q ≈ convert(AbstractMatrix{tab}, q) - else - @test Matrix{eltyb}(I, a_1, a_1)*q ≈ squareQ(convert(LinearAlgebra.AbstractQ{tab}, q)) - end + @test Matrix{eltyb}(I, a_1, a_1)*q ≈ squareQ(convert(LinearAlgebra.AbstractQ{tab}, q)) ac = copy(a) # would need rectangular ldiv! method @test_throws DimensionMismatch rq!(a[:, 1:5])\b == rq!(view(ac, :, 1:5))\b @@ -211,4 +207,9 @@ const Our=MatrixFactorizations @test rmul!(copy(c), Q) ≈ c*Matrix(Q) @test rmul!(copy(c), Q') ≈ c*Matrix(Q') end + + @testset "AbstractMatrix conversion" begin + Q = rq(randn(5,5)).Q + @test AbstractMatrix{Float64}(Q) isa Matrix{Float64} + end end