Skip to content

Commit dc61f29

Browse files
authored
Fix sparse array setindex(::Int, ::Vector) (#43678)
1 parent cbf6c1c commit dc61f29

File tree

2 files changed

+26
-17
lines changed

2 files changed

+26
-17
lines changed

stdlib/SparseArrays/src/sparsematrix.jl

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2878,6 +2878,7 @@ end
28782878

28792879
# Nonscalar A[I,J] = B: Convert B to a SparseMatrixCSC of the appropriate shape first
28802880
_to_same_csc(::AbstractSparseMatrixCSC{Tv, Ti}, V::AbstractMatrix, I...) where {Tv,Ti} = convert(SparseMatrixCSC{Tv,Ti}, V)
2881+
_to_same_csc(::AbstractSparseMatrixCSC{Tv, Ti}, V::AbstractMatrix, i::Integer, J) where {Tv,Ti} = convert(SparseMatrixCSC{Tv,Ti}, reshape(V, (1, length(J))))
28812882
_to_same_csc(::AbstractSparseMatrixCSC{Tv, Ti}, V::AbstractVector, I...) where {Tv,Ti} = convert(SparseMatrixCSC{Tv,Ti}, reshape(V, map(length, I)))
28822883

28832884
setindex!(A::AbstractSparseMatrixCSC{Tv}, B::AbstractVecOrMat, I::Integer, J::Integer) where {Tv} = _setindex_scalar!(A, B, I, J)
@@ -2886,12 +2887,20 @@ function setindex!(A::AbstractSparseMatrixCSC{Tv,Ti}, V::AbstractVecOrMat, Ix::U
28862887
require_one_based_indexing(A, V, Ix, Jx)
28872888
(I, J) = Base.ensure_indexable(to_indices(A, (Ix, Jx)))
28882889
checkbounds(A, I, J)
2889-
Base.setindex_shape_check(V, length(I), length(J))
2890+
nJ = length(J)
2891+
Base.setindex_shape_check(V, length(I), nJ)
28902892
B = _to_same_csc(A, V, I, J)
28912893

2894+
m, n = size(A)
2895+
if (!isempty(I) && (I[1] < 1 || I[end] > m)) || (!isempty(J) && (J[1] < 1 || J[end] > n))
2896+
throw(BoundsError(A, (I, J)))
2897+
end
2898+
if isempty(I) || isempty(J)
2899+
return A
2900+
end
2901+
28922902
issortedI = issorted(I)
28932903
issortedJ = issorted(J)
2894-
28952904
if !issortedI && !issortedJ
28962905
pI = sortperm(I); @inbounds I = I[pI]
28972906
pJ = sortperm(J); @inbounds J = J[pJ]
@@ -2904,20 +2913,6 @@ function setindex!(A::AbstractSparseMatrixCSC{Tv,Ti}, V::AbstractVecOrMat, Ix::U
29042913
B = B[:, pJ]
29052914
end
29062915

2907-
m, n = size(A)
2908-
mB, nB = size(B)
2909-
2910-
if (!isempty(I) && (I[1] < 1 || I[end] > m)) || (!isempty(J) && (J[1] < 1 || J[end] > n))
2911-
throw(BoundsError(A, (I, J)))
2912-
end
2913-
2914-
if isempty(I) || isempty(J)
2915-
return A
2916-
end
2917-
2918-
nI = length(I)
2919-
nJ = length(J)
2920-
29212916
colptrA = getcolptr(A); rowvalA = rowvals(A); nzvalA = nonzeros(A)
29222917
colptrB = getcolptr(B); rowvalB = rowvals(B); nzvalB = nonzeros(B)
29232918

@@ -2931,7 +2926,6 @@ function setindex!(A::AbstractSparseMatrixCSC{Tv,Ti}, V::AbstractVecOrMat, Ix::U
29312926
resize!(nzvalA, nnzS)
29322927

29332928
colB = 1
2934-
asgn_col = J[colB]
29352929

29362930
I_asgn = falses(m)
29372931
fill!(view(I_asgn, I), true)

test/arrayops.jl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2964,3 +2964,18 @@ end
29642964
@test c + zero(c) == c
29652965
end
29662966
end
2967+
2968+
@testset "Allow assignment of singleton array to sparse array #43644" begin
2969+
K = spzeros(3,3)
2970+
b = zeros(3,3)
2971+
b[3,:] = [1,2,3]
2972+
K[3,1:3] += [1.0 2.0 3.0]'
2973+
@test K == b
2974+
K[3:3,1:3] += zeros(1, 3)
2975+
@test K == b
2976+
K[3,1:3] += zeros(3)
2977+
@test K == b
2978+
K[3,:] += zeros(3,1)
2979+
@test K == b
2980+
@test_throws DimensionMismatch K[3,1:2] += [1.0 2.0 3.0]'
2981+
end

0 commit comments

Comments
 (0)