Repository navigation
DKX 2.5.0
The production solver program of #253: the operator assembled from products with it, the sparse direct route rebuilt on that assembly and made reusable across right-hand sides and the adjoint, and the gap deck's iteration growth traced to the speed resolution with six candidate causes measured and excluded.
The operator can be assembled (#254, #256, #259)
The sparse direct route sampled one column per operator application, which is what max_dense_size bounded and why it refused every production deck. It now recovers the matrix from products with groups of columns that share no row.
- The 66,004-unknown collaborator grid solves in 846 s to a relative residual of 1.3e-14, where the route previously refused it.
- Ruiz equilibration before factoring is what makes a supernodal backend usable: MKL PARDISO answered with a relative residual of 9.4e-2 and nine perturbed pivots as assembled, and 103 s to 1.2e-10 once scaled.
- #259 takes the 633,604-unknown deck from 8,800 products to 4,800, by dropping the requirement that the angular separation divide the grid. The recovered matrix is unchanged entrywise.
One factorization, many solves (#261)
Both direct routes return their factorization in SolveResult.factors and take it back through solve(..., factors=...); solve(..., transpose=True) solves the adjoint from those same factors.
| before | after | |
|---|---|---|
| three right-hand sides as three calls, structured (16,230 unknowns) | 0.96 s, 3 factorizations | 0.28 s, 0 |
| three right-hand sides as three calls, sparse (1,962 unknowns) | 1.19 s, 3 factorizations | 0.28 s, 0 |
| adjoint, sparse direct route | refused | 0.15 of a primal |
| focused solve suites | 406 s | 247 s |
The last row is a defect fixed in passing: _transposed_apply called jax.linear_transpose inside the callable it returned, re-tracing the whole operator on every adjoint application.
Reuse across a neighbouring operator is checked rather than assumed: the defect is measured against the operator actually passed in, and a solve that misses its tolerance refactorizes once, so recovery is bounded by a factorization rather than an unbounded Krylov wait.
Not admitted, and not claimed: the structured route's explicit adjoint lands at 1.31 against a 1.3 gate, and jax.grad misses on every differentiable route — reverse mode re-executes the forward pass and the adjoint already runs on the primal's factors, so factor reuse cannot close it.
Why the gap deck is slow (#258, #260)
Six candidate causes measured and excluded. The dropped collision coupling is not it, although it is 0.9999997 of A − M: retaining it exactly costs 17% more iterations. The cost is carried by Nx and not Nxi, and is independent of the tolerance across three decades. The preconditioned operator is strongly non-normal and more so with Nx, but a diagonal similarity removing 1.5e10 of that eigenvector conditioning moves the iteration count by at most 1.05x, so the balanced solve is killed on its own criterion.
Dependencies
Requires solvax>=0.24.0, whose compression (0.23.0) and equilibration (0.24.0) modules this release is built on.