Skip to content

Commit

Permalink
AbstractMatrix{T}(::SpecialMat{T}) should make a copy (#50495)
Browse files Browse the repository at this point in the history
Co-authored-by: Daniel Karrasch <[email protected]>
  • Loading branch information
dlfivefifty and dkarrasch authored Oct 14, 2023
1 parent 1911c00 commit b050af1
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 24 deletions.
3 changes: 2 additions & 1 deletion stdlib/LinearAlgebra/src/bidiag.jl
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,8 @@ promote_rule(::Type{<:Tridiagonal{T}}, ::Type{<:Bidiagonal{S}}) where {T,S} =
promote_rule(::Type{<:Tridiagonal}, ::Type{<:Bidiagonal}) = Tridiagonal

# 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)
AbstractMatrix{T}(A::Bidiagonal) where {T} = Bidiagonal{T}(A)
AbstractMatrix{T}(A::Bidiagonal{T}) where {T} = copy(A)

convert(::Type{T}, m::AbstractMatrix) where {T<:Bidiagonal} = m isa T ? m : T(m)::T

Expand Down
1 change: 1 addition & 0 deletions stdlib/LinearAlgebra/src/diagonal.jl
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ Diagonal{T}(D::Diagonal{T}) where {T} = D
Diagonal{T}(D::Diagonal) where {T} = Diagonal{T}(D.diag)

AbstractMatrix{T}(D::Diagonal) where {T} = Diagonal{T}(D)
AbstractMatrix{T}(D::Diagonal{T}) where {T} = copy(D)
Matrix(D::Diagonal{T}) where {T} = Matrix{promote_type(T, typeof(zero(T)))}(D)
Array(D::Diagonal{T}) where {T} = Matrix(D)
function Matrix{T}(D::Diagonal) where {T}
Expand Down
3 changes: 2 additions & 1 deletion stdlib/LinearAlgebra/src/hessenberg.jl
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ parent(H::UpperHessenberg) = H.data
similar(H::UpperHessenberg, ::Type{T}) where {T} = UpperHessenberg(similar(H.data, T))
similar(H::UpperHessenberg, ::Type{T}, dims::Dims{N}) where {T,N} = similar(H.data, T, dims)

AbstractMatrix{T}(H::UpperHessenberg) where {T} = UpperHessenberg(AbstractMatrix{T}(H.data))
AbstractMatrix{T}(H::UpperHessenberg) where {T} = UpperHessenberg{T}(H)
AbstractMatrix{T}(H::UpperHessenberg{T}) where {T} = copy(H)

copy(H::UpperHessenberg) = UpperHessenberg(copy(H.data))
real(H::UpperHessenberg{<:Real}) = H
Expand Down
2 changes: 2 additions & 0 deletions stdlib/LinearAlgebra/src/symmetric.jl
Original file line number Diff line number Diff line change
Expand Up @@ -308,9 +308,11 @@ parent(A::HermOrSym) = A.data
Symmetric{T,S}(A::Symmetric{T,S}) where {T,S<:AbstractMatrix{T}} = A
Symmetric{T,S}(A::Symmetric) where {T,S<:AbstractMatrix{T}} = Symmetric{T,S}(convert(S,A.data),A.uplo)
AbstractMatrix{T}(A::Symmetric) where {T} = Symmetric(convert(AbstractMatrix{T}, A.data), sym_uplo(A.uplo))
AbstractMatrix{T}(A::Symmetric{T}) where {T} = copy(A)
Hermitian{T,S}(A::Hermitian{T,S}) where {T,S<:AbstractMatrix{T}} = A
Hermitian{T,S}(A::Hermitian) where {T,S<:AbstractMatrix{T}} = Hermitian{T,S}(convert(S,A.data),A.uplo)
AbstractMatrix{T}(A::Hermitian) where {T} = Hermitian(convert(AbstractMatrix{T}, A.data), sym_uplo(A.uplo))
AbstractMatrix{T}(A::Hermitian{T}) where {T} = copy(A)

copy(A::Symmetric{T,S}) where {T,S} = (B = copy(A.data); Symmetric{T,typeof(B)}(B,A.uplo))
copy(A::Hermitian{T,S}) where {T,S} = (B = copy(A.data); Hermitian{T,typeof(B)}(B,A.uplo))
Expand Down
14 changes: 4 additions & 10 deletions stdlib/LinearAlgebra/src/triangular.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,14 @@ for t in (:LowerTriangular, :UnitLowerTriangular, :UpperTriangular, :UnitUpperTr
end
$t(A::$t) = A
$t{T}(A::$t{T}) where {T} = A
function $t(A::AbstractMatrix)
return $t{eltype(A), typeof(A)}(A)
end
function $t{T}(A::AbstractMatrix) where T
$t(convert(AbstractMatrix{T}, A))
end
$t(A::AbstractMatrix) = $t{eltype(A), typeof(A)}(A)
$t{T}(A::AbstractMatrix) where {T} = $t(convert(AbstractMatrix{T}, A))
$t{T}(A::$t) where {T} = $t(convert(AbstractMatrix{T}, A.data))

function $t{T}(A::$t) where T
Anew = convert(AbstractMatrix{T}, A.data)
$t(Anew)
end
Matrix(A::$t{T}) where {T} = Matrix{T}(A)

AbstractMatrix{T}(A::$t) where {T} = $t{T}(A)
AbstractMatrix{T}(A::$t{T}) where {T} = copy(A)

size(A::$t) = size(A.data)

Expand Down
37 changes: 25 additions & 12 deletions stdlib/LinearAlgebra/src/tridiag.jl
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,12 @@ julia> SymTridiagonal(B)
```
"""
function SymTridiagonal(A::AbstractMatrix)
if (diag(A, 1) == transpose.(diag(A, -1))) && all(issymmetric.(diag(A, 0)))
SymTridiagonal(diag(A, 0), diag(A, 1))
checksquare(A)
du = diag(A, 1)
d = diag(A)
dl = diag(A, -1)
if all(((x, y),) -> x == transpose(y), zip(du, dl)) && all(issymmetric, d)
SymTridiagonal(d, du)
else
throw(ArgumentError("matrix is not symmetric; cannot convert to SymTridiagonal"))
end
Expand All @@ -116,12 +120,12 @@ SymTridiagonal{T,V}(S::SymTridiagonal) where {T,V<:AbstractVector{T}} =
SymTridiagonal{T}(S::SymTridiagonal{T}) where {T} = S
SymTridiagonal{T}(S::SymTridiagonal) where {T} =
SymTridiagonal(convert(AbstractVector{T}, S.dv)::AbstractVector{T},
convert(AbstractVector{T}, S.ev)::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)::AbstractVector{T},
convert(AbstractVector{T}, S.ev)::AbstractVector{T})
AbstractMatrix{T}(S::SymTridiagonal) where {T} = SymTridiagonal{T}(S)
AbstractMatrix{T}(S::SymTridiagonal{T}) where {T} = copy(S)

function Matrix{T}(M::SymTridiagonal) where T
n = size(M, 1)
Mf = Matrix{T}(undef, n, n)
Expand Down Expand Up @@ -508,8 +512,8 @@ Tridiagonal(dl::V, d::V, du::V, du2::V) where {T,V<:AbstractVector{T}} = Tridiag
function Tridiagonal{T}(dl::AbstractVector, d::AbstractVector, du::AbstractVector) where {T}
Tridiagonal(map(x->convert(AbstractVector{T}, x), (dl, d, du))...)
end
function Tridiagonal{T,V}(A::Tridiagonal) where {T,V<:AbstractVector{T}}
Tridiagonal{T,V}(A.dl, A.d, A.du)
function Tridiagonal{T}(dl::AbstractVector, d::AbstractVector, du::AbstractVector, du2::AbstractVector) where {T}
Tridiagonal(map(x->convert(AbstractVector{T}, x), (dl, d, du, du2))...)
end

"""
Expand Down Expand Up @@ -540,12 +544,20 @@ 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))
dl, d, du = map(x -> convert(AbstractVector{T}, x)::AbstractVector{T}, (A.dl, A.d, A.du))
if isdefined(A, :du2)
Tridiagonal{T}(dl, d, du, convert(AbstractVector{T}, A.du2)::AbstractVector{T})
else
Tridiagonal{T}(dl, d, du)
end
end
Tridiagonal{T,V}(A::Tridiagonal{T,V}) where {T,V<:AbstractVector{T}} = A
function Tridiagonal{T,V}(A::Tridiagonal) where {T,V<:AbstractVector{T}}
dl, d, du = map(x -> convert(V, x)::V, (A.dl, A.d, A.du))
if isdefined(A, :du2)
Tridiagonal(dl, d, du, convert(AbstractVector{T}, A.du2)::AbstractVector{T})
Tridiagonal{T,V}(dl, d, du, convert(V, A.du2)::V)
else
Tridiagonal(dl, d, du)
Tridiagonal{T,V}(dl, d, du)
end
end

Expand Down Expand Up @@ -763,6 +775,7 @@ end
det(A::Tridiagonal) = det_usmani(A.dl, A.d, A.du)

AbstractMatrix{T}(M::Tridiagonal) where {T} = Tridiagonal{T}(M)
AbstractMatrix{T}(M::Tridiagonal{T}) where {T} = copy(M)
Tridiagonal{T}(M::SymTridiagonal{T}) where {T} = Tridiagonal(M)
function SymTridiagonal{T}(M::Tridiagonal) where T
if issymmetric(M)
Expand Down

2 comments on commit b050af1

@nanosoldier
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Executing the daily package evaluation, I will reply here when finished:

@nanosoldier runtests(isdaily = true)

@nanosoldier
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The package evaluation job you requested has completed - possible new issues were detected.
The full report is available.

Please sign in to comment.