diff --git a/stdlib/LinearAlgebra/src/bidiag.jl b/stdlib/LinearAlgebra/src/bidiag.jl index 9edea7ee06b8b..89bf143b3a973 100644 --- a/stdlib/LinearAlgebra/src/bidiag.jl +++ b/stdlib/LinearAlgebra/src/bidiag.jl @@ -5,16 +5,21 @@ struct Bidiagonal{T,V<:AbstractVector{T}} <: AbstractMatrix{T} dv::V # diagonal ev::V # sub/super diagonal uplo::Char # upper bidiagonal ('U') or lower ('L') - function Bidiagonal{T}(dv::V, ev::V, uplo::AbstractChar) where {T,V<:AbstractVector{T}} + function Bidiagonal{T,V}(dv, ev, uplo::AbstractChar) where {T,V<:AbstractVector{T}} @assert !has_offset_axes(dv, ev) if length(ev) != length(dv)-1 throw(DimensionMismatch("length of diagonal vector is $(length(dv)), length of off-diagonal vector is $(length(ev))")) end new{T,V}(dv, ev, uplo) end - function Bidiagonal(dv::V, ev::V, uplo::AbstractChar) where {T,V<:AbstractVector{T}} - Bidiagonal{T}(dv, ev, uplo) - end +end +function Bidiagonal{T,V}(dv, ev, uplo::Symbol) where {T,V<:AbstractVector{T}} + Bidiagonal{T,V}(dv, ev, char_uplo(uplo)) +end +function Bidiagonal{T}(dv::AbstractVector, ev::AbstractVector, uplo::Union{Symbol,AbstractChar}) where {T} + Bidiagonal(convert(AbstractVector{T}, dv)::AbstractVector{T}, + convert(AbstractVector{T}, ev)::AbstractVector{T}, + uplo) end """ @@ -57,7 +62,10 @@ julia> Bl = Bidiagonal(dv, ev, :L) # ev is on the first subdiagonal ``` """ function Bidiagonal(dv::V, ev::V, uplo::Symbol) where {T,V<:AbstractVector{T}} - Bidiagonal{T}(dv, ev, char_uplo(uplo)) + Bidiagonal{T,V}(dv, ev, char_uplo(uplo)) +end +function Bidiagonal(dv::V, ev::V, uplo::AbstractChar) where {T,V<:AbstractVector{T}} + Bidiagonal{T,V}(dv, ev, uplo) end """ @@ -95,6 +103,8 @@ function Bidiagonal(A::AbstractMatrix, uplo::Symbol) end Bidiagonal(A::Bidiagonal) = A +Bidiagonal{T}(A::Bidiagonal{T}) where {T} = A +Bidiagonal{T}(A::Bidiagonal) where {T} = Bidiagonal{T}(A.dv, A.ev, A.uplo) function getindex(A::Bidiagonal{T}, i::Integer, j::Integer) where T if !((1 <= i <= size(A,2)) && (1 <= j <= size(A,2))) @@ -165,11 +175,6 @@ promote_rule(::Type{<:Tridiagonal{T}}, ::Type{<:Bidiagonal{S}}) where {T,S} = @isdefined(T) && @isdefined(S) ? Tridiagonal{promote_type(T,S)} : Tridiagonal promote_rule(::Type{<:Tridiagonal}, ::Type{<:Bidiagonal}) = Tridiagonal -# No-op for trivial conversion Bidiagonal{T} -> Bidiagonal{T} -Bidiagonal{T}(A::Bidiagonal{T}) where {T} = A -# Convert Bidiagonal to Bidiagonal{T} by constructing a new instance with converted elements -Bidiagonal{T}(A::Bidiagonal) where {T} = - Bidiagonal(convert(AbstractVector{T}, A.dv), convert(AbstractVector{T}, A.ev), A.uplo) # When asked to convert Bidiagonal to AbstractMatrix{T}, preserve structure by converting to Bidiagonal{T} <: AbstractMatrix{T} AbstractMatrix{T}(A::Bidiagonal) where {T} = convert(Bidiagonal{T}, A) diff --git a/stdlib/LinearAlgebra/src/deprecated.jl b/stdlib/LinearAlgebra/src/deprecated.jl index 9afa1f21b388a..21602582d1d48 100644 --- a/stdlib/LinearAlgebra/src/deprecated.jl +++ b/stdlib/LinearAlgebra/src/deprecated.jl @@ -64,7 +64,8 @@ export lufact! # also uncomment constructor tests in test/linalg/bidiag.jl function Bidiagonal(dv::AbstractVector{T}, ev::AbstractVector{S}, uplo::Symbol) where {T,S} depwarn(string("`Bidiagonal(dv::AbstractVector{T}, ev::AbstractVector{S}, uplo::Symbol) where {T, S}`", - " is deprecated, manually convert both vectors to the same type instead."), :Bidiagonal) + " is deprecated, use `Bidiagonal{R}(dv, ev, uplo)` or `Bidiagonal{R,V}(dv, ev, uplo)` instead,", + " or convert both vectors to the same type manually."), :Bidiagonal) R = promote_type(T, S) Bidiagonal(convert(Vector{R}, dv), convert(Vector{R}, ev), uplo) end @@ -73,7 +74,8 @@ end # also uncomment constructor tests in test/linalg/tridiag.jl function SymTridiagonal(dv::AbstractVector{T}, ev::AbstractVector{S}) where {T,S} depwarn(string("`SymTridiagonal(dv::AbstractVector{T}, ev::AbstractVector{S}) ", - "where {T, S}` is deprecated, convert both vectors to the same type instead."), :SymTridiagonal) + "where {T, S}` is deprecated, use `SymTridiagonal{R}(dv, ev)` or `SymTridiagonal{R,V}(dv, ev)` instead,", + " or convert both vectors to the same type manually."), :SymTridiagonal) R = promote_type(T, S) SymTridiagonal(convert(Vector{R}, dv), convert(Vector{R}, ev)) end @@ -82,7 +84,8 @@ end # also uncomment constructor tests in test/linalg/tridiag.jl function Tridiagonal(dl::AbstractVector{Tl}, d::AbstractVector{Td}, du::AbstractVector{Tu}) where {Tl,Td,Tu} depwarn(string("`Tridiagonal(dl::AbstractVector{Tl}, d::AbstractVector{Td}, du::AbstractVector{Tu}) ", - "where {Tl, Td, Tu}` is deprecated, convert all vectors to the same type instead."), :Tridiagonal) + "where {Tl, Td, Tu}` is deprecated, use `Tridiagonal{T}(dl, d, du)` or `Tridiagonal{T,V}(dl, d, du)` instead,", + " or convert all three vectors to the same type manually."), :Tridiagonal) Tridiagonal(map(v->convert(Vector{promote_type(Tl,Td,Tu)}, v), (dl, d, du))...) end diff --git a/stdlib/LinearAlgebra/src/diagonal.jl b/stdlib/LinearAlgebra/src/diagonal.jl index 995620c97a876..a664dfd046c6a 100644 --- a/stdlib/LinearAlgebra/src/diagonal.jl +++ b/stdlib/LinearAlgebra/src/diagonal.jl @@ -4,7 +4,15 @@ struct Diagonal{T,V<:AbstractVector{T}} <: AbstractMatrix{T} diag::V + + function Diagonal{T,V}(diag) where {T,V<:AbstractVector{T}} + @assert !has_offset_axes(diag) + new{T,V}(diag) + end end +Diagonal(v::AbstractVector{T}) where {T} = Diagonal{T,typeof(v)}(v) +Diagonal{T}(v::AbstractVector) where {T} = Diagonal(convert(AbstractVector{T}, v)::AbstractVector{T}) + """ Diagonal(A::AbstractMatrix) @@ -47,11 +55,10 @@ julia> Diagonal(V) """ Diagonal(V::AbstractVector) -Diagonal{T}(V::AbstractVector{T}) where {T} = Diagonal{T,typeof(V)}(V) -Diagonal{T}(V::AbstractVector) where {T} = Diagonal{T}(convert(AbstractVector{T}, V)) - +Diagonal(D::Diagonal) = D Diagonal{T}(D::Diagonal{T}) where {T} = D -Diagonal{T}(D::Diagonal) where {T} = Diagonal{T}(convert(AbstractVector{T}, D.diag)) +Diagonal{T}(D::Diagonal) where {T} = Diagonal{T}(D.diag) + AbstractMatrix{T}(D::Diagonal) where {T} = Diagonal{T}(D) Matrix(D::Diagonal) = diagm(0 => D.diag) Array(D::Diagonal) = Matrix(D) diff --git a/stdlib/LinearAlgebra/src/hessenberg.jl b/stdlib/LinearAlgebra/src/hessenberg.jl index 050462c19d55f..8502ef896a68b 100644 --- a/stdlib/LinearAlgebra/src/hessenberg.jl +++ b/stdlib/LinearAlgebra/src/hessenberg.jl @@ -1,12 +1,19 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -struct Hessenberg{T,S<:AbstractMatrix} <: Factorization{T} +struct Hessenberg{T,S<:AbstractMatrix{T}} <: Factorization{T} factors::S τ::Vector{T} - Hessenberg{T,S}(factors::AbstractMatrix{T}, τ::Vector{T}) where {T,S<:AbstractMatrix} = - new(factors, τ) + + function Hessenberg{T,S}(factors, τ) where {T,S<:AbstractMatrix{T}} + @assert !has_offset_axes(factors, τ) + new{T,S}(factors, τ) + end end Hessenberg(factors::AbstractMatrix{T}, τ::Vector{T}) where {T} = Hessenberg{T,typeof(factors)}(factors, τ) +function Hessenberg{T}(factors::AbstractMatrix, τ::AbstractVector) where {T} + Hessenberg(convert(AbstractMatrix{T}, factors), convert(Vector{T}, v)) +end + Hessenberg(A::StridedMatrix) = Hessenberg(LAPACK.gehrd!(A)...) # iteration for destructuring into components @@ -63,7 +70,10 @@ hessenberg(A::StridedMatrix{T}) where T = struct HessenbergQ{T,S<:AbstractMatrix} <: AbstractMatrix{T} factors::S τ::Vector{T} - HessenbergQ{T,S}(factors::AbstractMatrix{T}, τ::Vector{T}) where {T,S<:AbstractMatrix} = new(factors, τ) + function HessenbergQ{T,S}(factors, τ) where {T,S<:AbstractMatrix} + @assert !has_offset_axes(factors) + new(factors, τ) + end end HessenbergQ(factors::AbstractMatrix{T}, τ::Vector{T}) where {T} = HessenbergQ{T,typeof(factors)}(factors, τ) HessenbergQ(A::Hessenberg) = HessenbergQ(A.factors, A.τ) diff --git a/stdlib/LinearAlgebra/src/ldlt.jl b/stdlib/LinearAlgebra/src/ldlt.jl index 4474dc1c9eeb5..61c282bf524e3 100644 --- a/stdlib/LinearAlgebra/src/ldlt.jl +++ b/stdlib/LinearAlgebra/src/ldlt.jl @@ -1,19 +1,26 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -struct LDLt{T,S<:AbstractMatrix} <: Factorization{T} +struct LDLt{T,S<:AbstractMatrix{T}} <: Factorization{T} data::S + + function LDLt{T,S}(data) where {T,S<:AbstractMatrix{T}} + @assert !has_offset_axes(data) + new{T,S}(data) + end end +LDLt(data::AbstractMatrix{T}) where {T} = LDLt{T,typeof(data)}(data) +LDLt{T}(data::AbstractMatrix) where {T} = LDLt(convert(AbstractMatrix{T}, data)::AbstractMatrix{T}) size(S::LDLt) = size(S.data) size(S::LDLt, i::Integer) = size(S.data, i) -LDLt{T,S}(F::LDLt) where {T,S<:AbstractMatrix} = LDLt{T,S}(convert(S, F.data)) -# NOTE: the annotation <:AbstractMatrix shouldn't be necessary, it is introduced -# to avoid an ambiguity warning (see issue #6383) -LDLt{T}(F::LDLt{S,U}) where {T,S,U<:AbstractMatrix} = LDLt{T,U}(F) +LDLt{T,S}(F::LDLt{T,S}) where {T,S<:AbstractMatrix{T}} = F +LDLt{T,S}(F::LDLt) where {T,S<:AbstractMatrix{T}} = LDLt{T,S}(convert(S, F.data)::S) +LDLt{T}(F::LDLt{T}) where {T} = F +LDLt{T}(F::LDLt) where {T} = LDLt(convert(AbstractMatrix{T}, F.data)::AbstractMatrix{T}) Factorization{T}(F::LDLt{T}) where {T} = F -Factorization{T}(F::LDLt{S,U}) where {T,S,U} = LDLt{T,U}(F) +Factorization{T}(F::LDLt) where {T} = LDLt{T}(F) # SymTridiagonal """ diff --git a/stdlib/LinearAlgebra/src/lq.jl b/stdlib/LinearAlgebra/src/lq.jl index 33c20d7f9320f..1cc1b746e349f 100644 --- a/stdlib/LinearAlgebra/src/lq.jl +++ b/stdlib/LinearAlgebra/src/lq.jl @@ -2,12 +2,19 @@ # LQ Factorizations -struct LQ{T,S<:AbstractMatrix} <: Factorization{T} +struct LQ{T,S<:AbstractMatrix{T}} <: Factorization{T} factors::S τ::Vector{T} - LQ{T,S}(factors::AbstractMatrix{T}, τ::Vector{T}) where {T,S<:AbstractMatrix} = new(factors, τ) + + function LQ{T,S}(factors, τ) where {T,S<:AbstractMatrix{T}} + @assert !has_offset_axes(factors) + new{T,S}(factors, τ) + end end LQ(factors::AbstractMatrix{T}, τ::Vector{T}) where {T} = LQ{T,typeof(factors)}(factors, τ) +function LQ{T}(factors::AbstractMatrix, τ::AbstractVector) where {T} + LQ(convert(AbstractMatrix{T}, factors), convert(Vector{T}, τ)) +end # iteration for destructuring into components Base.iterate(S::LQ) = (S.L, Val(:Q)) diff --git a/stdlib/LinearAlgebra/src/lu.jl b/stdlib/LinearAlgebra/src/lu.jl index df57bfb7c62db..68c085a68b47a 100644 --- a/stdlib/LinearAlgebra/src/lu.jl +++ b/stdlib/LinearAlgebra/src/lu.jl @@ -3,13 +3,24 @@ #################### # LU Factorization # #################### -struct LU{T,S<:AbstractMatrix} <: Factorization{T} +struct LU{T,S<:AbstractMatrix{T}} <: Factorization{T} factors::S ipiv::Vector{BlasInt} info::BlasInt - LU{T,S}(factors::AbstractMatrix{T}, ipiv::Vector{BlasInt}, info::BlasInt) where {T,S} = new(factors, ipiv, info) + + function LU{T,S}(factors, ipiv, info) where {T,S<:AbstractMatrix{T}} + @assert !has_offset_axes(factors) + new{T,S}(factors, ipiv, info) + end +end +function LU(factors::AbstractMatrix{T}, ipiv::Vector{BlasInt}, info::BlasInt) where {T} + LU{T,typeof(factors)}(factors, ipiv, info) +end +function LU{T}(factors::AbstractMatrix, ipiv::AbstractVector{<:Integer}, info::Integer) where {T} + LU(convert(AbstractMatrix{T}, factors), + convert(Vector{BlasInt}, ipiv), + BlasInt(info)) end -LU(factors::AbstractMatrix{T}, ipiv::Vector{BlasInt}, info::BlasInt) where {T} = LU{T,typeof(factors)}(factors, ipiv, info) # iteration for destructuring into components Base.iterate(S::LU) = (S.L, Val(:U)) diff --git a/stdlib/LinearAlgebra/src/qr.jl b/stdlib/LinearAlgebra/src/qr.jl index f53bf6b0a71e7..9f32d7c8d530e 100644 --- a/stdlib/LinearAlgebra/src/qr.jl +++ b/stdlib/LinearAlgebra/src/qr.jl @@ -34,12 +34,19 @@ The object has two fields: * `τ` is a vector of length `min(m,n)` containing the coefficients ``\tau_i``. """ -struct QR{T,S<:AbstractMatrix} <: Factorization{T} +struct QR{T,S<:AbstractMatrix{T}} <: Factorization{T} factors::S τ::Vector{T} - QR{T,S}(factors::AbstractMatrix{T}, τ::Vector{T}) where {T,S<:AbstractMatrix} = new(factors, τ) + + function QR{T,S}(factors, τ) where {T,S<:AbstractMatrix{T}} + @assert !has_offset_axes(factors) + new{T,S}(factors, τ) + end end QR(factors::AbstractMatrix{T}, τ::Vector{T}) where {T} = QR{T,typeof(factors)}(factors, τ) +function QR{T}(factors::AbstractMatrix, τ::AbstractVector) where {T} + QR(convert(AbstractMatrix{T}, factors), convert(Vector{T}, τ)) +end # iteration for destructuring into components Base.iterate(S::QR) = (S.Q, Val(:R)) @@ -94,12 +101,19 @@ The object has two fields: [^Schreiber1989]: R Schreiber and C Van Loan, "A storage-efficient WY representation for products of Householder transformations", SIAM J Sci Stat Comput 10 (1989), 53-57. [doi:10.1137/0910005](https://doi.org/10.1137/0910005) """ -struct QRCompactWY{S,M<:AbstractMatrix} <: Factorization{S} +struct QRCompactWY{S,M<:AbstractMatrix{S}} <: Factorization{S} factors::M T::Matrix{S} - QRCompactWY{S,M}(factors::AbstractMatrix{S}, T::AbstractMatrix{S}) where {S,M<:AbstractMatrix} = new(factors, T) + + function QRCompactWY{S,M}(factors, T) where {S,M<:AbstractMatrix{S}} + @assert !has_offset_axes(factors) + new{S,M}(factors, T) + end +end +QRCompactWY(factors::AbstractMatrix{S}, T::Matrix{S}) where {S} = QRCompactWY{S,typeof(factors)}(factors, T) +function QRCompactWY{S}(factors::AbstractMatrix, T::AbstractMatrix) where {S} + QRCompactWY(convert(AbstractMatrix{S}, factors), convert(Matrix{S}, T)) end -QRCompactWY(factors::AbstractMatrix{S}, T::AbstractMatrix{S}) where {S} = QRCompactWY{S,typeof(factors)}(factors, T) # iteration for destructuring into components Base.iterate(S::QRCompactWY) = (S.Q, Val(:R)) @@ -139,15 +153,23 @@ The object has three fields: * `jpvt` is an integer vector of length `n` corresponding to the permutation ``P``. """ -struct QRPivoted{T,S<:AbstractMatrix} <: Factorization{T} +struct QRPivoted{T,S<:AbstractMatrix{T}} <: Factorization{T} factors::S τ::Vector{T} jpvt::Vector{BlasInt} - QRPivoted{T,S}(factors::AbstractMatrix{T}, τ::Vector{T}, jpvt::Vector{BlasInt}) where {T,S<:AbstractMatrix} = - new(factors, τ, jpvt) + + function QRPivoted{T,S}(factors, τ, jpvt) where {T,S<:AbstractMatrix{T}} + @assert !has_offset_axes(factors, τ, jpvt) + new{T,S}(factors, τ, jpvt) + end end QRPivoted(factors::AbstractMatrix{T}, τ::Vector{T}, jpvt::Vector{BlasInt}) where {T} = QRPivoted{T,typeof(factors)}(factors, τ, jpvt) +function QRPivoted{T}(factors::AbstractMatrix, τ::AbstractVector, jpvt::AbstractVector) where {T} + QRPivoted(convert(AbstractMatrix{T}, factors), + convert(Vector{T}, τ), + convert(Vector{BlasInt}, jpvt)) +end # iteration for destructuring into components Base.iterate(S::QRPivoted) = (S.Q, Val(:R)) @@ -435,12 +457,19 @@ abstract type AbstractQ{T} <: AbstractMatrix{T} end The orthogonal/unitary ``Q`` matrix of a QR factorization stored in [`QR`](@ref) or [`QRPivoted`](@ref) format. """ -struct QRPackedQ{T,S<:AbstractMatrix} <: AbstractQ{T} +struct QRPackedQ{T,S<:AbstractMatrix{T}} <: AbstractQ{T} factors::S τ::Vector{T} - QRPackedQ{T,S}(factors::AbstractMatrix{T}, τ::Vector{T}) where {T,S<:AbstractMatrix} = new(factors, τ) + + function QRPackedQ{T,S}(factors, τ) where {T,S<:AbstractMatrix{T}} + @assert !has_offset_axes(factors) + new{T,S}(factors, τ) + end end QRPackedQ(factors::AbstractMatrix{T}, τ::Vector{T}) where {T} = QRPackedQ{T,typeof(factors)}(factors, τ) +function QRPackedQ{T}(factors::AbstractMatrix, τ::AbstractVector) where {T} + QRPackedQ(convert(AbstractMatrix{T}, factors), convert(Vector{T}, τ)) +end """ QRCompactWYQ <: AbstractMatrix @@ -448,12 +477,19 @@ QRPackedQ(factors::AbstractMatrix{T}, τ::Vector{T}) where {T} = QRPackedQ{T,typ The orthogonal/unitary ``Q`` matrix of a QR factorization stored in [`QRCompactWY`](@ref) format. """ -struct QRCompactWYQ{S, M<:AbstractMatrix} <: AbstractQ{S} +struct QRCompactWYQ{S, M<:AbstractMatrix{S}} <: AbstractQ{S} factors::M T::Matrix{S} - QRCompactWYQ{S,M}(factors::AbstractMatrix{S}, T::Matrix{S}) where {S,M<:AbstractMatrix} = new(factors, T) + + function QRCompactWYQ{S,M}(factors, T) where {S,M<:AbstractMatrix{S}} + @assert !has_offset_axes(factors) + new{S,M}(factors, T) + end end QRCompactWYQ(factors::AbstractMatrix{S}, T::Matrix{S}) where {S} = QRCompactWYQ{S,typeof(factors)}(factors, T) +function QRCompactWYQ{S}(factors::AbstractMatrix, T::AbstractMatrix) where {S} + QRCompactWYQ(convert(AbstractMatrix{S}, factors), convert(Matrix{S}, T)) +end QRPackedQ{T}(Q::QRPackedQ) where {T} = QRPackedQ(convert(AbstractMatrix{T}, Q.factors), convert(Vector{T}, Q.τ)) AbstractMatrix{T}(Q::QRPackedQ{T}) where {T} = Q diff --git a/stdlib/LinearAlgebra/src/svd.jl b/stdlib/LinearAlgebra/src/svd.jl index e47e3a47ad13b..b41c2ab9e4aee 100644 --- a/stdlib/LinearAlgebra/src/svd.jl +++ b/stdlib/LinearAlgebra/src/svd.jl @@ -1,14 +1,21 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license # Singular Value Decomposition -struct SVD{T,Tr,M<:AbstractArray} <: Factorization{T} +struct SVD{T,Tr,M<:AbstractArray{T}} <: Factorization{T} U::M S::Vector{Tr} Vt::M - SVD{T,Tr,M}(U::AbstractArray{T}, S::Vector{Tr}, Vt::AbstractArray{T}) where {T,Tr,M} = - new(U, S, Vt) + function SVD{T,Tr,M}(U, S, Vt) where {T,Tr,M<:AbstractArray{T}} + @assert !has_offset_axes(U, S, Vt) + new{T,Tr,M}(U, S, Vt) + end end SVD(U::AbstractArray{T}, S::Vector{Tr}, Vt::AbstractArray{T}) where {T,Tr} = SVD{T,Tr,typeof(U)}(U, S, Vt) +function SVD{T}(U::AbstractArray, S::AbstractVector{Tr}, Vt::AbstractArray) where {T,Tr} + SVD(convert(AbstractArray{T}, U), + convert(Vector{Tr}, S), + convert(AbstractArray{T}, Vt)) +end # iteration for destructuring into components Base.iterate(S::SVD) = (S.U, Val(:S)) diff --git a/stdlib/LinearAlgebra/src/symmetric.jl b/stdlib/LinearAlgebra/src/symmetric.jl index 0c2d413c7f3ef..49c6bd26d9bbe 100644 --- a/stdlib/LinearAlgebra/src/symmetric.jl +++ b/stdlib/LinearAlgebra/src/symmetric.jl @@ -4,6 +4,11 @@ struct Symmetric{T,S<:AbstractMatrix{<:T}} <: AbstractMatrix{T} data::S uplo::Char + + function Symmetric{T,S}(data, uplo) where {T,S<:AbstractMatrix{<:T}} + @assert !has_offset_axes(data) + new{T,S}(data, uplo) + end end """ Symmetric(A, uplo=:U) @@ -74,6 +79,11 @@ symmetric_type(::Type{T}) where {T<:Number} = T struct Hermitian{T,S<:AbstractMatrix{<:T}} <: AbstractMatrix{T} data::S uplo::Char + + function Hermitian{T,S}(data, uplo) where {T,S<:AbstractMatrix{<:T}} + @assert !has_offset_axes(data) + new{T,S}(data, uplo) + end end """ Hermitian(A, uplo=:U) diff --git a/stdlib/LinearAlgebra/src/triangular.jl b/stdlib/LinearAlgebra/src/triangular.jl index bbcc4b6d08efc..1f2485f2676f6 100644 --- a/stdlib/LinearAlgebra/src/triangular.jl +++ b/stdlib/LinearAlgebra/src/triangular.jl @@ -9,15 +9,23 @@ abstract type AbstractTriangular{T,S<:AbstractMatrix} <: AbstractMatrix{T} end for t in (:LowerTriangular, :UnitLowerTriangular, :UpperTriangular, :UnitUpperTriangular) @eval begin - struct $t{T,S<:AbstractMatrix} <: AbstractTriangular{T,S} + struct $t{T,S<:AbstractMatrix{T}} <: AbstractTriangular{T,S} data::S + + function $t{T,S}(data) where {T,S<:AbstractMatrix{T}} + @assert !has_offset_axes(data) + checksquare(data) + new{T,S}(data) + end end $t(A::$t) = A $t{T}(A::$t{T}) where {T} = A function $t(A::AbstractMatrix) - checksquare(A) return $t{eltype(A), typeof(A)}(A) end + function $t{T}(A::AbstractMatrix) where T + $t(convert(AbstractMatrix{T}, A)) + end function $t{T}(A::$t) where T Anew = convert(AbstractMatrix{T}, A.data) diff --git a/stdlib/LinearAlgebra/src/tridiag.jl b/stdlib/LinearAlgebra/src/tridiag.jl index 019eb9a172712..bd8e7cba3d5ef 100644 --- a/stdlib/LinearAlgebra/src/tridiag.jl +++ b/stdlib/LinearAlgebra/src/tridiag.jl @@ -6,7 +6,8 @@ struct SymTridiagonal{T,V<:AbstractVector{T}} <: AbstractMatrix{T} dv::V # diagonal ev::V # subdiagonal - function SymTridiagonal{T}(dv::V, ev::V) where {T,V<:AbstractVector{T}} + function SymTridiagonal{T,V}(dv, ev) where {T,V<:AbstractVector{T}} + @assert !has_offset_axes(dv, ev) if !(length(dv) - 1 <= length(ev) <= length(dv)) throw(DimensionMismatch("subdiagonal has wrong length. Has length $(length(ev)), but should be either $(length(dv) - 1) or $(length(dv)).")) end @@ -46,6 +47,11 @@ julia> SymTridiagonal(dv, ev) ``` """ SymTridiagonal(dv::V, ev::V) where {T,V<:AbstractVector{T}} = SymTridiagonal{T}(dv, ev) +SymTridiagonal{T}(dv::V, ev::V) where {T,V<:AbstractVector{T}} = SymTridiagonal{T,V}(dv, ev) +function SymTridiagonal{T}(dv::AbstractVector, ev::AbstractVector) where {T} + SymTridiagonal(convert(AbstractVector{T}, dv)::AbstractVector{T}, + convert(AbstractVector{T}, ev)::AbstractVector{T}) +end """ SymTridiagonal(A::AbstractMatrix) @@ -76,10 +82,18 @@ function SymTridiagonal(A::AbstractMatrix) end end +SymTridiagonal{T,V}(S::SymTridiagonal{T,V}) where {T,V<:AbstractVector{T}} = S +SymTridiagonal{T,V}(S::SymTridiagonal) where {T,V<:AbstractVector{T}} = + SymTridiagonal(convert(V, S.dv)::V, convert(V, S.ev)::V) +SymTridiagonal{T}(S::SymTridiagonal{T}) where {T} = S SymTridiagonal{T}(S::SymTridiagonal) where {T} = - SymTridiagonal(convert(AbstractVector{T}, S.dv), convert(AbstractVector{T}, S.ev)) + SymTridiagonal(convert(AbstractVector{T}, S.dv)::AbstractVector{T}, + convert(AbstractVector{T}, S.ev)::AbstractVector{T}) +SymTridiagonal(S::SymTridiagonal) = S + AbstractMatrix{T}(S::SymTridiagonal) where {T} = - SymTridiagonal(convert(AbstractVector{T}, S.dv), convert(AbstractVector{T}, S.ev)) + SymTridiagonal(convert(AbstractVector{T}, S.dv)::AbstractVector{T}, + convert(AbstractVector{T}, S.ev)::AbstractVector{T}) function Matrix{T}(M::SymTridiagonal) where T n = size(M, 1) Mf = zeros(T, n, n) @@ -392,7 +406,7 @@ struct Tridiagonal{T,V<:AbstractVector{T}} <: AbstractMatrix{T} d::V # diagonal du::V # sup-diagonal du2::V # supsup-diagonal for pivoting in LU - function Tridiagonal{T}(dl::V, d::V, du::V) where {T,V<:AbstractVector{T}} + function Tridiagonal{T,V}(dl, d, du) where {T,V<:AbstractVector{T}} @assert !has_offset_axes(dl, d, du) n = length(d) if (length(dl) != n-1 || length(du) != n-1) @@ -403,7 +417,7 @@ struct Tridiagonal{T,V<:AbstractVector{T}} <: AbstractMatrix{T} new{T,V}(dl, d, du) end # constructor used in lu! - function Tridiagonal{T,V}(dl::V, d::V, du::V, du2::V) where {T,V<:AbstractVector{T}} + function Tridiagonal{T,V}(dl, d, du, du2) where {T,V<:AbstractVector{T}} @assert !has_offset_axes(dl, d, du, du2) # length checks? new{T,V}(dl, d, du, du2) @@ -435,7 +449,11 @@ julia> Tridiagonal(dl, d, du) ⋅ ⋅ 3 0 ``` """ -Tridiagonal(dl::V, d::V, du::V) where {T,V<:AbstractVector{T}} = Tridiagonal{T}(dl, d, du) +Tridiagonal(dl::V, d::V, du::V) where {T,V<:AbstractVector{T}} = Tridiagonal{T,V}(dl, d, du) +Tridiagonal(dl::V, d::V, du::V, du2::V) where {T,V<:AbstractVector{T}} = Tridiagonal{T,V}(dl, d, du, du2) +function Tridiagonal{T}(dl::AbstractVector, d::AbstractVector, du::AbstractVector) where {T} + Tridiagonal(map(x->convert(AbstractVector{T}, x), (dl, d, du))...) +end """ Tridiagonal(A) @@ -462,6 +480,18 @@ julia> Tridiagonal(A) """ Tridiagonal(A::AbstractMatrix) = Tridiagonal(diag(A,-1), diag(A,0), diag(A,1)) +Tridiagonal(A::Tridiagonal) = A +Tridiagonal{T}(A::Tridiagonal{T}) where {T} = A +function Tridiagonal{T}(A::Tridiagonal) where {T} + dl, d, du = map(x->convert(AbstractVector{T}, x)::AbstractVector{T}, + (A.dl, A.d, A.du)) + if isdefined(A, :du2) + Tridiagonal(dl, d, du, convert(AbstractVector{T}, A.du2)::AbstractVector{T}) + else + Tridiagonal(dl, d, du) + end +end + size(M::Tridiagonal) = (length(M.d), length(M.d)) function size(M::Tridiagonal, d::Integer) if d < 1 @@ -624,8 +654,6 @@ end inv(A::Tridiagonal) = inv_usmani(A.dl, A.d, A.du) det(A::Tridiagonal) = det_usmani(A.dl, A.d, A.du) -Tridiagonal{T}(M::Tridiagonal) where {T} = - Tridiagonal(convert(AbstractVector{T}, M.dl), convert(AbstractVector{T}, M.d), convert(AbstractVector{T}, M.du)) AbstractMatrix{T}(M::Tridiagonal) where {T} = Tridiagonal{T}(M) Tridiagonal{T}(M::SymTridiagonal{T}) where {T} = Tridiagonal(M) function SymTridiagonal{T}(M::Tridiagonal) where T diff --git a/stdlib/LinearAlgebra/test/bidiag.jl b/stdlib/LinearAlgebra/test/bidiag.jl index 9641b0eb61640..f90a13caddaa3 100644 --- a/stdlib/LinearAlgebra/test/bidiag.jl +++ b/stdlib/LinearAlgebra/test/bidiag.jl @@ -42,9 +42,14 @@ srand(1) @test Bidiagonal(ubd, :U) == Bidiagonal(Matrix(ubd), :U) == ubd @test Bidiagonal(lbd, :L) == Bidiagonal(Matrix(lbd), :L) == lbd end + @test eltype(Bidiagonal{elty}([1,2,3,4], [1.0f0,2.0f0,3.0f0], :U)) == elty + @test isa(Bidiagonal{elty,Vector{elty}}(GenericArray(dv), ev, :U), Bidiagonal{elty,Vector{elty}}) # enable when deprecations for 0.7 are dropped # @test_throws MethodError Bidiagonal(dv, GenericArray(ev), :U) # @test_throws MethodError Bidiagonal(GenericArray(dv), ev, :U) + BI = Bidiagonal([1,2,3,4], [1,2,3], :U) + @test Bidiagonal(BI) === BI + @test isa(Bidiagonal{elty}(BI), Bidiagonal{elty}) end @testset "getindex, setindex!, size, and similar" begin diff --git a/stdlib/LinearAlgebra/test/diagonal.jl b/stdlib/LinearAlgebra/test/diagonal.jl index 202cee62a62f6..344b9a37af733 100644 --- a/stdlib/LinearAlgebra/test/diagonal.jl +++ b/stdlib/LinearAlgebra/test/diagonal.jl @@ -27,6 +27,11 @@ srand(1) @test Diagonal{elty}(x)::Diagonal{elty,typeof(x)} == DM @test Diagonal{elty}(x).diag === x end + @test eltype(Diagonal{elty}([1,2,3,4])) == elty + @test isa(Diagonal{elty,Vector{elty}}(GenericArray([1,2,3,4])), Diagonal{elty,Vector{elty}}) + DI = Diagonal([1,2,3,4]) + @test Diagonal(DI) === DI + @test isa(Diagonal{elty}(DI), Diagonal{elty}) # issue #26178 @test_throws MethodError convert(Diagonal, [1, 2, 3, 4]) end diff --git a/stdlib/LinearAlgebra/test/tridiag.jl b/stdlib/LinearAlgebra/test/tridiag.jl index 0573db496d2de..29e5942ea248f 100644 --- a/stdlib/LinearAlgebra/test/tridiag.jl +++ b/stdlib/LinearAlgebra/test/tridiag.jl @@ -72,11 +72,32 @@ end @test TT.d === x @test TT.du === y end + ST = SymTridiagonal{elty}([1,2,3,4], [1,2,3]) + @test eltype(ST) == elty + TT = Tridiagonal{elty}([1,2,3], [1,2,3,4], [1,2,3]) + @test eltype(TT) == elty + ST = SymTridiagonal{elty,Vector{elty}}(d, GenericArray(dl)) + @test isa(ST, SymTridiagonal{elty,Vector{elty}}) + TT = Tridiagonal{elty,Vector{elty}}(GenericArray(dl), d, GenericArray(dl)) + @test isa(TT, Tridiagonal{elty,Vector{elty}}) # enable when deprecations for 0.7 are dropped # @test_throws MethodError SymTridiagonal(dv, GenericArray(ev)) # @test_throws MethodError SymTridiagonal(GenericArray(dv), ev) # @test_throws MethodError Tridiagonal(GenericArray(ev), dv, GenericArray(ev)) # @test_throws MethodError Tridiagonal(ev, GenericArray(dv), ev) + # @test_throws MethodError SymTridiagonal{elty}(dv, GenericArray(ev)) + # @test_throws MethodError Tridiagonal{elty}(GenericArray(ev), dv, GenericArray(ev)) + STI = SymTridiagonal([1,2,3,4], [1,2,3]) + TTI = Tridiagonal([1,2,3], [1,2,3,4], [1,2,3]) + TTI2 = Tridiagonal([1,2,3], [1,2,3,4], [1,2,3], [1,2]) + @test SymTridiagonal(STI) === STI + @test Tridiagonal(TTI) === TTI + @test Tridiagonal(TTI2) === TTI2 + @test isa(SymTridiagonal{elty}(STI), SymTridiagonal{elty}) + @test isa(Tridiagonal{elty}(TTI), Tridiagonal{elty}) + TTI2y = Tridiagonal{elty}(TTI2) + @test isa(TTI2y, Tridiagonal{elty}) + @test TTI2y.du2 == convert(Vector{elty}, [1,2]) end @testset "interconversion of Tridiagonal and SymTridiagonal" begin @test Tridiagonal(dl, d, dl) == SymTridiagonal(d, dl) @@ -291,8 +312,12 @@ end @test_throws DimensionMismatch Tldlt\rand(elty,n+1) @test size(Tldlt) == size(Ts) if elty <: AbstractFloat + @test LinearAlgebra.LDLt{elty,SymTridiagonal{elty,Vector{elty}}}(Tldlt) === Tldlt + @test LinearAlgebra.LDLt{elty}(Tldlt) === Tldlt + @test typeof(convert(LinearAlgebra.LDLt{Float32,Matrix{Float32}},Tldlt)) == + LinearAlgebra.LDLt{Float32,Matrix{Float32}} @test typeof(convert(LinearAlgebra.LDLt{Float32},Tldlt)) == - LinearAlgebra.LDLt{Float32,SymTridiagonal{elty,Vector{elty}}} + LinearAlgebra.LDLt{Float32,SymTridiagonal{Float32,Vector{Float32}}} end for vv in (copy(v), view(v, 1:n)) invFsv = Fs\vv