numerics 0.1.0
Loading...
Searching...
No Matches
Solver Best Practices

Use the weakest solver whose mathematical assumptions match the system.

Linear System Classes

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.

Preserve Structure

Prefer constructors that keep mathematical structure in the type:

auto A = num::pde::backward_euler_operator(grid, coeff);
num::SolverResult info = num::cg(A, rhs, x);
BackwardEulerOperator2D backward_euler_operator(int N, double coeff)
SolverResult cg(const Matrix &A, const Vector &b, Vector &x, real tol=1e-10, idx max_iter=1000, Backend backend=default_backend)
Definition cg.cpp:8

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:

num::SparseMatrix A = assemble_spd_matrix();
auto Aspd = num::operators::assume_spd(Aop);
num::SolverResult info = num::cg(Aspd, b, x);
Sparse matrix in Compressed Sparse Row (CSR) format.
Definition sparse.hpp:17
SPDOp< Op > assume_spd(Op op)
Adapt a SparseMatrix to the operator protocol.
Definition sparse_op.hpp:15

assume_spd is an unchecked mathematical cast. It should be used when the discretization, assembly routine, or factorization guarantees the property.

Matrix Properties

Stored dense matrices can also carry declared structure:

num::Matrix A = assemble_dense_spd_matrix();
auto Aspd = num::linalg::make_spd(A);
auto F = num::cholesky(Aspd);
SPDMatrix< Matrix > make_spd(Matrix A, real tol=1e-12)
CholeskyResult cholesky(const linalg::SPDMatrix< Matrix > &A)
Definition cholesky.cpp:7
void cholesky_solve(const CholeskyResult &f, const Vector &b, Vector &x)
Definition cholesky.cpp:40

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.

Preconditioning

Use PCG for SPD systems when CG iteration counts are too high:

num::SparseMatrix A = assemble_spd_matrix();
JacobiPreconditioner jacobi_preconditioner(const Matrix &A)
SolverResult pcg(const Op &A, const M &M_op, const Vector &b, Vector &x, real tol=1e-10, idx max_iter=1000, Backend backend=default_backend)
Definition pcg.hpp:17

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.

Matrix-Free Operators

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:

[N](const num::Vector& u, num::Vector& Lu) {
apply_negative_laplacian(u, Lu, N);
},
N * N);
CallableOp< F > make_op(F f, idx rows, idx cols)
Definition callable.hpp:39

For advection, Jacobians, upwind discretizations, or nonsymmetric preconditioned systems, use GMRES:

auto J = num::operators::make_op(apply_jacobian, n);
num::gmres(J, rhs, x, 1e-8, 1000, 40);
SolverResult gmres(const Op &A, const Vector &b, Vector &x, real tol=1e-6, idx max_iter=1000, idx restart=30)
Operator GMRES for any adapter.
Definition gmres.hpp:25

The unified solve(problem, algorithm) form is useful when the algorithm is selected at the call site:

num::solve(num::LinearProblem{J, rhs}, num::GMRES{.tol = 1e-8, .restart = 40});
ODEResult solve(const P &prob, const RK45 &alg, ObserverFn obs=nullptr)
Definition solve.hpp:32
constexpr real e
Definition math.hpp:44
Linear system A x = b. A is any matrix or LinearOperator; b the RHS. Non-owning view over A and b (bi...
Definition problems.hpp:30
Result of a linear solve: the solution vector plus convergence stats.
Definition solve.hpp:24

Practical Rule

Start from the mathematical class of the operator:

SPD -> Cholesky, CG, PCG
symmetric indefinite -> MINRES
general square -> LU, GMRES
rectangular -> QR, SVD

Then choose direct or iterative form from size, sparsity, and whether only the action \(y=Ax\) is available.