Skip to content

Commit 2be114e

Browse files
committed
wip rewrite spdiagm with pairs
instead of using one tuple with diagonals and one tuple with vectors [ci skip]
1 parent d668a95 commit 2be114e

File tree

1 file changed

+24
-43
lines changed

1 file changed

+24
-43
lines changed

base/sparse/sparsematrix.jl

+24-43
Original file line numberDiff line numberDiff line change
@@ -1117,7 +1117,7 @@ For expert drivers and additional information, see [`permute!`](@ref).
11171117
11181118
# Examples
11191119
```jldoctest
1120-
julia> A = spdiagm([1, 2, 3, 4], 0, 4, 4) + spdiagm([5, 6, 7], 1, 4, 4)
1120+
julia> A = spdiagm(0 => [1, 2, 3, 4], 1 => [5, 6, 7])
11211121
4×4 SparseMatrixCSC{Int64,Int64} with 7 stored entries:
11221122
[1, 1] = 1
11231123
[1, 2] = 5
@@ -3298,57 +3298,46 @@ function istril(A::SparseMatrixCSC)
32983298
return true
32993299
end
33003300

3301-
# Create a sparse diagonal matrix by specifying multiple diagonals
3302-
# packed into a tuple, alongside their diagonal offsets and matrix shape
33033301

3304-
function spdiagm_internal(B, d)
3305-
ndiags = length(d)
3306-
if length(B) != ndiags; throw(ArgumentError("first argument should be a tuple of length(d)=$ndiags arrays of diagonals")); end
3302+
function spdiagm_internal(kv::Pair{<:Integer, <:AbstractVector}...)
33073303
ncoeffs = 0
3308-
for vec in B
3309-
ncoeffs += length(vec)
3304+
for p in kv
3305+
ncoeffs += length(p.second)
33103306
end
33113307
I = Vector{Int}(ncoeffs)
33123308
J = Vector{Int}(ncoeffs)
3313-
V = Vector{promote_type(map(eltype, B)...)}(ncoeffs)
3314-
id = 0
3309+
V = Vector{promote_type(map(x -> eltype(x.second), kv)...)}(ncoeffs)
33153310
i = 0
3316-
for vec in B
3317-
id += 1
3318-
diag = d[id]
3319-
numel = length(vec)
3320-
if diag < 0
3321-
row = -diag
3311+
for p in kv
3312+
numel = length(p.second)
3313+
if p.first < 0
3314+
row = -p.first
33223315
col = 0
3323-
elseif diag > 0
3316+
elseif p.first > 0
33243317
row = 0
3325-
col = diag
3318+
col = p.first
33263319
else
33273320
row = 0
33283321
col = 0
33293322
end
3330-
range = 1+i:numel+i
3331-
I[range] = row+1:row+numel
3332-
J[range] = col+1:col+numel
3333-
copy!(view(V, range), vec)
3323+
r = 1+i:numel+i
3324+
I[r] = row+1:row+numel
3325+
J[r] = col+1:col+numel
3326+
copy!(view(V, r), p.second)
33343327
i += numel
33353328
end
3336-
3337-
return (I,J,V)
3329+
return I, J, V
33383330
end
33393331

33403332
"""
3341-
spdiagm(B, d[, m, n])
3333+
spdiagm(kv::Pair{<:Integer, <:AbstractVector}...)
33423334
3343-
Construct a sparse diagonal matrix. `B` is a tuple of vectors containing the diagonals and
3344-
`d` is a tuple containing the positions of the diagonals. In the case the input contains only
3345-
one diagonal, `B` can be a vector (instead of a tuple) and `d` can be the diagonal position
3346-
(instead of a tuple), defaulting to 0 (diagonal). Optionally, `m` and `n` specify the size
3347-
of the resulting sparse matrix.
3335+
Construct a sparse diagonal matrix from the diagonal-number/vector pair `kv`,
3336+
placing each vector `kv.second` on the `kv.first` diagonal.
33483337
33493338
# Examples
33503339
```jldoctest
3351-
julia> spdiagm(([1,2,3,4],[4,3,2,1]),(-1,1))
3340+
julia> spdiagm(-1 => [1,2,3,4], 1 => [4,3,2,1])
33523341
5×5 SparseMatrixCSC{Int64,Int64} with 8 stored entries:
33533342
[2, 1] = 1
33543343
[1, 2] = 4
@@ -3360,20 +3349,12 @@ julia> spdiagm(([1,2,3,4],[4,3,2,1]),(-1,1))
33603349
[4, 5] = 1
33613350
```
33623351
"""
3363-
function spdiagm(B, d, m::Integer, n::Integer)
3364-
(I,J,V) = spdiagm_internal(B, d)
3365-
return sparse(I,J,V,m,n)
3366-
end
3367-
3368-
function spdiagm(B, d)
3369-
(I,J,V) = spdiagm_internal(B, d)
3370-
return sparse(I,J,V)
3352+
function spdiagm(kv::Pair{<:Integer, <:AbstractVector}...)
3353+
I, J, V = spdiagm_internal(kv...)
3354+
n = max(dimlub(I), dimlub(J))
3355+
return sparse(I, J, V, n, n)
33713356
end
33723357

3373-
spdiagm(B::AbstractVector, d::Number, m::Integer, n::Integer) = spdiagm((B,), (d,), m, n)
3374-
3375-
spdiagm(B::AbstractVector, d::Number=0) = spdiagm((B,), (d,))
3376-
33773358
## expand a colptr or rowptr into a dense index vector
33783359
function expandptr(V::Vector{<:Integer})
33793360
if V[1] != 1 throw(ArgumentError("first index must be one")) end

0 commit comments

Comments
 (0)