Skip to content

Return an n x 1 matrix from SparseMatrixCSC of a sparse vector view - #1113

Merged
ViralBShah merged 2 commits into
mainfrom
vs/csc-from-vector-view
Oct 26, 2026
Merged

ViralBShah merged 2 commits into
mainfrom
vs/csc-from-vector-view

Conversation

@ViralBShah

@ViralBShah ViralBShah commented Oct 26, 2026 •

Copy link
Copy Markdown
Member

SparseMatrixCSC(view(A, :, j)) returns a SparseVector, so a constructor of SparseMatrixCSC returns something that is not a SparseMatrixCSC. The same holds for SparseMatrixCSC{Tv} and for a view of a sparse vector, while SparseMatrixCSC{Tv,Ti} of the same view, and SparseMatrixCSC of a SparseVector, return an n x 1 matrix.

Before

using SparseArrays
A = sparse([1.0 0; 0 1])
for C in (SparseMatrixCSC, SparseMatrixCSC{Float64}, SparseMatrixCSC{Float64,Int})
    r = C(view(A, :, 1)); println(C, " => ", typeof(r), " ", size(r))
end
SparseMatrixCSC => SparseVector{Float64, Int64} (2,)
SparseMatrixCSC{Float64} => SparseVector{Float64, Int64} (2,)
SparseMatrixCSC{Float64, Int64} => SparseMatrixCSC{Float64, Int64} (2, 1)

After

SparseMatrixCSC => SparseMatrixCSC{Float64, Int64} (2, 1)
SparseMatrixCSC{Float64} => SparseMatrixCSC{Float64, Int64} (2, 1)
SparseMatrixCSC{Float64, Int64} => SparseMatrixCSC{Float64, Int64} (2, 1)

The wrapper constructors in sparseconvert.jl return _sparsem(A) directly when the eltype matches, and _sparsem of a 1-d view is the SparseVector that indexing the parent gives. Two methods on SubArray{<:Any,1} now pass that vector on to SparseMatrixCSC, as the typed {Tv,Ti} constructor already does. sparse(view(A, :, j)) is unchanged and still returns a SparseVector. This touches dispatch.

Potential breakage: this changes the result type of code that works today. A caller relying on SparseMatrixCSC(view(A, :, j)) being a SparseVector, for example indexing it with one index as a vector or passing it where a vector is required, now gets an n x 1 matrix. sparse(view(A, :, j)) or A[:, j] gives the vector.

Dense has no constructor from a vector: Matrix(v) and Matrix(view(M, :, 1)) throw a MethodError. A sparse vector has long converted to an n x 1 matrix, through SparseMatrixCSC(x) and convert(SparseMatrixCSC, x), so a view of one now does the same. Matching dense exactly would break those. A view of a dense vector, which dense cannot convert either, threw a TypeError from an internal invoke. It now throws the MethodError that Matrix gives:

Before

julia> SparseMatrixCSC(view([1.0, 2.0], :))
ERROR: TypeError: in invoke: argument type error, expected Tuple{AbstractMatrix}, got a value of type Tuple{SubArray{Float64, 1, Vector{Float64}, Tuple{Base.Slice{Base.OneTo{Int64}}}, true}}

After

julia> SparseMatrixCSC(view([1.0, 2.0], :))
ERROR: MethodError: no method matching SparseMatrixCSC(::SubArray{Float64, 1, Vector{Float64}, Tuple{Base.Slice{Base.OneTo{Int64}}}, true})

🤖 Generated with Claude Code

@codecov

codecov Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 66.66667% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 94.72%. Comparing base (353601e) to head (7535d57).
⚠️ Report is 5 commits behind head on main.

Files with missing lines Patch % Lines
src/sparseconvert.jl 66.66% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1113      +/-   ##
==========================================
- Coverage   94.72%   94.72%   -0.01%     
==========================================
  Files          16       16              
  Lines       10318    10323       +5     
==========================================
+ Hits         9774     9778       +4     
- Misses        544      545       +1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

ViralBShah and others added 2 commits October 26, 2026 13:55
`SparseMatrixCSC(view(A, :, j))` and `SparseMatrixCSC{Tv}(view(A, :, j))` returned a
`SparseVector`; they now return the `n x 1` matrix that `SparseMatrixCSC{Tv,Ti}` of
the same view and `SparseMatrixCSC` of a sparse vector already return.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…atrix does

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ViralBShah
ViralBShah force-pushed the vs/csc-from-vector-view branch from 578600d to 7535d57 Compare October 26, 2026 13:58
@ViralBShah
ViralBShah merged commit 1a56603 into main Oct 26, 2026
12 checks passed
@ViralBShah
ViralBShah deleted the vs/csc-from-vector-view branch October 26, 2026 16:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant