Skip to content

perf(lambda-rs): Compute the determinant via Gaussian elimination for smaller matrices#194

Merged
vmarcella merged 4 commits intomainfrom
vmarcella/optimize-determinant
Mar 12, 2026
Merged

perf(lambda-rs): Compute the determinant via Gaussian elimination for smaller matrices#194
vmarcella merged 4 commits intomainfrom
vmarcella/optimize-determinant

Conversation

@vmarcella
Copy link
Member

Summary

Optimize determinant computation in lambda-rs matrix math by replacing recursive Laplace expansion with Gaussian elimination plus partial pivoting. This reduces determinant evaluation from factorial-time growth to cubic-time growth for square matrices and adds stack-allocated fast paths for common 3x3 and 4x4 cases.

Related Issues

None linked.

Changes

  • Replace recursive determinant expansion in crates/lambda-rs/src/math/matrix.rs with Gaussian elimination and partial pivoting.
  • Add fixed-size stack fast paths for 3x3 and 4x4 matrices to avoid heap allocation in common transform-sized matrices.
  • Change the larger-matrix fallback scratch space from Vec<Vec<f32>> to a contiguous row-major Vec<f32> for better cache locality and fewer allocations.

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • Feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation (updates to docs, specs, tutorials, or comments)
  • Refactor (code change that neither fixes a bug nor adds a feature)
  • Performance (change that improves performance)
  • Test (adding or updating tests)
  • Build/CI (changes to build process or CI configuration)

Affected Crates

  • lambda-rs
  • lambda-rs-platform
  • lambda-rs-args
  • lambda-rs-logging
  • Other:

Checklist

  • Code follows the repository style guidelines (cargo +nightly fmt --all)
  • Code passes clippy (cargo clippy --workspace --all-targets -- -D warnings)
  • Tests pass (cargo test --workspace)
  • New code includes appropriate documentation
  • Public API changes are documented
  • Breaking changes are noted in this PR description

Testing

Commands run:

cargo test -p lambda-rs math::matrix

Manual verification steps (if applicable):

  1. Confirm determinant() uses stack fast paths for 3x3 and 4x4 matrices.
  2. Confirm larger matrices use a contiguous flat scratch buffer instead of nested vectors.

Screenshots/Recordings

Not applicable.

Platform Testing

  • macOS
  • Windows
  • Linux

Additional Notes

Asymptotic runtime for determinant computation improves from O(n!) under recursive Laplace expansion to O(n^3) with Gaussian elimination. Space remains O(n^2), with lower constant overhead for both fixed-size and larger-matrix paths.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR optimizes determinant computation in lambda-rs matrix math by replacing factorial-time Laplace expansion with Gaussian elimination (partial pivoting), adding allocation-free fast paths for common transform sizes.

Changes:

  • Implement Gaussian-elimination-based determinant with partial pivoting.
  • Add stack-allocated determinant paths for 3x3 and 4x4 matrices.
  • Switch the larger-matrix scratch space to a contiguous row-major Vec<f32> buffer.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +288 to +290
if pivot_abs <= f32::EPSILON {
return 0.0;
}
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

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

The singular-pivot detection uses an absolute threshold pivot_abs <= f32::EPSILON, which will incorrectly return 0.0 for valid matrices whose pivots are small in magnitude (e.g., a diagonal matrix with leading entry 1e-8 has a non-zero determinant but would be treated as singular). Consider checking pivot_abs == 0.0 (or using a relative tolerance based on matrix scale) so non-zero determinants aren’t collapsed to zero.

Copilot uses AI. Check for mistakes.
Comment on lines +462 to +464
if pivot_abs <= f32::EPSILON {
return Ok(0.0);
}
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

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

The fallback elimination path also treats pivot_abs <= f32::EPSILON as singular. This is an absolute threshold and can make determinant() return 0.0 for non-singular matrices with small-magnitude values. Use an exact-zero check or a relative tolerance derived from the matrix magnitude to avoid incorrect zero determinants.

Copilot uses AI. Check for mistakes.
Comment on lines +430 to +438
if rows == 4 {
let mut data = [[0.0_f32; 4]; 4];
for (i, row) in data.iter_mut().enumerate() {
for (j, value) in row.iter_mut().enumerate() {
*value = self.at(i, j);
}
}
return Ok(determinant_gaussian_stack::<4>(data));
}
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

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

New 4x4 stack fast-path and the >4 generic elimination path aren’t covered by tests in this module (current determinant tests only exercise 2x2 and 3x3). Please add tests for at least one 4x4 determinant and one larger matrix (e.g., 5x5) to validate correctness and pivoting/sign behavior.

Copilot uses AI. Check for mistakes.
@github-actions
Copy link

github-actions bot commented Mar 12, 2026

✅ Coverage Report

📊 View Full HTML Report (download artifact)

Overall Coverage

Metric Value
Total Line Coverage 76.98%
Lines Covered 12881 / 16732

Changed Files in This PR

File Coverage Lines
crates/lambda-rs/src/math/matrix.rs 88.06% 413/469

PR Files Coverage: 88.05% (413/469 lines)


Generated by cargo-llvm-cov · Latest main coverage

Last updated: 2026-03-12 20:36:18 UTC · Commit: 9bdf71e

@vmarcella vmarcella merged commit 52e6a34 into main Mar 12, 2026
10 checks passed
@vmarcella vmarcella deleted the vmarcella/optimize-determinant branch March 12, 2026 20:43
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.

2 participants