numerics 0.1.0
Loading...
Searching...
No Matches
gauss_seidel.cpp
Go to the documentation of this file.
2#include <cmath>
3#include <stdexcept>
4
5namespace num {
6
7// Gauss-Seidel -- sequential update order, parallel residual when omp backend.
8//
9// Note: standard Gauss-Seidel has sequential data dependencies (x[i] depends
10// on x[0..i-1] updated in the same sweep). We keep the sequential update
11// order here and parallelise only the residual computation. For a truly
12// parallel relaxation scheme, use the Jacobi solver with Backend::omp.
13SolverResult gauss_seidel(const Matrix &A, const Vector &b, Vector &x, real tol,
14 idx max_iter, Backend backend) {
15 constexpr real zero_diag_tol = 1e-15;
16 idx n = b.size();
17 if (A.rows() != n || A.cols() != n || x.size() != n)
18 throw std::invalid_argument("Dimension mismatch in Gauss-Seidel solver");
19
20 SolverResult result{0, 0.0, false};
21
22 for (idx iter = 0; iter < max_iter; ++iter) {
23 // Sequential update -- maintain GS convergence properties
24 for (idx i = 0; i < n; ++i) {
25 if (std::abs(A(i, i)) < zero_diag_tol)
26 throw std::runtime_error("Zero diagonal in Gauss-Seidel at row " +
27 std::to_string(i));
28 real sigma = 0.0;
29 for (idx j = 0; j < n; ++j)
30 if (j != i)
31 sigma += A(i, j) * x[j];
32 x[i] = (b[i] - sigma) / A(i, i);
33 }
34
35 // Residual ||b - Ax||
36 real res = 0.0;
37#ifdef NUMERICS_HAS_OMP
38#pragma omp parallel for reduction(+ : res) \
39 schedule(static) if (backend == Backend::omp)
40#endif
41 for (idx i = 0; i < n; ++i) {
42 real ri = b[i];
43 for (idx j = 0; j < n; ++j)
44 ri -= A(i, j) * x[j];
45 res += ri * ri;
46 }
47 result.residual = std::sqrt(res);
48 result.iterations = iter + 1;
49
50 if (result.residual < tol) {
51 result.converged = true;
52 break;
53 }
54 }
55 return result;
56}
57
58} // namespace num
constexpr idx size() const noexcept
Definition vector.hpp:80
Dense row-major matrix with optional GPU storage.
Definition matrix.hpp:12
constexpr idx rows() const noexcept
Definition matrix.hpp:24
constexpr idx cols() const noexcept
Definition matrix.hpp:25
Gauss-Seidel iterative solver.
double real
Definition types.hpp:10
Backend
Selects which backend handles a linalg operation.
Definition policy.hpp:19
std::size_t idx
Definition types.hpp:11
constexpr real e
Definition math.hpp:43
SolverResult gauss_seidel(const Matrix &A, const Vector &b, Vector &x, real tol=1e-10, idx max_iter=1000, Backend backend=default_backend)
Gauss-Seidel iterative solver for Ax = b.