All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
0.4.4 - 2026-07-13
- Make numerical invariants and errors explicit
- Require Rust 1.97.0
-
[breaking] Make numerical invariants and errors explicit
668daed- add structured error reasons, locations, origins, and factorization context
- make determinant, exact-conversion, LU, and LDLT paths range-safe and mathematically explicit
- validate benchmark inputs independently and require reproducible, provenance-backed performance evidence
- centralize tool versions, adopt nextest profiles, and replace Codacy with repository-owned checks and SARIF reporting
-
Consolidate setup abort handling
b9e453e- Share
OrAbortacross exact and comparison benchmarks while preserving contextual panic behavior. - Centralize Clippy policy in Cargo.toml for consistent local and CI checks.
- Keep
unreachable_pubenforced while allowing intentional crate-visible helpers. - Enable CodeRabbit's request-changes review workflow.
- Share
- Bump python-multipart in the uv group across 1 directory
6bb4fb7 - Bump zizmorcore/zizmor-action from 0.5.6 to 0.5.7
4a999a6 - Bump github/codeql-action/upload-sarif
85c0a7b - Bump actions/checkout from 6.0.2 to 7.0.0
0f0f956 - Bump astral-sh/setup-uv from 8.1.0 to 8.2.0
259acaa - Bump codecov/codecov-action from 6.0.1 to 7.0.0
035807c - Bump vulnerable Python tooling dependencies
4990260
-
Add mathematical basis and clarify numerical guarantees
31b7b1e- define the binary64, factorization, determinant-filter, exact-arithmetic, tolerance, and error contracts
- align README, API documentation, examples, and LDLT diagnostics with guarantees over stored values
- audit academic references and extend Criterion coverage for determinant error-bound paths
-
Clarify determinant and LDLT failure contracts
e257343- State the determinant sign condition without ambiguous Markdown delimiters.
- Distinguish singular zero pivots from coupled zero-pivot LDLT rejections.
- Align citation and contributor guidance with the positive-definite domain.
-
Make v0.4.3 comparisons correctness-aware
4ac5af9- Adapt the shared benchmark harness across v0.4.3 API differences without changing measured operations
- Exclude invalid balanced-range baselines while requiring current samples and reporting unavailable comparisons
- Preserve benchmark provenance, suite-specific fallback commands, and publication rollback guarantees
- Harden Windows Git input, changelog links, and version-reference parsing across platforms
-
Harden exact arithmetic and benchmark publication
db2fad5- add
DeterminantWithErrorBoundfor paired determinant estimates and certified bounds - scale exact systems independently and round exact values directly to IEEE-754
- fail benchmark publication closed on invalid samples or mismatched provenance
- make release and changelog tooling transactional, path-safe, and Windows-portable
- align benchmark CI with pinned local tools and least-privilege publishing
- add
-
Update setuptools requirement in the dependencies group
6a6c339Updates the requirements on setuptools to permit the latest version.
Updates
setuptoolsto 83.0.0 -
Avoid duplicate review checks
5e15d92- Use the legacy required status while preserving automatic approvals.
- Add explicit dense D3 determinant coverage and document the D4 error bound.
-
[breaking] Require Rust 1.97.0
4033f1f- Align Cargo, the pinned toolchain, Clippy, dependency-audit triggers, and maintainer guidance with the new baseline.
- Audit Rust 1.97 integer bit helpers against exact-arithmetic hot paths and retain existing operations where alternatives do not preserve performance.
- Correct v0.4.3 citation metadata and document exact decomposition and solve scaling accurately.
-
Restore det_direct throughput for D=2..4
f6d6885- Reintroduce branch-free dense expansions for D=2 and D=3.
- Share D=4 minors while retaining guarded sparse evaluation.
- Preserve non-finite handling for mathematically inactive terms.
-
Restore small-matrix det_sign_exact throughput
b8bfa9f- Reuse proof-bearing shared minors for D4 determinant and permanent evaluation.
- Restore the dense D3 filter while preserving sparse, overflow, and underflow fallbacks.
- Require headline benchmarks to exercise the intended filter and document historical harness overhead.
-
Improve inf_norm throughput
dc28f98- Check row-sum finiteness once per completed row on the success path.
- Replay only overflowing rows to preserve the first failing matrix coordinate.
- Preserve left-to-right accumulation and const evaluation across dimensions.
-
Improve dot and norm2_sq throughput
ece54d7- Check accumulator finiteness once after the success-path reduction.
- Replay only non-finite reductions to preserve the first failing step.
- Preserve left-to-right fused accumulation and const evaluation.
0.4.3 - 2026-06-09
- Make exact f64 conversions strict
-
Guard README dependency snippets
7137fee- Add a generic docs-version sync check that compares Markdown dependency snippets against the Cargo package name and version
- Run the docs-version check from the repository Semgrep policy lane
- Refresh README determinant examples with explicit fallible handling and hidden doctest mirrors
- Update CI uv pins to 0.11.19
-
Report determinant scale overflow precisely
928f62b- Add a typed LaError::DeterminantScaleOverflow path for exact determinant scale exponent failures
- Convert det_exact_f64 directly from the shared Bareiss integer/exponent pair while preserving Overflow for finite-f64 conversion failures
- Reuse vector finiteness scanning across raw and proof-bearing constructors
- Harden docs version sync checks for reordered inline-table dependency snippets and pruned Markdown traversal
-
Add release performance comparison workflow
53b5fde- Extend vs_linalg with LDLT/Cholesky benchmark rows and shared deterministic inputs.
- Add smoke coverage that checks la-stack, nalgebra, and faer agree on benchmark inputs.
- Expand bench-compare to support latest-vs-last reports, suite/scope selection, peer baseline context, and clearer malformed Criterion diagnostics.
- Document the benchmark methodology, release baseline workflow, roadmap direction, and contributor guidance.
-
Publish release benchmark baselines
9497ca5- Add a release-only benchmark workflow that saves full Criterion baselines for published releases and attaches the archived baseline to the GitHub Release.
- Keep the regular benchmark workflow focused on PR and main-branch comparison runs.
- Document how to restore archived release baselines for future performance comparisons.
-
Feat!(api): make Matrix and Vector finite by construction
1fa2f55 -
[breaking] Make exact f64 conversions strict
8e33f1a- Add explicit rounded exact-to-f64 APIs for determinant and solve results
- Report exact conversion failures with typed Unrepresentable reasons
- Remove finite proof wrapper APIs now that Matrix and Vector carry finiteness directly
- Move error and tolerance contracts into first-class modules with prelude exports
- Update exact benchmarks to distinguish strict Result paths from rounded f64 paths
- Document and exercise the rounded fallback pattern for RequiresRounding errors
-
[breaking] Make exact f64 conversions strict
89f3720- Make Matrix and Vector the finite-by-construction public types for exact arithmetic.
- Add rounded exact-to-f64 APIs for determinant and solve callers that want explicit lossy conversion.
- Return typed Unrepresentable reasons when strict exact-to-f64 conversion would round or become non-finite.
- Specialize D4 exact determinants and keep determinant/error-bound zero coefficients from evaluating overflowing absent terms.
- Update exact benchmark comparison reporting to compare strict and rounded APIs against legacy v0.4.2 rows.
-
Archive release performance reports
2817d01- Add an archive-performance utility that promotes curated benchmark reports into docs/PERFORMANCE.md while archiving prior release comparisons
- Generate release comparisons in isolated temporary worktrees, including legacy command fallback for published tags
- Wire release and historical archive recipes into just, Python packaging, and release documentation
-
Automate published performance report archiving
d31e26a- Track the latest curated release comparison in docs/PERFORMANCE.md and archive older comparisons under docs/archive/performance/
- Let performance-archive-published discover the latest stable GitHub release and previous stable baseline automatically
- Generate release comparisons in isolated temporary worktrees, with release-asset restore and local baseline fallback paths
- Update benchmark and release docs to use the scripted workflow instead of manual checkout steps
-
Split local and release performance comparisons
7258525- Add default performance-local and performance-release workflows that infer the relevant release tags and run in temporary worktrees.
- Add a performance-github-assets workflow for comparing stored GitHub Actions release benchmark assets without local cargo runs.
- Normalize release tags before fetching, downloading assets, or checking out detached worktrees.
- Update performance docs, release guidance, and generated report instructions to use the new benchmark workflows.
-
Add vs_linalg-only performance checks
d7c1487- Add local workflows for comparing current non-exact la-stack kernels against a release baseline without rerunning current nalgebra/faer or exact benchmarks.
- Route archive-performance baseline and current benchmark commands by suite, with legacy fallback support for older release worktrees.
- Document the faster release-signal workflow and expand Semgrep fixtures for benchmark, example, doctest, and public panic-path rules.
-
Cover determinant scale overflow boundaries
532093a- Extract determinant scale exponent calculation into a private helper
- Assert typed DeterminantScaleOverflow errors for dimension conversion and exponent product overflow
-
Harden support script parsing
87e1d00- Require Python 3.13 for support-script tooling and align Ruff/Ty with that baseline.
- Replace mypy with strict Ty checking in the Python workflow.
- Parse TOML, JSON, argparse, and Semgrep inputs into typed boundary objects before downstream use.
- Reject malformed Criterion estimates, non-finite timings, invalid confidence intervals, and malformed Semgrep result shapes.
-
Harden Rust release hygiene
8e12c93- Promote missing documentation and dead code lints to deny-level checks.
- Forbid unsafe code explicitly across Rust modules and benchmark targets.
- Document the LU/LDLT empty-matrix convention for D=0.
- Move exact benchmark input generation into typed helpers and consolidate exact benchmark operation dispatch.
-
Sync citation metadata for v0.4.2
f473ec5- Update CITATION.cff with the v0.4.2 version and release date.
- Align the Python utility package metadata and lockfile with the crate release.
- Add citation metadata validation to the release checklist and config lint flow.
- Include CITATION.cff in YAML/CFF formatting checks.
-
Make release documentation links portable
dd4ad19
-
Escape path regex in benchmark parser test
1222c93Use a literal regex pattern for the malformed Criterion JSON diagnostic so Windows paths with backslashes do not break pytest's match expression.
-
Align ty with Python 3.13
b9e0ba0 -
Preserve coordinates for overflowed accumulators
1d976b3- Return matrix-cell metadata when inf-norm row sums or symmetry tolerance scaling overflow.
- Avoid reparsing finite-by-construction RHS vectors in LU and LDLT solves.
-
Re-raise unexpected archive failures
7938386- Limit archive-performance CLI error handling to expected validation, filesystem, subprocess, and runtime failures.
- Let unexpected exceptions propagate so benchmark archiving bugs surface during development.
-
Improve factorization kernel
8837df1- Preserve the tiny-dimension update shape for D2-D5 to avoid regressing the core fixed-size path
- Fuse multiplier computation with trailing updates for larger dimensions to reduce extra column walks
- Rely on the LDLT factorization proof instead of a redundant final finite-storage scan
-
Optimize exact and factorized solve kernels
1690355- Split LU and LDLT solve paths so tiny matrices keep the direct kernels while larger fixed dimensions avoid extra substitution work.
- Convert dyadic exact solve results directly to finite f64 and preserve UnrepresentableReason recovery semantics on strict conversion failures.
- Modernize release branch commands and keep just recipes sorted.
0.4.2 - 2026-06-04
-
Feat!(matrix): enforce fallible matrix invariants
e26c283 -
Feat!(api): enforce fallible numeric invariants
adfc33b -
Feat!(matrix): make determinant API tolerance-free
11a355c -
Feat!(api): hide finite and symmetry proofs behind matrix APIs
7219336 -
Guard public Rust examples against unwrap
df1130a- Add repository-owned Semgrep rules for unwrap and expect usage in public doctests, examples, and benchmarks.
- Add fixture-based Semgrep rule tests and include them in the lint workflow.
- Update examples and benchmarks to model typed fallible flow or operation-labeled benchmark failures.
-
Feat!(api): enforce finite Matrix and Vector construction
92ba403
-
Remove redundant cache restore keys for cargo-llvm-cov
f75a01cRemove the broad restore-keys pattern to ensure only exact version matches are used from the cache, preventing potential version mismatches during CI runs.
-
Revert "ci: modernize tooling checks and example execution"
a4b9f64 -
Reapply "ci: modernize tooling checks and example execution"
758321a -
Encode nonzero mantissas in exact decomposition
7a664ed- Replace the exact-arithmetic zero mantissa sentinel with
Option<NonZeroU64>. - Carry nonzero mantissa proof through matrix/vector decomposition and BigInt scaling.
- Clarify determinant documentation around uncertified
det()bounds. - Keep SPD determinant proptests on the tolerance-aware LU path.
- Replace the exact-arithmetic zero mantissa sentinel with
-
Simplify finite proof wrappers
54b603c- Use the checked proof-wrapper constructors as the single internal path for finite matrices and vectors.
- Remove exact-arithmetic tests that duplicated the matrix and vector non-finite boundary checks.
- Bump taiki-e/install-action from 2.75.18 to 2.75.22
d6c944b - Bump actions/setup-node from 6.3.0 to 6.4.0
1fc57e1 - Bump pastey from 0.2.1 to 0.2.2 in the dependencies group
5b215d5 - Bump taiki-e/install-action from 2.75.22 to 2.77.3
3e5ce42 - Bump actions-rust-lang/setup-rust-toolchain
8532b08 - Bump taiki-e/install-action from 2.77.3 to 2.78.3
bef2caf - Bump the dependencies group across 1 directory with 2 updates
ba01a14 - Bump taiki-e/install-action from 2.78.3 to 2.80.0
480e61b - Bump codecov/codecov-action from 6.0.0 to 6.0.1
3ca8eed
-
Document feature requirement for exact APIs
19b10d5 -
Document scalar scope and release roadmap
bfb0393- Clarify that la-stack intentionally supports f64 floating-point APIs plus optional exact rationals, not alternate scalar families.
- Add a roadmap covering the v0.4.x stable-Rust issue sequence and the v0.5.0 generic_const_exprs anchor.
- Refresh generated changelog entries and archived changelog grouping.
-
Document finite RHS solve validation
075aed7- Document that LU and LDLT solve_vec reject non-finite RHS entries with LaError::NonFinite metadata.
- Cite the Bareiss reference in the exact solve helper docs and describe exact-arithmetic growth and complexity.
- Cover finite proof defaults and non-finite RHS solve boundaries in unit tests.
-
Clarify finite solve and norm guarantees
fb71485- State that LU and LDLT solve_vec use floating-point substitution without a certified absolute rounding-error bound.
- Clarify that inf_norm reports NonFinite for unchecked stored NaN/∞ as well as row-sum overflow.
- Exercise the unchecked finite-proof fixture path directly in exact tests.
-
Update v0.4.2 release notes
7e11f93
-
Reject overflowed symmetry tolerance scaling
a7b052a- Enforce the tolerance contract around symmetry checks by surfacing scaled tolerance overflow as a typed non-finite intermediate error.
- Document finite, non-negative tolerance requirements across tolerance-taking matrix APIs.
- Add regression coverage for invalid tolerance construction and symmetry tolerance overflow.
- Update exact examples to propagate typed crate errors instead of unwrapping.
-
Harden Semgrep fixture parsing
ac44c07- Ignore non-canonical todoruleid annotations when counting expected rule hits.
- Reject malformed Semgrep JSON results with clear stderr diagnostics instead of propagating KeyError.
-
Revalidate finite proof conversions
419a90fEnsure internal finite proof conversions cannot accept raw Matrix or Vector storage without checking the invariant.
- Revalidate TryFrom<Matrix<D>> and TryFrom<Vector<D>> before constructing finite wrappers.
- Measure exact random percentile benchmarks over repeated corpus timings and cumulative input sets.
- Tighten Codecov status thresholds and extend benchmark workflow timeout.
- Keep Semgrep constructor fixtures aligned with public API guardrails.
-
Revalidate public compute inputs
ffca00e- Parse Matrix and Vector storage into private finite proof-bearing types at public compute boundaries.
- Reject unchecked non-finite storage before LU, LDLT, determinant, norm, dot, and exact-arithmetic paths can proceed.
- Keep unchecked proof-wrapper constructors crate-private for internal paths with local finiteness proofs.
- Document the private proof-bearing invariant model in the API overview and roadmap.
-
Migrate coverage to cargo-llvm-cov
66f2117 -
Align shared security and release tooling
b303509- Run CI through pinned uv and cached Cargo tooling across all supported platforms.
- Add repository Semgrep rules, action allowlist coverage, CodeQL, zizmor, and SARIF workflows.
- Raise the Rust and Python tooling floors to Rust 1.96 and Python 3.12.
- Add archive-aware changelog generation, post-processing, and tag-release tooling.
- Preserve exact arithmetic overflow reporting without non-finite sentinel defaults.
-
Modernize tooling checks and example execution
da626bc- Run examples from prebuilt binaries instead of invoking cargo run for each example.
- Add check/fix recipe aliases and guard documented command ordering with Semgrep.
- Document the Rust-native Markdown, YAML, TOML, spelling, and workflow action policy.
- Tighten Python/tooling setup by pinning pytest, using .python-version in CI, and hardening setup-tool version checks.
- Keep CI running the full just ci workflow across Ubuntu, macOS, and Windows.
-
Restore checked factorization throughput
f2e6d56- Move LU and LDLT non-finite factor checks out of cubic update loops while preserving completed-storage validation before factors escape.
- Borrow factor rows and finite vector arrays in solve, dot, and norm paths to avoid avoidable copies.
- Refresh v0.4.2 release artifacts, LU solve benchmark docs, and release workflow docs.
- Preserve README benchmark table spacing in the Criterion plot updater.
0.4.1 - 2026-04-21
- Propagate NaN in Matrix::inf_norm #85
- Add adversarial-input coverage for exact arithmetic #80
- Integer-only forward elimination for gauss_solve #72
-
Regression tests for solver and determinant overflow handling
f763b11Add test cases to verify that LDLT and LU solvers, as well as determinant calculations, correctly detect and return
LaError::NonFinitewhen intermediate calculations overflow to infinity despite having finite inputs. -
Defensive-path test coverage for LU and LDLT solve_vec
87d426fAdd unit tests to exercise internal safety nets in the LU and LDLT diagonal solve routines. These tests manually construct factors with invalid diagonals (NaN or sub-tolerance) to verify that solve_vec correctly surfaces NonFinite and Singular errors, even though these states are unreachable via the standard factorization APIs.
-
Const-ify Lu/Ldlt det + solve_vec and Matrix inf_norm + det_errbound
81ecb35Make six public methods
const fn, completing const-evaluation parity withMatrix::det_directandVector::dotnow that MSRV 1.95 exposesf64::mul_addas const (1.94) andcore::hint::cold_pathas const (1.95):Lu::det,Lu::solve_vecLdlt::det,Ldlt::solve_vecMatrix::inf_norm,Matrix::det_errbound
Iterator chains (
.iter().map().sum(),.enumerate().take(i),.enumerate().skip(i + 1),.iter_mut().enumerate().take(D)) were rewritten aswhileloops since they are not const-stable.Fix error-variant correctness in both solve_vec paths:
- A corrupt stored
U/Ddiagonal at(i, i)now surfaces asLaError::NonFinite { row: Some(i), col: i }, matching the convention used byMatrix::det,Lu::factor, andLdlt::factor. - A computed-intermediate overflow keeps
row: None, col: i. - Previously both were conflated into
row: None, col: i, defeating debuggability for callers who construct factorizations directly.
Sharpen
LaError::NonFinitevariant docs and the# Errorssections ofLu::solve_vec/Ldlt::solve_vecto spell out the(row, col)contract for each failure mode. -
Fast-filter boundary proptests for exact determinant sign
6357db3Introduce proptests to verify that the floating-point determinant sign matches the exact sign whenever the error bound is satisfied. This validates the correctness of the Shewchuk-style filter used in determinant calculations.
Additionally, improve test reliability by correcting the diagonal dominance calculation to properly account for the maximum off-diagonal magnitude and refactor matrix-vector multiplication helpers to use idiomatic iterators.
-
Finalize documentation, benchmarks, and error handling
0b98d3fSynchronize the CHANGELOG, README, and REFERENCES for the upcoming release. This includes documenting the new absolute error bound coefficients for determinants, adding a dedicated section for AI agent governance, and refining internal error helpers to use a more consistent coordinate convention for non-finite values.
-
Consolidate and expand const-evaluability tests via macros
f8d80a0Refactor manual const-evaluation tests in
LdltandMatrixinto macros to standardize coverage across matrix dimensions 2 through 5. This ensures all determinant and norm variants are fully exercised at compile time. -
Refactor solve_exact to use hybrid Bareiss forward elimination
ecbbe8aMigrate the exact linear solver to a hybrid approach that performs O(D³) forward elimination using fraction-free Bareiss updates on integers, limiting BigRational arithmetic to the O(D²) back-substitution phase. This eliminates per-entry GCD overhead during elimination. Internal f64 decomposition is unified via f64_decompose, and f64_to_bigrational is moved to test scope.
-
Polish exact module (Component struct, errors, perf)
53a5be6Major refactor of
src/exact.rs:- Extract shared Bareiss primitives (
decompose_matrix,decompose_vec,component_to_bigint,build_bigint_matrix,build_bigint_vec,bareiss_forward_eliminate) sobareiss_det_intandgauss_solveshare a single integer-Bareiss core. - Hybrid BigInt/BigRational solve: forward elimination runs entirely in
BigIntwith fraction-free Bareiss updates on(A | b); only theO(D²)back-substitution phase lifts intoBigRational. mem::takein back-substitution eliminates per-entryclone()calls onrhs[i],a[i][j],a[i][i].
Structured errors replace preconditions:
decompose_matrix/decompose_vecfoldis_finite()into the same pass that decomposes each entry and returnErr(LaError::NonFinite { row, col })on the first non-finite cell.bareiss_det_int,bareiss_det,gauss_solvenow returnResult<_, LaError>; error propagates to every public entry point via?.validate_finiteandvalidate_finite_vecremoved (dead after the refactor);det_sign_exactrelies on IEEE 754 NaN/∞ propagation throughdet_direct()plusbareiss_det_intfor Stage-2 validation.
- Extract shared Bareiss primitives (
-
Add adversarial-input coverage for exact arithmetic #80
5bf5815Expand benchmark, unit-test, and proptest coverage of the exact-arithmetic APIs to catch tail cases that fixed well-conditioned inputs miss.
Benchmarks (benches/exact.rs):
- Factor out
bench_extreme_grouphelper running the same four benches (det_sign_exact,det_exact,solve_exact,solve_exact_f64) so adversarial groups are directly comparable. - Extend
exact_near_singular_3x3with the two solve benches (the primary motivating use case for exact solve was previously unmeasured). - Add
exact_large_entries_3x3(entries nearf64::MAX / 2) to stress intermediate BigInt growth during Bareiss forward elimination. - Add
exact_hilbert_4x4/exact_hilbert_5x5to stress thef64_decompose → BigIntscaling path on ill-conditioned inputs. - Tighten bench
expect(...)messages to name the invariant each call relies on (e.g. "non-singular matrix with finite entries") so panics identify both where (Criterion bench name) and why.
Unit tests (src/exact.rs):
solve_exact_near_singular_3x3_integer_x0— integer-x0 round-trip through the 2^-50-perturbed matrix.solve_exact_large_entries_3x3_unit_vector—A·[1,0,0] = [big,1,1]round-trip withf64::MAX/2diagonal.det_sign_exact_large_entries_3x3_positive— asserts the fast filter falls through (det_directis non-finite) anddet_exact_f64returnsOverflow { index: None }.det_sign_exact_hilbert_positive_{3,4,5}d— Hilbert is SPD, sign = 1.solve_exact_hilbert_residual_{3,4,5}d— residualA·x - bis exactly zero inBigRational, stronger than integer round-trips since Hilbert entries are non-terminating in binary.
Proptests (tests/proptest_exact.rs):
solve_exact_integer_roundtrip_{2..5}d— random diagonally-dominant integerAand small-integerx0, verifysolve(A, A·x0) == x0exactly.solve_exact_residual_{2..5}d— randomA+ small-integerb, verifyA · solve(A, b) == bexactly (catches back-sub bugs on fractional solutions).det_sign_exact_agrees_with_det_exact_{2..5}d— on full (non-diagonal) small-integer matrices, assertsdet_sign_exact() == det_exact().sign()(exercises the filter/fallback boundary previously only diagonal-tested).
Prelude (src/lib.rs):
- Re-export
BigIntalongsideBigRational(crate root + prelude). - Re-export
FromPrimitive,Signed,ToPrimitivefromnum-traitsin the prelude so the re-exportedBigRationalis actually usable for construction (from_f64,from_i64) and sign queries without forcing downstream users to addnum-bigint/num-rational/num-traitsto their own Cargo.toml. Additive; no public API breaks.
Tooling (scripts/bench_compare.py + test_bench_compare.py):
- Register the three new adversarial groups in
EXACT_GROUPS. - Extend
_group_headingwith human-readable titles ("Large entries 3x3", "Hilbert 4x4", "Hilbert 5x5"). - Add group-heading unit tests for the new cases.
Test results (
just ci):- cargo test --features exact: 368 lib + 20 proptest_exact + 40 other proptests + 34 doc-tests — all pass
- cargo test (no features): 175 lib + 40 proptests + 29 doc-tests — all pass
- Python: 104 tests pass (ty, mypy, ruff clean)
- Clippy (pedantic + nursery + cargo,
-D warnings): clean - fmt, taplo, yamllint, shellcheck, spell-check, bench-compile, examples: clean
- Factor out
-
Expand exact-arithmetic re-exports and adversarial benchmarks
b1a491dUpdate the
exactfeature to re-exportBigIntand essentialnum-traits(FromPrimitive, ToPrimitive, Signed) alongsideBigRational. This simplifies downstream usage by removing the need for direct dependencies on thenumecosystem for common operations.Additionally, formalize adversarial-input benchmarking for near-singular, large-entry, and Hilbert matrices to better track performance on ill-conditioned data. CI benchmark comparisons are now more resilient to newly added benchmarks via
--baseline-lenient. -
Update AGENTS.md
1e0648d
- Bump taiki-e/install-action from 2.73.0 to 2.75.7
a1d1c1e - Bump actions/download-artifact from 4.3.0 to 8.0.1
8772ea2 - Bump rand from 0.9.2 to 0.9.4
b91670a - Bump actions/upload-artifact from 7.0.0 to 7.0.1
7579274 - Bump actions/github-script from 8.0.0 to 9.0.0
a522abd - Bump actions/cache from 5.0.4 to 5.0.5
b12d95c - Bump actions-rust-lang/setup-rust-toolchain
c728774 - Bump astral-sh/setup-uv from 8.0.0 to 8.1.0
7a18733 - Bump taiki-e/install-action from 2.75.7 to 2.75.18
433cfc1
-
Strengthen LDLT symmetry precondition and add is_symmetric API
1693307LDLT factorization assumes the input matrix is symmetric, but the contract was only implied by one sentence in the module and struct docs. Asymmetric inputs silently produce mathematically meaningless factorizations in release builds (the
debug_assert_symmetriccheck is compiled out), and callers had no supported way to validate symmetry up front.
-
Report infinite vs finite off-diagonal pairs as asymmetric
1805779Update Matrix::first_asymmetry to flag any non-finite difference between off-diagonal pairs as an asymmetry. This prevents cases where a single infinite entry paired with a finite entry would incorrectly pass as symmetric because the matrix's infinite norm blew the tolerance up to infinity, making the comparison
diff > epsreturn false.
-
Bump MSRV to Rust 1.95 and adopt new stable features
0ab3c33- Bump rust-version to 1.95 in Cargo.toml
- Bump channel to 1.95.0 in rust-toolchain.toml
- Add core::hint::cold_path() hints at cold/error branches:
- src/exact.rs: validate_finite, validate_finite_vec, gauss_solve singular return, det_exact_f64 / solve_exact_f64 overflow returns, det_sign_exact Stage 2 Bareiss fallback
- src/lu.rs: Lu::factor and Lu::solve_vec NonFinite / Singular returns
- src/ldlt.rs: Ldlt::factor and Ldlt::solve_vec NonFinite / Singular returns
- src/matrix.rs: det_direct D >= 5 fallback arm (legal because cold_path is const fn in 1.95) and det NonFinite / overflow scan
- Refactor det_sign_exact Stage 1 fast filter to use match + if let guard with let-chain, replacing the tuple destructure; semantics unchanged
Test results (local
just ci):- cargo fmt --all -- --check: clean
- cargo clippy --workspace --all-targets --all-features -D warnings -W clippy::pedantic -W clippy::nursery -W clippy::cargo: clean
- cargo test --features exact --lib: 258 passed, 0 failed
- cargo test --features exact (doctests + examples): 31 passed, 0 failed
- RUSTDOCFLAGS='-D warnings' cargo doc --no-deps --features exact: clean
- python tests: 101 passed
-
Integer-only forward elimination for gauss_solve #72
a1d3bdbReplace BigRational-only gauss_solve with a hybrid that runs Bareiss fraction-free forward elimination in BigInt on the augmented (A | b) system, then back-substitutes in BigRational. Eliminates GCD normalization from the O(D^3) phase while keeping rational overhead limited to the cheaper O(D^2) back-sub.
Scope f64_to_bigrational to cfg(test); production code paths now use f64_decompose directly (shared with bareiss_det_int).
Closes #72
Co-Authored-By: Oz oz-agent@warp.dev
0.4.0 - 2026-04-11
- Integer-only Bareiss determinant via BigInt #64
- Custom f64 → BigRational via IEEE 754 bit decomposition #63
-
Add benchmark comparison tool and performance documentation
d448fc3Introduce a Python script to compare Criterion results across baselines and generate markdown reports. Integrate performance snapshots into the release workflow and add justfile recipes for baseline management to track exact arithmetic performance.
-
Update version to 0.3.0 and refine metadata keywords
cc0e967Update CITATION.cff to reflect the v0.3.0 release. Keywords are updated to include exact arithmetic and robust predicates, with existing terms standardized to kebab-case.
-
Refine benchmark comparison reporting and documentation
e1b5955Refactor the
bench_compare.pyscript to group results by dimension and add a new test suite. Consolidate all benchmarking workflows into a new dedicated guide and move machine-specific performance snapshots to.gitignore. -
Expand test coverage for benchmark comparison edge cases
bced7d9 -
Update documentation and tests for integer-only Bareiss
2ee3f05Update architecture descriptions in AGENTS.md and REFERENCES.md to reflect the move from BigRational to integer-only BigInt arithmetic. Add unit tests for bareiss_det_int covering negative inputs and pivot swapping. Refine gh CLI patterns for automated issue listing.
-
Restrict benchmark baselines to main and improve reporting
9a7caa2Update internal CI logic to ensure Criterion baselines are only saved and uploaded for the main branch. Add error handling to regression reporting to provide clear feedback when comparison data is missing.
- Bump astral-sh/setup-uv from 7.3.1 to 7.5.0
0505061 - Bump taiki-e/install-action from 2.68.25 to 2.68.31
dcff501 - Bump actions-rust-lang/setup-rust-toolchain
4678d2e - Bump actions/cache from 5.0.3 to 5.0.4
633c6e2 - Bump taiki-e/install-action from 2.68.34 to 2.69.6
89a306b - Bump astral-sh/setup-uv from 7.5.0 to 7.6.0
676a6ff - Bump codecov/codecov-action from 5.5.2 to 5.5.3
2c15dc1 - Bump the dependencies group with 2 updates
23ade13 - Bump taiki-e/install-action from 2.69.6 to 2.70.1
4073197 - Bump codecov/codecov-action from 5.5.3 to 6.0.0
b3e1380 - Bump taiki-e/install-action from 2.70.1 to 2.73.0
7de720d - Bump astral-sh/setup-uv from 7.6.0 to 8.0.0
af40753
-
Improve non-finite error reporting and coordinate accuracy
d4b1452Refine error reporting by ensuring correct column indices in LDLT decomposition and LU back-substitution. Add missing finiteness checks to LU solve paths and update determinant calculations to provide specific row/column coordinates for non-finite inputs.
-
Add performance regression detection for exact-arithmetic benchmarks
44bce99Add a GitHub Actions workflow that detects performance regressions in the exact-arithmetic benchmark suite on PRs and pushes to main.
- On push to main: run exact benchmarks, save Criterion baseline as artifact (30-day retention)
- On PRs: find latest main baseline artifact, download, run benchmarks with --baseline comparison, report regressions in job summary
- Regressions are warning-only — the workflow never blocks PRs
- Uses artifact-based baselines (not cache) for robustness: explicit provenance, no silent eviction, fork-safe
- Validated locally: --save-baseline and --baseline flags confirmed working with Criterion
-
Stack-backed storage for exact arithmetic kernels
b64ac60Replace heap-allocated Vec<Vec<BigRational>> with stack-backed [[BigRational; D]; D] arrays in bareiss_det and gauss_solve, and return [BigRational; D] from gauss_solve directly — eliminating per-call heap traffic and a redundant clone in solve_exact.
Exact kernel changes (src/exact.rs):
- bareiss_det: Vec<Vec<BigRational>> → [[BigRational; D]; D] via std::array::from_fn
- gauss_solve: Vec<Vec<BigRational>> augmented matrix → separate [[BigRational; D]; D] + [BigRational; D] (avoids unstable const-generic [T; D+1])
- gauss_solve return type: Vec<BigRational> → [BigRational; D]
- solve_exact: drop intermediate clone, forward array directly
Error enrichment (src/lib.rs, src/lu.rs, src/ldlt.rs, src/matrix.rs, src/exact.rs):
- LaError::NonFinite gains row: Option<usize> for full (row, col) location on matrix inputs; None for vectors/intermediates
- LaError::Overflow becomes a struct variant with index: Option<usize> to identify which solution component overflowed
- Display messages updated to show positional context
-
Custom f64 → BigRational via IEEE 754 bit decomposition #63
0a8ce5bReplace
BigRational::from_float(x)inf64_to_bigrationalwith manual IEEE 754 binary64 bit decomposition andBigRational::new_raw, bypassing the unnecessary GCD normalization thatfrom_floatperforms internally.- Decompose f64 into sign, biased exponent, and significand fields
- Strip trailing zeros from the significand so the fraction is already in lowest terms (odd numerator over power-of-two denominator)
- Handle zero (±0.0), subnormals, and normal values; panic on NaN/Inf
- Add 15 dedicated unit tests: ±zero, integers, fractions, powers of two, subnormals, round-trip fidelity, lowest-terms, and panic cases
- Add IEEE 754-2019 [9] and Goldberg [10] references to REFERENCES.md
- Add module-level and function-level doc citations
-
Integer-only Bareiss determinant via BigInt #64
d422b25Replace the BigRational Bareiss determinant with a pure BigInt path: all f64 entries are decomposed into mantissa × 2^exponent, scaled to a common integer base, and eliminated without any rational arithmetic. The result is reconstructed as BigRational only at the end.
- Add f64_decompose helper (extracted from f64_to_bigrational)
- Add bareiss_det_int: integer-only Bareiss returning (BigInt, i32)
- Add bigint_exp_to_bigrational: reconstruction with trailing-zero reduction (no full GCD needed)
- Refactor bareiss_det as thin wrapper over bareiss_det_int
- Optimize det_sign_exact to read sign from BigInt directly (skip BigRational reconstruction entirely)
- Import std::array::from_fn for shorter call sites
- Replace clippy cast suppression with exact try_from conversions
- Update AGENTS.md with non-interactive gh CLI patterns
- 24 new tests (256 total): f64_decompose, bareiss_det_int (D=0–5, fractional, all-zeros, sign), bigint_exp_to_bigrational (positive/ negative exp, reduction, negative values)
Performance (vs pre-bigint baseline on Apple M4 Max): det_exact: 16x (D=2) → 39x (D=5) faster det_exact_f64: 10x (D=2) → 38x (D=5) faster det_sign_exact: 40x at D=5 (bypasses BigRational entirely) Near-singular: 18x faster
Older releases are archived by minor series: