Skip to content

feat!(matrix): enforce fallible matrix invariants#124

Merged
acgetchell merged 1 commit into
mainfrom
feat/109-fallible-matrix-invariants
Jun 3, 2026
Merged

feat!(matrix): enforce fallible matrix invariants#124
acgetchell merged 1 commit into
mainfrom
feat/109-fallible-matrix-invariants

Conversation

@acgetchell
Copy link
Copy Markdown
Owner

@acgetchell acgetchell commented Jun 3, 2026

  • Add typed errors for unsupported runtime dimensions, out-of-bounds indices, invalid tolerances, and asymmetric matrices.
  • Add checked matrix accessors and stack-matrix runtime dispatch up to D=7.
  • Validate symmetry, tolerances, and non-finite entries before symmetry checks and factorization return typed errors.
  • Update LDLT documentation and README guidance for runtime asymmetry rejection.

BREAKING CHANGE: Matrix::is_symmetric now returns Result<bool, LaError>, and Matrix::first_asymmetry now returns Result<Option<(usize, usize)>, LaError>.

BREAKING CHANGE: LaError no longer implements Eq because InvalidTolerance stores the original f64 tolerance value.

BREAKING CHANGE: Matrix::ldlt rejects asymmetric inputs with LaError::Asymmetric, and LU/LDLT reject negative, NaN, or infinite tolerances with LaError::InvalidTolerance.

Summary by CodeRabbit

  • New Features

    • Added new error variants providing detailed context for invalid dimensions, out-of-bounds access, invalid tolerances, and asymmetric matrices.
    • Introduced a macro for stack-matrix dispatch supporting dimensions up to 7.
    • Added bounds-checked element access methods.
    • Symmetry validation now returns typed errors for better error reporting.
  • Bug Fixes

    • Asymmetric matrices are now rejected before factorization begins.
  • Documentation

    • Expanded guidance on handling asymmetric matrices with links to validation methods.
    • Added documentation lint configuration.

- Add typed errors for unsupported runtime dimensions, out-of-bounds indices,
  invalid tolerances, and asymmetric matrices.
- Add checked matrix accessors and stack-matrix runtime dispatch up to D=7.
- Validate symmetry, tolerances, and non-finite entries before symmetry checks
  and factorization return typed errors.
- Update LDLT documentation and README guidance for runtime asymmetry rejection.

BREAKING CHANGE: Matrix::is_symmetric now returns Result<bool, LaError>, and
Matrix::first_asymmetry now returns Result<Option<(usize, usize)>, LaError>.

BREAKING CHANGE: LaError no longer implements Eq because InvalidTolerance
stores the original f64 tolerance value.

BREAKING CHANGE: Matrix::ldlt rejects asymmetric inputs with LaError::Asymmetric,
and LU/LDLT reject negative, NaN, or infinite tolerances with
LaError::InvalidTolerance.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 3, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

The PR extends the linear-algebra error surface with four new LaError variants (UnsupportedDimension, IndexOutOfBounds, InvalidTolerance, Asymmetric), adds bounds-checked matrix access methods, transforms symmetry validation from non-fallible predicates to Result-returning functions, and enforces asymmetric-input rejection in LDLT factorization using the new typed errors.

Changes

Error Type and Validation API Surface

Layer / File(s) Summary
LaError variants and constructor API
src/lib.rs
Four new error variants with structured fields (UnsupportedDimension, IndexOutOfBounds, InvalidTolerance, Asymmetric) and const constructor functions are added; Eq is removed from LaError derive attributes while retaining PartialEq.
Error display formatting and prelude exports
src/lib.rs
Display impl updated to format all four new LaError variants with user-facing messages; MAX_STACK_MATRIX_DISPATCH_DIM constant and try_with_stack_matrix! macro added to public prelude.
try_with_stack_matrix! macro and validation tests
src/lib.rs
Macro dispatches runtime dimensions (0..=7) to concrete Matrix<N> types, initializes zero-constructed matrices, and converts unsupported dimensions to typed errors; unit tests cover dispatch for specific dimensions, zero-dimension support, unsupported-dimension reporting, and error-type conversion via From<LaError>.

Matrix Access and Symmetry Validation

Layer / File(s) Summary
Bounds-checked element access methods
src/matrix.rs, tests/proptest_matrix.rs
get_checked and set_checked const methods return Result<f64, LaError> and Result<(), LaError> with LaError::IndexOutOfBounds containing contextual row/col/dim; property-based tests validate in-bounds success, out-of-bounds error structure, and field values.
Symmetry validation methods returning Result with error handling
src/matrix.rs
is_symmetric and first_asymmetry signatures change to return Result<bool, LaError> and Result<Option<(usize, usize)>, LaError>; tolerance validation added, new symmetry_epsilon helper detects NaN/∞ stored entries separately from asymmetry, overflow-related edge cases tested.
Matrix documentation and test infrastructure updates
src/matrix.rs, tests/proptest_matrix.rs
lu and ldlt documentation updated to include InvalidTolerance and Asymmetric error cases; test module imports adjusted; generated tests updated to handle Result-returning symmetry methods and new get_checked/set_checked assertions.

LDLT Factorization Precondition Enforcement

Layer / File(s) Summary
LDLT documentation and validation flow updates
src/ldlt.rs
Module and method-level documentation updated to state asymmetric inputs are rejected with LaError::Asymmetric before factorization (not just in debug builds); validation boundary and error precedence clarified.
Asymmetry rejection helper and error precedence tests
src/ldlt.rs
New reject_asymmetric helper calls first_asymmetry with fixed tolerance; error precedence tests confirm non-finite off-diagonal detection occurs before asymmetry checking; new tests for asymmetric input and invalid tolerance variants with expected field values.

LU and Documentation Updates

Layer / File(s) Summary
LU validation boundary documentation and test coverage
src/lu.rs
Lu::factor doc comment expanded to define it as sole LU-construction validation boundary rejecting invalid tolerances before any LU logic; new invalid_tolerance_rejected test exercises negative, NaN, and ∞ tolerance rejection.
Configuration and documentation updates
Cargo.toml, README.md
Cargo.toml adds rustdoc lint configuration to deny broken_intra_doc_links; README adds la-stack documentation image badge and updates LDLT section to document LaError::Asymmetric rejection with linked symmetry-checking methods.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related issues

Possibly related PRs

  • acgetchell/la-stack#93: Both PRs focus on LDLT symmetry precondition validation; #93 adds the is_symmetric/first_asymmetry checks, while this PR transforms them to Result-returning functions and uses them to enforce asymmetry rejection in Ldlt::factor.
  • acgetchell/la-stack#47: Both PRs extend LaError with new variants and update Display formatting in src/lib.rs.
  • acgetchell/la-stack#11: The retrieved PR adds the initial Ldlt and Matrix::ldlt LDLT implementation; this PR then modifies Ldlt::factor validation flow to enforce asymmetry rejection and updates symmetry/tolerance APIs.

Suggested labels

rust, api, breaking change, testing, documentation, enhancement

Poem

🐰 From debug assertions into daylight bright,
Errors now typed with context and sight,
Bounds are checked, asymmetry caught,
LU and LDLT with validation wrought—
A stiffer spine for linear might!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: enforcing fallible matrix invariants through typed error handling and runtime validation checks.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/109-fallible-matrix-invariants

Comment @coderabbitai help to get the list of available commands and usage tips.

@acgetchell acgetchell enabled auto-merge June 3, 2026 05:46
@acgetchell acgetchell self-assigned this Jun 3, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented Jun 3, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.55%. Comparing base (bfb0393) to head (e26c283).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #124      +/-   ##
==========================================
- Coverage   99.62%   99.55%   -0.08%     
==========================================
  Files           5        5              
  Lines        2150     2255     +105     
==========================================
+ Hits         2142     2245     +103     
- Misses          8       10       +2     
Flag Coverage Δ
unittests 99.55% <100.00%> (-0.08%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/lib.rs (1)

710-714: 💤 Low value

Consider adding D=6 to the dispatch test invocations.

The gen_stack_matrix_dispatch_tests! macro is invoked for D=2,3,4,5,7 but skips D=6. While the macro arm for dimension 6 exists in try_with_stack_matrix!, adding gen_stack_matrix_dispatch_tests!(6); would ensure full coverage of all supported dispatch arms.

🧪 Proposed fix to add D=6 test
     gen_stack_matrix_dispatch_tests!(2);
     gen_stack_matrix_dispatch_tests!(3);
     gen_stack_matrix_dispatch_tests!(4);
     gen_stack_matrix_dispatch_tests!(5);
+    gen_stack_matrix_dispatch_tests!(6);
     gen_stack_matrix_dispatch_tests!(7);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib.rs` around lines 710 - 714, Add the missing D=6 invocation to the
dispatch test generators: call gen_stack_matrix_dispatch_tests!(6); alongside
the existing calls (gen_stack_matrix_dispatch_tests!(2/3/4/5/7)) so the dispatch
coverage matches the try_with_stack_matrix! arm for dimension 6; this ensures
gen_stack_matrix_dispatch_tests! covers D=6 as well.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/lib.rs`:
- Around line 710-714: Add the missing D=6 invocation to the dispatch test
generators: call gen_stack_matrix_dispatch_tests!(6); alongside the existing
calls (gen_stack_matrix_dispatch_tests!(2/3/4/5/7)) so the dispatch coverage
matches the try_with_stack_matrix! arm for dimension 6; this ensures
gen_stack_matrix_dispatch_tests! covers D=6 as well.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 196d09af-757f-4c41-8cd3-b9b7fc93805c

📥 Commits

Reviewing files that changed from the base of the PR and between bfb0393 and e26c283.

⛔ Files ignored due to path filters (1)
  • docs/assets/la-stack.jpg is excluded by !**/*.jpg
📒 Files selected for processing (7)
  • Cargo.toml
  • README.md
  • src/ldlt.rs
  • src/lib.rs
  • src/lu.rs
  • src/matrix.rs
  • tests/proptest_matrix.rs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant