42struct ConjugateGradientSolverParams
44 using params = ConjugateGradientSolverParams;
53 double abstol = std::numeric_limits<double>::min();
65 ConjugateGradientSolverParams() =
default;
68 : ARCCORE_ALINA_PARAMS_IMPORT_VALUE(p,
maxiter)
69 , ARCCORE_ALINA_PARAMS_IMPORT_VALUE(p,
tol)
70 , ARCCORE_ALINA_PARAMS_IMPORT_VALUE(p,
abstol)
71 , ARCCORE_ALINA_PARAMS_IMPORT_VALUE(p,
ns_search)
72 , ARCCORE_ALINA_PARAMS_IMPORT_VALUE(p,
verbose)
74 p.check_params({
"maxiter",
"tol",
"abstol",
"ns_search",
"verbose" });
79 ARCCORE_ALINA_PARAMS_EXPORT_VALUE(p, path,
maxiter);
80 ARCCORE_ALINA_PARAMS_EXPORT_VALUE(p, path,
tol);
81 ARCCORE_ALINA_PARAMS_EXPORT_VALUE(p, path,
abstol);
82 ARCCORE_ALINA_PARAMS_EXPORT_VALUE(p, path,
ns_search);
83 ARCCORE_ALINA_PARAMS_EXPORT_VALUE(p, path,
verbose);
100 using Backend = Backend_;
101 using backend_type = Backend;
102 using BackendType = Backend;
104 typedef typename Backend::vector vector;
105 typedef typename Backend::value_type value_type;
108 typedef typename math::scalar_of<value_type>::type scalar_type;
111 typename math::rhs_of<value_type>::type>::return_type coef_type;
118 const params& prm = params(),
119 const backend_params& backend_prm = backend_params(),
120 const InnerProduct& inner_product = InnerProduct())
121 : SolverBase(context)
124 , r(Backend::create_vector(n, backend_prm))
125 , s(Backend::create_vector(n, backend_prm))
126 , p(Backend::create_vector(n, backend_prm))
127 , q(Backend::create_vector(n, backend_prm))
128 , inner_product(inner_product)
143 template <
class Matrix,
class Precond,
class Vec1,
class Vec2>
144 SolverResult operator()(
const Matrix& A,
const Precond& P,
const Vec1& rhs, Vec2&& x)
const
146 static const coef_type one = math::identity<coef_type>();
147 static const coef_type zero = math::zero<coef_type>();
151 scalar_type norm_rhs = norm(rhs);
152 if (norm_rhs < Alina::detail::eps<scalar_type>(1)) {
154 norm_rhs = math::identity<scalar_type>();
158 return SolverResult(0, norm_rhs);
162 scalar_type eps = std::max(prm.tol * norm_rhs, prm.abstol);
164 coef_type rho1 = 2 * eps * one;
165 coef_type rho2 = zero;
167 backend::residual(rhs, A, x, *r);
168 scalar_type res_norm = norm(*r);
171 for (; iter < prm.maxiter && math::norm(res_norm) > eps; ++iter) {
175 rho1 = inner_product(*r, *s);
178 backend::axpby(one, *s, rho1 / rho2, *p);
180 backend::copy(*s, *p);
182 backend::spmv(one, A, *p, zero, *q);
184 coef_type alpha = rho1 / inner_product(*q, *p);
186 backend::axpby(alpha, *p, one, x);
187 backend::axpby(-alpha, *q, one, *r);
191 std::cout << iter <<
"\t" << std::scientific << res_norm / norm_rhs << std::endl;
194 return SolverResult(iter, res_norm / norm_rhs);
207 template <
class Precond,
class Vec1,
class Vec2>
210 return (*
this)(P.system_matrix(), P, rhs, x);
215 return backend::bytes(*r) +
223 return os <<
"Type: CG"
224 <<
"\nUnknowns: " << s.n
225 <<
"\nMemory footprint: " << human_readable_memory(s.
bytes())
226 <<
"\nparams: maxiter " << s.prm.
maxiter
227 <<
"\nparams: tol " << s.prm.
tol
228 <<
"\nparams: abstol " << s.prm.
abstol
229 <<
"\nparams: ns_search " << s.prm.
ns_search
230 <<
"\nparams: verbose " << s.prm.
verbose
242 std::shared_ptr<vector> r;
243 std::shared_ptr<vector> s;
244 std::shared_ptr<vector> p;
245 std::shared_ptr<vector> q;
247 InnerProduct inner_product;
250 scalar_type norm(
const Vec& x)
const
252 return sqrt(math::norm(inner_product(x, x)));
ConjugateGradientSolver(const AlinaContext &context, size_t n, const params &prm=params(), const backend_params &backend_prm=backend_params(), const InnerProduct &inner_product=InnerProduct())
Preallocates necessary data structures for the system of size n.