EllAlgo 1.6.13
Loading...
Searching...
No Matches
conjugate_gradient2.hpp
Go to the documentation of this file.
1
9#ifndef CONJUGATE_GRADIENT2_HPP
10#define CONJUGATE_GRADIENT2_HPP
11
12#include <cmath>
13#include <stdexcept>
14#include <string>
15
16// GCC 13 with -Wall -Werror emits -Werror=alloc-size-larger-than= when a size_t
17// parameter is passed to std::vector constructor, because the compiler can't prove
18// the allocation won't exceed PTRDIFF_MAX. This is a false positive when sizes
19// are bounded by actual matrix dimensions at runtime.
20#if defined(__GNUC__) && !defined(__clang__)
21# pragma GCC diagnostic push
22# pragma GCC diagnostic ignored "-Walloc-size-larger-than="
23#endif
24
51template <typename Matrix, typename Vector>
52Vector conjugate_gradient2(const Matrix& A, const Vector& b, Vector& x_vector, double tol = 1e-5,
53 int max_iter = 1000) {
54 using T = typename Vector::value_type;
55
56 Vector residual = b - A * x_vector;
57 Vector director = residual;
58 T r_norm_sq = residual.dot(residual);
59
60 for (int i = 0; i < max_iter; ++i) {
61 Vector Ap = A * director;
62 T alpha = r_norm_sq / director.dot(Ap);
63 x_vector += alpha * director;
64 residual -= alpha * Ap;
65 T r_norm_sq_new = residual.dot(residual);
66
67 if (std::sqrt(r_norm_sq_new) < tol) {
68 return x_vector;
69 }
70
71 T beta = r_norm_sq_new / r_norm_sq;
72 director = residual + beta * director;
73 r_norm_sq = r_norm_sq_new;
74 }
75
76 throw std::runtime_error("Conjugate Gradient did not converge after " + std::to_string(max_iter)
77 + " iterations");
78}
79
80#if defined(__GNUC__) && !defined(__clang__)
81# pragma GCC diagnostic pop
82#endif
83
84#endif // CONJUGATE_GRADIENT_HPP
Square matrix with flat std::vector<double> storage.
Definition ell_matrix.hpp:63
Vector conjugate_gradient2(const Matrix &A, const Vector &b, Vector &x_vector, double tol=1e-5, int max_iter=1000)
Definition conjugate_gradient2.hpp:52