Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion .github/actions/setup-just/action.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
name: Set up just
description: Resolve the pinned just version from justfile and install it.

inputs:
cache:
description: Restore and save the installed just binary in the Actions cache.
required: false
default: "true"

outputs:
version:
description: Resolved just version from justfile.
Expand Down Expand Up @@ -45,7 +51,15 @@ runs:

echo "version=$version" >> "$GITHUB_OUTPUT"

- name: Install just
- name: Install just with caching
if: inputs.cache == 'true'
uses: taiki-e/cache-cargo-install-action@9ee83daaa7b96a6fab930949ecf1122bba04a389 # v3.0.8
with:
tool: just@${{ steps.resolve.outputs.version }}

- name: Install just without caching
if: inputs.cache != 'true'
shell: bash
env:
JUST_VERSION: ${{ steps.resolve.outputs.version }}
run: cargo install --locked just --version "$JUST_VERSION"
9 changes: 6 additions & 3 deletions .github/workflows/release-benchmarks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,12 @@ jobs:
uses: actions-rust-lang/setup-rust-toolchain@166cdcfd11aee3cb47222f9ddb555ce30ddb9659 # v1.17.0
with:
cache: false
cache-bin: false

- name: Set up just
uses: ./.github/actions/setup-just # zizmor: ignore[self-repository] actionlint 1.7.12 does not accept $/...
with:
cache: false

- name: Resolve cargo-nextest version
id: cargo_nextest_version
Expand All @@ -56,9 +59,9 @@ jobs:
echo "version=$version" >> "$GITHUB_OUTPUT"

- name: Install cargo-nextest
uses: taiki-e/cache-cargo-install-action@9ee83daaa7b96a6fab930949ecf1122bba04a389 # v3.0.8
with:
tool: cargo-nextest@${{ steps.cargo_nextest_version.outputs.version }}
env:
CARGO_NEXTEST_VERSION: ${{ steps.cargo_nextest_version.outputs.version }}
run: cargo install --locked cargo-nextest --version "$CARGO_NEXTEST_VERSION"

- name: Validate benchmark inputs
run: just test-bench-inputs
Expand Down
20 changes: 20 additions & 0 deletions .github/workflows/zizmor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,27 @@ jobs:
with:
persist-credentials: false

- name: Set up just
uses: ./.github/actions/setup-just # zizmor: ignore[self-repository] actionlint 1.7.12 does not accept $/...

- name: Resolve zizmor version
id: zizmor_version
shell: bash
run: |
set -euo pipefail

version="$(just --evaluate zizmor_version)"
if [[ -z "$version" ]]; then
echo "::error::Could not resolve zizmor_version from justfile"
exit 1
fi

echo "version=$version" >> "$GITHUB_OUTPUT"

- name: Run zizmor
uses: zizmorcore/zizmor-action@70fb788f84895a7701f5643d103d587e460b5c99 # v0.6.3
with:
inputs: .github
online-audits: true
persona: regular
version: ${{ steps.zizmor_version.outputs.version }}
717 changes: 210 additions & 507 deletions AGENTS.md

Large diffs are not rendered by default.

37 changes: 34 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ checks spelling. Python support tooling is locked with `uv` and checked by
Ruff, Ty, and Semgrep. GitHub Actions references are SHA-pinned, restricted to
an explicit allowlist, and kept with readable version comments for review.

`just zizmor` uses the same pinned scanner and `regular` persona as the SARIF
workflow. It runs online audits using `ZIZMOR_GITHUB_TOKEN`, `GH_TOKEN`,
`GITHUB_TOKEN`, or an authenticated `gh auth token`, in that order, without
printing the token. Without authentication it reports an offline fallback;
SHA/version-comment resolution and other online findings are then unchecked.
Use `ZIZMOR_OFFLINE=true just zizmor` to request offline audits explicitly.
Zizmor owns remote action SHA/tag resolution; Semgrep guards explicit scanner
version configuration and cache isolation in release workflows.

CI runs `just ci` on Ubuntu, macOS, and Windows to keep platform coverage
aligned with the local comprehensive validation path.

Expand Down Expand Up @@ -128,6 +137,23 @@ For final validation of a non-core change, compose each affected surface once:
- Benchmark inputs or harnesses: `just test-bench-inputs` or `just bench-compile`
- Examples: `just examples`

For individual edited file formats, use these focused checks and formatters:

| Surface | Commands |
|---------|----------|
| JSON | `jq empty <file>.json` or `just validate-json` |
| TOML | `just toml-lint`, `just toml-fmt-check`; format with `just toml-fmt` |
| GitHub Actions | `just action-lint` |
| Shell scripts | `just shell-fix`, then `just shell-check` |
| YAML | `just yaml-fix`, then `just yaml-lint` |
| Markdown | `just markdown-fix`, then `just markdown-ci` |

Run `just spell-check` after editing; `markdown-ci` already includes it. Add
legitimate technical terms to `typos.toml` under `[default.extend-words]`.
Detailed test design, dimension coverage, and benchmark measurement rules live
in [Testing guidance](docs/dev/testing.md). README and guide doctest requirements
live in [Documentation guidance](docs/dev/docs.md).

Run `just ci` for core Rust, public behavior, or GitHub-equivalent validation.
It composes leaf validators directly and runs `clippy-all-targets` to match the
GitHub Clippy SARIF workflow. Unit and integration tests still run together once
Expand All @@ -147,13 +173,17 @@ Use the existing canonical documents instead of duplicating their guidance:
| Topic | Canonical reference |
|-------|---------------------|
| Agent rules and repository invariants | [`AGENTS.md`](AGENTS.md) |
| GitHub and agent commit-message procedures | [`docs/dev/MANAGING_CHANGES.md`](docs/dev/MANAGING_CHANGES.md) |
| Module, feature, and file ownership | [`docs/code_organization.md`](docs/code_organization.md) |
| Test design and dimension coverage | [`docs/dev/testing.md`](docs/dev/testing.md) |
| Documentation ownership and rustdoc maintenance | [`docs/dev/docs.md`](docs/dev/docs.md) |
| User-facing API, examples, and project scope | [`README.md`](README.md) |
| Mathematical basis and numerical validity | [`docs/mathematical_basis.md`](docs/mathematical_basis.md) |
| Package metadata, features, and dependencies | [`Cargo.toml`](Cargo.toml) |
| Commands and validation workflow | [`justfile`](justfile), `just --list` |
| Python support tooling | [`scripts/README.md`](scripts/README.md) |
| Benchmark methodology and baselines | [`docs/BENCHMARKING.md`](docs/BENCHMARKING.md) |
| Coverage workflow and reports | [`docs/COVERAGE.md`](docs/COVERAGE.md) |
| Coverage workflow and reports | [`docs/MEASURING_COVERAGE.md`](docs/MEASURING_COVERAGE.md) |
| Citations and bibliography | [`CITATION.cff`](CITATION.cff), [`REFERENCES.md`](REFERENCES.md) |
| Security reporting and support | [`SECURITY.md`](SECURITY.md) |
| Releases and changelog generation | [`docs/RELEASING.md`](docs/RELEASING.md), [`CHANGELOG.md`](CHANGELOG.md) |
Expand Down Expand Up @@ -212,7 +242,7 @@ benefit that justifies it.
Core Rust, Cargo, or public-behavior changes must pass `just ci` before a pull
request is ready. Documentation, configuration, Python, test-only,
benchmark-only, and example-only changes use the matching focused validators
documented in [`AGENTS.md`](AGENTS.md). Pull requests are reviewed for correctness,
listed in [Validation Workflow](#validation-workflow). Pull requests are reviewed for correctness,
mathematical accuracy, tests, documentation, style, dependency impact, and
performance. Non-substantive whitespace or formatting churn may be declined
unless it is part of an intentional tooling cleanup.
Expand All @@ -231,7 +261,8 @@ canonical rules and invariants for AI coding assistants and autonomous agents
working on this codebase.

AI tools, including ChatGPT, Claude, CodeRabbit, Codex, KiloCode, and WARP, are
expected to read and follow `AGENTS.md` when proposing or applying changes.
expected to read and follow `AGENTS.md` and its task-relevant linked guidance
when proposing or applying changes.

Portions of this library were developed with the assistance of these tools:

Expand Down
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

84 changes: 47 additions & 37 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ while keeping the API intentionally small and explicit.
## Contents

- [Introduction](#-introduction)
- [Use this crate when](#-use-this-crate-when)
- [Quickstart](#-quickstart)
- [Mathematical basis](#-mathematical-basis)
- [Design goals](#-design-goals)
- [Anti-goals](#-anti-goals)
- [Use this crate when](#-use-this-crate-when)
- [Scalar and bounded-value types](#-scalar-and-bounded-value-types)
- [Features](#-features)
- [Adaptive determinant filtering (D ≤ 4)](#adaptive-determinant-filtering-d--4)
Expand All @@ -49,26 +49,40 @@ while keeping the API intentionally small and explicit.

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

- `Vector<const D: usize>` for fixed-length `f64` vectors backed by `[f64; D]`
- `gram_matrix(&[Vector<N>; M])` for allocation-free `Matrix<M>` construction
from pairwise vector inner products, with bit-for-bit symmetry. Gram matrices
encode lengths and angles and support simplex/facet volume calculations; see
[Gram matrices and geometric measures](REFERENCES.md#gram-matrices-and-geometric-measures).
[Gram matrices and geometric measures][refs-gram].
Each independent dot product is checked once;
rounding has no certified error bound, and positive definiteness or affine
independence must still be established by factorization or the caller.
Benchmark square simplex and rectangular facet inputs through dimension 8
with `cargo bench --locked --features bench --bench gram`.
- `Matrix<const D: usize>` for fixed-size square `f64` matrices backed by `[[f64; D]; D]`
- `Interval` and `IntervalMatrix<const D: usize>` for outward-rounded,
proof-bearing determinant filters through D=7
- `ScalarWithErrorBound` for proof-bearing fixed-vector dot products and
affine differences over finite `f64` inputs
- `RationalVector<const D: usize>` and `RationalMatrix<const D: usize>` for
exact rational inputs behind the optional `"exact"` feature
- `Lu<const D: usize>` for LU factorization with partial pivoting (solve + det)
- `Ldlt<const D: usize>` for no-pivot factorization intended for exactly
symmetric positive-definite matrices (solve + det; typed pivot diagnostics)
- `Lu<const D: usize>` for LU factorization with partial pivoting (solve + det)
- `Matrix<const D: usize>` for fixed-size square `f64` matrices backed by `[[f64; D]; D]`
- `RationalVector<const D: usize>` and `RationalMatrix<const D: usize>` for
exact rational inputs behind the optional `"exact"` feature
- `ScalarWithErrorBound` for proof-bearing fixed-vector dot products and
affine differences over finite `f64` inputs
- `Vector<const D: usize>` for fixed-length `f64` vectors backed by `[f64; D]`

## ✅ Use this crate when

- Robust predicates matter for geometry-style workloads near degeneracy
- Stack allocation and `Copy` value semantics fit your data flow
- You need a certified sign or threshold comparison for a fixed-vector dot
product or `axis · (left - right)` expression
- You need a cheap, sound interval filter for determinant expressions assembled
from rounded binary64 operations
- You need exact determinants, exact determinant signs, or exact linear solves
for fixed-size systems
- You prefer a default build with no runtime dependencies
- You want explicit LU / LDLT / determinant APIs rather than a broad algebra toolkit
- Your matrices and vectors have small, fixed dimensions known at compile time

## 🚀 Quickstart

Expand Down Expand Up @@ -123,29 +137,31 @@ provide a certified solution error bound.
## 🧮 Mathematical basis

`la-stack` operates on finite IEEE 754 binary64 values in small, fixed
dimensions. Its floating-point paths use LU with partial pivoting, LDLT without
pivoting for exactly symmetric positive-definite matrices, and closed-form
dimensions. Its floating-point paths use [LU with partial pivoting][refs-lu],
[LDLT without pivoting][refs-ldlt] for exactly symmetric positive-definite matrices, and closed-form
determinants through D=4. These results remain subject to conditioning and
binary64 rounding;
factorization tolerances are rejection thresholds, not accuracy guarantees. For
D≤4, direct determinants can be paired with a conservative absolute roundoff
bound when its range preconditions hold. Fixed-vector dot products and direct
affine differences can likewise return a paired estimate and certified absolute
D≤4, direct determinants can be paired with a
[conservative absolute roundoff bound][refs-det-bound] when its range
preconditions hold. [Fixed-vector dot products and direct affine differences][refs-reductions]
can likewise return a paired estimate and certified absolute
roundoff bound without enabling arbitrary-precision dependencies.

Derived binary64 expressions can instead be assembled with `Interval`
subtraction, addition, multiplication, negation, and square. The resulting
`IntervalMatrix<D>` determinant sign is certified through D=7 when its enclosure
`IntervalMatrix<D>` [determinant sign][refs-interval] is certified through D=7 when its enclosure
separates zero; the singleton `[0, 0]` also certifies exact zero. Every other
overlap with zero is explicitly inconclusive. This default-feature surface is
distinct from arbitrary-precision exact arithmetic.

With `features = ["exact"]`, callers can either lift stored binary64 inputs
losslessly or supply already-exact rational inputs for exact determinant signs,
determinant values, and solves. Exactness over binary64 input starts at the
losslessly or supply already-exact rational inputs for
[exact determinant signs][refs-exact-sign], determinant values, and
[solves][refs-exact-solve]. Exactness over binary64 input starts at the
stored values and cannot recover information rounded away before construction.
See the
[mathematical basis](https://github.com/acgetchell/la-stack/blob/v0.4.5/docs/mathematical_basis.md)
[mathematical basis](https://github.com/acgetchell/la-stack/blob/main/docs/mathematical_basis.md)
for the algorithms, validity boundaries, and supporting references.

## 🎯 Design goals
Expand Down Expand Up @@ -191,20 +207,6 @@ for current release planning.
- Broad general-purpose linear algebra: use [`nalgebra`](https://crates.io/crates/nalgebra)
- Large matrices/dimensions with parallelism: use [`faer`](https://crates.io/crates/faer)

## ✅ Use this crate when

- Your matrices and vectors have small, fixed dimensions known at compile time
- Stack allocation and `Copy` value semantics fit your data flow
- You want explicit LU / LDLT / determinant APIs rather than a broad algebra toolkit
- You need exact determinants, exact determinant signs, or exact linear solves
for fixed-size systems
- You need a cheap, sound interval filter for determinant expressions assembled
from rounded binary64 operations
- You need a certified sign or threshold comparison for a fixed-vector dot
product or `axis · (left - right)` expression
- Robust predicates matter for geometry-style workloads near degeneracy
- You prefer a default build with no runtime dependencies

## 🔢 Scalar and bounded-value types

The public point-value scalar model deliberately has two input domains:
Expand Down Expand Up @@ -359,10 +361,10 @@ for the full contracts.
## 🗺️ Documentation Map

- [API guide][api-guide] — worked examples, API selection, storage, and error contracts.
- [Mathematical basis](https://github.com/acgetchell/la-stack/blob/v0.4.5/docs/mathematical_basis.md) — algorithms, numerical guarantees, and limitations.
- [Mathematical basis](https://github.com/acgetchell/la-stack/blob/main/docs/mathematical_basis.md) — algorithms, numerical guarantees, and limitations.
- [Benchmarking](https://github.com/acgetchell/la-stack/blob/v0.4.5/docs/BENCHMARKING.md) — benchmark suites, comparison workflows, and measurement methodology.
- [Performance reports](https://github.com/acgetchell/la-stack/blob/v0.4.5/docs/PERFORMANCE.md) — release-to-release measurement results and provenance.
- [Coverage](https://github.com/acgetchell/la-stack/blob/v0.4.5/docs/COVERAGE.md) — local and CI coverage commands and report locations.
- [Performance reports](https://github.com/acgetchell/la-stack/blob/main/docs/performance.md) — release-to-release measurement results and provenance.
- [Coverage](https://github.com/acgetchell/la-stack/blob/main/docs/MEASURING_COVERAGE.md) — local and CI coverage commands and report locations.
- [Roadmap](https://github.com/acgetchell/la-stack/blob/v0.4.5/docs/roadmap.md) — release planning, future directions, and non-goals.
- [Releasing](https://github.com/acgetchell/la-stack/blob/v0.4.5/docs/RELEASING.md) — release preparation, validation, and publication.

Expand Down Expand Up @@ -395,7 +397,7 @@ For the full per-kernel comparison methodology, algorithm citations, input
construction, and release-comparison workflow details, see
[docs/BENCHMARKING.md](https://github.com/acgetchell/la-stack/blob/v0.4.5/docs/BENCHMARKING.md).
For the current release-to-release performance snapshot, see
[docs/PERFORMANCE.md](https://github.com/acgetchell/la-stack/blob/v0.4.5/docs/PERFORMANCE.md).
[docs/performance.md](https://github.com/acgetchell/la-stack/blob/main/docs/performance.md).
The exact release suite includes the already-exact rational-input groups for
D=2 through D=8. Those rows report `RationalMatrix::det_sign`, `det`, and
`solve` alongside straightforward `BigRational` Gaussian determinant and solve
Expand Down Expand Up @@ -482,7 +484,7 @@ CI runs `just ci` on Ubuntu, macOS, and Windows to keep platform coverage
aligned with the local comprehensive validation path.

For coverage commands and report locations, see
[`docs/COVERAGE.md`](https://github.com/acgetchell/la-stack/blob/v0.4.5/docs/COVERAGE.md).
[`docs/MEASURING_COVERAGE.md`](https://github.com/acgetchell/la-stack/blob/main/docs/MEASURING_COVERAGE.md).
For the full contributor workflow, see
[CONTRIBUTING.md](https://github.com/acgetchell/la-stack/blob/v0.4.5/CONTRIBUTING.md).

Expand Down Expand Up @@ -517,3 +519,11 @@ BSD 3-Clause License. See [LICENSE](https://github.com/acgetchell/la-stack/blob/
[clippy-badge]: https://github.com/acgetchell/la-stack/actions/workflows/rust-clippy.yml/badge.svg
[clippy-workflow]: https://github.com/acgetchell/la-stack/actions/workflows/rust-clippy.yml
[lu-solve-benchmark]: https://raw.githubusercontent.com/acgetchell/la-stack/v0.4.5/docs/assets/bench/vs_linalg_lu_solve_median.svg
[refs-det-bound]: https://github.com/acgetchell/la-stack/blob/main/REFERENCES.md#absolute-error-bound-for-closed-form-determinants
[refs-exact-sign]: https://github.com/acgetchell/la-stack/blob/main/REFERENCES.md#exact-determinant-sign-adaptive-precision-integer-arithmetic
[refs-exact-solve]: https://github.com/acgetchell/la-stack/blob/main/REFERENCES.md#exact-linear-system-solve-hybrid-bareiss--bigrational
[refs-gram]: https://github.com/acgetchell/la-stack/blob/main/REFERENCES.md#gram-matrices-and-geometric-measures
[refs-interval]: https://github.com/acgetchell/la-stack/blob/main/REFERENCES.md#outward-rounded-interval-determinant-sign
[refs-ldlt]: https://github.com/acgetchell/la-stack/blob/main/REFERENCES.md#ldlᵀ-factorization-exactly-symmetric-positive-definite-inputs
[refs-lu]: https://github.com/acgetchell/la-stack/blob/main/REFERENCES.md#lu-decomposition-gaussian-elimination-with-partial-pivoting
[refs-reductions]: https://github.com/acgetchell/la-stack/blob/main/REFERENCES.md#certified-fixed-vector-reductions
Loading
Loading