Skip to content

Commit 3cfda5a

Browse files
AbstractMatrix{T}(::SpecialMat{T}) should make a copy (#50495)
Co-authored-by: Daniel Karrasch <[email protected]>
1 parent ea5f6bb commit 3cfda5a

File tree

6 files changed

+36
-24
lines changed

6 files changed

+36
-24
lines changed

src/bidiag.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,8 @@ promote_rule(::Type{<:Tridiagonal{T}}, ::Type{<:Bidiagonal{S}}) where {T,S} =
228228
promote_rule(::Type{<:Tridiagonal}, ::Type{<:Bidiagonal}) = Tridiagonal
229229

230230
# When asked to convert Bidiagonal to AbstractMatrix{T}, preserve structure by converting to Bidiagonal{T} <: AbstractMatrix{T}
231-
AbstractMatrix{T}(A::Bidiagonal) where {T} = convert(Bidiagonal{T}, A)
231+
AbstractMatrix{T}(A::Bidiagonal) where {T} = Bidiagonal{T}(A)
232+
AbstractMatrix{T}(A::Bidiagonal{T}) where {T} = copy(A)
232233

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

src/diagonal.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ Diagonal{T}(D::Diagonal{T}) where {T} = D
112112
Diagonal{T}(D::Diagonal) where {T} = Diagonal{T}(D.diag)
113113

114114
AbstractMatrix{T}(D::Diagonal) where {T} = Diagonal{T}(D)
115+
AbstractMatrix{T}(D::Diagonal{T}) where {T} = copy(D)
115116
Matrix(D::Diagonal{T}) where {T} = Matrix{promote_type(T, typeof(zero(T)))}(D)
116117
Array(D::Diagonal{T}) where {T} = Matrix(D)
117118
function Matrix{T}(D::Diagonal) where {T}

src/hessenberg.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ parent(H::UpperHessenberg) = H.data
6262
similar(H::UpperHessenberg, ::Type{T}) where {T} = UpperHessenberg(similar(H.data, T))
6363
similar(H::UpperHessenberg, ::Type{T}, dims::Dims{N}) where {T,N} = similar(H.data, T, dims)
6464

65-
AbstractMatrix{T}(H::UpperHessenberg) where {T} = UpperHessenberg(AbstractMatrix{T}(H.data))
65+
AbstractMatrix{T}(H::UpperHessenberg) where {T} = UpperHessenberg{T}(H)
66+
AbstractMatrix{T}(H::UpperHessenberg{T}) where {T} = copy(H)
6667

6768
copy(H::UpperHessenberg) = UpperHessenberg(copy(H.data))
6869
real(H::UpperHessenberg{<:Real}) = H

src/symmetric.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,9 +308,11 @@ parent(A::HermOrSym) = A.data
308308
Symmetric{T,S}(A::Symmetric{T,S}) where {T,S<:AbstractMatrix{T}} = A
309309
Symmetric{T,S}(A::Symmetric) where {T,S<:AbstractMatrix{T}} = Symmetric{T,S}(convert(S,A.data),A.uplo)
310310
AbstractMatrix{T}(A::Symmetric) where {T} = Symmetric(convert(AbstractMatrix{T}, A.data), sym_uplo(A.uplo))
311+
AbstractMatrix{T}(A::Symmetric{T}) where {T} = copy(A)
311312
Hermitian{T,S}(A::Hermitian{T,S}) where {T,S<:AbstractMatrix{T}} = A
312313
Hermitian{T,S}(A::Hermitian) where {T,S<:AbstractMatrix{T}} = Hermitian{T,S}(convert(S,A.data),A.uplo)
313314
AbstractMatrix{T}(A::Hermitian) where {T} = Hermitian(convert(AbstractMatrix{T}, A.data), sym_uplo(A.uplo))
315+
AbstractMatrix{T}(A::Hermitian{T}) where {T} = copy(A)
314316

315317
copy(A::Symmetric{T,S}) where {T,S} = (B = copy(A.data); Symmetric{T,typeof(B)}(B,A.uplo))
316318
copy(A::Hermitian{T,S}) where {T,S} = (B = copy(A.data); Hermitian{T,typeof(B)}(B,A.uplo))

src/triangular.jl

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,14 @@ for t in (:LowerTriangular, :UnitLowerTriangular, :UpperTriangular, :UnitUpperTr
1919
end
2020
$t(A::$t) = A
2121
$t{T}(A::$t{T}) where {T} = A
22-
function $t(A::AbstractMatrix)
23-
return $t{eltype(A), typeof(A)}(A)
24-
end
25-
function $t{T}(A::AbstractMatrix) where T
26-
$t(convert(AbstractMatrix{T}, A))
27-
end
22+
$t(A::AbstractMatrix) = $t{eltype(A), typeof(A)}(A)
23+
$t{T}(A::AbstractMatrix) where {T} = $t(convert(AbstractMatrix{T}, A))
24+
$t{T}(A::$t) where {T} = $t(convert(AbstractMatrix{T}, A.data))
2825

29-
function $t{T}(A::$t) where T
30-
Anew = convert(AbstractMatrix{T}, A.data)
31-
$t(Anew)
32-
end
3326
Matrix(A::$t{T}) where {T} = Matrix{T}(A)
3427

3528
AbstractMatrix{T}(A::$t) where {T} = $t{T}(A)
29+
AbstractMatrix{T}(A::$t{T}) where {T} = copy(A)
3630

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

src/tridiag.jl

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,12 @@ julia> SymTridiagonal(B)
103103
```
104104
"""
105105
function SymTridiagonal(A::AbstractMatrix)
106-
if (diag(A, 1) == transpose.(diag(A, -1))) && all(issymmetric.(diag(A, 0)))
107-
SymTridiagonal(diag(A, 0), diag(A, 1))
106+
checksquare(A)
107+
du = diag(A, 1)
108+
d = diag(A)
109+
dl = diag(A, -1)
110+
if all(((x, y),) -> x == transpose(y), zip(du, dl)) && all(issymmetric, d)
111+
SymTridiagonal(d, du)
108112
else
109113
throw(ArgumentError("matrix is not symmetric; cannot convert to SymTridiagonal"))
110114
end
@@ -116,12 +120,12 @@ SymTridiagonal{T,V}(S::SymTridiagonal) where {T,V<:AbstractVector{T}} =
116120
SymTridiagonal{T}(S::SymTridiagonal{T}) where {T} = S
117121
SymTridiagonal{T}(S::SymTridiagonal) where {T} =
118122
SymTridiagonal(convert(AbstractVector{T}, S.dv)::AbstractVector{T},
119-
convert(AbstractVector{T}, S.ev)::AbstractVector{T})
123+
convert(AbstractVector{T}, S.ev)::AbstractVector{T})
120124
SymTridiagonal(S::SymTridiagonal) = S
121125

122-
AbstractMatrix{T}(S::SymTridiagonal) where {T} =
123-
SymTridiagonal(convert(AbstractVector{T}, S.dv)::AbstractVector{T},
124-
convert(AbstractVector{T}, S.ev)::AbstractVector{T})
126+
AbstractMatrix{T}(S::SymTridiagonal) where {T} = SymTridiagonal{T}(S)
127+
AbstractMatrix{T}(S::SymTridiagonal{T}) where {T} = copy(S)
128+
125129
function Matrix{T}(M::SymTridiagonal) where T
126130
n = size(M, 1)
127131
Mf = Matrix{T}(undef, n, n)
@@ -508,8 +512,8 @@ Tridiagonal(dl::V, d::V, du::V, du2::V) where {T,V<:AbstractVector{T}} = Tridiag
508512
function Tridiagonal{T}(dl::AbstractVector, d::AbstractVector, du::AbstractVector) where {T}
509513
Tridiagonal(map(x->convert(AbstractVector{T}, x), (dl, d, du))...)
510514
end
511-
function Tridiagonal{T,V}(A::Tridiagonal) where {T,V<:AbstractVector{T}}
512-
Tridiagonal{T,V}(A.dl, A.d, A.du)
515+
function Tridiagonal{T}(dl::AbstractVector, d::AbstractVector, du::AbstractVector, du2::AbstractVector) where {T}
516+
Tridiagonal(map(x->convert(AbstractVector{T}, x), (dl, d, du, du2))...)
513517
end
514518

515519
"""
@@ -540,12 +544,20 @@ Tridiagonal(A::AbstractMatrix) = Tridiagonal(diag(A,-1), diag(A,0), diag(A,1))
540544
Tridiagonal(A::Tridiagonal) = A
541545
Tridiagonal{T}(A::Tridiagonal{T}) where {T} = A
542546
function Tridiagonal{T}(A::Tridiagonal) where {T}
543-
dl, d, du = map(x->convert(AbstractVector{T}, x)::AbstractVector{T},
544-
(A.dl, A.d, A.du))
547+
dl, d, du = map(x -> convert(AbstractVector{T}, x)::AbstractVector{T}, (A.dl, A.d, A.du))
548+
if isdefined(A, :du2)
549+
Tridiagonal{T}(dl, d, du, convert(AbstractVector{T}, A.du2)::AbstractVector{T})
550+
else
551+
Tridiagonal{T}(dl, d, du)
552+
end
553+
end
554+
Tridiagonal{T,V}(A::Tridiagonal{T,V}) where {T,V<:AbstractVector{T}} = A
555+
function Tridiagonal{T,V}(A::Tridiagonal) where {T,V<:AbstractVector{T}}
556+
dl, d, du = map(x -> convert(V, x)::V, (A.dl, A.d, A.du))
545557
if isdefined(A, :du2)
546-
Tridiagonal(dl, d, du, convert(AbstractVector{T}, A.du2)::AbstractVector{T})
558+
Tridiagonal{T,V}(dl, d, du, convert(V, A.du2)::V)
547559
else
548-
Tridiagonal(dl, d, du)
560+
Tridiagonal{T,V}(dl, d, du)
549561
end
550562
end
551563

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

765777
AbstractMatrix{T}(M::Tridiagonal) where {T} = Tridiagonal{T}(M)
778+
AbstractMatrix{T}(M::Tridiagonal{T}) where {T} = copy(M)
766779
Tridiagonal{T}(M::SymTridiagonal{T}) where {T} = Tridiagonal(M)
767780
function SymTridiagonal{T}(M::Tridiagonal) where T
768781
if issymmetric(M)

0 commit comments

Comments
 (0)