|
numerics 0.1.0
|
Use the weakest solver whose mathematical assumptions match the system.
For a general linear system
\[ Ax=b , \]
choose the method from the structure of \(A\):
| Matrix/operator class | Condition | Routine |
|---|---|---|
| SPD | \(A=A^T,\; x^T A x>0\) | cg, pcg, cholesky |
| symmetric indefinite | \(A=A^T\) | minres |
| nonsymmetric/general | no symmetry assumption | gmres, lu |
| rectangular/least squares | \(\min_x \|Ax-b\|_2\) | qr_solve, svd |
Do not use CG as a general-purpose Krylov method. If symmetry or positive definiteness is not known, use GMRES.
Prefer constructors that keep mathematical structure in the type:
backward_euler_operator owns the assembled sparse matrix and carries the SPD operator tag. The solver call is short because the PDE builder supplies the structure.
When structure comes from outside the library, state it explicitly:
assume_spd is an unchecked mathematical cast. It should be used when the discretization, assembly routine, or factorization guarantees the property.
Stored dense matrices can also carry declared structure:
make_spd checks symmetry and the Cholesky pivots before constructing the SPD wrapper. Use assume_spd only when the construction, discretization, or prior factorization already proves the property.
Use PCG for SPD systems when CG iteration counts are too high:
A preconditioner represents applying \(M^{-1}r\), not forming \(M^{-1}\) explicitly. The preconditioner must be compatible with the solver class: SPD-compatible preconditioners for PCG, general preconditioners for general Krylov methods.
For matrix-free code, runtime SPD validation is generally not available. The library cannot inspect all entries of \(A\) because they are never assembled. Use property wrappers only when the formula is known:
For advection, Jacobians, upwind discretizations, or nonsymmetric preconditioned systems, use GMRES:
The unified solve(problem, algorithm) form is useful when the algorithm is selected at the call site:
Start from the mathematical class of the operator:
Then choose direct or iterative form from size, sparsity, and whether only the action \(y=Ax\) is available.