10#ifndef CONJUGATE_GRADIENT_HPP
11#define CONJUGATE_GRADIENT_HPP
23#if defined(__GNUC__) && !defined(__clang__)
24# pragma GCC diagnostic push
25# pragma GCC diagnostic ignored "-Walloc-size-larger-than="
49 Vector0(
const std::vector<double>& v) : data(v) {}
65 const double&
operator[](
size_t i)
const {
return data[i]; }
72 size_t size()
const {
return data.size(); }
81 for (
size_t i = 0; i <
size(); ++i) data[i] += rhs[i];
91 for (
size_t i = 0; i <
size(); ++i) data[i] -= rhs[i];
101 for (
auto& val : data) val *= scalar;
113 for (
size_t i = 0; i <
size(); ++i)
sum += data[i] * other[i];
122 double norm()
const {
return std::sqrt(
dot(*
this)); }
125 std::vector<double> data;
195 std::vector<double>&
operator[](
size_t i) {
return data[i]; }
203 const std::vector<double>&
operator[](
size_t i)
const {
return data[i]; }
210 size_t rows()
const {
return data.size(); }
217 size_t cols()
const {
return data[0].size(); }
227 for (
size_t i = 0; i <
rows(); ++i) {
228 for (
size_t j = 0; j <
cols(); ++j) {
229 result[i] += data[i][j] * v[j];
236 std::vector<std::vector<double>> data;
286template <
typename Matrix0,
typename Vector0>
288 double tol = 1e-5,
int max_iter = 1000) {
289 size_t ndim = b.
size();
294 double r_norm_sq = residual.
dot(residual);
296 for (
int i = 0; i < max_iter; ++i) {
298 double alpha = r_norm_sq / director.
dot(Ap);
299 x_vector += alpha * director;
300 residual -= alpha * Ap;
301 double r_norm_sq_new = residual.
dot(residual);
303 if (std::sqrt(r_norm_sq_new) < tol) {
307 double beta = r_norm_sq_new / r_norm_sq;
308 director = residual + beta * director;
309 r_norm_sq = r_norm_sq_new;
312 throw std::runtime_error(
"Conjugate Gradient did not converge after " + std::to_string(max_iter)
316#if defined(__GNUC__) && !defined(__clang__)
317# pragma GCC diagnostic pop
double sum(const Arr &a)
Sum of all elements.
Definition arr.hpp:260
A simple matrix class for conjugate gradient calculations.
Definition conjugate_gradient.hpp:179
size_t cols() const
Get the number of columns.
Definition conjugate_gradient.hpp:217
const std::vector< double > & operator[](size_t i) const
Access row i of the matrix (const version)
Definition conjugate_gradient.hpp:203
Vector0 dot(const Vector0 &v) const
Multiply the matrix by a vector.
Definition conjugate_gradient.hpp:225
std::vector< double > & operator[](size_t i)
Access row i of the matrix.
Definition conjugate_gradient.hpp:195
size_t rows() const
Get the number of rows.
Definition conjugate_gradient.hpp:210
Matrix0(size_t rows, size_t cols)
Construct a new Matrix0 object.
Definition conjugate_gradient.hpp:187
A simple vector class for conjugate gradient calculations.
Definition conjugate_gradient.hpp:35
Vector0 & operator*=(double scalar)
Multiply this vector by a scalar.
Definition conjugate_gradient.hpp:100
const double & operator[](size_t i) const
Access element at index i (const version)
Definition conjugate_gradient.hpp:65
Vector0(size_t size)
Construct a new Vector0 object with given size.
Definition conjugate_gradient.hpp:42
double norm() const
Compute the L2 norm of the vector.
Definition conjugate_gradient.hpp:122
Vector0 & operator-=(const Vector0 &rhs)
Subtract another vector from this vector.
Definition conjugate_gradient.hpp:90
double & operator[](size_t i)
Access element at index i.
Definition conjugate_gradient.hpp:57
double dot(const Vector0 &other) const
Compute the dot product with another vector.
Definition conjugate_gradient.hpp:111
Vector0(const std::vector< double > &v)
Construct a new Vector0 from a std::vector.
Definition conjugate_gradient.hpp:49
size_t size() const
Get the size of the vector.
Definition conjugate_gradient.hpp:72
Vector0 & operator+=(const Vector0 &rhs)
Add another vector to this vector.
Definition conjugate_gradient.hpp:80
Vector0 operator+(Vector0 lhs, const Vector0 &rhs)
Element-wise vector addition.
Definition conjugate_gradient.hpp:135
Vector0 operator*(Vector0 v, double scalar)
Scalar-vector multiplication (vector * scalar)
Definition conjugate_gradient.hpp:159
Vector0 operator-(Vector0 lhs, const Vector0 &rhs)
Element-wise vector subtraction.
Definition conjugate_gradient.hpp:147
Vector0 conjugate_gradient(const Matrix0 &A, const Vector0 &b, const Vector0 *x0=nullptr, double tol=1e-5, int max_iter=1000)
Solve Ax = b using the conjugate gradient method.
Definition conjugate_gradient.hpp:287