la-stack 0.4.3

Fast, stack-allocated linear algebra for fixed dimensions
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.4.3] - 2026-06-09

### ⚠️ Breaking Changes

- Make exact f64 conversions strict

### Added

- Guard README dependency snippets [`7137fee`]https://github.com/acgetchell/la-stack/commit/7137fee16ab33e08f4dc6a60e02417e3e7c4e020

  - 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`]https://github.com/acgetchell/la-stack/commit/928f62bba0d837afe04cb8ccb3fbfed6b095d8f7
  - 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`]https://github.com/acgetchell/la-stack/commit/53b5fde13f3e4afbd3db80d324185a091203cb75
  - 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`]https://github.com/acgetchell/la-stack/commit/9497ca5f88dd7800bdf3823123e2a295fcb5ced1
  - 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`]https://github.com/acgetchell/la-stack/commit/1fa2f55cfac6f249a7e2bf30922901539e580dd8
- [**breaking**] Make exact f64 conversions strict [`8e33f1a`]https://github.com/acgetchell/la-stack/commit/8e33f1a8ec291bfcb6312375969efce076421e96
  - 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`]https://github.com/acgetchell/la-stack/commit/89f3720ecde9f12d7a0f42e79394836615e8fd97
  - 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`]https://github.com/acgetchell/la-stack/commit/2817d01374ad0aeab98d6f48a3dae9b30f878a8a
  - 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`]https://github.com/acgetchell/la-stack/commit/d31e26a9d7a47a6c3089028630640bcff5afe7c0
  - 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`]https://github.com/acgetchell/la-stack/commit/7258525590f2ed68d41879e71c833010e408e7f7
  - 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`]https://github.com/acgetchell/la-stack/commit/d7c1487115e1a8e5bb1ec4fcc7592786e300e2ce
  - 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.

### Changed

- Cover determinant scale overflow boundaries [`532093a`]https://github.com/acgetchell/la-stack/commit/532093a1ed9f65ace159f80aac290907d570ea8a

  - 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`]https://github.com/acgetchell/la-stack/commit/87e1d0042ad2de7888c1a065ab78524a63f4c045
  - 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`]https://github.com/acgetchell/la-stack/commit/8e12c935fe54e265e8ceb640702267ec0e71b7b1
  - 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.

### Documentation

- Sync citation metadata for v0.4.2 [`f473ec5`]https://github.com/acgetchell/la-stack/commit/f473ec50946e5f668e9ad9a2d978e499dcb10f04

  - 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.

### Fixed

- Escape path regex in benchmark parser test [`1222c93`]https://github.com/acgetchell/la-stack/commit/1222c9325c7b7ea0e1a174e4ee6f0f08e1f7e94b

  Use 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`]https://github.com/acgetchell/la-stack/commit/b9e0ba08e54a15d8eddd5c5c53edc37bbc03939a
- Preserve coordinates for overflowed accumulators [`1d976b3`]https://github.com/acgetchell/la-stack/commit/1d976b346172ad4eca37c68a3ec31817eeca8529

  - 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`]https://github.com/acgetchell/la-stack/commit/7938386166f1f3f5cf594c5def67458d48e19a98
  - 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.

### Performance

- Improve factorization kernel [`8837df1`]https://github.com/acgetchell/la-stack/commit/8837df1f54a9fa2c20abc1487cfce4de8c8e09c5

  - 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`]https://github.com/acgetchell/la-stack/commit/1690355bf27c2cbba685ba0cd70486275c7620b8
  - 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

### Added

- Feat!(matrix): enforce fallible matrix invariants [`e26c283`]https://github.com/acgetchell/la-stack/commit/e26c28358b2358100353b2895441b68892e92cd7
- Feat!(api): enforce fallible numeric invariants [`adfc33b`]https://github.com/acgetchell/la-stack/commit/adfc33b945b259721bd1067e797ed2e7d4ec0e6e
- Feat!(matrix): make determinant API tolerance-free [`11a355c`]https://github.com/acgetchell/la-stack/commit/11a355c099eaf366daec8c95af61b6934f914960
- Feat!(api): hide finite and symmetry proofs behind matrix APIs
  [`7219336`]https://github.com/acgetchell/la-stack/commit/721933671c28eb71953f1386a201622d6171caf7
- Guard public Rust examples against unwrap [`df1130a`]https://github.com/acgetchell/la-stack/commit/df1130a7ad0ba69a1072ef231e14f3efb7e4b8de

  - 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`]https://github.com/acgetchell/la-stack/commit/92ba4034b194875c62a27f24dfbf6d43f380f54e

### Changed

- Remove redundant cache restore keys for cargo-llvm-cov [`f75a01c`]https://github.com/acgetchell/la-stack/commit/f75a01c99c8dbcc8b6ffc36ae9f94ba968a2f111

  Remove 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`]https://github.com/acgetchell/la-stack/commit/a4b9f64235f53274270ef9272634a61f653dad87
- Reapply "ci: modernize tooling checks and example execution"
  [`758321a`]https://github.com/acgetchell/la-stack/commit/758321acf872b1f17286ff3bb7bee6a807e4b440
- Encode nonzero mantissas in exact decomposition [`7a664ed`]https://github.com/acgetchell/la-stack/commit/7a664ede2f4add168c5813f8d24e16732fa03b30

  - 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.
- Simplify finite proof wrappers [`54b603c`]https://github.com/acgetchell/la-stack/commit/54b603c21f0eb5b4d63ff334fac7f8cc325ebc2e
  - 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.

### Dependencies

- Bump taiki-e/install-action from 2.75.18 to 2.75.22 [`d6c944b`]https://github.com/acgetchell/la-stack/commit/d6c944bb7dd30bb00dfe820bc355c4351cb1f242
- Bump actions/setup-node from 6.3.0 to 6.4.0 [`1fc57e1`]https://github.com/acgetchell/la-stack/commit/1fc57e1d5a2e9aed2cc67c90a6ce63b9eb469e2e
- Bump pastey from 0.2.1 to 0.2.2 in the dependencies group [`5b215d5`]https://github.com/acgetchell/la-stack/commit/5b215d5a87a25744d313867471943a614e81abd0
- Bump taiki-e/install-action from 2.75.22 to 2.77.3 [`3e5ce42`]https://github.com/acgetchell/la-stack/commit/3e5ce4273cbe02e0792747b8170efde5d079ae0c
- Bump actions-rust-lang/setup-rust-toolchain [`8532b08`]https://github.com/acgetchell/la-stack/commit/8532b084168e07cfe6b48bb90fa2e533cb69d990
- Bump taiki-e/install-action from 2.77.3 to 2.78.3 [`bef2caf`]https://github.com/acgetchell/la-stack/commit/bef2cafcedd072857742da53256dd472a5855655
- Bump the dependencies group across 1 directory with 2 updates
  [`ba01a14`]https://github.com/acgetchell/la-stack/commit/ba01a14346b84fd6385ee8a6acff8b2180080df5
- Bump taiki-e/install-action from 2.78.3 to 2.80.0 [`480e61b`]https://github.com/acgetchell/la-stack/commit/480e61b85638fb044edccd8116eec777f5588f7d
- Bump codecov/codecov-action from 6.0.0 to 6.0.1 [`3ca8eed`]https://github.com/acgetchell/la-stack/commit/3ca8eed89997379e6cbad863ecc274bba1651749

### Documentation

- Document feature requirement for exact APIs [`19b10d5`]https://github.com/acgetchell/la-stack/commit/19b10d552e83b6a7f9e91695b4850b8fab3f4550
- Document scalar scope and release roadmap [`bfb0393`]https://github.com/acgetchell/la-stack/commit/bfb039386588f94b95561c610181ca6d486acd6e

  - 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`]https://github.com/acgetchell/la-stack/commit/075aed78cf8264fc920258f1f1d977ddd589ffd7
  - 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`]https://github.com/acgetchell/la-stack/commit/fb71485cac0b464b2fa9ee949140a558b7738781
  - 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`]https://github.com/acgetchell/la-stack/commit/7e11f930b94bbba99c1c426e68a515bbefb8c489

### Fixed

- Reject overflowed symmetry tolerance scaling [`a7b052a`]https://github.com/acgetchell/la-stack/commit/a7b052af5dc6361198bbfe1e17d6b1f0ba225ed7

  - 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`]https://github.com/acgetchell/la-stack/commit/ac44c078cc4435d5beca27f1890fbb4046cf5952
  - 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 [`419a90f`]https://github.com/acgetchell/la-stack/commit/419a90f7267608051736498154ac5e6faf0909c5

  Ensure 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`]https://github.com/acgetchell/la-stack/commit/ffca00e9dd6fde5e57c8064f69807a76e45a469e
  - 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.

### Maintenance

- Migrate coverage to cargo-llvm-cov [`66f2117`]https://github.com/acgetchell/la-stack/commit/66f21173344033b3003dd6e46b8400b08e6fdd40
- Align shared security and release tooling [`b303509`]https://github.com/acgetchell/la-stack/commit/b3035095964d9491f0a3d5c4fb790ab5c22cd06f

  - 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`]https://github.com/acgetchell/la-stack/commit/da626bcca899aa91d58f728db433a53a46179e92
  - 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.

### Performance

- Restore checked factorization throughput [`f2e6d56`]https://github.com/acgetchell/la-stack/commit/f2e6d560bd1cb327ff0616644ef704a865520e32

  - 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

### Merged Pull Requests

- Propagate NaN in Matrix::inf_norm [#85]https://github.com/acgetchell/la-stack/pull/85
- Add adversarial-input coverage for exact arithmetic [#80]https://github.com/acgetchell/la-stack/pull/80
- Integer-only forward elimination for gauss_solve [#72]https://github.com/acgetchell/la-stack/pull/72

### Added

- Regression tests for solver and determinant overflow handling
  [`f763b11`]https://github.com/acgetchell/la-stack/commit/f763b119bcc57276b83f370b0bf7abce654c7eb8

  Add test cases to verify that LDLT and LU solvers, as well as determinant
  calculations, correctly detect and return `LaError::NonFinite` when
  intermediate calculations overflow to infinity despite having finite
  inputs.
- Defensive-path test coverage for LU and LDLT solve_vec [`87d426f`]https://github.com/acgetchell/la-stack/commit/87d426fca1627445b804fd26b62fc7d9d4f0ae48

  Add 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
  [`81ecb35`]https://github.com/acgetchell/la-stack/commit/81ecb35bdaf159f1f44d1eb24274ecf82c6567d5

  Make six public methods `const fn`, completing const-evaluation parity
  with `Matrix::det_direct` and `Vector::dot` now that MSRV 1.95 exposes
  `f64::mul_add` as const (1.94) and `core::hint::cold_path` as const
  (1.95):

  - `Lu::det`, `Lu::solve_vec`
  - `Ldlt::det`, `Ldlt::solve_vec`
  - `Matrix::inf_norm`, `Matrix::det_errbound`

  Iterator chains (`.iter().map().sum()`, `.enumerate().take(i)`,
  `.enumerate().skip(i + 1)`, `.iter_mut().enumerate().take(D)`) were
  rewritten as `while` loops since they are not const-stable.

  Fix error-variant correctness in both solve_vec paths:
  - A corrupt stored `U` / `D` diagonal at `(i, i)` now surfaces as
    `LaError::NonFinite { row: Some(i), col: i }`, matching the
    convention used by `Matrix::det`, `Lu::factor`, and `Ldlt::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::NonFinite` variant docs and the `# Errors` sections of
  `Lu::solve_vec` / `Ldlt::solve_vec` to spell out the `(row, col)`
  contract for each failure mode.
- Fast-filter boundary proptests for exact determinant sign [`6357db3`]https://github.com/acgetchell/la-stack/commit/6357db35c70bca1b93e6bbf9a4fd231913631950

  Introduce 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.

### Changed

- Finalize documentation, benchmarks, and error handling [`0b98d3f`]https://github.com/acgetchell/la-stack/commit/0b98d3f6dbdd74699c318c4744a2b2f9a1b78481

  Synchronize 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 [`f8d80a0`]https://github.com/acgetchell/la-stack/commit/f8d80a01e9913f87e1b19b2ad5ffbc0994e2bfdb

  Refactor manual const-evaluation tests in `Ldlt` and `Matrix` into 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
  [`ecbbe8a`]https://github.com/acgetchell/la-stack/commit/ecbbe8a571ccaeb9cfedbf0269b8db44d43a5773

  Migrate 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) [`53a5be6`]https://github.com/acgetchell/la-stack/commit/53a5be6abecc0af332398236ed6803ed75564b03

  Major 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`) so `bareiss_det_int` and `gauss_solve`
    share a single integer-Bareiss core.
  - Hybrid BigInt/BigRational solve: forward elimination runs entirely in
    `BigInt` with fraction-free Bareiss updates on `(A | b)`; only the
    `O(D²)` back-substitution phase lifts into `BigRational`.
  - `mem::take` in back-substitution eliminates per-entry `clone()` calls
    on `rhs[i]`, `a[i][j]`, `a[i][i]`.

  Structured errors replace preconditions:
  - `decompose_matrix` / `decompose_vec` fold `is_finite()` into the same
    pass that decomposes each entry and return
    `Err(LaError::NonFinite { row, col })` on the first non-finite cell.
  - `bareiss_det_int`, `bareiss_det`, `gauss_solve` now return
    `Result<_, LaError>`; error propagates to every public entry point via
    `?`.
  - `validate_finite` and `validate_finite_vec` removed (dead after the
    refactor); `det_sign_exact` relies on IEEE 754 NaN/∞ propagation
    through `det_direct()` plus `bareiss_det_int` for Stage-2 validation.
- Add adversarial-input coverage for exact arithmetic [#80]https://github.com/acgetchell/la-stack/pull/80
  [`5bf5815`]https://github.com/acgetchell/la-stack/commit/5bf5815cb165c3b6145c5592420a58085a66efaa

  Expand 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_group` helper 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_3x3` with the two solve benches (the
    primary motivating use case for exact solve was previously unmeasured).
  - Add `exact_large_entries_3x3` (entries near `f64::MAX / 2`) to stress
    intermediate BigInt growth during Bareiss forward elimination.
  - Add `exact_hilbert_4x4` / `exact_hilbert_5x5` to stress the
    `f64_decompose → BigInt` scaling 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 with `f64::MAX/2` diagonal.
  - `det_sign_exact_large_entries_3x3_positive` — asserts the fast filter
    falls through (`det_direct` is non-finite) and `det_exact_f64` returns
    `Overflow { index: None }`.
  - `det_sign_exact_hilbert_positive_{3,4,5}d` — Hilbert is SPD, sign = 1.
  - `solve_exact_hilbert_residual_{3,4,5}d` — residual `A·x - b` is exactly
    zero in `BigRational`, 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
    integer `A` and small-integer `x0`, verify `solve(A, A·x0) == x0` exactly.
  - `solve_exact_residual_{2..5}d` — random `A` + small-integer `b`, verify
    `A · solve(A, b) == b` exactly (catches back-sub bugs on fractional
    solutions).
  - `det_sign_exact_agrees_with_det_exact_{2..5}d` — on full (non-diagonal)
    small-integer matrices, asserts `det_sign_exact() == det_exact().sign()`
    (exercises the filter/fallback boundary previously only diagonal-tested).

  Prelude (src/lib.rs):
  - Re-export `BigInt` alongside `BigRational` (crate root + prelude).
  - Re-export `FromPrimitive`, `Signed`, `ToPrimitive` from `num-traits` in
    the prelude so the re-exported `BigRational` is actually usable for
    construction (`from_f64`, `from_i64`) and sign queries without forcing
    downstream users to add `num-bigint` / `num-rational` / `num-traits` to
    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_heading` with 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
- Expand exact-arithmetic re-exports and adversarial benchmarks
  [`b1a491d`]https://github.com/acgetchell/la-stack/commit/b1a491d902ccdaba6f9cd2e6f8e05514b6dfa3de

  Update the `exact` feature to re-export `BigInt` and essential `num-traits`
  (FromPrimitive, ToPrimitive, Signed) alongside `BigRational`. This
  simplifies downstream usage by removing the need for direct dependencies
  on the `num` ecosystem 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`]https://github.com/acgetchell/la-stack/commit/1e0648dad3147ef127c775d8969b7cd214a2a6ed

### Dependencies

- Bump taiki-e/install-action from 2.73.0 to 2.75.7 [`a1d1c1e`]https://github.com/acgetchell/la-stack/commit/a1d1c1edba7d5bf6928de4e8cab86ba853685430
- Bump actions/download-artifact from 4.3.0 to 8.0.1 [`8772ea2`]https://github.com/acgetchell/la-stack/commit/8772ea2f18cf1b94a21e269b4bc0c8e0a3b650eb
- Bump rand from 0.9.2 to 0.9.4 [`b91670a`]https://github.com/acgetchell/la-stack/commit/b91670a46f82306dde5433ca7c406a8757e3fc59
- Bump actions/upload-artifact from 7.0.0 to 7.0.1 [`7579274`]https://github.com/acgetchell/la-stack/commit/7579274d56ab8c46eae6906c07a3c0d0fd41c84f
- Bump actions/github-script from 8.0.0 to 9.0.0 [`a522abd`]https://github.com/acgetchell/la-stack/commit/a522abdabf211d47f0f52cbfc2a349fa72ce87e2
- Bump actions/cache from 5.0.4 to 5.0.5 [`b12d95c`]https://github.com/acgetchell/la-stack/commit/b12d95c8ce242ea6014c6a6aaa7845ff501d2e4d
- Bump actions-rust-lang/setup-rust-toolchain [`c728774`]https://github.com/acgetchell/la-stack/commit/c72877460efba3d598f64ff253d2df8f3695acb1
- Bump astral-sh/setup-uv from 8.0.0 to 8.1.0 [`7a18733`]https://github.com/acgetchell/la-stack/commit/7a18733ba0f39102678bbe30772fcde10f20e9d8
- Bump taiki-e/install-action from 2.75.7 to 2.75.18 [`433cfc1`]https://github.com/acgetchell/la-stack/commit/433cfc1b01c9128e93c82cb553aa63d4091bace3

### Documentation

- Strengthen LDLT symmetry precondition and add is_symmetric API
  [`1693307`]https://github.com/acgetchell/la-stack/commit/1693307c58e30a804e9b79abc783af99be8dc947

  LDLT 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_symmetric` check is compiled out), and
  callers had no supported way to validate symmetry up front.

### Fixed

- Propagate NaN in Matrix::inf_norm [#85]https://github.com/acgetchell/la-stack/pull/85
  [`16ffa45`]https://github.com/acgetchell/la-stack/commit/16ffa45ade11b21a179cad8fcecc51d802086a1d
- Report infinite vs finite off-diagonal pairs as asymmetric [`1805779`]https://github.com/acgetchell/la-stack/commit/1805779dbca49183fbfa95c68ec00984966aa551

  Update 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 > eps` return false.

### Maintenance

- Bump MSRV to Rust 1.95 and adopt new stable features [`0ab3c33`]https://github.com/acgetchell/la-stack/commit/0ab3c336074f2b866256fbe5db8a8ec5306d580a

  - 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

### Performance

- Integer-only forward elimination for gauss_solve [#72]https://github.com/acgetchell/la-stack/pull/72
  [`a1d3bdb`]https://github.com/acgetchell/la-stack/commit/a1d3bdbdb6fcb778a78a2a3d0cb66b79484e1472

  Replace 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

### Merged Pull Requests

- Integer-only Bareiss determinant via BigInt [#64]https://github.com/acgetchell/la-stack/pull/64
- Custom f64 → BigRational via IEEE 754 bit decomposition [#63]https://github.com/acgetchell/la-stack/pull/63

### Added

- Add benchmark comparison tool and performance documentation
  [`d448fc3`]https://github.com/acgetchell/la-stack/commit/d448fc3e3c884d6145580e5a40eb265bf1f83cb8

  Introduce 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.

### Changed

- Update version to 0.3.0 and refine metadata keywords [`cc0e967`]https://github.com/acgetchell/la-stack/commit/cc0e967aedb4eabbcd98714b16ef67a8290c112e

  Update 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 [`e1b5955`]https://github.com/acgetchell/la-stack/commit/e1b5955fb5024232e34e9df9701bb24fb98efa15

  Refactor the `bench_compare.py` script 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`]https://github.com/acgetchell/la-stack/commit/bced7d988bd2f42cb6bb5af9c54dabdcf787a5fc
- Update documentation and tests for integer-only Bareiss [`2ee3f05`]https://github.com/acgetchell/la-stack/commit/2ee3f05caecfdf1a23b61257a7465b3bb6d63614

  Update 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 [`9a7caa2`]https://github.com/acgetchell/la-stack/commit/9a7caa241b5f476c2659772f3189468b10fcba2e

  Update 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.

### Dependencies

- Bump astral-sh/setup-uv from 7.3.1 to 7.5.0 [`0505061`]https://github.com/acgetchell/la-stack/commit/050506123b1da9bc79b04e7d8b44d8195d115199
- Bump taiki-e/install-action from 2.68.25 to 2.68.31 [`dcff501`]https://github.com/acgetchell/la-stack/commit/dcff501354df2e6434fd6f817a7c15b86a40685f
- Bump actions-rust-lang/setup-rust-toolchain [`4678d2e`]https://github.com/acgetchell/la-stack/commit/4678d2e8b121c3116d638b59b03eca95510888fe
- Bump actions/cache from 5.0.3 to 5.0.4 [`633c6e2`]https://github.com/acgetchell/la-stack/commit/633c6e234dc4a94744fa433f41bceb84efe1c99c
- Bump taiki-e/install-action from 2.68.34 to 2.69.6 [`89a306b`]https://github.com/acgetchell/la-stack/commit/89a306b64bf586ec201957953afac0a3d9c13eb7
- Bump astral-sh/setup-uv from 7.5.0 to 7.6.0 [`676a6ff`]https://github.com/acgetchell/la-stack/commit/676a6ffe3df416ab316daa84119161893eeeadd0
- Bump codecov/codecov-action from 5.5.2 to 5.5.3 [`2c15dc1`]https://github.com/acgetchell/la-stack/commit/2c15dc1a0c93f75dd23e0d540041bc01f2e3b71a
- Bump the dependencies group with 2 updates [`23ade13`]https://github.com/acgetchell/la-stack/commit/23ade1343e575edead08ab49a4e361c9e37f5ca0
- Bump taiki-e/install-action from 2.69.6 to 2.70.1 [`4073197`]https://github.com/acgetchell/la-stack/commit/40731976f465f69bacb0a6dc4b8520fb9bc9c8f4
- Bump codecov/codecov-action from 5.5.3 to 6.0.0 [`b3e1380`]https://github.com/acgetchell/la-stack/commit/b3e1380e0b8df85478648036eeb1d9b2c79aaac5
- Bump taiki-e/install-action from 2.70.1 to 2.73.0 [`7de720d`]https://github.com/acgetchell/la-stack/commit/7de720dfb8328d01843cfabd15d23086ee98832b
- Bump astral-sh/setup-uv from 7.6.0 to 8.0.0 [`af40753`]https://github.com/acgetchell/la-stack/commit/af40753130fac56d48da7fce2f18b11dc391ebe6

### Fixed

- Improve non-finite error reporting and coordinate accuracy [`d4b1452`]https://github.com/acgetchell/la-stack/commit/d4b14524a02b49a1a8e832818913ab875c4e5fe0

  Refine 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.

### Maintenance

- Add performance regression detection for exact-arithmetic benchmarks
  [`44bce99`]https://github.com/acgetchell/la-stack/commit/44bce99bcae8f852dbf7500e71fa182730e08bca

  Add 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

### Performance

- Stack-backed storage for exact arithmetic kernels [`b64ac60`]https://github.com/acgetchell/la-stack/commit/b64ac60e286bcdc1c21334ab271e6ffacfadc187

  Replace heap-allocated Vec&lt;Vec&lt;BigRational&gt;&gt; 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&lt;Vec&lt;BigRational&gt;&gt; → [[BigRational; D]; D] via
    std::array::from_fn
  - gauss_solve: Vec&lt;Vec&lt;BigRational&gt;&gt; augmented matrix → separate
    [[BigRational; D]; D] + [BigRational; D] avoids unstable
    const-generic [T; D+1]
  - gauss_solve return type: Vec&lt;BigRational&gt; → [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&lt;usize&gt; for full (row, col)
    location on matrix inputs; None for vectors/intermediates
  - LaError::Overflow becomes a struct variant with index: Option&lt;usize&gt;
    to identify which solution component overflowed
  - Display messages updated to show positional context
- Custom f64 → BigRational via IEEE 754 bit decomposition [#63]https://github.com/acgetchell/la-stack/pull/63
  [`0a8ce5b`]https://github.com/acgetchell/la-stack/commit/0a8ce5b45e21fa88e4e9832bc6ada38b3ba68eeb

  Replace `BigRational::from_float(x)` in `f64_to_bigrational` with manual
  IEEE 754 binary64 bit decomposition and `BigRational::new_raw`, bypassing
  the unnecessary GCD normalization that `from_float` performs 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]https://github.com/acgetchell/la-stack/pull/64
  [`d422b25`]https://github.com/acgetchell/la-stack/commit/d422b251ca86a914522f80285964d4513bca1817

  Replace 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

## Archives

Older releases are archived by minor series:

- [0.3.x]docs/archive/changelog/0.3.md
- [0.2.x]docs/archive/changelog/0.2.md
- [0.1.x]docs/archive/changelog/0.1.md

[0.4.3]: https://github.com/acgetchell/la-stack/compare/v0.4.2...v0.4.3
[0.4.2]: https://github.com/acgetchell/la-stack/compare/v0.4.1...v0.4.2
[0.4.1]: https://github.com/acgetchell/la-stack/compare/v0.4.0...v0.4.1
[0.4.0]: https://github.com/acgetchell/la-stack/compare/v0.3.0...v0.4.0