numerics
Loading...
Searching...
No Matches
jacobi.cpp
Go to the documentation of this file.
2#include <cmath>
3#include <stdexcept>
4
5namespace num {
6
8 real tol, idx max_iter, Backend backend) {
9 constexpr real zero_diag_tol = 1e-15;
10 idx n = b.size();
11 if (A.rows() != n || A.cols() != n || x.size() != n)
12 throw std::invalid_argument("Dimension mismatch in Jacobi solver");
13
14 Vector x_new(n);
15 SolverResult result{0, 0.0, false};
16
17 for (idx iter = 0; iter < max_iter; ++iter) {
18 // Compute all updates from the previous iterate simultaneously
19#ifdef NUMERICS_HAS_OMP
20 #pragma omp parallel for schedule(static) if(backend == Backend::omp)
21#endif
22 for (idx i = 0; i < n; ++i) {
23 if (std::abs(A(i, i)) < zero_diag_tol)
24 throw std::runtime_error("Zero diagonal in Jacobi solver at row " +
25 std::to_string(i));
26 real sigma = 0.0;
27 for (idx j = 0; j < n; ++j)
28 if (j != i) sigma += A(i, j) * x[j];
29 x_new[i] = (b[i] - sigma) / A(i, i);
30 }
31
32 for (idx i = 0; i < n; ++i) x[i] = x_new[i];
33
34 // Residual ||b - Ax||
35 real res = 0.0;
36#ifdef NUMERICS_HAS_OMP
37 #pragma omp parallel for reduction(+:res) schedule(static) if(backend == Backend::omp)
38#endif
39 for (idx i = 0; i < n; ++i) {
40 real ri = b[i];
41 for (idx j = 0; j < n; ++j) ri -= A(i, j) * x[j];
42 res += ri * ri;
43 }
44 result.residual = std::sqrt(res);
45 result.iterations = iter + 1;
46
47 if (result.residual < tol) {
48 result.converged = true;
49 break;
50 }
51 }
52 return result;
53}
54
55} // namespace num
constexpr idx size() const noexcept
Definition vector.hpp:77
Dense row-major matrix with optional GPU storage.
Definition matrix.hpp:12
Jacobi iterative solver.
double real
Definition types.hpp:10
Backend
Selects which backend handles a linalg operation.
Definition policy.hpp:19
constexpr T ipow(T x) noexcept
Compute x^N at compile time via repeated squaring.
std::size_t idx
Definition types.hpp:11
constexpr real e
Definition math.hpp:41
SolverResult jacobi(const Matrix &A, const Vector &b, Vector &x, real tol=1e-10, idx max_iter=1000, Backend backend=default_backend)
Jacobi iterative solver for Ax = b.
Definition jacobi.cpp:7