Skip to content
Draft
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion src/bidiag.jl
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,13 @@ function Matrix{T}(A::Bidiagonal) where T
end
return B
end
Matrix(A::Bidiagonal{T}) where {T} = Matrix{promote_type(T, typeof(zero(T)))}(A)
function Matrix(A::Bidiagonal{T}) where {T}
if haszero(T)
Matrix{promote_type(T, typeof(zero(T)))}(A)
else
convert(Matrix, [x for x in A])
end
end
Array(A::Bidiagonal) = Matrix(A)
promote_rule(::Type{Matrix{T}}, ::Type{<:Bidiagonal{S}}) where {T,S} =
@isdefined(T) && @isdefined(S) ? Matrix{promote_type(T,S)} : Matrix
Expand Down
3 changes: 2 additions & 1 deletion src/dense.jl
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,8 @@ norm2(x::Union{Array{T},StridedVector{T}}) where {T<:BlasFloat} =
Return whether a type `T` has a unique zero element defined using `zero(T)`.
If a type `M` specializes `zero(M)`, it may also choose to set `haszero(M)` to `true`.
By default, `haszero` is assumed to be `false`, in which case the zero elements
are deduced from values rather than the type.
are deduced from values rather than the type. In general, if a type defines `zero(::Type{MyType})`,
it should also define `haszero(::Type{MyType}) = true`.

!!! note
`haszero` is a conservative check that is used to dispatch to
Expand Down
8 changes: 7 additions & 1 deletion src/diagonal.jl
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,13 @@ 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)
function Matrix(D::Diagonal{T}) where {T}
if haszero(T)
Matrix{promote_type(T, typeof(zero(T)))}(D)
else
convert(Matrix, [i for i in D])
end
end
Matrix(D::Diagonal{Any}) = Matrix{Any}(D)
Array(D::Diagonal{T}) where {T} = Matrix(D)
function Matrix{T}(D::Diagonal) where {T}
Expand Down
16 changes: 14 additions & 2 deletions src/tridiag.jl
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,13 @@ function Matrix{T}(M::SymTridiagonal) where T
end
return Mf
end
Matrix(M::SymTridiagonal{T}) where {T} = Matrix{promote_type(T, typeof(zero(T)))}(M)
function Matrix(M::SymTridiagonal{T}) where {T}
if haszero(T)
Matrix{promote_type(T, typeof(zero(T)))}(M)
else
convert(Matrix, [x for x in M])
end
end
Array(M::SymTridiagonal) = Matrix(M)

size(A::SymTridiagonal) = (n = length(A.dv); (n, n))
Expand Down Expand Up @@ -620,7 +626,13 @@ function Matrix{T}(M::Tridiagonal) where {T}
end
A
end
Matrix(M::Tridiagonal{T}) where {T} = Matrix{promote_type(T, typeof(zero(T)))}(M)
function Matrix(M::Tridiagonal{T}) where {T}
if haszero(T)
Matrix{promote_type(T, typeof(zero(T)))}(M)
else
convert(Matrix, [x for x in M])
end
end
Array(M::Tridiagonal) = Matrix(M)

similar(M::Tridiagonal, ::Type{T}) where {T} = Tridiagonal(similar(M.dl, T), similar(M.d, T), similar(M.du, T))
Expand Down
7 changes: 7 additions & 0 deletions test/bidiag.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1164,4 +1164,11 @@ end
@test opnorm(B, Inf) == opnorm(Matrix(B), Inf)
end

@testset "Matrix conversion without zero" begin
D = Bidiagonal(fill(ones(2,2), 4), fill(ones(2,2), 3), :U)
M = Matrix(D)
@test M isa Matrix{eltype(D)}
@test M == D
end

end # module TestBidiagonal
7 changes: 7 additions & 0 deletions test/diagonal.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1473,4 +1473,11 @@ end
@test opnorm(D, Inf) == opnorm(A, Inf)
end

@testset "Matrix conversion without zero" begin
D = Diagonal(fill(ones(2,2), 4))
M = Matrix(D)
@test M isa Matrix{eltype(D)}
@test M == D
end

end # module TestDiagonal
2 changes: 2 additions & 0 deletions test/special.jl
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ Random.seed!(1)
struct TypeWithZero end
Base.promote_rule(::Type{TypeWithoutZero}, ::Type{TypeWithZero}) = TypeWithZero
Base.convert(::Type{TypeWithZero}, ::TypeWithoutZero) = TypeWithZero()
LinearAlgebra.haszero(::Type{TypeWithoutZero}) = true
LinearAlgebra.haszero(::Type{TypeWithZero}) = true
Base.zero(x::Union{TypeWithoutZero, TypeWithZero}) = zero(typeof(x))
Base.zero(::Type{<:Union{TypeWithoutZero, TypeWithZero}}) = TypeWithZero()
LinearAlgebra.symmetric(::TypeWithoutZero, ::Symbol) = TypeWithoutZero()
Expand Down
9 changes: 9 additions & 0 deletions test/tridiag.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1099,4 +1099,13 @@ end
@test opnorm(S, Inf) == opnorm(Matrix(S), Inf)
end

@testset "Matrix conversion without zero" begin
dv, ev = fill(ones(2,2), 2), fill(ones(2,2), 1)
for T in (Tridiagonal(ev, dv, ev), SymTridiagonal(dv, ev))
M = Matrix(T)
@test M isa Matrix
@test M == T
end
end

end # module TestTridiagonal
Loading