Skip to content

sparse lu: report an exact zero pivot as LuError::NumericSingular in both backends (#132) - #147

Merged
shinaoka merged 1 commit into
mainfrom
fix/132-sparse-lu-numeric-singular
Oct 29, 2026
Merged

shinaoka merged 1 commit into
mainfrom
fix/132-sparse-lu-numeric-singular

Conversation

@shinaoka

Copy link
Copy Markdown
Member

The numeric sparse LU returned Ok for a numerically singular matrix, and the solve then returned NaN. Upstream reported the simplicial backend (sarah-quinones/faer#339); the supernodal backend has the same defect.

Closes #132.

What changes

  • New error variant. LuError::NumericSingular { index }, the shape the upstream maintainer asked for in upstream PR sarah-quinones/faer#332 (closed unmerged). The maintainer approved it (option 1, 2026-10-29).
  • Simplicial backend. Returns the error when the chosen pivot is exactly zero. The check reads the pivot itself (abs1), not the modulus used by the pivot search, because a complex modulus underflows to zero for a nonzero subnormal entry.
  • Supernodal backend. Returns the error when a diagonal entry of a factored panel, which is U's pivot, is exactly zero.
  • index. Counts elimination steps in the fill-reducing column order, the same way SymbolicSingular's does.
  • Tolerance. Only an exact zero is reported. Tolerance-based detection is sparse LU: tolerance-based numeric singularity detection (follow-up to #132) #146 (an issue only).
  • API change. This adds a variant to an exhaustive public enum. No tensor4all consumer references the sparse LuError; I checked tlinalg-rs, tcontract-rs and tenferro-rs.
  • Records.
    • PATCHSET row.
    • upstream-reports/faer-028-sparse-lu-numeric-singular: a standalone program that reproduces the defect on faer 0.24.4 in both backends.

Provenance

I wrote the fix from the upstream report. No code comes from upstream PR #332, and nothing was posted to Codeberg.

Verification

  • Tests, each run in both backends:
    • codeberg_339: the upstream reproduction at f32, f64, c32 and c64.
    • numeric_singular_after_an_elimination_step: a 4x4 singular/nonsingular pair.
    • nonzero_subnormal_pivot_is_not_singular.
  • Before the fix: the first two fail without the checks. The third fails if the simplicial check reads the modulus instead of the pivot.
  • Other checks:
    • All 31 sparse library tests and the sparse doctests pass.
    • cargo +1.89.0 check passes.
    • Clippy reports nothing in the changed files.
    • Nightly rustfmt leaves no diff in my edits; the only remaining diffs are three that already exist on main.
  • The standalone report program prints Ok and then x = [NaN, NaN] for both backends on faer 0.24.4.
  • Independent review (gpt-6.1-sol):
    • It found the subnormal complex modulus case, now fixed and pinned by a test.
    • It also corrected the report README's explanation: in this program the factors stay finite, and the NaN comes from the solve dividing by the zero pivot.

🤖 Generated with Claude Code

…both backends (#132; upstream #339)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@shinaoka
shinaoka merged commit 517ef27 into main Oct 29, 2026
7 checks passed
@shinaoka
shinaoka deleted the fix/132-sparse-lu-numeric-singular branch October 29, 2026 10:56
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.

sparse LU: a numerically singular matrix factors as Ok, and the solve returns NaN (upstream #339)

1 participant