Skip to main content

Crate sparse_ldlt

Crate sparse_ldlt 

Source
Expand description

Pure-Rust, dependency-free sparse symmetric-indefinite LDLᵀ factorization.

Factors a symmetric sparse matrix A = L D Lᵀ, where L is unit-lower-triangular and D is a signed diagonal, then solves A x = b. Because D may carry negative entries, this handles symmetric indefinite systems (KKT / saddle-point problems, shifted eigenvalue matrices K - σM, quasi-definite systems) - not just positive-definite ones - and it exposes D so you can read the matrix inertia (the number of negative eigenvalues, by Sylvester’s law) for Sturm eigenvalue counts.

Most pure-Rust sparse factorizations only offer positive-definite Cholesky and do not expose the signed pivots; this crate fills that gap with a small, self-contained implementation of the standard up-looking sparse LDLᵀ (elimination-tree) method described in T. A. Davis, Direct Methods for Sparse Linear Systems (SIAM, 2006).

It has no dependencies and works on stable Rust. The matrix is supplied in compressed-sparse-column (CSC) form; only the upper triangle (entries with row ≤ col in each column) is read, so a fully-populated symmetric matrix is also accepted.

No pivoting is performed: like every un-pivoted LDLᵀ it breaks down if a diagonal entry of D reaches zero (LdltError::ZeroPivot) - and, just as importantly, if a pivot’s magnitude has been destroyed by cancellation (LdltError::NearZeroPivot). The second case is the dangerous one: such a pivot still carries a sign, but that sign is rounding noise, and the sign pattern of D IS the matrix inertia, so a silently-returned near-zero pivot is a silently wrong eigenvalue count. Both are reported, never swallowed. SparseLdlt::factor_shifted retries the breakdown with a diagonal shift and tells you, via SparseLdlt::shift, exactly how far it moved the matrix. Non-finite input values (NaN / ±inf) are rejected up front rather than silently propagating through the factors.

§Example

use sparse_ldlt::SparseLdlt;
// Symmetric indefinite 3x3 matrix (full storage), CSC:
//   [ 2  1  0 ]
//   [ 1 -3  1 ]
//   [ 0  1  2 ]
let col_ptr = vec![0, 2, 5, 7];
let row_idx = vec![0, 1,  0, 1, 2,  1, 2];
let values  = vec![2.0, 1.0,  1.0, -3.0, 1.0,  1.0, 2.0];
let f = SparseLdlt::factor(3, &col_ptr, &row_idx, &values).unwrap();
let x = f.solve(&[1.0, 2.0, 3.0]).unwrap();
// one negative pivot => one negative eigenvalue (inertia)
assert_eq!(f.d().iter().filter(|&&v| v < 0.0).count(), 1);

Structs§

SparseLdlt
An L D Lᵀ factorization of a symmetric matrix.

Enums§

LdltError
Failure modes of the factorization and solves.

Constants§

NEAR_ZERO_PIVOT_REL
Relative tolerance below which a pivot counts as destroyed rather than merely small.

Functions§

amd
Approximate minimum degree ordering (Amestoy, Davis & Duff 1996) - the fill-reducing elimination order for a symmetric sparse matrix.