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.0is accepted). Asymmetric inputs passed toMatrix::ldltreturn a typedLaError::Asymmetriccontaining both observed values and the required allowed difference of zero. The tolerance-basedMatrix::first_asymmetryandMatrix::is_symmetricmethods remain useful diagnostics, but do not prove the exact precondition required by LDLT. Uselu()when exact symmetry or positive definiteness is not guaranteed. A negative LDLT diagonal or a zero diagonal with nonzero remaining coupling returnsLaError::NotPositiveSemidefinitewith a typedPositiveSemidefiniteViolation. An uncoupled zero or positive pivot at or below the caller’s tolerance returnsLaError::Singularwith a numericalSingularityReason. Because these pivots are computed in binary64, success is not an exact positive-definiteness certificate for the stored matrix.