1 #ifndef SOPT_CONJUGATE_GRADIENT
2 #define SOPT_CONJUGATE_GRADIENT
4 #include "sopt/config.h"
48 template <
typename VECTOR,
typename T1,
typename T2>
50 Eigen::MatrixBase<T2>
const &
b)
const {
51 return implementation(x, A,
b);
56 template <
typename VECTOR,
typename T1,
typename T2>
57 typename std::enable_if<not std::is_base_of<Eigen::EigenBase<T1>, T1>::value, Diagnostic>::type
58 operator()(VECTOR &x, T1
const &A, Eigen::MatrixBase<T2>
const &
b)
const {
59 return implementation(x, details::wrap<typename VECTOR::PlainObject>(A),
b);
64 template <
typename T0,
typename A_TYPE>
66 Eigen::MatrixBase<T0>
const &
b)
const {
83 if (
tolerance <= 0e0)
throw std::domain_error(
"Incorrect tolerance input");
103 template <
typename VECTOR,
typename T1,
typename MATRIXLIKE>
104 Diagnostic implementation(VECTOR &x, MATRIXLIKE
const &A, Eigen::MatrixBase<T1>
const &
b)
const;
107 template <
typename VECTOR,
typename T1,
typename MATRIXLIKE>
108 ConjugateGradient::Diagnostic ConjugateGradient::implementation(
109 VECTOR &x, MATRIXLIKE
const &A, Eigen::MatrixBase<T1>
const &
b)
const {
111 using Real =
typename real_type<Scalar>::type;
114 if (std::abs((
b.transpose().conjugate() *
b)(0)) <
tolerance()) {
124 Real residual = std::abs((residuals.transpose().conjugate() * residuals)(0));
129 Scalar const alpha = residual / (p.transpose().conjugate() * Ap)(0);
131 residuals -= alpha * Ap;
133 Real new_residual = std::abs((residuals.transpose().conjugate() * residuals)(0));
134 SOPT_LOW_LOG(
"CG iteration {} - residuals: {}", i, new_residual);
135 if (std::abs(new_residual) <
tolerance()) {
136 residual = new_residual;
140 p = residuals + new_residual / residual * p;
141 residual = new_residual;
143 return {i, residual, residual <
tolerance()};
Solves $Ax = b$ for $x$, given $A$ and $b$.
void tolerance(t_real const &tolerance)
Sets tolerance criteria.
t_real tolerance() const
Tolerance criteria.
virtual ~ConjugateGradient()
void itermax(t_uint const &itermax)
Sets maximum number of iterations.
ConjugateGradient(t_uint itermax=std::numeric_limits< t_uint >::max(), t_real tolerance=1e-8)
Creates conjugate gradient operator.
t_uint itermax() const
Maximum number of iterations.
std::enable_if< not std::is_base_of< Eigen::EigenBase< T1 >, T1 >::value, Diagnostic >::type operator()(VECTOR &x, T1 const &A, Eigen::MatrixBase< T2 > const &b) const
Computes $x$ for $Ax=b$.
Diagnostic operator()(VECTOR &x, Eigen::MatrixBase< T1 > const &A, Eigen::MatrixBase< T2 > const &b) const
Computes $x$ for $Ax=b$.
DiagnosticAndResult< typename T0::Scalar > operator()(A_TYPE const &A, Eigen::MatrixBase< T0 > const &b) const
Computes $x$ for $Ax=b$.
#define SOPT_LOW_LOG(...)
Low priority message.
double t_real
Root of the type hierarchy for real numbers.
size_t t_uint
Root of the type hierarchy for unsigned integers.
Eigen::Array< T, Eigen::Dynamic, Eigen::Dynamic > Image
A 2-dimensional list of elements of given type.
Eigen::Matrix< T, Eigen::Dynamic, 1 > Vector
A vector of a given type.
Values indicating how the algorithm ran and its result;.
Values indicating how the algorithm ran.
t_uint niters
Number of iterations.
bool good
Wether convergence was achieved.
sopt::Vector< Scalar > Vector