Essential guidance for AI assistants working in this repository.
When making changes in this repo, prioritize (in order):
- Correctness
- Speed
- Coverage (but keep the code idiomatic Rust)
- NEVER run
git commit,git push,git tag, or any git commands that modify version control state - ALLOWED: Run read-only git commands (e.g.
git --no-pager status,git --no-pager diff,git --no-pager log,git --no-pager show,git --no-pager blame) to inspect changes/history - ALWAYS use
git --no-pagerwhen reading git output - Suggest git commands that modify version control state for the user to run manually
When user requests commit message generation:
- Run
git --no-pager diff --cached --stat - Generate conventional commit format:
<type>: <brief summary> - Types:
feat,fix,refactor,perf,docs,test,chore,style,ci,build - Include body with organized bullet points and test results
- Present in code block (no language) - user will commit manually
- ALLOWED: Run formatters/linters:
cargo fmt,cargo clippy,cargo doc,taplo fmt,taplo lint,uv run ruff check --fix,uv run ruff format,shfmt -w,shellcheck -x,npx markdownlint --fix,typos,actionlint - NEVER: Use
sed,awk,perlfor code edits - ALWAYS: Use
edit_filestool for edits (andcreate_filefor new files) - EXCEPTION: Shell text tools OK for read-only analysis only
- JSON: Validate with
jq empty <file>.jsonafter editing (orjust validate-json) - TOML: Lint/format with taplo:
just toml-lint,just toml-fmt-check,just toml-fmt - GitHub Actions: Validate workflows with
just action-lint(usesactionlint) - Spell check: Run
just spell-checkafter editing; add legitimate technical terms totypos.tomlunder[default.extend-words] - Shell scripts: Run
shfmt -w scripts/*.shandshellcheck -x scripts/*.shafter editing - YAML: Use
just yaml-lintandjust yaml-fix - Markdown: Use
just markdown-checkandjust markdown-fix
- Prefer borrowed APIs by default:
take references (
&T,&mut T,&[T]) as arguments and return borrowed views (&T,&[T]) when possible. Only take ownership or returnVec/allocated data when required.
This library uses const-generic dimensions. Tests for dimension-generic code
must cover D=2 through D=5 whenever possible.
Define a macro that accepts a dimension literal and generates the full set of test functions for that dimension. Invoke it once per dimension:
macro_rules! gen_tests {
($d:literal) => {
paste! {
#[test]
fn [<test_foo_ $d d>]() {
// assertions …
}
}
};
}
gen_tests!(2);
gen_tests!(3);
gen_tests!(4);
gen_tests!(5);The macro body should be thin — primarily calling const-generic helpers and
asserting results. This keeps the macro readable and the helpers independently
testable.
src/matrix.rs—gen_public_api_matrix_tests!src/lu.rs—gen_public_api_pivoting_solve_vec_and_det_tests!,gen_public_api_tridiagonal_smoke_solve_vec_and_det_tests!src/ldlt.rs—gen_public_api_ldlt_identity_tests!,gen_public_api_ldlt_diagonal_tests!src/exact.rs—gen_det_exact_tests!,gen_det_exact_f64_tests!,gen_solve_exact_tests!,gen_solve_exact_f64_tests!
Some tests are inherently dimension-specific (e.g. known values for a crafted matrix, error-handling with a specific layout). These do not need macro-ification.
- Use
uv runfor all Python scripts (neverpython3orpythondirectly) - Use pytest for tests (not unittest)
- Type checking:
just python-checkincludes type checking (blocking - all code must pass type checks) - Add type hints to new code
just fix # Apply formatters/auto-fixes (mutating)
just check # Lint/validators (non-mutating)
just ci # Full CI simulation (checks + tests + examples + bench compile)
just test # Lib + doc tests (fast)
just test-all # All tests (Rust + Python)
just examples # Run all examples- All tests (Rust + Python):
just test-all - Benchmark comparison (generate
docs/PERFORMANCE.md):just bench-compare(snapshot) orjust bench-compare v0.3.0(vs baseline) - Benchmarks:
cargo bench(orjust bench) - Benchmarks (exact arithmetic):
just bench-exact - Benchmarks (save baseline):
just bench-save-baseline v0.3.0 - Build (debug):
cargo build(orjust build) - Build (release):
cargo build --release(orjust build-release) - Changelog (generate full):
just changelog(runsgit-cliff -o CHANGELOG.md+ post-processing) - Changelog (prepend unreleased):
just changelog-unreleased v0.3.0 - Coverage (CI XML):
just coverage-ci - Coverage (HTML):
just coverage - Create release tag:
just tag v0.3.0(creates annotated tag from CHANGELOG.md section) - Fast compile check (no binary produced):
cargo check(orjust check-fast) - Fast Rust tests (lib + doc):
just test - Format:
cargo fmt(orjust fmt) - Integration tests:
just test-integration - Lint (Clippy):
cargo clippy --all-targets --all-features -- -D warnings(orjust clippy) - Lint (Clippy, exact feature):
cargo clippy --features exact --all-targets -- -D warnings(orjust clippy-exact) - Lint/validate:
just check - Pre-commit validation / CI simulation:
just ci(lint + tests + examples + bench compile) - Python setup:
uv sync --group dev(orjust python-sync) - Python tests:
just test-python - Run a single test (by name filter):
cargo test solve_2x2_basic(or the full path:cargo test lu::tests::solve_2x2_basic) - Run exact-feature tests:
cargo test --features exact --verbose(orjust test-exact) - Run examples:
just examples(orcargo run --example det_5x5/cargo run --example solve_5x5/cargo run --example ldlt_solve_3x3/cargo run --example const_det_4x4/cargo run --features exact --example exact_det_3x3/cargo run --features exact --example exact_sign_3x3/cargo run --features exact --example exact_solve_3x3) - Spell check:
just spell-check(usestypos.tomlat repo root; add false positives to[default.extend-words])
- Never edit
CHANGELOG.mddirectly - it's auto-generated from git commits - Use
just changelogto regenerate - Use
just changelog-unreleased <version>to prepend unreleased changes
When using gh to view issues, PRs, or other GitHub objects:
-
ALWAYS use
--jsonwith| catto avoid pager and scope errors:gh issue view 64 --repo acgetchell/la-stack --json title,body | cat -
To extract specific fields cleanly, combine
--jsonwith--jq:gh issue view 64 --repo acgetchell/la-stack --json title,body --jq '.title + "\n" + .body' | cat
-
AVOID plain
gh issue view N— it may fail withread:projectscope errors or open a pager. -
For arbitrary Markdown (backticks, quotes, special characters) in comments, prefer
--body-file -with a heredoc:gh issue comment 64 --repo acgetchell/la-stack --body-file - <<'EOF' ## Heading Body with `backticks`, **bold**, and apostrophes that's safe. EOF
Use the gh CLI to read, create, and edit issues:
- Read:
gh issue view <number> --json title,body,labels,milestone | cat - List:
gh issue list --json number,title,labels --jq '.[] | "#\(.number) \(.title)"' | cat(add--label enhancement,--milestone v0.4.0, etc. to filter) - Create:
gh issue create --title "..." --body "..." --label enhancement --label rust - Edit:
gh issue edit <number> --add-label "...",--milestone "...",--title "..." - Comment:
gh issue comment <number> --body "..." - Close:
gh issue close <number>(with optional--reason completedor--reason "not planned")
When creating or updating issues:
- Labels: Use appropriate labels:
enhancement,bug,performance,documentation,rust,python, etc. - Milestones: Assign to the appropriate milestone (e.g.,
v0.3.0,v0.4.0) - Dependencies: Document relationships in issue body and comments:
- "Depends on: #XXX" - this issue cannot start until #XXX is complete
- "Blocks: #YYY" - #YYY cannot start until this issue is complete
- "Related: #ZZZ" - related work but not blocking
- Relationships: GitHub automatically parses blocking keywords in comments to create visual relationships:
- Use
gh issue comment <number> --body "Blocked by #XXX"to mark an issue as blocked - Use
gh issue comment <number> --body "Blocks #YYY"to mark an issue as blocking another - GitHub will automatically create the relationship graph in the web UI
- Example:
gh issue comment 217 --body "Blocked by #207"creates a blocking dependency
- Use
- Issue body format: Include clear sections: Summary, Current State, Proposed Changes, Benefits, Implementation Notes
- Cross-referencing: Always reference related issues/PRs using #XXX notation for automatic linking
exact— enables exact arithmetic methods viaBigRational:det_exact(),det_exact_f64(),det_sign_exact(),solve_exact(), andsolve_exact_f64(). Also re-exportsBigRationalfrom the crate root and prelude. Gatessrc/exact.rs, additional tests, and theexact_det_3x3/exact_sign_3x3/exact_solve_3x3examples. Clippy, doc builds, and test commands have dedicated--features exactvariants.
- This is a single Rust library crate (no
src/main.rs). The crate root issrc/lib.rs. - The linear algebra implementation is split across:
src/lib.rs: crate root + shared items (LaError,DEFAULT_SINGULAR_TOL,DEFAULT_PIVOT_TOL) + re-exportssrc/vector.rs:Vector<const D: usize>([f64; D])src/matrix.rs:Matrix<const D: usize>([[f64; D]; D]) + helpers (get,set,inf_norm,det,det_direct)src/lu.rs:Lu<const D: usize>factorization with partial pivoting (solve_vec,det)src/ldlt.rs:Ldlt<const D: usize>factorization without pivoting for symmetric SPD/PSD matrices (solve_vec,det)src/exact.rs: exact arithmetic behindfeatures = ["exact"]:- Determinants:
det_exact(),det_exact_f64(),det_sign_exact()via integer-only Bareiss inBigInt(bareiss_det_int);det_sign_exact()adds a Shewchuk-style f64 filter for fast sign resolution - Linear system solve:
solve_exact(),solve_exact_f64()via Gaussian elimination with first-non-zero pivoting inBigRational
- Determinants:
- Rust tests are inline
#[cfg(test)]modules in eachsrc/*.rsfile. - Python tests live in
scripts/tests/and run viajust test-python(uv run pytest). - The public API re-exports these items from
src/lib.rs. - The
justfiledefines all dev workflows (seejust --list). - Dev-only benchmarks live in
benches/vs_linalg.rs(Criterion + nalgebra/faer comparison) andbenches/exact.rs(exact arithmetic across D=2–5). - Python scripts under
scripts/:bench_compare.py: exact-arithmetic benchmark comparison across releases (generatesdocs/PERFORMANCE.md)criterion_dim_plot.py: benchmark plotting (CSV + SVG + README table update)tag_release.py: annotated tag creation from CHANGELOG.md sectionspostprocess_changelog.py: strips trailing blank lines from git-cliff outputsubprocess_utils.py: safe subprocess wrappers for git commands
- Release workflow is documented in
docs/RELEASING.md.
- If you publish this crate to crates.io, prefer updating documentation before publishing a new version (doc-only changes still require a version bump on crates.io).
- Never use
sed,awk,python, orperlto edit code or write file changes. - These tools may be used for read-only inspection, parsing, or analysis, but never for writing.