Numerical Methods: Solving the Continuous on the Discrete

Numerical methods form the computational discipline dedicated to approximating solutions to continuous mathematical problems using finite, discrete computing machines. Because digital computers represent real numbers with finite bit lengths, exact mathematical solutions to differential equations, large linear systems, and continuous optimization problems are rarely achievable.

Numerical analysis provides the mathematical framework for constructing algorithms that balance computational complexity, numerical stability, and rigorous truncation error bounds.


1. Machine Precision, Error Analysis, and Conditioning

IEEE 754 Floating-Point Representation

In IEEE 754 double-precision arithmetic (binary64), a real number x is stored across 64 bits: 1 sign bit (s), 11 exponent bits (e), and 52 fraction/mantissa bits (m):

x = (-1)^s \times 2^{e - 1023} \times \left(1 + \sum_{i=1}^{52} b_{52-i} 2^{-i}\right)

The machine epsilon \epsilon_{\text{mach}} = 2^{-52} \approx 2.2204 \times 10^{-16} represents the upper bound on the relative error due to rounding:

\left|\frac{\operatorname{fl}(x) - x}{x}\right| \le \epsilon_{\text{mach}}
IEEE 754 Double-Precision Layout (64-bit):
+---+----------------------+----------------------------------------------------+
| s |   Exponent (11 bits) |               Significand / Mantissa (52 bits)     |
+---+----------------------+----------------------------------------------------+
 63  62                  52 51                                                 0

Forward vs. Backward Error and Conditioning

For a continuous mathematical problem f(x) evaluated via a numerical algorithm \hat{f}(x):

  1. Forward Error: \Delta y = \|\hat{f}(x) - f(x)\|
  2. Backward Error: The smallest perturbation \Delta x in input space such that \hat{f}(x) = f(x + \Delta x).
  3. Backward Stability: An algorithm is backward stable if for every x, the backward error satisfies \frac{\|\Delta x\|}{\|x\|} = \mathcal{O}(\epsilon_{\text{mach}}).

The Condition Number \kappa measures the intrinsic sensitivity of the mathematical problem to perturbations, independent of the algorithm:

\kappa = \lim_{\delta \to 0} \sup_{\|\Delta x\| \le \delta} \frac{\|f(x + \Delta x) - f(x)\| / \|f(x)\|}{\|\Delta x\| / \|x\|}

For a linear system A x = b, the condition number with respect to matrix inversion is:

\kappa(A) = \|A\| \cdot \|A^{-1}\| = \frac{\sigma_{\max}(A)}{\sigma_{\min}(A)}

where \sigma_{\max}, \sigma_{\min} are the maximum and minimum singular values of A. A rule of thumb is that if \kappa(A) \approx 10^k, solving A x = b in double precision loses approximately k decimal digits of accuracy.

Catastrophic Cancellation

Catastrophic cancellation occurs when subtracting two nearly equal floating-point numbers x \approx y, amplifying the relative error of the lower-order bits. For example, evaluating roots of a x^2 + b x + c = 0 when b^2 \gg 4ac:

x_1 = \frac{-b - \operatorname{sign}(b)\sqrt{b^2 - 4ac}}{2a}, \quad x_2 = \frac{2c}{-b - \operatorname{sign}(b)\sqrt{b^2 - 4ac}}

Computing x_2 = \frac{-b + \sqrt{b^2-4ac}}{2a} directly induces severe cancellation, whereas the algebraic reformulations above preserve full machine precision.


2. Numerical Linear Algebra

Solving large systems of linear equations A x = b is the computational bottleneck in finite element analysis (FEA), machine learning backpropagation, and fluid dynamics simulations.

Direct vs. Iterative Solvers:
--------------------------------------------------------------------------------
System Type             Recommended Method               Complexity
--------------------------------------------------------------------------------
Dense (Small/Medium)    LU Factorization (Pivoting)      O(2/3 n³)
Symmetric Pos. Definite Cholesky Factorization (L L^T)   O(1/3 n³) [Twice as fast as LU]
Overdetermined (Least Sq)QR via Householder Reflections   O(2 m n² - 2/3 n³)
Large Sparse Symmetric  Preconditioned Conjugate Gradient O(k · nnz(A))
Large Sparse Asymmetric GMRES / BiCGSTAB                 O(k · nnz(A) + k² n)
--------------------------------------------------------------------------------

Direct Factorizations

  1. LU Decomposition with Partial Pivoting (P A = L U): Permutes rows via P such that the pivot elements satisfy |u_{ii}| \ge |u_{ji}| for j > i, bounding element growth during Gaussian elimination.
  2. Cholesky Factorization (A = L L^T): For symmetric positive-definite (SPD) matrices A \succ 0, all diagonal entries are real and strictly positive:
    L_{jj} = \sqrt{A_{jj} - \sum_{k=1}^{j-1} L_{jk}^2}, \quad L_{ij} = \frac{1}{L_{jj}} \left(A_{ij} - \sum_{k=1}^{j-1} L_{ik} L_{jk}\right)
  3. QR Factorization via Householder Reflections: Constructs orthogonal matrices Q = H_1 H_2 \dots H_n where H_k = I - 2 \frac{v_k v_k^T}{v_k^T v_k}, producing unconditional numerical stability without pivoting.

Krylov Subspace Iterative Methods

For large sparse matrices (n > 10^6), direct \mathcal{O}(n^3) factorizations require excessive memory. Krylov subspace methods project A onto the subspace \mathcal{K}_k(A, r_0) = \operatorname{span}\{r_0, A r_0, A^2 r_0, \dots, A^{k-1} r_0\}.

The Conjugate Gradient (CG) algorithm minimizes the energy norm \|x_k - x^*\|_A over \mathcal{K}_k:

import numpy as np

def conjugate_gradient(A: np.ndarray, b: np.ndarray, x0: np.ndarray = None, tol: float = 1e-10, max_iter: int = 1000):
    """
    Solves A x = b for Symmetric Positive Definite (SPD) matrix A using Conjugate Gradient.
    """
    n = len(b)
    x = np.zeros(n) if x0 is None else x0.copy()
    r = b - A @ x
    p = r.copy()
    rs_old = np.dot(r, r)
    
    for i in range(max_iter):
        Ap = A @ p
        alpha = rs_old / np.dot(p, Ap)
        x += alpha * p
        r -= alpha * Ap
        rs_new = np.dot(r, r)
        
        if np.sqrt(rs_new) < tol:
            return x, i + 1
            
        p = r + (rs_new / rs_old) * p
        rs_old = rs_new
        
    return x, max_iter

Convergence rate is governed by the condition number \kappa(A):

\|x_k - x^*\|_A \le 2 \left(\frac{\sqrt{\kappa(A)} - 1}{\sqrt{\kappa(A)} + 1}\right)^k \|x_0 - x^*\|_A

Preconditioning transforms the system into M^{-1} A x = M^{-1} b such that \kappa(M^{-1} A) \approx 1.


3. Nonlinear Equations and Unconstrained Optimization

Newton-Raphson Method and Quadratic Convergence

To solve f(x) = 0 for f: \mathbb{R} \to \mathbb{R}:

x_{k+1} = x_k - \frac{f(x_k)}{f'(x_k)}

Theorem (Quadratic Convergence): If f \in C^2, f'(x^*) \neq 0, and x_0 is sufficiently close to x^*, the error e_k = x_k - x^* satisfies:

\lim_{k \to \infty} \frac{|e_{k+1}|}{|e_k|^2} = \left|\frac{f''(x^*)}{2 f'(x^*)}\right|

This doubles the number of correct significant figures at every iteration near the root.

Convergence Comparison for Root Finding:
--------------------------------------------------------------------------------
Method                  Order of Convergence (p)     Function Evals / Step
--------------------------------------------------------------------------------
Bisection               p = 1 (Linear)               1 eval (Guaranteed robust)
Secant Method           p = (1 + √5)/2 ≈ 1.618       1 eval (No derivative needed)
Newton-Raphson          p = 2 (Quadratic)            2 evals (f and f')
Halley's Method         p = 3 (Cubic)                3 evals (f, f', and f'')
--------------------------------------------------------------------------------

Multi-Dimensional Optimization & Quasi-Newton (BFGS)

For unconstrained minimization \min_{x \in \mathbb{R}^n} f(x), pure Newton updates x_{k+1} = x_k - [\nabla^2 f(x_k)]^{-1} \nabla f(x_k) require \mathcal{O}(n^3) operations per step to compute and invert the Hessian \nabla^2 f(x).

The Broyden-Fletcher-Goldfarb-Shanno (BFGS) method iteratively updates an inverse Hessian approximation H_k \approx (\nabla^2 f(x_k))^{-1} with rank-2 matrix updates:

s_k = x_{k+1} - x_k, \quad y_k = \nabla f(x_{k+1}) - \nabla f(x_k), \quad \rho_k = \frac{1}{y_k^T s_k}
H_{k+1} = (I - \rho_k s_k y_k^T) H_k (I - \rho_k y_k s_k^T) + \rho_k s_k s_k^T

This maintains positive definiteness (H_{k+1} \succ 0) and guarantees superlinear convergence with only \mathcal{O}(n^2) complexity per step.


4. Numerical Quadrature (Integration)

Numerical integration approximates definite integrals I(f) = \int_a^b f(x) dx \approx \sum_{i=0}^n w_i f(x_i).

Quadrature Rules:
+-------------------+-----------------------------------+-----------------------+
| Method            | Formula / Stencil                 | Error Order           |
+-------------------+-----------------------------------+-----------------------+
| Trapezoidal Rule  | h/2 [f(a) + 2∑f(x_i) + f(b)]       | O(h²) · f''(ξ)        |
| Simpson's 1/3 Rule| h/3 [f_0 + 4∑f_odd + 2∑f_even + fn]| O(h⁴) · f⁽⁴⁾(ξ)       |
| Gauss-Legendre    | ∑ w_i f(x_i) on Legendre roots    | Exact for poly ≤ 2n-1 |
+-------------------+-----------------------------------+-----------------------+

Gauss-Legendre Quadrature

By choosing non-equispaced evaluation nodes x_i as the roots of the n-th degree Legendre polynomial P_n(x) on [-1, 1], Gaussian quadrature achieves the maximum possible algebraic degree of exactness: an n-point rule integrates all polynomials up to degree 2n - 1 exactly.


5. Ordinary Differential Equations (ODEs) and Stiff Systems

Solving the initial value problem (IVP):

\frac{dy}{dt} = f(t, y), \quad y(t_0) = y_0

Runge-Kutta Methods and the Butcher Tableau

The general s-stage explicit Runge-Kutta method computes:

k_i = f\left(t_n + c_i h, y_n + h \sum_{j=1}^{i-1} a_{ij} k_j\right), \quad i = 1, \dots, s
y_{n+1} = y_n + h \sum_{i=1}^s b_i k_i

For the classical 4th-order Runge-Kutta (RK4):

\begin{array}{c|cccc} 0 & & & & \\ 1/2 & 1/2 & & & \\ 1/2 & 0 & 1/2 & & \\ 1 & 0 & 0 & 1 & \\ \hline & 1/6 & 1/3 & 1/3 & 1/6 \end{array}

RK4 has a local truncation error of \mathcal{O}(h^5) and global error of \mathcal{O}(h^4).

def rk4_step(f, t: float, y: np.ndarray, h: float) -> np.ndarray:
    """Executes a single 4th-order Runge-Kutta step."""
    k1 = f(t, y)
    k2 = f(t + 0.5 * h, y + 0.5 * h * k1)
    k3 = f(t + 0.5 * h, y + 0.5 * h * k2)
    k4 = f(t + h, y + h * k3)
    return y + (h / 6.0) * (k1 + 2.0 * k2 + 2.0 * k3 + k4)

Stiffness and Absolute Stability

A system of ODEs y' = A y is stiff if the eigenvalues \lambda_i of the Jacobian J = \frac{\partial f}{\partial y} have negative real parts with vastly different magnitudes:

\text{Stiffness Ratio} = \frac{\max_i |\operatorname{Re}(\lambda_i)|}{\min_i |\operatorname{Re}(\lambda_i)|} \gg 1

Applying explicit forward Euler y_{n+1} = (1 + h \lambda) y_n to the test equation y' = \lambda y (\operatorname{Re}(\lambda) < 0) requires |1 + h \lambda| \le 1 for numerical stability, forcing an impractically small step size:

h \le \frac{2}{|\lambda_{\max}|}
Stability Regions in Complex z = hλ Plane:
       Explicit Forward Euler                   Implicit Backward Euler
          (Bounded Circle)                     (Unbounded Exterior Region)
              | Im(z)                                    | Im(z)
              |                                          |
          +---+---+                                  XXXX|XXXX
        /     |     \                                XXXX|XXXX
       |   Stable    | Re(z)                         XXXX+---+XXXX  Re(z)
        \   Region  /                                XXXX|   |XXXX (Stable everywhere
          +---+---+                                  XXXX|XXXX      except inside circle)
              |                                          |

A-Stability and Implicit Solvers

An ODE solver is A-stable if its stability region includes the entire left half of the complex plane \mathbb{C}^- = \{z \in \mathbb{C} : \operatorname{Re}(z) \le 0\}.


6. Algorithmic Decision Architecture

                                [ Numerical Problem ]
                                          |
        +------------------+--------------+------------------+------------------+
        |                  |                                 |                  |
   [Linear System]   [Nonlinear Opt]                   [Integration]         [ODEs]
        |                  |                                 |                  |
    Sparse / SPD?      Hessian cheap?                   Smooth bounds?      Stiff system?
     /        \          /        \                       /       \            /      \
   Yes         No      Yes         No                   Yes        No        Yes       No
   /            \      /            \                   /           \        /          \
[PCG]        [LU /   [Newton]    [BFGS /             [Gauss-    [Adaptive [Implicit    [Adaptive
              GMRES]             L-BFGS]             Legendre]   Simpson]  BDF/Radau]   RK45]

7. References

  1. Golub, G. H., & Van Loan, C. F. (2013). Matrix Computations (4th ed.). Johns Hopkins University Press.
  2. Trefethen, L. N., & Bau, D. (2022). Numerical Linear Algebra (25th Anniversary ed.). SIAM.
  3. Nocedal, J., & Wright, S. J. (2006). Numerical Optimization (2nd ed.). Springer.
  4. Hairer, E., Nørsett, S. P., & Wanner, G. (1993). Solving Ordinary Differential Equations I: Nonstiff Problems. Springer.
  5. Hairer, E., & Wanner, G. (1996). Solving Ordinary Differential Equations II: Stiff and Differential-Algebraic Problems. Springer.
  6. Higham, N. J. (2002). Accuracy and Stability of Numerical Algorithms (2nd ed.). SIAM.