Skip to content

struct SparseMatrixCSC cannot be constructed correctly with "repeating" entries #618

@FangXieTHU

Description

@FangXieTHU

In many use cases, constructing CSC matrices with "repeating" entries in each column is usually convenient and memory efficient.
In particular, when the same entry appears multiple times, we usually expect that the values for these entries will be added together.
However, it seems that directly using SparseMatrixCSC does not work as intended.

In the following minimal example, I tried to construct an identity matrix using both the IJV format (sparse matrix A) and using CSC format (sparse matrix B).

The entry at [1, 1] appeared twice, each time with value 0.5. Therefore, I would expect the matrix should behave as an 3 dimensional identity matrix.

Using IJV format, the matrix behaves exactly as what I expected. However, the direct construction B using CSC format does not always work properly in the following ways:

  1. It cannot be displayed properly. The matrix element at [1, 1] shows 0.5.
  2. Converting it into dense matrix by Matrix(B) also returns a matrix with 0.5 at [1, 1].
  3. Interestingly, the matrix-vector multiplication operators involving sparse matrix B works correctly.

I am wondering if this behavior of CSC matrix construction is intended, or if this is a glitch in the implementation of display and Matrix functions?

If it is not intended, I believe it would be helpful to get it patched.
If it is intentional, I would like to ask whether it might be possible to introduce an alternative method for constructing CSC-format sparse matrices with repeating entries.

Many thanks to the SparseArrays.jl team for their help and support.

using SparseArrays

col_idx::Vector{Int64} = [1, 1, 2, 3]
row_idx::Vector{Int64} = [1, 1, 2, 3]

colptr::Vector{Int64} = [1, 3, 4, 5]
val::Vector{Float64} = [0.5, 0.5, 1.0, 1.0]

A = sparse(col_idx, row_idx, val, 3, 3)
B = SparseMatrixCSC(3, 3, colptr, row_idx, val)

display(A)
display(B)
display(Matrix(B))

x::Vector{Float64} = [1.0, 1.0, 1.0]

display(A * x)
display(B * x)
display(Matrix(B) * x)

Output:

3×3 SparseMatrixCSC{Float64, Int64} with 3 stored entries:
 1.0   ⋅    ⋅
  ⋅   1.0   ⋅
  ⋅    ⋅   1.0
3×3 SparseMatrixCSC{Float64, Int64} with 4 stored entries:
 0.5   ⋅    ⋅
  ⋅   1.0   ⋅
  ⋅    ⋅   1.0
3×3 Matrix{Float64}:
 0.5  0.0  0.0
 0.0  1.0  0.0
 0.0  0.0  1.0
3-element Vector{Float64}:
 1.0
 1.0
 1.0
3-element Vector{Float64}:
 1.0
 1.0
 1.0
3-element Vector{Float64}:
 0.5
 1.0
 1.0

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