Skip to content

Commit 9a3ef6b

Browse files
diagm for non-square matrices (#31654)
* diagm for non-square matrices * change to positional m,n arguments * Update stdlib/LinearAlgebra/src/dense.jl Co-Authored-By: andreasnoack <andreas@noack.dk>
1 parent aa078e6 commit 9a3ef6b

File tree

2 files changed

+25
-5
lines changed

2 files changed

+25
-5
lines changed

src/sparsematrix.jl

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3357,9 +3357,13 @@ end
33573357

33583358
"""
33593359
spdiagm(kv::Pair{<:Integer,<:AbstractVector}...)
3360+
spdiagm(m::Integer, n::Ingeger, kv::Pair{<:Integer,<:AbstractVector}...)
33603361
3361-
Construct a square sparse diagonal matrix from `Pair`s of vectors and diagonals.
3362-
Vector `kv.second` will be placed on the `kv.first` diagonal.
3362+
Construct a sparse diagonal matrix from `Pair`s of vectors and diagonals.
3363+
Each vector `kv.second` will be placed on the `kv.first` diagonal. By
3364+
default (if `size=nothing`), the matrix is square and its size is inferred
3365+
from `kv`, but a non-square size `m`×`n` (padded with zeros as needed)
3366+
can be specified by passing `m,n` as the first arguments.
33633367
33643368
# Examples
33653369
```jldoctest
@@ -3375,10 +3379,15 @@ julia> spdiagm(-1 => [1,2,3,4], 1 => [4,3,2,1])
33753379
[4, 5] = 1
33763380
```
33773381
"""
3378-
function spdiagm(kv::Pair{<:Integer,<:AbstractVector}...)
3382+
spdiagm(kv::Pair{<:Integer,<:AbstractVector}...) = _spdiagm(nothing, kv...)
3383+
spdiagm(m::Integer, n::Integer, kv::Pair{<:Integer,<:AbstractVector}...) = _spdiagm((Int(m),Int(n)), kv...)
3384+
function _spdiagm(size, kv::Pair{<:Integer,<:AbstractVector}...)
33793385
I, J, V = spdiagm_internal(kv...)
3380-
n = max(dimlub(I), dimlub(J))
3381-
return sparse(I, J, V, n, n)
3386+
mmax, nmax = dimlub(I), dimlub(J)
3387+
mnmax = max(mmax, nmax)
3388+
m, n = something(size, (mnmax,mnmax))
3389+
(m mmax && n nmax) || throw(DimensionMismatch("invalid size=$size"))
3390+
return sparse(I, J, V, m, n)
33823391
end
33833392

33843393
## expand a colptr or rowptr into a dense index vector

test/sparse.jl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1583,6 +1583,17 @@ end
15831583
end
15841584
# promotion
15851585
@test spdiagm(0 => [1,2], 1 => [3.5], -1 => [4+5im]) == [1 3.5; 4+5im 2]
1586+
1587+
# non-square:
1588+
for m=1:4, n=2:4
1589+
if m < 2 || n < 3
1590+
@test_throws DimensionMismatch spdiagm(m,n, 0 => x, 1 => x)
1591+
else
1592+
M = zeros(m,n)
1593+
M[1:2,1:3] = [1 1 0; 0 1 1]
1594+
@test spdiagm(m,n, 0 => x, 1 => x) == M
1595+
end
1596+
end
15861597
end
15871598

15881599
@testset "diag" begin

0 commit comments

Comments
 (0)