Crate la_stack

Crate la_stack 

Source
Expand description

Β§la-stack

Crates.io Downloads License Docs.rs CI rust-clippy analyze codecov Audit dependencies Codacy Security Scan

Fast, stack-allocated linear algebra for fixed dimensions in Rust.

This crate grew from the need to support delaunay with fast, stack-allocated linear algebra primitives and algorithms while keeping the API intentionally small and explicit.

Β§πŸ“ Introduction

la-stack provides a handful of const-generic, stack-backed building blocks:

  • Vector<const D: usize> for fixed-length vectors ([f64; D] today)
  • Matrix<const D: usize> for fixed-size square matrices ([[f64; D]; D] today)
  • Lu<const D: usize> for LU factorization with partial pivoting (solve + det)

§✨ Design goals

  • βœ… Copy types where possible
  • βœ… Const-generic dimensions (no dynamic sizes)
  • βœ… Explicit algorithms (LU, solve, determinant)
  • βœ… No runtime dependencies (dev-dependencies are for contributors only)
  • βœ… Stack storage only (no heap allocation in core types)
  • βœ… unsafe forbidden

§🚫 Anti-goals

Β§πŸ”’ Scalar types

Today, the core types are implemented for f64. The intent is to support f32 and f64 (and f128 if/when Rust gains a stable primitive for it). Longer term, we may add optional arbitrary-precision support (e.g. via rug) depending on performance.

Β§πŸš€ Quickstart

Add this to your Cargo.toml:

[dependencies]
la-stack = "0.1"

Solve a 5Γ—5 system via LU:

use la_stack::prelude::*;

// This system requires pivoting (a[0][0] = 0), so it's a good LU demo.
// A = J - I: zeros on diagonal, ones elsewhere.
let a = Matrix::<5>::from_rows([
    [0.0, 1.0, 1.0, 1.0, 1.0],
    [1.0, 0.0, 1.0, 1.0, 1.0],
    [1.0, 1.0, 0.0, 1.0, 1.0],
    [1.0, 1.0, 1.0, 0.0, 1.0],
    [1.0, 1.0, 1.0, 1.0, 0.0],
]);

let b = Vector::<5>::new([14.0, 13.0, 12.0, 11.0, 10.0]);

let lu = a.lu(DEFAULT_PIVOT_TOL).unwrap();
let x = lu.solve_vec(b).unwrap().into_array();

// Floating-point rounding is expected; compare with a tolerance.
let expected = [1.0, 2.0, 3.0, 4.0, 5.0];
for (x_i, e_i) in x.iter().zip(expected.iter()) {
    assert!((*x_i - *e_i).abs() <= 1e-12);
}

§🧩 API at a glance

TypeStoragePurposeKey methods
Vector<D>[f64; D]Fixed-length vectornew, zero, dot, norm2_sq
Matrix<D>[[f64; D]; D]Fixed-size square matrixfrom_rows, zero, identity, lu, det
Lu<D>Matrix<D> + pivot arrayFactorization for solves/detsolve_vec, det

Storage shown above reflects the current f64 implementation.

Β§πŸ“‹ Examples

The examples/ directory contains small, runnable programs:

just examples
# or:
cargo run --example solve_5x5
cargo run --example det_5x5

§🀝 Contributing

A short contributor workflow:

cargo install just
just ci           # lint + fast tests + bench compile
just commit-check # lint + all tests + examples

For the full set of developer commands, see just --list and WARP.md.

Β§πŸ“Š Benchmarks (vs nalgebra/faer)

LU solve (factor + solve): median time vs dimension

Raw data: docs/assets/bench/vs_linalg_lu_solve_median.csv

Summary (median time; lower is better). The β€œla-stack vs nalgebra/faer” columns show the % time reduction relative to each baseline (positive = la-stack faster):

Dla-stack median (ns)nalgebra median (ns)faer median (ns)la-stack vs nalgebrala-stack vs faer
22.04318.278159.281+88.8%+98.7%
313.44923.337196.591+42.4%+93.2%
427.80754.199226.222+48.7%+87.7%
546.07573.548290.914+37.4%+84.2%
8138.187177.453379.886+22.1%+63.6%
16626.078594.055897.044-5.4%+30.2%
322,684.6962,502.0312,909.466-7.3%+7.7%
6416,721.57614,875.77012,493.628-12.4%-33.8%

Β§πŸ“„ License

BSD 3-Clause License. See LICENSE.

ModulesΒ§

prelude
Common imports for ergonomic usage.

StructsΒ§

Lu
LU decomposition (PA = LU) with partial pivoting.
Matrix
Fixed-size square matrix DΓ—D, stored inline.
Vector
Fixed-size vector of length D, stored inline.

EnumsΒ§

LaError
Linear algebra errors.

ConstantsΒ§

DEFAULT_PIVOT_TOL
Default absolute pivot tolerance used for singularity detection.