Skip to content

Repeated index in A[I, J] = B corrupts the matrix (duplicate row) or drops values (duplicate column) #811

Description

@yurivish

When assigning to a repeated index, a SparseMatrixCSC instead stores multiple assigned values. The last write should win, but with a sparse matrix the assignment corrupts the matrix:

julia> using SparseArrays

julia> A = spzeros(2, 2);

julia> A[[1, 1], 1] = [5.0, 6.0];

julia> Matrix(A) 
2×2 Matrix{Float64}:
 6.0  0.0
 0.0  0.0

julia> A # incorrect value and number of stored entries
2×2 SparseMatrixCSC{Float64, Int64} with 2 stored entries:
 5.0   
      

julia> sum(A) # incorrect sum
11.0

julia> sum(Matrix(A))
6.0

julia> B = zeros(2, 2);

julia> B = zeros(2, 2);^C

julia> B[[1, 1], 1] = [5.0, 6.0];

julia> B
2×2 Matrix{Float64}:
 6.0  0.0
 0.0  0.0

Possible cause (AI-diagnosed)

setindex!(A::AbstractSparseMatrixCSC, V::AbstractVecOrMat, I, J) in sparsematrix.jl sorts I and J but assumes they contain no repeats. In the column merge

rowB = I[rowvalB[ptrB]]          # two rows of B map to the same row of A: both are emitted
...
colptrA[col+1] = ptrS
colB += 1                        # one column of B per distinct column of A: later duplicates in J are never visited

and the final _checkbuffers(A) only checks buffer lengths. A minimal fix is to fall back to the generic element-wise loop when !allunique(I) || !allunique(J) (which gives the Matrix semantics), or to throw an ArgumentError for repeated indices.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions