Skip to content

Commit 2099987

Browse files
authored
Make Matrix cntr work for structured matrices for zero(T) !isa T (#44707)
1 parent e0c5e96 commit 2099987

File tree

5 files changed

+36
-5
lines changed

5 files changed

+36
-5
lines changed

stdlib/LinearAlgebra/src/bidiag.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ function Matrix{T}(A::Bidiagonal) where T
180180
B[n,n] = A.dv[n]
181181
return B
182182
end
183-
Matrix(A::Bidiagonal{T}) where {T} = Matrix{T}(A)
183+
Matrix(A::Bidiagonal{T}) where {T} = Matrix{promote_type(T, typeof(zero(T)))}(A)
184184
Array(A::Bidiagonal) = Matrix(A)
185185
promote_rule(::Type{Matrix{T}}, ::Type{<:Bidiagonal{S}}) where {T,S} =
186186
@isdefined(T) && @isdefined(S) ? Matrix{promote_type(T,S)} : Matrix

stdlib/LinearAlgebra/src/dense.jl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,8 @@ Vector `kv.second` will be placed on the `kv.first` diagonal.
257257
By default the matrix is square and its size is inferred
258258
from `kv`, but a non-square size `m`×`n` (padded with zeros as needed)
259259
can be specified by passing `m,n` as the first arguments.
260+
For repeated diagonal indices `kv.first` the values in the corresponding
261+
vectors `kv.second` will be added.
260262
261263
`diagm` constructs a full matrix; if you want storage-efficient
262264
versions with fast arithmetic, see [`Diagonal`](@ref), [`Bidiagonal`](@ref)
@@ -277,6 +279,13 @@ julia> diagm(1 => [1,2,3], -1 => [4,5])
277279
4 0 2 0
278280
0 5 0 3
279281
0 0 0 0
282+
283+
julia> diagm(1 => [1,2,3], 1 => [1,2,3])
284+
4×4 Matrix{Int64}:
285+
0 2 0 0
286+
0 0 4 0
287+
0 0 0 6
288+
0 0 0 0
280289
```
281290
"""
282291
diagm(kv::Pair{<:Integer,<:AbstractVector}...) = _diagm(nothing, kv...)

stdlib/LinearAlgebra/src/diagonal.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ Diagonal{T}(D::Diagonal{T}) where {T} = D
7777
Diagonal{T}(D::Diagonal) where {T} = Diagonal{T}(D.diag)
7878

7979
AbstractMatrix{T}(D::Diagonal) where {T} = Diagonal{T}(D)
80-
Matrix(D::Diagonal{T}) where {T} = Matrix{T}(D)
81-
Array(D::Diagonal{T}) where {T} = Matrix{T}(D)
80+
Matrix(D::Diagonal{T}) where {T} = Matrix{promote_type(T, typeof(zero(T)))}(D)
81+
Array(D::Diagonal{T}) where {T} = Matrix(D)
8282
function Matrix{T}(D::Diagonal) where {T}
8383
n = size(D, 1)
8484
B = zeros(T, n, n)

stdlib/LinearAlgebra/src/tridiag.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ function Matrix{T}(M::SymTridiagonal) where T
134134
Mf[n,n] = symmetric(M.dv[n], :U)
135135
return Mf
136136
end
137-
Matrix(M::SymTridiagonal{T}) where {T} = Matrix{T}(M)
137+
Matrix(M::SymTridiagonal{T}) where {T} = Matrix{promote_type(T, typeof(zero(T)))}(M)
138138
Array(M::SymTridiagonal) = Matrix(M)
139139

140140
size(A::SymTridiagonal) = (length(A.dv), length(A.dv))
@@ -583,7 +583,7 @@ function Matrix{T}(M::Tridiagonal) where {T}
583583
A[n,n] = M.d[n]
584584
A
585585
end
586-
Matrix(M::Tridiagonal{T}) where {T} = Matrix{T}(M)
586+
Matrix(M::Tridiagonal{T}) where {T} = Matrix{promote_type(T, typeof(zero(T)))}(M)
587587
Array(M::Tridiagonal) = Matrix(M)
588588

589589
similar(M::Tridiagonal, ::Type{T}) where {T} = Tridiagonal(similar(M.dl, T), similar(M.d, T), similar(M.du, T))

stdlib/LinearAlgebra/test/special.jl

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,28 @@ Random.seed!(1)
104104
@test LowerTriangular(C) == LowerTriangular(Cdense)
105105
end
106106
end
107+
108+
@testset "Matrix constructor for !isa(zero(T), T)" begin
109+
# the following models JuMP.jl's VariableRef and AffExpr, resp.
110+
struct TypeWithoutZero end
111+
struct TypeWithZero end
112+
Base.promote_rule(::Type{TypeWithoutZero}, ::Type{TypeWithZero}) = TypeWithZero
113+
Base.convert(::Type{TypeWithZero}, ::TypeWithoutZero) = TypeWithZero()
114+
Base.zero(::Type{<:Union{TypeWithoutZero, TypeWithZero}}) = TypeWithZero()
115+
LinearAlgebra.symmetric(::TypeWithoutZero, ::Symbol) = TypeWithoutZero()
116+
Base.transpose(::TypeWithoutZero) = TypeWithoutZero()
117+
d = fill(TypeWithoutZero(), 3)
118+
du = fill(TypeWithoutZero(), 2)
119+
dl = fill(TypeWithoutZero(), 2)
120+
D = Diagonal(d)
121+
Bu = Bidiagonal(d, du, :U)
122+
Bl = Bidiagonal(d, dl, :L)
123+
Tri = Tridiagonal(dl, d, du)
124+
Sym = SymTridiagonal(d, dl)
125+
for M in (D, Bu, Bl, Tri, Sym)
126+
@test Matrix(M) == zeros(TypeWithZero, 3, 3)
127+
end
128+
end
107129
end
108130

109131
@testset "Binary ops among special types" begin

0 commit comments

Comments
 (0)