Checkpoint incomplete calibration work (cond SDT green, evap SST failing) plus related solver/UI changes so the next pass can fix and extend safely. Co-authored-by: Cursor <cursoragent@cursor.com>
1.6 KiB
faer vs nalgebra dense LU — comparative report (Story 1.5, 2026-07-19)
Environment: Windows 11 x64, rustc 1.89 (stable, pinned), release profile, criterion 0.5.
Backends: NalgebraLuSolver (nalgebra 0.33 LU) vs FaerLuSolver (faer 0.24.4 partial-pivot LU), both behind the LinearSolver trait with identical Ruiz equilibration and zero-alloc solve.
| Benchmark | nalgebra | faer | ratio (faer/nalgebra) |
|---|---|---|---|
| factor 9×9 (mock cycle Jacobian) | 308 ns | 1.23 µs | 4.0× slower |
| solve-per-RHS 9×9 | 83 ns | 245 ns | 3.0× slower |
| factor 50×50 (synthetic dense) | 19.4 µs | 20.4 µs | 1.05× slower |
| solve-per-RHS 50×50 | 589 ns | 1.11 µs | 1.9× slower |
Verdict
At Entropyk's current system sizes (n ≤ ~100), faer is NOT faster than nalgebra — the assembled-matrix conversion (nalgebra → faer column-major Mat) costs at factor time on small n, and faer's threading edge only materializes at larger n. faer stays an opt-in alternative (solver.linear_backend = "faer" / ENTROPYK_LINEAR_BACKEND=faer); nalgebra remains the default — the strangler data does not justify retirement, and none was planned in this story.
Revisit when: (a) block-dense/Schur systems push n into the hundreds (Epic 2 / Story 1.8), (b) faer-sparse becomes relevant, (c) batch/parallel solves can exploit faer's rayon threading (Epic 4).
Parity (AC#3): reference cycles A/B/C converge identically within 1e-6 relative on both backends; full solver corpus green on both paths (38/38 test binaries, 0 FAILED).
Reproduce: cargo bench -p entropyk-solver --bench lu_backends