Solver Derivation Lab
This lab derives the numerical updates used in silva_networks.solvers. The
goal is to let a reader start from the equilibrium equation and end at the exact
objects returned by the package.
Residual Form
The fixed point
is equivalent to the root problem
The package records residuals as
Every solver accepts a transition function f, an initial state z0, and a
SolverConfig. Every solver returns SolverResult(z, residuals, iterations,
converged, solver).
Damped Picard
The simplest iteration evaluates the transition and blends it with the old state:
For \(\alpha=1\), this is ordinary Picard iteration. For \(0<\alpha<1\), the step is damped. The contraction argument follows the fixed-point theorem of Banach [41]. If \(f_\theta\) is a contraction with constant \(L<1\), then
This is why damping is a stability control rather than a cosmetic parameter.
The package field is SolverConfig.alpha.
Anderson Acceleration
Anderson acceleration [10] [11] keeps recent states and transition values:
Let \(R_k=F_k-X_k\). The next point is a mixture of previous transition values:
The coefficients minimize the residual mixture subject to summing to one:
The KKT system implemented in anderson is
The package names are:
| Symbol | Package field |
|---|---|
| \(m\) | SolverConfig.history |
| \(\lambda\) | SolverConfig.ridge |
| mixture damping | SolverConfig.beta |
| residual tolerance | SolverConfig.tol |
Anderson is fast when the residual history spans useful correction directions. It can be less stable when the least-squares system is ill-conditioned; the ridge term is the package's first stabilizer.
Broyden Inverse Update
Broyden's quasi-Newton method [12] solves the root problem \(r(z)=0\) by maintaining an approximate inverse Jacobian \(B_k\approx J_r(z_k)^{-1}\). The step is
Let
The inverse secant condition is
The package uses the good-Broyden inverse update:
The denominator is checked for numerical safety. If it is too small, the update is skipped and the current inverse approximation is retained.
GMRES For The Adjoint
Implicit differentiation needs the linear adjoint solve
where \(T_\alpha(z)=(1-\alpha)z+\alpha f(z,x)\). The package exposes this
through implicit_adjoint_solve.
GMRES [13] solves \(Au=b\) without materializing \(A\). Starting with \(r_0=b-Au_0\), Arnoldi iteration constructs orthonormal basis vectors \(q_1,\ldots,q_k\) and an upper Hessenberg matrix \(H_k\):
The approximate solution is
For SILVA adjoints, the matrix-vector product is
PyTorch computes \(J_T^\top v\) by vector-Jacobian product, so the full Jacobian is not needed.
Solver Selection
| Need | Suggested solver |
|---|---|
| Transparent baseline, stable maps | Picard |
| Faster fixed-point solve for small and medium states | Anderson |
| Root-finding behavior with compact states | Broyden |
| Linear implicit-adjoint diagnostics | GMRES |
Minimal Check
import torch
from silva_networks import SolverConfig, fixed_point
W = torch.tensor([[0.2, 0.1], [0.0, 0.3]])
b = torch.tensor([0.5, -0.2])
def f(z):
return torch.tanh(W @ z + b)
z0 = torch.zeros(2)
result = fixed_point(f, z0, SolverConfig(solver="anderson", max_iter=20, tol=1e-6))
print(result.z)
print(result.residuals)
The residuals should decrease until the tolerance or iteration budget stops the solve.
Check result.converged, result.iterations, and result.info["termination"]
alongside the curve. When comparing methods, keep the transition, initial
state, tolerance definition, and numerical precision fixed.
Primary sources for Anderson acceleration, Broyden updates, and GMRES are listed in Solvers and Linear Algebra. The executable comparison is in Solvers and Jacobians.
Where to Go Next
| Question | Page |
|---|---|
| Which solver configurations are public? | Solvers API |
| What mathematical assumptions support convergence? | Fixed Points |
| Where can I inspect residual and stability traces? | Interactive Diagnostics Lab |