Skip to content

Expose CHOLMOD's reciprocal condition number estimate as CHOLMOD.rcond - #776

Open
ViralBShah wants to merge 1 commit into
mainfrom
cholmod-rcond
Open

Expose CHOLMOD's reciprocal condition number estimate as CHOLMOD.rcond#776
ViralBShah wants to merge 1 commit into
mainfrom
cholmod-rcond

Conversation

@ViralBShah

Copy link
Copy Markdown
Member

Fixes #118.

cholmod_rcond was already wrapped in src/solvers/wrappers.jl (both the
_l_ and 32-bit variants), it just had no Julia-level caller, so the
functionality was unreachable. This adds a thin rcond(F::CHOLMOD.Factor) in
the index-type loop next to check_factor, plus a docstring, a public
declaration, an entry in the solvers API page, and tests.

What the estimate is

CHOLMOD computes it from the factor diagonal alone — smallest abs entry over
largest — squared for an LL' factorization, so that cholesky and ldlt of
the same matrix agree:

julia> A = sparse(Diagonal([1.0, 2.0, 4.0]));

julia> CHOLMOD.rcond(cholesky(A)), CHOLMOD.rcond(ldlt(A))
(0.25, 0.25)

(diag of the Cholesky factor is [1, √2, 2], so (1/2)^2; diag of the
LDL' factor is [1, 2, 4], so 1/4 unsquared.)

How good it is

Worth being explicit about in the docstring, since "condition number" invites
the assumption of a norm-based estimate. Over 300 random sparse SPD matrices I
compared it against the true 1 / cond(Matrix(A), 2):

  • it never fell below the true value (0 violations), consistent with the
    interlacing of Cholesky pivots between λmin and λmax;
  • it was up to 91x optimistic.

So it is exact for diagonal matrices and an upper bound in general — safe for
detecting a badly conditioned or singular factorization, not for measuring
conditioning. The docstring says so.

API choice

I did not overload LinearAlgebra.cond for CHOLMOD.Factor. cond(A, 1)
and cond(A, Inf) already exist for AbstractSparseMatrixCSC via
opnormestinv, and they are norm-based estimates of a different quality; having
cond(F) silently return 1/(a diagonal-ratio estimate) seemed likely to
mislead. Exposing it under its own name matches what the issue asked for
(access to cholmod_rcond) and leaves cond free if a real norm-based estimate
for factorizations is wanted later. Happy to change if you would rather have
cond(F).

Testing

New testset runs for every Tv × Ti combination the CHOLMOD tests already
cover (Float32/Float64 × Int32/Int64), 5 tests each: the exact diagonal
case for both cholesky and ldlt, the 1-by-1 case (1.0), the singular case
(0.0, via check=false), and the bound against 1 / cond(A, 2). The full
test/cholmod.jl passes with no failures, and the new jldoctest passes under
Documenter (confirmed it is actually executed by breaking it once).

🤖 Generated with Claude Code

https://claude.ai/code/session_01L8HenXTVrASo1sBZVGhpDQ

@codecov

codecov Bot commented Sep 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.06%. Comparing base (ba58e74) to head (09be1ea).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #776   +/-   ##
=======================================
  Coverage   92.06%   92.06%           
=======================================
  Files          12       12           
  Lines        8377     8379    +2     
=======================================
+ Hits         7712     7714    +2     
  Misses        665      665           

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

`cholmod_rcond` was already wrapped in `wrappers.jl` but unreachable from
Julia. Add a thin `rcond(F::Factor)` in the index-type loop and document what
the estimate actually is: min/max of the factor diagonal, squared for `LL'`, so
that `cholesky` and `ldlt` of the same matrix agree.

It is exact for diagonal matrices and an upper bound on `1 / cond(A, 2)`
otherwise -- verified over 300 random SPD matrices, where it never dipped below
the true value and was up to 91x optimistic. Documented as a way to detect a
badly conditioned or singular factorization rather than to measure conditioning.

Fixes #118.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L8HenXTVrASo1sBZVGhpDQ
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.

condition number estimate from cholesky factorisation

1 participant