Summary
The LDLT factorization assumes the input matrix is symmetric, but this precondition is only enforced via debug_assert_symmetric in debug builds. In release, an asymmetric input silently produces wrong results. The documentation should make this contract much more prominent.
Current State
Ldlt::factor calls debug_assert_symmetric(&a) only under #[cfg(debug_assertions)]
- The doc comment on
Matrix::ldlt says "intended for symmetric positive definite (SPD) and positive semi-definite (PSD) matrices" but doesn't warn about undefined behavior for asymmetric inputs
- The struct-level doc says "It assumes the input matrix is symmetric and (numerically) SPD/PSD" but this is easy to miss
Proposed Changes
- Add a prominent
# Preconditions or # Correctness section to Matrix::ldlt documentation explicitly stating that the input must be symmetric, and that violation produces silently wrong results in release builds
- Consider adding a brief note that symmetry is checked only in debug builds (
debug_assert)
- Optionally, add a cheap spot-check in release builds (e.g., check
a[0][1] == a[1][0] and a[0][D-1] == a[D-1][0] for D≥2) as a lightweight guard. This would be O(1) rather than the current O(D²) full check.
Benefits
- Users are clearly warned about the symmetry requirement
- Follows Rust documentation conventions for preconditions (similar to how
sort_unstable documents its comparison contract)
Summary
The LDLT factorization assumes the input matrix is symmetric, but this precondition is only enforced via
debug_assert_symmetricin debug builds. In release, an asymmetric input silently produces wrong results. The documentation should make this contract much more prominent.Current State
Ldlt::factorcallsdebug_assert_symmetric(&a)only under#[cfg(debug_assertions)]Matrix::ldltsays "intended for symmetric positive definite (SPD) and positive semi-definite (PSD) matrices" but doesn't warn about undefined behavior for asymmetric inputsProposed Changes
# Preconditionsor# Correctnesssection toMatrix::ldltdocumentation explicitly stating that the input must be symmetric, and that violation produces silently wrong results in release buildsdebug_assert)a[0][1] == a[1][0]anda[0][D-1] == a[D-1][0]for D≥2) as a lightweight guard. This would be O(1) rather than the current O(D²) full check.Benefits
sort_unstabledocuments its comparison contract)