numerics 0.1.0
Loading...
Searching...
No Matches
cg.hpp
Go to the documentation of this file.
1/// @file cg.hpp
2/// @brief Conjugate gradient solvers.
3///
4/// Solves \f$Ax=b\f$ for symmetric positive definite \f$A\f$ using
5/// \f$\mathcal{K}_k(A,r_0)=\mathrm{span}\{r_0,Ar_0,\ldots,A^{k-1}r_0\}\f$.
6#pragma once
7#include "core/matrix.hpp"
8#include "core/policy.hpp"
9#include "core/vector.hpp"
11#include "operator/concepts.hpp"
12#include <cmath>
13#include <stdexcept>
14
15namespace num {
16
17SolverResult cg(const Matrix& A,
18 const Vector& b,
19 Vector& x,
20 real tol = 1e-10,
21 idx max_iter = 1000,
22 Backend backend = default_backend);
23
24/// @brief Operator CG for any \f$y=A x\f$ adapter.
25template<class Op>
26 requires operators::LinearOperator<Op, Vector, Vector>
27SolverResult cg(const Op& A,
28 const Vector& b,
29 Vector& x,
30 real tol = 1e-10,
31 idx max_iter = 1000,
32 Backend backend = default_backend) {
33 const idx n = b.size();
34 if (A.rows() != n || A.cols() != n || x.size() != n) {
35 throw std::invalid_argument("Dimension mismatch in operator CG solver");
36 }
37
38 Vector r(n), p(n), Ap(n);
39 A.apply(x, r);
40 for (idx i = 0; i < n; ++i) {
41 r[i] = b[i] - r[i];
42 p[i] = r[i];
43 }
44
45 real rsold = dot(r, r, backend);
46 SolverResult result{0, std::sqrt(rsold), false};
47
48 for (idx iter = 0; iter < max_iter; ++iter) {
49 result.iterations = iter + 1;
50 A.apply(p, Ap);
51
52 const real pAp = dot(p, Ap, backend);
53 if (std::abs(pAp) < real(1e-15)) {
54 break;
55 }
56 const real alpha = rsold / pAp;
57
58 axpy(alpha, p, x, backend);
59 axpy(-alpha, Ap, r, backend);
60
61 const real rsnew = dot(r, r, backend);
62 result.residual = std::sqrt(rsnew);
63 if (result.residual < tol) {
64 result.converged = true;
65 break;
66 }
67
68 const real beta = rsnew / rsold;
69 scale(p, beta, backend);
70 axpy(real(1), r, p, backend);
71 rsold = rsnew;
72 }
73 return result;
74}
75
76} // namespace num
constexpr idx size() const noexcept
Definition vector.hpp:83
Backend enum and default backend selection.
Dense row-major matrix templated over scalar type T.
double real
Definition types.hpp:10
Backend
Definition policy.hpp:7
real beta(real a, real b)
B(a, b) – beta function.
Definition math.hpp:248
std::size_t idx
Definition types.hpp:11
void scale(Vector &v, real alpha, Backend b=default_backend)
Compute .
Definition vector.cpp:15
BasicMatrix< real > Matrix
Double-precision dense matrix with full backend dispatch (CPU + GPU).
Definition matrix.hpp:127
real dot(const Vector &x, const Vector &y, Backend b=default_backend)
Compute .
Definition vector.cpp:65
constexpr real e
Definition math.hpp:44
BasicVector< real > Vector
Real-valued dense vector with full backend dispatch (CPU + GPU)
Definition vector.hpp:129
void axpy(real alpha, const Vector &x, Vector &y, Backend b=default_backend)
Compute .
Definition vector.cpp:44
constexpr Backend default_backend
Definition policy.hpp:53
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
Concepts for operator-oriented numerical algorithms.
Common result type shared by all iterative solvers.
idx iterations
Number of iterations performed.
Dense vector storage and operations.