Skip to main content

Module ldlt

Module ldlt 

Source
Expand description

LDLT determinants and exact symmetry.

Compute a determinant for a symmetric positive-definite matrix via LDLT (no pivoting).

For these matrices, LDLᵀ is a square-root-free Cholesky form. Multiplying each column of L by the square root of the corresponding diagonal entry yields a Cholesky factor:

use la_stack::prelude::*;

fn main() -> Result<(), LaError> {
    // This matrix is symmetric positive-definite (A = L*L^T) so LDLT works without pivoting.
    let a = Matrix::<5>::try_from_rows([
        [1.0, 1.0, 0.0, 0.0, 0.0],
        [1.0, 2.0, 1.0, 0.0, 0.0],
        [0.0, 1.0, 2.0, 1.0, 0.0],
        [0.0, 0.0, 1.0, 2.0, 1.0],
        [0.0, 0.0, 0.0, 1.0, 2.0],
    ])?;

    let ldlt = match a.ldlt(DEFAULT_SINGULAR_TOL) {
        Ok(ldlt) => ldlt,
        Err(err @ LaError::Asymmetric {
            row,
            col,
            upper,
            lower,
            allowed_abs_diff,
            ..
        }) => {
            eprintln!(
                "LDLT mismatch at ({row}, {col}): {upper} vs {lower} (allowed {allowed_abs_diff})"
            );
            return Err(err);
        }
        Err(err) => return Err(err),
    };

    let det = ldlt.det()?;
    assert!((det - 1.0).abs() <= 1e-12);

    Ok(())
}

⚠️ LDLT invariant: The input matrix must be exactly symmetric: every mirrored pair must compare equal (+0.0 == -0.0 is accepted). Asymmetric inputs passed to Matrix::ldlt return a typed LaError::Asymmetric containing both observed values and the required allowed difference of zero. The tolerance-based Matrix::first_asymmetry and Matrix::is_symmetric methods remain useful diagnostics, but do not prove the exact precondition required by LDLT. Use lu() when exact symmetry or positive definiteness is not guaranteed. A negative LDLT diagonal or a zero diagonal with nonzero remaining coupling returns LaError::NotPositiveSemidefinite with a typed PositiveSemidefiniteViolation. An uncoupled zero or positive pivot at or below the caller’s tolerance returns LaError::Singular with a numerical SingularityReason. Because these pivots are computed in binary64, success is not an exact positive-definiteness certificate for the stored matrix.