iterative-solver 0.0
IterativeSolver.h
1#ifndef LINEARALGEBRA_SRC_MOLPRO_LINALG_ITSOLV_ITERATIVESOLVER_H
2#define LINEARALGEBRA_SRC_MOLPRO_LINALG_ITSOLV_ITERATIVESOLVER_H
3#include <molpro/linalg/array/ArrayHandler.h>
4#include <molpro/linalg/array/Span.h>
5#include <molpro/linalg/itsolv/Options.h>
6#include <molpro/linalg/itsolv/Statistics.h>
7#include <molpro/linalg/itsolv/subspace/Dimensions.h>
8#include <molpro/linalg/itsolv/wrap.h>
9#include <molpro/linalg/itsolv/Logger.h>
10
11#include <molpro/linalg/array/DistrArray.h>
12#include <molpro/linalg/array/util/Distribution.h>
13
14#include <memory>
15#include <ostream>
16#include <vector>
17
18namespace molpro::profiler {
19class Profiler;
20}
21namespace molpro::linalg::itsolv {
22
23template <typename T>
25 template <typename C>
26 constexpr static std::true_type test(typename C::iterator*);
27
28 template <typename>
29 constexpr static std::false_type test(...);
30
31 constexpr static bool value =
32 std::is_same<std::true_type, decltype(test<typename std::remove_reference<T>::type>(0))>::value;
33};
34
35template <typename T, typename = std::enable_if_t<std::is_base_of<molpro::linalg::array::DistrArray, T>::value>>
36void precondition_default(const VecRef<T>& action, const std::vector<double>& shift, const T& diagonals) {
37 auto diagonals_local_buffer = diagonals.local_buffer();
38 for (size_t k = 0; k < action.size(); k++) {
39 auto action_local_buffer = action[k].get().local_buffer();
40 auto& distribution = action[k].get().distribution();
41 auto range = distribution.range(molpro::mpi::rank_global());
42 for (auto i = range.first; i < range.second; i++)
43 (*action_local_buffer)[i - range.first] /= ((*diagonals_local_buffer)[i - range.first] - shift[k] + 1e-15);
44 }
45}
46
47template <class T>
48void precondition_default(const VecRef<T>& action, const std::vector<double>& shift, const T& diagonals,
49 typename T::iterator* = nullptr // SFINAE
50) {
51 for (size_t k = 0; k < action.size(); k++) {
52 auto& a = action[k].get();
53 std::transform(diagonals.begin(), diagonals.end(), a.begin(), a.begin(),
54 [shift, k](const auto& first, const auto& second) { return second / (first - shift[k] + 1e-15); });
55 }
56}
57
58template <typename T, typename = std::enable_if_t<!std::is_base_of<molpro::linalg::array::DistrArray, T>::value>,
59 class = void>
60void precondition_default(const VecRef<T>& action, const std::vector<double>& shift, const T& diagonals,
61 typename std::enable_if<!has_iterator<T>::value, void*>::type = nullptr // SFINAE
62) {
63 throw std::logic_error("Unimplemented preconditioner");
64}
65
77template <typename R, typename P = std::map<size_t, typename R::value_type>>
78class Problem {
79public:
80 Problem() = default;
81 virtual ~Problem() = default;
82 using container_t = R;
83 using p_container_t = P;
84 using value_t = typename R::value_type;
85
94 virtual value_t residual(const R& parameters, R& residual) const { return 0; }
95
102 virtual void action(const CVecRef<R>& parameters, const VecRef<R>& action) const { return; }
103
114 virtual bool diagonals(container_t& d) const { return false; }
115
125 virtual void precondition(const VecRef<R>& residual, const std::vector<value_t>& shift) const { return; }
126
137 virtual void precondition(const VecRef<R>& residual, const std::vector<value_t>& shift, const R& diagonals) const {
139 }
140
148 virtual bool RHS(R& RHS, unsigned int instance) const { return false;}
149
155 virtual std::vector<double> pp_action_matrix(const std::vector<P>& pparams) const {
156 if (not pparams.empty())
157 throw std::logic_error("P-space unavailable: unimplemented pp_action_matrix() in Problem class");
158 return std::vector<double>(0);
159 }
160
167 virtual void p_action(const std::vector<std::vector<value_t>>& p_coefficients, const CVecRef<P>& pparams,
168 const VecRef<container_t>& actions) const {
169 if (not pparams.empty())
170 throw std::logic_error("P-space unavailable: unimplemented p_action() in Problem class");
171 }
172
182 virtual bool test_parameters(unsigned int instance, R& parameters) const { return false; }
183};
184
201template <class R, class Q, class P>
203public:
204 using value_type = typename R::value_type;
208 using VectorP = std::vector<value_type>;
213 using fapply_on_p_type = std::function<void(const std::vector<VectorP>&, const CVecRef<P>&, const VecRef<R>&)>;
214
215 virtual ~IterativeSolver() = default;
216 IterativeSolver() = default;
220 IterativeSolver<R, Q, P>& operator=(IterativeSolver<R, Q, P>&&) noexcept = default;
221
249 virtual bool solve(const VecRef<R>& parameters, const VecRef<R>& actions, const Problem<R>& problem,
250 bool generate_initial_guess = false) = 0;
251 virtual bool solve(R& parameters, R& actions, const Problem<R>& problem, bool generate_initial_guess = false) = 0;
252 virtual bool solve(std::vector<R>& parameters, std::vector<R>& actions, const Problem<R>& problem,
253 bool generate_initial_guess = false) = 0;
254
265 virtual int add_vector(const VecRef<R>& parameters, const VecRef<R>& actions) = 0;
266
267 // FIXME this should be removed in favour of VecRef interface
268 virtual int add_vector(std::vector<R>& parameters, std::vector<R>& action) = 0;
269 virtual int add_vector(R& parameters, R& action, value_type value = 0) = 0;
270
285 virtual size_t add_p(const CVecRef<P>& pparams, const array::Span<value_type>& pp_action_matrix,
286 const VecRef<R>& parameters, const VecRef<R>& action, fapply_on_p_type apply_p) = 0;
287
288 // FIXME Is this needed?
289 virtual void clearP() = 0;
290
292 virtual void solution(const std::vector<int>& roots, const VecRef<R>& parameters, const VecRef<R>& residual) = 0;
293
295 virtual void solution_params(const std::vector<int>& roots, const VecRef<R>& parameters) = 0;
296
298 virtual size_t end_iteration(const VecRef<R>& parameters, const VecRef<R>& residual) = 0;
299
303 virtual bool end_iteration_needed() = 0;
304
315 virtual std::vector<size_t> suggest_p(const CVecRef<R>& solution, const CVecRef<R>& residual, size_t max_number,
316 double threshold) = 0;
317
318 virtual void solution(const std::vector<int>& roots, std::vector<R>& parameters, std::vector<R>& residual) = 0;
319 virtual void solution(R& parameters, R& residual) = 0;
320 virtual void solution_params(const std::vector<int>& roots, std::vector<R>& parameters) = 0;
321 virtual void solution_params(R& parameters) = 0;
322 virtual size_t end_iteration(std::vector<R>& parameters, std::vector<R>& action) = 0;
323 virtual size_t end_iteration(R& parameters, R& action) = 0;
324
328 virtual const std::vector<int>& working_set() const = 0;
331 virtual std::vector<scalar_type> working_set_eigenvalues() const {
332 return std::vector<scalar_type>(working_set().size(), 0);
333 }
336 virtual size_t n_roots() const = 0;
337 virtual void set_n_roots(size_t nroots) = 0;
338 virtual const std::vector<scalar_type>& errors() const = 0;
339 virtual const Statistics& statistics() const = 0;
341 virtual void report(std::ostream& cout, bool endl = true) const = 0;
343 virtual void report() const = 0;
344
346 virtual void set_convergence_threshold(double thresh) = 0;
348 virtual double convergence_threshold() const = 0;
350 virtual void set_convergence_threshold_value(double thresh) = 0;
352 virtual double convergence_threshold_value() const = 0;
353 [[deprecated("Set the verbosity on the logger directly")]]
354 virtual void set_verbosity(Verbosity v) = 0;
355 virtual void set_verbosity(int v) = 0;
356 [[deprecated("Query the logger directly")]]
357 virtual Verbosity get_verbosity() const = 0;
358 virtual void set_max_iter(int n) = 0;
359 virtual int get_max_iter() const = 0;
360 virtual void set_max_p(int n) = 0;
361 virtual int get_max_p() const = 0;
362 virtual void set_p_threshold(double thresh) = 0;
363 virtual double get_p_threshold() const = 0;
364 virtual const subspace::Dimensions& dimensions() const = 0;
365 // FIXME Missing parameters: SVD threshold
368 virtual void set_options(const Options& options) = 0;
371 virtual std::shared_ptr<Options> get_options() const = 0;
376 virtual scalar_type value() const = 0;
381 virtual bool nonlinear() const = 0;
387 virtual const std::shared_ptr<molpro::profiler::Profiler>& profiler() const = 0;
392 virtual void set_logger(std::shared_ptr<Logger> logger) = 0;
393 virtual Logger &logger() = 0;
403 virtual bool test_problem(const Problem<R>& problem, R& v0, R& v1, int verbosity = 0,
404 double threshold = 1e-5) const = 0;
405};
406
411template <class R, class Q, class P>
412class LinearEigensystem : public IterativeSolver<R, Q, P> {
413public:
416 virtual std::vector<scalar_type> eigenvalues() const = 0;
418 virtual void set_hermiticity(bool hermitian) = 0;
420 virtual bool get_hermiticity() const = 0;
421};
422
423template <class R, class Q, class P>
424class LinearEquations : public IterativeSolver<R, Q, P> {
425public:
427 virtual void add_equations(const CVecRef<R>& rhs) = 0;
428 virtual void add_equations(const std::vector<R>& rhs) = 0;
429 virtual void add_equations(const R& rhs) = 0;
430 virtual CVecRef<Q> rhs() const = 0;
432 virtual void set_hermiticity(bool hermitian) = 0;
434 virtual bool get_hermiticity() const = 0;
435};
436
438template <class R, class Q, class P>
439class Optimize : public IterativeSolver<R, Q, P> {};
440
442template <class R, class Q, class P>
443class NonLinearEquations : public IterativeSolver<R, Q, P> {};
444
445} // namespace molpro::linalg::itsolv
446
447#endif // LINEARALGEBRA_SRC_MOLPRO_LINALG_ITSOLV_ITERATIVESOLVER_H
decltype(value_type_L{} *value_type_R{}) value_type
Definition: ArrayHandler.h:181
decltype(check_abs< value_type >()) value_type_abs
Definition: ArrayHandler.h:182
Base class defining the interface common to all iterative solvers.
Definition: IterativeSolver.h:202
typename R::value_type value_type
The underlying type of elements of vectors.
Definition: IterativeSolver.h:204
virtual void set_profiler(molpro::profiler::Profiler &profiler)=0
Attach a profiler in order to collect performance data.
virtual void report() const =0
Writes a report to std::cout.
IterativeSolver(const IterativeSolver< R, Q, P > &)=delete
typename array::ArrayHandler< R, R >::value_type_abs value_type_abs
Definition: IterativeSolver.h:207
virtual scalar_type value() const =0
Report the function value for the current optimum solution.
virtual void set_verbosity(Verbosity v)=0
virtual bool test_problem(const Problem< R > &problem, R &v0, R &v1, int verbosity=0, double threshold=1e-5) const =0
Test a supplied problem class.
virtual void report(std::ostream &cout, bool endl=true) const =0
Writes a report to cout output stream.
virtual double convergence_threshold_value() const =0
Reports the value convergence threshold.
virtual double get_p_threshold() const =0
IterativeSolver(IterativeSolver< R, Q, P > &&) noexcept=default
virtual void set_p_threshold(double thresh)=0
typename array::ArrayHandler< R, Q >::value_type scalar_type
Definition: IterativeSolver.h:206
virtual void solution(const std::vector< int > &roots, const VecRef< R > &parameters, const VecRef< R > &residual)=0
Construct solution and residual for a given set of roots.
virtual bool solve(const VecRef< R > &parameters, const VecRef< R > &actions, const Problem< R > &problem, bool generate_initial_guess=false)=0
Simplified one-call solver.
virtual const subspace::Dimensions & dimensions() const =0
virtual void set_n_roots(size_t nroots)=0
virtual void solution_params(const std::vector< int > &roots, const VecRef< R > &parameters)=0
Constructs parameters of selected roots.
std::function< void(const std::vector< VectorP > &, const CVecRef< P > &, const VecRef< R > &)> fapply_on_p_type
Definition: IterativeSolver.h:213
virtual bool nonlinear() const =0
Report whether the class is a non-linear solver.
virtual int add_vector(const VecRef< R > &parameters, const VecRef< R > &actions)=0
Take, typically, a current solution and residual, and add it to the solution space.
virtual void set_options(const Options &options)=0
std::vector< value_type > VectorP
Definition: IterativeSolver.h:210
virtual const std::shared_ptr< molpro::profiler::Profiler > & profiler() const =0
virtual size_t add_p(const CVecRef< P > &pparams, const array::Span< value_type > &pp_action_matrix, const VecRef< R > &parameters, const VecRef< R > &action, fapply_on_p_type apply_p)=0
Add P-space vectors to the expansion set for linear methods.
virtual double convergence_threshold() const =0
Reports the convergence threshold.
virtual Verbosity get_verbosity() const =0
IterativeSolver< R, Q, P > & operator=(const IterativeSolver< R, Q, P > &)=delete
virtual std::vector< scalar_type > working_set_eigenvalues() const
Definition: IterativeSolver.h:331
virtual bool end_iteration_needed()=0
signal whether end_iteration should be called
virtual size_t end_iteration(const VecRef< R > &parameters, const VecRef< R > &residual)=0
Behaviour depends on the solver.
virtual std::shared_ptr< Options > get_options() const =0
virtual void set_logger(std::shared_ptr< Logger > logger)=0
Set the logger instance that shall be used.
virtual void set_convergence_threshold_value(double thresh)=0
Sets the value convergence threshold.
virtual void set_convergence_threshold(double thresh)=0
Sets the convergence threshold.
virtual const Statistics & statistics() const =0
virtual const std::vector< scalar_type > & errors() const =0
virtual std::vector< size_t > suggest_p(const CVecRef< R > &solution, const CVecRef< R > &residual, size_t max_number, double threshold)=0
Get the solver's suggestion of which degrees of freedom would be best to add to the P-space.
virtual size_t n_roots() const =0
virtual const std::vector< int > & working_set() const =0
Working set of roots that are not yet converged.
Interface for a specific iterative solver, it can add special member functions or variables.
Definition: IterativeSolver.h:412
virtual bool get_hermiticity() const =0
Gets hermiticity of kernel, if true than it is hermitian, otherwise it is not.
virtual void set_hermiticity(bool hermitian)=0
Sets hermiticity of kernel.
virtual std::vector< scalar_type > eigenvalues() const =0
The calculated eigenvalues of the subspace matrix.
Definition: IterativeSolver.h:424
virtual void add_equations(const CVecRef< R > &rhs)=0
virtual void add_equations(const std::vector< R > &rhs)=0
virtual bool get_hermiticity() const =0
Gets hermiticity of kernel, if true than it is hermitian, otherwise it is not.
virtual CVecRef< Q > rhs() const =0
virtual void set_hermiticity(bool hermitian)=0
Sets hermiticity of kernel.
virtual void add_equations(const R &rhs)=0
Definition: Logger.h:428
Solves non-linear system of equations using methods such as DIIS.
Definition: IterativeSolver.h:443
Optimises to a stationary point using methods such as L-BFGS.
Definition: IterativeSolver.h:439
Abstract class defining the problem-specific interface for the simplified solver interface to Iterati...
Definition: IterativeSolver.h:78
virtual void action(const CVecRef< R > &parameters, const VecRef< R > &action) const
Calculate the action of the kernel matrix on a set of parameters. Used by linear solvers,...
Definition: IterativeSolver.h:102
R container_t
Definition: IterativeSolver.h:82
virtual std::vector< double > pp_action_matrix(const std::vector< P > &pparams) const
Calculate the kernel matrix in the P space.
Definition: IterativeSolver.h:155
P p_container_t
Definition: IterativeSolver.h:83
virtual void precondition(const VecRef< R > &residual, const std::vector< value_t > &shift) const
Apply preconditioning to a residual vector in order to predict a step towards the solution.
Definition: IterativeSolver.h:125
typename R::value_type value_t
Definition: IterativeSolver.h:84
virtual bool diagonals(container_t &d) const
Optionally provide the diagonal elements of the underlying kernel. If implemented and returning true,...
Definition: IterativeSolver.h:114
virtual void p_action(const std::vector< std::vector< value_t > > &p_coefficients, const CVecRef< P > &pparams, const VecRef< container_t > &actions) const
Calculate the action of the kernel matrix on a set of vectors in the P space.
Definition: IterativeSolver.h:167
virtual value_t residual(const R &parameters, R &residual) const
Calculate the residual vector. Used by non-linear solvers (NonLinearEquations, Optimize) only.
Definition: IterativeSolver.h:94
virtual bool test_parameters(unsigned int instance, R &parameters) const
Provide values of R vectors for testing the problem class. For use in a non-linear solver,...
Definition: IterativeSolver.h:182
virtual bool RHS(R &RHS, unsigned int instance) const
Return the inhomogeneous part of a linear equation system.
Definition: IterativeSolver.h:148
virtual void precondition(const VecRef< R > &residual, const std::vector< value_t > &shift, const R &diagonals) const
Apply preconditioning to a residual vector in order to predict a step towards the solution.
Definition: IterativeSolver.h:137
4-parameter interpolation of a 1-dimensional function given two points for which function values and ...
Definition: helper.h:11
void precondition_default(const VecRef< T > &action, const std::vector< double > &shift, const T &diagonals)
Definition: IterativeSolver.h:36
std::vector< std::reference_wrapper< const A > > CVecRef
Definition: wrap.h:14
std::vector< std::reference_wrapper< A > > VecRef
Definition: wrap.h:11
Verbosity
Specifies how much detail IterativeSolver::solve should write to output.
Definition: Options.h:12
const std::shared_ptr< const molpro::Options > options()
Get the Options object associated with iterative-solver.
Definition: options.cpp:4
profiler::Profiler Profiler
Access point for different options in iterative solvers.
Definition: Options.h:20
Information about performance of IterativeSolver instance.
Definition: Statistics.h:10
Definition: IterativeSolver.h:24
static constexpr bool value
Definition: IterativeSolver.h:31
static constexpr std::true_type test(typename C::iterator *)
static constexpr std::false_type test(...)
Stores partitioning of XSpace into P, Q and R blocks with sizes and offsets for each one.
Definition: Dimensions.h:8