Skip to content

LU factorizations and complex matrix types#136

Open
luke-kiernan wants to merge 4 commits into
masterfrom
lk/lu-factorizations
Open

LU factorizations and complex matrix types#136
luke-kiernan wants to merge 4 commits into
masterfrom
lk/lu-factorizations

Conversation

@luke-kiernan
Copy link
Copy Markdown
Collaborator

Add the new LU factorization types and make errors a bit more informative.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 21, 2026

Codecov Report

❌ Patch coverage is 96.15385% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 90.41%. Comparing base (1a86e54) to head (40ced3c).

Files with missing lines Patch % Lines
src/sparse.jl 96.15% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #136      +/-   ##
==========================================
+ Coverage   90.12%   90.41%   +0.28%     
==========================================
  Files           6        6              
  Lines        1874     1899      +25     
==========================================
+ Hits         1689     1717      +28     
+ Misses        185      182       -3     

☔ View full report in Codecov by Sentry.
📢 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.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends the sparse solver bindings by adding libSparse LU factorization variants, updating the default factorization choice to use LU for square non-symmetric matrices on macOS ≥ 15.5, and improving error reporting by translating libSparse status codes into more specific Julia exceptions.

Changes:

  • Add LU factorization kinds (LU / LUUnpivoted / LUSPP / LUTPP) and related new enum values.
  • Change factor! default selection to prefer LU (macOS ≥ 15.5) for square non-symmetric matrices, otherwise QR.
  • Centralize libSparse status handling via _libsparse_throw and add LU-focused tests gated on macOS version.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/sparse.jl Adds LU factorization enum values, updates default factorization selection, and introduces centralized status→exception translation.
test/sparse_tests.jl Updates singular-matrix error expectation and adds LU factorization tests gated on macOS ≥ 15.5.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/sparse.jl Outdated
Comment thread test/sparse_tests.jl
@eval begin
N = 50
# Square, non-symmetric, well-conditioned.
jlA = sprand($T, N, N, 0.1) + $T(N) * I
@luke-kiernan luke-kiernan changed the title add LU factorizations; better errors LU factorizations and complex matrix types May 21, 2026
@luke-kiernan luke-kiernan requested a review from Copilot May 21, 2026 23:54
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (2)

src/sparse.jl:850

  • attributes |= ATT_UNIT_TRIANGULAR is incorrect for a multi-bit enum field: ATT_TRI_LOWER/UPPER already set the kind bits to ATT_TRIANGULAR, and OR-ing in ATT_UNIT_TRIANGULAR sets both kind bits, which encodes ATT_SYMMETRIC and can make a unit-triangular matrix appear symmetric. Instead, clear the kind field with the appropriate mask and then set it to ATT_UNIT_TRIANGULAR while preserving the independent triangle/transpose bits.
    if attributes in (ATT_TRI_LOWER, ATT_TRI_UPPER) &&
                    all(diag(sparseM) .== one(eltype(sparseM)))
        attributes |= ATT_UNIT_TRIANGULAR
    end

src/sparse.jl:873

  • istri (and therefore istriu/istril) only recognizes ATT_TRIANGULAR but not ATT_UNIT_TRIANGULAR. After fixing the kind-field assignment, unit-triangular matrices will not be detected as triangular. Consider treating both ATT_TRIANGULAR and ATT_UNIT_TRIANGULAR as triangular kinds when implementing istri/istriu/istril.
istri(M::AASparseMatrix) = (M.matrix.structure.attributes
                                    & ATT_KIND_MASK_COMPLEX) == ATT_TRIANGULAR
LinearAlgebra.istriu(M::AASparseMatrix) = istri(M) && (M.matrix.structure.attributes &
                                        ATT_LOWER_TRIANGLE == ATT_UPPER_TRIANGLE)
LinearAlgebra.istril(M::AASparseMatrix) = istri(M) && (M.matrix.structure.attributes &
                                        ATT_LOWER_TRIANGLE == ATT_LOWER_TRIANGLE)

Comment thread src/sparse.jl
Comment on lines 831 to +845
function AASparseMatrix(sparseM::SparseMatrixCSC{T, Int64},
attributes::att_type = ATT_ORDINARY) where T<:vTypes
if issymmetric(sparseM) && attributes == ATT_ORDINARY
return AASparseMatrix(tril(sparseM), ATT_SYMMETRIC | ATT_LOWER_TRIANGLE)
elseif (istril(sparseM) || istriu(sparseM)) && attributes == ATT_ORDINARY
attributes = istril(sparseM) ? ATT_TRI_LOWER : ATT_TRI_UPPER
if attributes == ATT_ORDINARY
# `ishermitian` falls back to `issymmetric` for real T, so this branch
# is taken for real-symmetric and complex-Hermitian alike — both map
# to the Cholesky-amenable kind for their respective attribute layout.
if ishermitian(sparseM)
kind = T <: Complex ? ATT_HERMITIAN : ATT_SYMMETRIC
return AASparseMatrix(tril(sparseM), kind | ATT_LOWER_TRIANGLE)
elseif T <: Complex && issymmetric(sparseM)
# Complex symmetric (not Hermitian) — rare but valid; not Cholesky-amenable.
return AASparseMatrix(tril(sparseM), ATT_SYMMETRIC | ATT_LOWER_TRIANGLE)
elseif istril(sparseM) || istriu(sparseM)
attributes = istril(sparseM) ? ATT_TRI_LOWER : ATT_TRI_UPPER
end
Comment thread src/sparse.jl
# Cholesky for symmetric; on macOS 15.5+ LU for square non-symmetric
# (faster than QR for square solves); QR otherwise.
nrow, ncol = size(aa_fact.matrixObj)
lu_ok = something(_macos_version[], v"0.0.0") >= v"15.5"
Comment thread src/sparse.jl Outdated
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.

2 participants