Skip to content

Multiply Symmetric/Hermitian sparse matrices by sparse matrices and vectors in O(nnz) - #869

Open
ViralBShah wants to merge 2 commits into
mainfrom
vs/symherm-sparse-mul
Open

ViralBShah wants to merge 2 commits into
mainfrom
vs/symherm-sparse-mul

Conversation

@ViralBShah

@ViralBShah ViralBShah commented Sep 20, 2026

Copy link
Copy Markdown
Member
using LinearAlgebra, SparseArrays
n = 3000; A = sprandn(n, n, 5/n); B = sprandn(n, n, 5/n)
Symmetric(A) * B               # 13.4 s, vs 1 ms for A * B
Symmetric(A) * Symmetric(B)    # 13.8 s

* has sparse methods for plain, column-view, triangular and adjoint/transpose sparse factors, but none for Symmetric/Hermitian of a sparse matrix, so a product of one with any other sparse factor went to LinearAlgebra's generic * and an elementwise sweep into a sparse destination. This adds four methods (three for a sparse matrix on the other side, one for a sparse vector) that materialize the symmetric factor with sparse (O(nnz), like the copy the adjoint methods already make, and like +/- with these wrappers) and use the existing sparse product. The result type is unchanged, a SparseMatrixCSC. This touches dispatch; detect_ambiguities against LinearAlgebra and Base reports none and the Aqua job passes.

Nightly, n = 3000, 5 nonzeros per column:

product main PR
Symmetric(A) * B 13400 ms 1.18 ms
A * Symmetric(B) 13700 ms 1.18 ms
Symmetric(A) * Symmetric(B) 13800 ms 1.30 ms
Symmetric(A) * Hermitian(B) 14200 ms not re-timed
Hermitian(Ac) * Hermitian(Ac, :L) (complex) 53800 ms 1.37 ms
Symmetric(A) * x, x a SparseVector with 1% stored 1.99 ms 0.082 ms
A * B (reference) 0.99 ms 0.99 ms

At n = 300, where main finishes quickly enough to sweep: A' * Symmetric(B) 210 → 0.085 ms, UpperTriangular(A) * Symmetric(B) 120 → 0.042 ms, Symmetric(A) * UpperTriangular(B) 100 → 0.039 ms.

Tests: Symmetric, Hermitian and Symmetric of a column view against plain, adjoint, transpose, triangular, column-view and symmetric/Hermitian sparse factors on both sides, real and complex, plus a SparseVector and a sparse column view on the right, checking the result type and the value against dense. Dispatch is proven with MulCount: five products of n × n identities cost exactly n multiplications, against 550 to 1200 on main for n = 10, and the sparse-vector product costs what P * x costs (20 against 110). Full Pkg.test() passes on nightly.

Left out: mul! into a sparse destination. That is slow for every pair of sparse factors, not only these wrappers (mul!(C, A, B) with plain A, B and sparse C takes 488 ms at n = 1000 against 0.31 ms for A * B, since it runs the dense tiled generic product and writes C by index), so it is a separate change.

Written by Claude Code (Claude Fable 5.1).

🤖 Generated with Claude Code

ViralBShah and others added 2 commits September 20, 2026 09:12
…n O(nnz)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… O(nnz)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@ViralBShah ViralBShah changed the title Multiply Symmetric/Hermitian sparse matrices by sparse matrices in O(nnz) Multiply Symmetric/Hermitian sparse matrices by sparse matrices and vectors in O(nnz) Sep 20, 2026
@codecov

codecov Bot commented Sep 20, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.01%. Comparing base (3a77d00) to head (cae45bb).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #869   +/-   ##
=======================================
  Coverage   93.01%   93.01%           
=======================================
  Files          12       12           
  Lines        9076     9080    +4     
=======================================
+ Hits         8442     8446    +4     
  Misses        634      634           

☔ 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.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant