Skip to content

Commit

Permalink
Make Matrix cntr work for structured matrices for zero(T) !isa T (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
dkarrasch authored Mar 24, 2022
1 parent e0c5e96 commit 2099987
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 5 deletions.
2 changes: 1 addition & 1 deletion stdlib/LinearAlgebra/src/bidiag.jl
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ function Matrix{T}(A::Bidiagonal) where T
B[n,n] = A.dv[n]
return B
end
Matrix(A::Bidiagonal{T}) where {T} = Matrix{T}(A)
Matrix(A::Bidiagonal{T}) where {T} = Matrix{promote_type(T, typeof(zero(T)))}(A)
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
9 changes: 9 additions & 0 deletions stdlib/LinearAlgebra/src/dense.jl
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,8 @@ Vector `kv.second` will be placed on the `kv.first` diagonal.
By default the matrix is square and its size is inferred
from `kv`, but a non-square size `m`×`n` (padded with zeros as needed)
can be specified by passing `m,n` as the first arguments.
For repeated diagonal indices `kv.first` the values in the corresponding
vectors `kv.second` will be added.
`diagm` constructs a full matrix; if you want storage-efficient
versions with fast arithmetic, see [`Diagonal`](@ref), [`Bidiagonal`](@ref)
Expand All @@ -277,6 +279,13 @@ julia> diagm(1 => [1,2,3], -1 => [4,5])
4 0 2 0
0 5 0 3
0 0 0 0
julia> diagm(1 => [1,2,3], 1 => [1,2,3])
4×4 Matrix{Int64}:
0 2 0 0
0 0 4 0
0 0 0 6
0 0 0 0
```
"""
diagm(kv::Pair{<:Integer,<:AbstractVector}...) = _diagm(nothing, kv...)
Expand Down
4 changes: 2 additions & 2 deletions stdlib/LinearAlgebra/src/diagonal.jl
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ 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)
Matrix(D::Diagonal{T}) where {T} = Matrix{T}(D)
Array(D::Diagonal{T}) where {T} = Matrix{T}(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}
n = size(D, 1)
B = zeros(T, n, n)
Expand Down
4 changes: 2 additions & 2 deletions stdlib/LinearAlgebra/src/tridiag.jl
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ function Matrix{T}(M::SymTridiagonal) where T
Mf[n,n] = symmetric(M.dv[n], :U)
return Mf
end
Matrix(M::SymTridiagonal{T}) where {T} = Matrix{T}(M)
Matrix(M::SymTridiagonal{T}) where {T} = Matrix{promote_type(T, typeof(zero(T)))}(M)
Array(M::SymTridiagonal) = Matrix(M)

size(A::SymTridiagonal) = (length(A.dv), length(A.dv))
Expand Down Expand Up @@ -583,7 +583,7 @@ function Matrix{T}(M::Tridiagonal) where {T}
A[n,n] = M.d[n]
A
end
Matrix(M::Tridiagonal{T}) where {T} = Matrix{T}(M)
Matrix(M::Tridiagonal{T}) where {T} = Matrix{promote_type(T, typeof(zero(T)))}(M)
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
22 changes: 22 additions & 0 deletions stdlib/LinearAlgebra/test/special.jl
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,28 @@ Random.seed!(1)
@test LowerTriangular(C) == LowerTriangular(Cdense)
end
end

@testset "Matrix constructor for !isa(zero(T), T)" begin
# the following models JuMP.jl's VariableRef and AffExpr, resp.
struct TypeWithoutZero end
struct TypeWithZero end
Base.promote_rule(::Type{TypeWithoutZero}, ::Type{TypeWithZero}) = TypeWithZero
Base.convert(::Type{TypeWithZero}, ::TypeWithoutZero) = TypeWithZero()
Base.zero(::Type{<:Union{TypeWithoutZero, TypeWithZero}}) = TypeWithZero()
LinearAlgebra.symmetric(::TypeWithoutZero, ::Symbol) = TypeWithoutZero()
Base.transpose(::TypeWithoutZero) = TypeWithoutZero()
d = fill(TypeWithoutZero(), 3)
du = fill(TypeWithoutZero(), 2)
dl = fill(TypeWithoutZero(), 2)
D = Diagonal(d)
Bu = Bidiagonal(d, du, :U)
Bl = Bidiagonal(d, dl, :L)
Tri = Tridiagonal(dl, d, du)
Sym = SymTridiagonal(d, dl)
for M in (D, Bu, Bl, Tri, Sym)
@test Matrix(M) == zeros(TypeWithZero, 3, 3)
end
end
end

@testset "Binary ops among special types" begin
Expand Down

0 comments on commit 2099987

Please sign in to comment.