Skip to content

Commit d3b7012

Browse files
acgetchelloz-agent
andcommitted
test: add LDLT NonFinite coverage tests; update README example
- Add tests for L-multiplier overflow and trailing submatrix overflow during LDLT factorization - Add test for forward substitution overflow in LDLT solve_vec - Update README det_sign_exact example for Result API (.unwrap()) Co-Authored-By: Oz <oz-agent@warp.dev>
1 parent 717d5cf commit d3b7012

3 files changed

Lines changed: 42 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [Unreleased]
9+
10+
### Fixed
11+
12+
- Return Result from det_sign_exact, rename NonFinite field [`717d5cf`](https://github.com/acgetchell/la-stack/commit/717d5cf13af77764e8941004cdf2c153c260690f)
13+
814
## [0.2.0] - 2026-03-07
915

1016
### Added
@@ -46,6 +52,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
4652

4753
- Replace cspell with typos-cli, bump MSRV to 1.94.0 [`6db12be`](https://github.com/acgetchell/la-stack/commit/6db12bebdc332f93f9663c0c0be8e785ab449fa6)
4854
- Add changelog tooling (git-cliff + tag script) [`5475651`](https://github.com/acgetchell/la-stack/commit/547565142a374d6a7fed432dd6dbaa8b24cf98a1)
55+
- Release v0.2.0 [`922006d`](https://github.com/acgetchell/la-stack/commit/922006d4a6d905bdb66b7eb729e0cb4eca1da70a)
4956

5057
### Performance
5158

@@ -138,6 +145,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
138145

139146
- Add tarpaulin coverage upload [`7486dfd`](https://github.com/acgetchell/la-stack/commit/7486dfd54e16a6dbde41575c3f35a1acb65f57d2)
140147

148+
[unreleased]: https://github.com/acgetchell/la-stack/compare/v0.2.0..HEAD
141149
[0.2.0]: https://github.com/acgetchell/la-stack/compare/v0.1.3..v0.2.0
142150
[0.1.3]: https://github.com/acgetchell/la-stack/compare/v0.1.2..v0.1.3
143151
[0.1.2]: https://github.com/acgetchell/la-stack/compare/v0.1.1..v0.1.2

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ let m = Matrix::<3>::from_rows([
153153
[4.0, 5.0, 6.0],
154154
[7.0, 8.0, 9.0],
155155
]);
156-
assert_eq!(m.det_sign_exact(), 0); // exactly singular
156+
assert_eq!(m.det_sign_exact().unwrap(), 0); // exactly singular
157157
```
158158

159159
For D ≤ 4, a fast f64 filter (error-bounded `det_direct()`) resolves the sign

src/ldlt.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,4 +333,37 @@ mod tests {
333333
let err = a.ldlt(DEFAULT_SINGULAR_TOL).unwrap_err();
334334
assert_eq!(err, LaError::NonFinite { col: 0 });
335335
}
336+
337+
#[test]
338+
fn nonfinite_l_multiplier_overflow() {
339+
// d = 1e-11 > tol, but l = 1e300 / 1e-11 = 1e311 overflows f64.
340+
let a = Matrix::<2>::from_rows([[1e-11, 1e300], [1e300, 1.0]]);
341+
let err = a.ldlt(DEFAULT_SINGULAR_TOL).unwrap_err();
342+
assert_eq!(err, LaError::NonFinite { col: 0 });
343+
}
344+
345+
#[test]
346+
fn nonfinite_trailing_submatrix_overflow() {
347+
// L multiplier is finite (1e200), but the rank-1 update
348+
// (-1e200 * 1.0) * 1e200 + 1.0 overflows.
349+
let a = Matrix::<2>::from_rows([[1.0, 1e200], [1e200, 1.0]]);
350+
let err = a.ldlt(DEFAULT_SINGULAR_TOL).unwrap_err();
351+
assert_eq!(err, LaError::NonFinite { col: 0 });
352+
}
353+
354+
#[test]
355+
fn nonfinite_solve_vec_forward_substitution_overflow() {
356+
// SPD matrix with large L multiplier: L[1,0] = 1e153.
357+
// Forward substitution overflows: y[1] = 0 - 1e153 * 1e156 = -inf.
358+
let a = Matrix::<3>::from_rows([
359+
[1.0, 1e153, 0.0],
360+
[1e153, 1e306 + 1.0, 0.0],
361+
[0.0, 0.0, 1.0],
362+
]);
363+
let ldlt = a.ldlt(DEFAULT_SINGULAR_TOL).unwrap();
364+
365+
let b = Vector::<3>::new([1e156, 0.0, 0.0]);
366+
let err = ldlt.solve_vec(b).unwrap_err();
367+
assert_eq!(err, LaError::NonFinite { col: 1 });
368+
}
336369
}

0 commit comments

Comments
 (0)